On Jun 28, 2008, at 9:50 AM, Shot (Piotr S.) wrote:
@qv_method = :graph_merger
that we are not creating an instance here).
Yeah, that would be the cherry on top. 
I couldn’t come up with any nice solution; note that you can
initialize
this class anywhere, so if you have some other place that does any
kind
of program setup, you can do it there. Otherwise, doing it right after
the class is defined is the nicest solution in my opinion.
ruby classes are evaluated top down at load time so, to achieve the
effect of init you just need to delete some code
module ArtDecomp::Config
@debug = false
@processes = 1
@qu_method = :graph_merger
@qv_method = :graph_merger
@silicone = Set[Arch[4,2], Arch[5,1]]
class << self
attr_accessor :debug, :processes, :qu_method, :qv_method, :silicone
end
end
and the ‘init’ code is called at load time.
a @ http://codeforpeople.com/
ara.t.howard:
ruby classes are evaluated top down at load time so, to
achieve the effect of init you just need to delete some code
…
and the ‘init’ code is called at load time.
Ah, so perfect! Thanks a lot!
– Shot
El Domingo, 29 de Junio de 2008, Shot (Piotr S.) escribió:
ara.t.howard:
ruby classes are evaluated top down at load time so, to
achieve the effect of init you just need to delete some code
…
and the ‘init’ code is called at load time.
Ah, so perfect! Thanks a lot!
The problem here is that those code is runned in load time, so if that
code
depends on other project libraries or classes you must take care of
loading
them first. This is not problem when calling “init” after loading all
the
classes or when using “normal” objects (XXXX.new).
I hate to resurrect this thread, but I have a problem that I can’t
seem to solve and I didn’t want to rehash the original suggestions.
I need a global Logger within a framework I wrote. The trouble is that
I need to be able to instantiate multiple independent copies of this
framework within the same Ruby runtime (specifically Jruby).
If I do this it doesn’t work for more than one instance:
module Namespace
Logger = # instantiate some logger
module Submodule
class Klass
def foo
Logger.log(“in Klass#foo”)
end
end
end
end
I can load and instantiate this only once in the runtime. If I try to
do it a second time, it’s like I have reopened the class/module and
Logger gets redefined. Each instantiation shares the same global
Logger which is not what I want. I want each one to have their own
instance.
Is this possible? Any recommendations for solving it?
cr
Iñaki Baz C.:
ara.t.howard:
ruby classes are evaluated top down at load time so, to
achieve the effect of init you just need to delete some code
…
and the ‘init’ code is called at load time.
The problem here is that those code is runned in load time, so if that
code depends on other project libraries or classes you must take care
of loading them first. This is not problem when calling “init” after
loading all the classes or when using “normal” objects (XXXX.new).
Right. I also figured out that in my case, I need to be able to reset
the config class to its default state when testing it, so I need an
init/reset method anyway.
– Shot
On Aug 4, 2008, at 1:43 PM, Chuck R. wrote:
Logger = # instantiate some logger
I can load and instantiate this only once in the runtime. If I try
to do it a second time, it’s like I have reopened the class/module
and Logger gets redefined. Each instantiation shares the same global
Logger which is not what I want. I want each one to have their own
instance.
Is this possible? Any recommendations for solving it?
cr
something similar to:
module Namespace
module Logger
def Logger.key *key
@key = key.first unless key.empty?
end
def instance
@instances = Hash.new{|h,k| @instances[key || :default ] ||= new}
end
%w( debug info warn error fatal ).each do |method|
module_eval <<-code
def Logger.#{ method }(*a, &b)
instance.#{ method }(*a, &b)
end
end
end
end
end
Namespace::Logger.key Thread.current.object_id # or something unique
Namespace::Logger.info{ ‘foobar’ }
a @ http://codeforpeople.com/
On Aug 4, 2008, at 3:35 PM, ara.t.howard wrote:
Is this possible? Any recommendations for solving it?
module Logger
def Logger.#{ method }(*a, &b)
Namespace::Logger.info{ ‘foobar’ }
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
Ara, thanks for the help.
cr
On Aug 4, 2008, at 5:38 PM, Chuck R. wrote:
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
On Aug 4, 2008, at 6:30 PM, Chuck R. wrote:
def Logger.key= *key
@instances[@key]
end
Namespace::Logger.key = which is later used by
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.
Here’s proof it doesn’t work as currently written. I’m hoping there’s
a trick I don’t know about ruby that will allow this to work.
cr
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[k || :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
class Bar
def initialize(value)
Namespace::Logger.key = value
end
def foo
Namespace::Logger.info { "called with Logger.key
[#{Namespace::Logger.key}] " }
end
end
end
a = Namespace::Bar.new 17
b = Namespace::Bar.new 24
a.foo
b.foo
– output –
I, [2008-08-04T19:06:50.597418 #91765] INFO – : called with
Logger.key [24]
I, [2008-08-04T19:06:50.598877 #91765] INFO – : called with
Logger.key [24]