Travail sur un petit script Ruby qui va sortir pour le web et les analyses des différents services. J'ai un module avec plusieurs classes à l'intérieur:
module Crawler
class Runner
class Options
class Engine
end
Je veux partager un enregistreur parmi tous ceux de ces classes. Normalement, je venais de mettre cela dans une constante dans le module et de le référencer comme suit:
Crawler::LOGGER.info("Hello, world")
Le problème est que je ne peux pas créer mon journal instance jusqu'à ce que je sais d'où la sortie est en cours. Vous démarrez le robot via la ligne de commande et à ce stade, vous pouvez dire ce que vous voulez exécuter dans le développement (journal de sortie vers STDOUT) ou de production (journal de sortie passe à un fichier, un crawler.log):
crawler --environment=production
J'ai une classe Options
qui analyse les options passées au travers de la ligne de commande. C'est seulement à ce point que je ne sais comment instancier l'enregistreur, le bon emplacement de la sortie.
Donc, ma question est: comment/où j'ai mis mon enregistreur objet, de telle sorte que toutes mes classes ont accès?
J'ai pu passer mon journal instance pour chaque new()
appel pour chaque instance de classe que j'ai créer, mais je sais qu'il y a un mieux, Rubyish façon de le faire. J'imagine un peu bizarre variable de classe dans le module partagé avec class << self
ou une autre magie. :)
Un peu plus de détails: Runner
commence tout en passant les options de ligne de commande à l' Options
de la classe et obtient en retour un objet avec un couple de variables d'instance:
module Crawler
class Runner
def initialize(argv)
@options = Options.new(argv)
# feels like logger initialization should go here
# @options.log_output => STDOUT or string (log file name)
# @options.log_level => Logger::DEBUG or Logger::INFO
@engine = Engine.new()
end
def run
@engine.go
end
end
end
runner = Runner.new(ARGV)
runner.run
J'ai besoin du code en Engine
à être en mesure d'accéder à l'objet logger (avec un couple de plusieurs classes qui sont initialisées à l'intérieur d' Engine
). À l'aide!
Tout cela pourrait être évité si vous pouviez juste de modifier dynamiquement l'emplacement de la sortie d'un déjà-instancié Enregistreur (similaire à la façon dont vous modifiez le niveau de log). J'avais l'instancier à STDOUT et puis l'évolution vers un fichier si je suis dans la production. Je ne vois d'une suggestion, quelque part sur la modification de Rubis $stdout variable globale, qui permettrait de rediriger la sortie dans un endroit autre que STDOUT, mais cela semble assez hacky.
Merci!