From: Jamis Buck Date: 2004-10-10T23:15:08+09:00 Subject: Re: DI service change notifications (Syringe) leon breedt wrote: > hi, > > i'm playing around with Syringe (http://ruby.jamisbuck.org/syringe/), Wow. I'm surprised -- I haven't even made an announcement about it, except on my blog. You realize, I hope, that Syringe is in a HUGE state of flux right now, and the API is guaranteed to change in all kinds of non-backwards-compatible ways, right? > env = { :log_filename => 'test.log' } > container.register(:log_filename) { env[:log_filename] } > container.register(:logger) { |c| Logger.new(c.log_filename) } > > now, since one can change the value in env, when making that change, > the matching :log_filename service would be flagged as dirty, and, on > next usage, the block executed again, and logger logs to different > file without program restart. > > good idea? crap? A new service model would not really help in this case, because once the Logger.new constructor is called, the log_filename has already been returned as a string. What you need is to create an object that represents the filename, without _being_ the filename, and have its #to_str method defined to return the filename: class LogFilename def to_str "test.log" end end Then, you can register the :log_filename service to an instance of that: container.register( :log_filename ) { LogFilename.new } If you define LogFilename correctly, you could then change the string that gets returned there, and have all consumers of the filename take advantage of that. But, there's a problem. In your example, you had Logger be the consumer of the filename. Logger is not designed to allow the filename to be changed. You would have to actually have a new logger instance be created and substituted in place, something Ruby doesn't support without using proxy objects (unless you're using evil.rb). SO. What is needed is a way to allow consumers of consumers of :log_filename (that is to say, consumers of :logger) to detect when the :log_filename service was modified and then grab a new instance of :logger. What is really needed, though, is an implementation of Logger that allows the filename to be changed on the fly. If that existed, there would be an easier (i.e., more tractable) solution. -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis