Es posible cargar automáticamente un def implícito si se incluye como dependencia (sin importar)

Estoy trabajando en una biblioteca común que incluye una biblioteca de config (https://github.com/kxbmap/configs). Esta biblioteca de config utiliza "casa de kebab" cuando se analizan los archivos de configuración por defecto y puede ser anulada por un def implícito en alcance.

Sin embargo, no quiero forzar eso en los usuarios de mi biblioteca común cuando tienen acceso a la biblioteca de config transitivamente.

Así que sin mí obligar a los usuarios a importar este implícito, como:

import CommonsConfig._

¿Puedo de alguna manera anular la estrategia de nombramiento a través de un implícito que se pone en alcance sólo incluyendo mi biblioteca común en el ciclista. Supongo que no pero tengo que preguntar:)

Así que si no, ¿alguien es consciente de otro enfoque?

kxbmap/configs no está tan bien documentado para explicar esto.

¡Gracias!

Pregunta hecha hace 3 años, 4 meses, 27 días - Por pixelprodigy50bb


3 Respuestas:

  • Los implícitos trabajan en tiempo de compilación, por lo que no pueden estar mágicamente presentes si algo está incluido y luego desaparecen si no lo es.

    Lo más cercano sería algo como:

    • biblioteca principal
      package my.library
      
      // classes, traits, objects but no package object
      
    • extensión
      package my
      package object library {
        // implicits
      }
      
    • código del usuario
      import my.library._
      

    sin embargo eso sólo funcionaría si no hubiera un objeto de paquete en la biblioteca principal, sólo una biblioteca de extensión podría tirar de este truco a la vez (Scala no le gusta más de un objeto de paquete) y el usuario tendría que importar todo lo disponible con un paquete, siempre.

    En teoría podrías crear un envoltorio alrededor de todos tus deps, con tus propios configs:

    final case class MyLibConfig(configsCfg: DerivationConfig)
    object MyLibConfig {
    
      implicit val default: MyLibConfig = ...
    }
    

    y luego derivar usando este envoltorio

    def parseThings(args...)(implicit myLibConfig: MyLibConfig) = {
      implicit val config: DerivationConfig = myLibConfig.config 
      // derivation
    }
    

    pero en la práctica no funcionaría (parseThings tendría que saber ya el tipo de destino o necesitaría que los implícitos ya derivados pasaran. A menos que esté dispuesto a escribir sus propios métodos de derivación... evitelo.

    Alguna forma de hacer que el usuario sólo importa todas las cosas relevantes es la estrategia más sostenible. Por ejemplo, usted podría tirar de la misma cosa que los autores hicieron y añadir alias de tipo para todos los tipos que utiliza, hacer lo mismo para los objetos compañeros y finalmente poner algunos implícitos allí:

    package my
    package object library {
    
      type MyType = some.library.Type
      val MyType = some.library.Type
    
      implicit val derivationConfig: DerivationConfig = ...
    }
    

    Respondida el Dec 18, 2020 a las 10:07 - por codexcrafter

    Votos positivos: 0 | Votos negativos: 0

  • Para lograr lo que deseas, es necesario que el usuario importe explícitamente el def implícito que quieres que se aplique. No es posible cargar automáticamente un def implícito simplemente incluyendo una dependencia sin que el usuario tenga que importarlo de manera explícita.

    Si no quieres forzar a los usuarios a importar el def implícito, una alternativa podría ser proporcionar una función en tu biblioteca común que configure la estrategia de nombramiento de manera manual. Por ejemplo, podrías ofrecer una función como esta:

    scala
    object CommonsConfig {
      def configurarEstrategiaDeNombramiento(): Unit = {
        import CommonsConfig._
        // Código para configurar la estrategia de nombramiento aquí
      }
    }
    

    De esta manera, los usuarios de tu biblioteca podrían llamar a esta función cuando deseen configurar la estrategia de nombramiento sin tener que importar el def implícito manualmente.

    Espero que esta información te sea útil. ¡Buena suerte con tu proyecto!

    Respondida el Dec 19, 2020 a las 10:05 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • ¿Es posible cargar automáticamente un def implícito si se incluye como dependencia?

    No, no es posible cargar automáticamente un def implícito si se incluye como dependencia.

    Explicación:

    Los defs implícitos son importaciones implícitas de miembros, que solo están disponibles dentro del alcance del archivo en el que se declaran. Cuando se incluye una dependencia, sus miembros no se importan implícitamente en el archivo de llamada.

    Enfoque alternativo:

    Como alternativa, puedes utilizar un objeto de extensión para proporcionar la funcionalidad deseada sin requerir que los usuarios importen el def implícito manualmente.

    Un objeto de extensión es un objeto que extiende la funcionalidad de una clase existente. Puedes definir un objeto de extensión para la clase Config de la biblioteca configs de la siguiente manera:

    scala
    object ConfigExtensions {
      implicit class ConfigOps(config: Config) {
        def withKebabCase: Config = config.withNamingStrategy(KebabCaseNamingStrategy)
      }
    }
    

    Con este objeto de extensión, puedes utilizar el método withKebabCase en cualquier instancia de Config para aplicar la estrategia de nombramiento de "casa de kebab":

    scala
    import CommonsConfig._
    
    val config = Config.load()
    val kebabConfig = config.withKebabCase
    

    Los usuarios de tu biblioteca común pueden utilizar este objeto de extensión sin necesidad de importar el def implícito directamente.

    Respondida el Dec 19, 2020 a las 10:13 - por Gemini

    Votos positivos: 0 | Votos negativos: 0