From: Mark Hubbart Date: 2005-04-15T05:02:05+09:00 Subject: Re: class locals as class methods On 4/14/05, Trans wrote: > Mark Hubbart wrote: > > I think meta-programming would suffer. > > > > # a Foo that is sort of like a Bar > > class FooBar < Foo > > bar_methods = Bar.instance_methods - self.instance_methods > > bar_methods.each{ ... } > > end > > > > FooBar.bar_methods => ????? > > > > It would be like penalizing people for using metaprogramming > techniques :( > > Hmm... I would think that code would work just fine. I'm not suggesting > that local vars be displaced, if that is what you mean, only that they > overlap. So a class local var is a class method is a class local var. > It is the same namespace afterall (i.e. self resoves to the same thing) > so that's okay too. Am I understanding your example? [snip example] I don't think so. I was referring to intermediate local variables that you use inside classes when metaprogramming. I think I elided too much code there; I just didn't want to bother thinking something up to take up the elipses :) I'm just saying that you don't necessarily want all your temporary variables to be permanently accessible. Also, there are garbage collection implications. local variables are not usually thought to be hanging around forever. > > Perhaps, if you just want to set attributes: > > > > class Class > > def set(name, value) > > self.class_eval "def self.#{name}() @@#{name} end" > > self.class_eval "@@#{name} = > ObjectSpace._id2ref(#{value.object_id})" > > end > > end > > ==>nil > > class Foo > > set :foo, "yep!" > > end > > ==>"yep!" > > Foo.foo > > ==>"yep!" > > > > I'm sure it could be condensed even further, if needed. > > Sure, that's one fair way. There are a number of ways to do it, like > the simple first examples I gave. But all of them seem, well, > contrived. In other words, there's no sort of obvious standard to this > kind of thing. And worse to me, the solutions all look like they've > been hit up with an ugly stick ;-) > > > Off topic now, I thought there was an equivalent of > > #instance_variable_set for class variables? It would seem not. I > > wonder why. > > Hmm... I don't know, maybe b/c this is less characters? > > Klass.class_eval { @@x = "foo" } Doesn't work for arbitrary variables. Maybe this can be done without a string-based eval or ObjectSpace._id2ref, but I couldn't quickly figure out how: class Class def class_attr_accessor( name ) self.class_eval "def #{name}() @@#{name} end" self.class_eval "def #{name}=(val) @@#{name}=val end" end end compare to attr_accessor, which could be defined in pure ruby without the evil string-based-eval. class Class def attr_accessor(name) attr_name = :"@@#{name}" name_eq = :"#{name}=" define_method(name){ instance_variable_get(attr_name)} define_method(name_eq){ instance_variable_get(attr_name)} end end cheers, Mark