Praca nad małym skryptem w języku Ruby, który wychodzi do internetu i indeksuje różne usługi. Mam w środku moduł z kilkoma klasami:Ruby - współudział loggera między modułami/klasami
module Crawler
class Runner
class Options
class Engine
end
Chcę udostępnić jeden rejestrator wśród wszystkich tych klas. Normalnie bym po prostu umieścić to na stałe w module i odwoływać się do niej tak:
Crawler::LOGGER.info("Hello, world")
Problem polega na tym, że nie mogę tworzyć moje wystąpienie rejestratora dopóki wiem gdzie wyjście dzieje. Uruchomieniu robota poprzez linię poleceń iw tym momencie można powiedzieć, to chcesz uruchomić w rozwoju (log wyjście idzie do STDOUT) lub produkcji (log wyjście idzie do pliku, crawler.log):
crawler --environment=production
Mam klasę Options
, która analizuje opcje przekazywane za pomocą wiersza polecenia. Tylko w tym momencie wiem, jak utworzyć rejestrator z poprawną lokalizacją wyjściową.
Moje pytanie brzmi: jak/gdzie umieścić obiekt mojego rejestratora, aby wszystkie moje klasy miały dostęp do niego?
Mogę przekazać moją instancję rejestratora do każdego wywołania new()
dla każdej instancji klasy, którą utworzę, ale wiem, że musi być lepsza, sposób Rubyish to zrobić. Wyobrażam sobie jakąś dziwną zmienną klasy w module, która jest wspólna z class << self
lub inną magią. :)
Trochę więcej szczegółów: Runner
zaczyna wszystko przez przekazanie opcji wiersza polecenia do klasy Options
i wróci obiekt z kilku zmiennych instancji:
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
Potrzebuję kod w celu Engine
mieć dostęp do obiektu rejestratora (wraz z kilkoma więcej klasami, które są inicjowane wewnątrz Engine
). Wsparcie!
Wszystko to można było uniknąć, gdybyś mógł dynamicznie zmienić lokalizację wyjściową już utworzonego programu rejestrującego (podobnie jak zmieniasz poziom rejestrowania). Utworzę go STDOUT, a następnie przejdę do pliku, jeśli jestem w produkcji. Widziałem gdzieś sugestię zmiany globalnej zmiennej Ruby $ stdout, która przekierowywała wyjście gdzieś poza STDOUT, ale wydaje się to dość hackowe.
Dzięki!
Dzięki Chuck! Właśnie to robiłem po drobnych testach na moim końcu! –