From: Sean O'Halpin Date: 2005-11-27T04:58:57+09:00 Subject: Re: Nubish questions about syntax and gems On 11/26/05, Ross Bamford wrote: > Hi Sean, Hi Ross, > I guess if I > wanted to pass a block in that way, I'd have to get a Proc for the > closure? I've seen code like: > > some_method(proc { |s| s.do_something }) > > which seems a bit nasty to me. Yes - you'd have to pass it as a regular argument. > Nice one. Gotta get used to this 'effectively adding keywords' thing too. > I've gotten around the fact that class definitions can call methods, now I > need to get used to it being _my_ methods :) A class definition is executable code. The ability to define methods that execute within the class definition is one of the most powerful techniques available in Ruby. [snip stuff about a class being an instance of Class] > > This is where I am going around in circles. It's an instance of Class, but > it also has a class, Class. So, Class.class == Class. Is that right ? Yes. If it's any consolation, it took me a fair bit of head scratching before the 'aha' moment ;) > Hmm, I think I need to go back to the book on class variables. I can't > quite see how they fit in, especially with respect to singleton class and > stuff. Thanks for your explanation, though - it's just me :( @@class_variables seem to be a bit of a hack to me (at least in 1.8.x). The double '@' is deliberately ugly. They obey different scoping rules to other variables in that they look for the nearest enclosing class regardless of self. This is a little test that (to me) shows how wacky the scoping rules are for class variables: class A @@foo = "class variable foo" @foo = "class instance variable foo" def self.evaluate(txt) instance_eval txt end def self.eval_block(&block) instance_eval &block end end begin p A.instance_eval { @@foo } rescue => e puts e end @@foo = "hi" p A.instance_eval { [self, @@foo, @foo] } p A.evaluate("[self, @@foo, @foo]") p A.eval_block { [self, @@foo, @foo] } class B @@foo = "B's class variable foo" @foo = "B instance foo" def self.eval_block(&block) instance_eval &block end end p B.eval_block { [self, @@foo, @foo] } __END__ uninitialized class variable @@foo in Object [A, "hi", "class instance variable foo"] [A, "class variable foo", "class instance variable foo"] [A, "hi", "class instance variable foo"] [B, "B's class variable foo", "B instance foo"] I'd be grateful if anyone can explain this behaviour (i.e. why the call to B.eval_block gets B's class variable but the call to A gets the outer scope). Regards, Sean