From: Ross Bamford Date: 2005-11-27T06:07:28+09:00 Subject: Re: Nubish questions about syntax and gems On Sat, 26 Nov 2005 19:58:57 -0000, Sean O'Halpin wrote: > 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. > I get the feeling that eval is the more general solution. I'll stick with that. >> 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. > I'm starting to see that now. The flexibility has really shaken me up, I must say :) > [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 ;) > :) Don't worry, I've been falling around in the dark for a few weeks now - it's only the past few days that I've started getting these moments of clarity. It's probably no coincidence that I've developed a reflex where i type 'irb' a lot ;) >> 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. > Have to agree, so far they seem pretty counter-intuitive to me. > This is a little test that (to me) shows how wacky the scoping rules > are for class variables: > >> [ ... ] >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). > The scoping issues are beyond me right now, but it seems pretty bizarre that outer scope is ignored there. I noticed that if you modify it thus: 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] } class C @@foo = "C's class variable foo" @foo = "C instance foo" def self.eval_block(&block) instance_eval &block end end # N.B. Not C, just B again 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"] [B, "C's class variable foo", "B instance foo"] To me, that seems stranger still. It seems that it's getting the last defined @@foo, no matter what? Cheers, -- Ross Bamford - rosco@roscopeco.remove.co.uk