wattpad vez ves tag raras que primera preguntas novio miedo conocerse scala logging singleton

scala - ves - tag tu primera vez



¿Cómo iniciar sesión en Scala*sin*una referencia al registrador en*cada instancia*? (4)

¿Cómo declaro en un rasgo que la clase implementadora debe tener un objeto singleton de tipo X, y que este objeto singleton debe ser accesible a través del método def x: X?

Declare un rasgo que deben ser implementados por sus objetos complementarios.

trait Meta[Base] { val logger = LoggerFactory.getLogger(getClass) }

Cree un rasgo base para sus clases, las subclases tienen que sobrescribir el método meta.

trait Base { def meta: Meta[Base] def logger = meta.logger }

Una clase cualquiera que sea con un objeto compañero:

object Whatever extends Meta[Base] class Whatever extends Base { def meta = Whatever def doSomething = { logger.log("oops") } }

De esta manera, solo necesitas tener una referencia al metaobjeto.

Podemos usar la clase Whatever como esta.

object Sample { def main(args: Array[String]) { val whatever = new Whatever whatever.doSomething } }

He visto un ejemplo de inicio de sesión en Scala, y generalmente se ve así:

import org.slf4j.LoggerFactory trait Loggable { private lazy val logger = LoggerFactory.getLogger(getClass) protected def debug(msg: => AnyRef, t: => Throwable = null): Unit = {...} }

Esto parece independiente del marco de registro concreto. Si bien esto hace el trabajo, también introduce un valioso valor perezoso en todas las instancias que desean realizar el registro, que bien podrían ser todas las instancias de toda la aplicación. Esto me parece demasiado pesado, en particular si tiene muchos "casos pequeños" de algún tipo específico.

¿Hay una manera de poner el registrador en el objeto de la clase concreta en su lugar, simplemente mediante el uso de la herencia? Si tengo que declarar explícitamente el registrador en el objeto de la clase y referirme explícitamente a él desde la clase / rasgo, entonces he escrito casi tanto código como si no hubiera reutilizado nada.

Expresado en un contexto específico que no sea de registro, el problema sería:

¿Cómo declaro en un rasgo que la clase implementadora debe tener un objeto singleton de tipo X, y que este objeto singleton debe ser accesible a través del método def x: X?

No puedo simplemente definir un método abstracto, porque solo podría haber una implementación única en la clase. Quiero que el registro en una superclase me obtenga el singleton de super clase, y el registro en la subclase me obtenga el singleton de subclase. O mejor dicho, quiero que el registro en Scala funcione como el registro tradicional en Java, usando registradores estáticos específicos de la clase que realiza el registro. Mi conocimiento actual de Scala me dice que esto simplemente no es posible sin hacerlo exactamente de la misma manera que lo hace en Java, sin mucho o ningún beneficio al usar el Scala "mejor".


La optimización temprana es la raíz de todo mal

Dejemos claro primero una cosa: si tu rasgo se ve así:

trait Logger { lazy val log = Logger.getLogger }

Entonces lo que no has hecho es como sigue:

  • NO has creado una instancia de registrador por cada instancia de tu tipo
  • No te has dado un recuerdo ni un problema de rendimiento (a menos que lo hayas hecho)

Lo que has hecho es lo siguiente:

  • Tienes una referencia extra en cada instancia de tu tipo.
  • Cuando accede al registrador por primera vez, es probable que esté realizando una búsqueda en el mapa.

Tenga en cuenta que, incluso si creó un registrador separado para cada instancia de su tipo (lo que hago con frecuencia, incluso si mi programa contiene cientos de miles de estos, de modo que tengo un control muy preciso sobre mi registro), casi ¡Ciertamente todavía no tendrá un rendimiento ni un problema de memoria !

Una "solución" es (por supuesto), hacer que el objeto complementario implemente la interfaz del registrador:

object MyType extends Logger class MyType { import MyType._ log.info("Yay") }


Creo que no se puede obtener automáticamente el objeto singleton correspondiente de una clase o requerir que exista tal singleton.

Una razón es que no puede saber el tipo de singleton antes de que se defina. No estoy seguro, si esto ayuda o si es la mejor solución a su problema, pero si desea requerir que se defina algún metaobjeto con un rasgo específico, podría definir algo como:

trait HasSingleton[Traits] { def meta: Traits } trait Log { def classname: String def log { println(classname) } } trait Debug { def debug { print("Debug") } } class A extends HasSingleton[Log] { def meta = A // Needs to be defined with a Singleton (or any object which inherits from Log} def f { meta.log } } object A extends Log { def classname = "A" } class B extends HasSingleton[Log with Debug] { // we want to use Log and Debug here def meta = B def g { meta.log meta.debug } } object B extends Log with Debug { def classname = "B" } (new A).f // A (new B).g // B // Debug


No estoy seguro de entender su pregunta completamente. Así que pido disculpas por adelantado si esta no es la respuesta que está buscando.

Defina un object que puso su logger , luego cree un trait complementario.

object Loggable { private val logger = "I''m a logger" } trait Loggable { import Loggable._ def debug(msg: String) { println(logger + ": " + msg) } }

Así que ahora puedes usarlo así:

scala> abstract class Abstraction scala> class Implementation extends Abstraction with Loggable scala> val test = new Implementation scala> test.debug("error message") I''m a logger: error message

¿Responde esto a tu pregunta?