From: Chuck Remes Date: 2008-08-05T08:30:40+09:00 Subject: Re: Is it ellegant to use a global variable to store a Logger object? On Aug 4, 2008, at 5:38 PM, Chuck Remes wrote: > > For lurkers, here is some slightly corrected code (the above doesn't > compile). > > require 'logger' > > module Namespace > module Logger > def Logger.key= *key > @key = key.first unless key.empty? > end > > def Logger.key > @key > end > > def Logger.instance > @instances ||= Hash.new { |h,k| h[key || :default ] > = ::Logger.new(STDOUT) } > @instances[@key] > end > > %w( debug info warn error fatal ).each do |method| > module_eval <<-code > def Logger.#{ method }(*a, &b) > instance.#{ method }(*a, &b) > end > code > end > end > end Hmmm... I puzzled through this all the way home and came to the conclusion that I don't know why, or if, this works. If we are saving information in an instance variable in a class method, clearly that instance variable can be overwritten by another writer, yes? These class methods are visible to anyone who can this module in scope, therefore the @key variable can be pretty volatile. This whole setup is predicated on WriterA calling Namespace::Logger.key = which is later used by Namespace::Logger.instance as an index into a hash to lookup the correct ::Logger object in @instances. However, there is no guarantee that @key will remain for WriterA. If WriterB comes along and makes the same call, that writer replaces with its own value. If that didn't happen, then how would @instances store references to everyone's ::Logger objects? These variables must be shared for that to work. Right? If true, I'm back to square one. Each writer would have to pass in their own unique key so they lookup the right ::Logger object. Now instead of injecting the ::Logger object into all of my classes, I have to make sure the @key value is known by all. Please correct me where I am wrong. cr