From: David Alan Black Date: 2001-09-26T10:26:49+09:00 Subject: [ruby-talk:21703] Re: strange behaviors Hello -- On Wed, 26 Sep 2001, Avdi B. Grimm wrote: > Hello, > > In the process of a frighteningly productive spate of Ruby coding > today, I ran across some seeming quirks in the language. I'm curious > whether these are bugs, features, known eccentricities, or what, so I > thought I'd post them and see if anyone else is familiar with the > behaviors I encountered. > > Quirk #1: Inconsistent name resolution in instance methods This is mentioned in the pickaxe (page 78). (Albeit with a typo, in the first printing :-) It's not really inconsistent: it's part of the whole process of Ruby deciding what's a method and what's a variable, which involves looking for assignments and inferring variableness from them (so that "thing = 10" means that "thing" is a local variable). That's not a very full explanation, but tiredness is descending and I want to say more about Quirk #2 :-) > Quirk #2: Constants aren't dynamically resolved [...] > class Parent > CONSTANT = "foo" > > def Parent.implicit > CONSTANT # always resolves to Parent::CONSTANT > end > > def Parent.explicit > self::CONSTANT # resolves dynamically > end > end > > class Child < Parent > CONSTANT = "bar" > end > > puts Child.implicit # prints "foo" > puts Child.explicit # prints "bar" > > > The implicit internal reference to CONSTANT always yields the value of > CONSTANT for the class in which the current method was defined. To > get the value of CONSTANT for the current class, I must explicitly ask > for it with self::CONSTANT. The thing is, constants aren't supposed to be dynamic -- they're supposed to be constant :-) So where you've written: CONSTANT = "foo" def Parent.implicit CONSTANT end the effect is as if you'd simply written: def Parent.implicit "foo" end So when you then call Child.implicit, and Ruby looks for the method and finds it in Parent, there's nothing to resolve. The method behaves a certain way, based on its definition. Here's a further example which might clarify this: class Parent # as above CONSTANT = "foo" def Parent.implicit; CONSTANT; end def Parent.explicit; self::CONSTANT; end end class Child < Parent CONSTANT = "bar" puts Parent.implicit puts self.implicit def Parent.implicit; CONSTANT; end puts Parent.implicit puts self.implicit end => foo foo bar bar David -- David Alan Black home: dblack@candle.superlink.net work: blackdav@shu.edu Web: http://pirate.shu.edu/~blackdav