disclaimer: Code taken from the ruby koans
This is from a discussion of constants scoping within classes. Here is the defintion of a couple few classes:
class Animal LEGS = 4 def legs_in_animal LEGS end end class MyAnimals LEGS = 2 class Bird < Animal def legs_in_bird LEGS end end end
At this point doing MyAnimals::Bird.new.legs_in_bird
results in 2 and I understand why--search lexical space for the constant before the inheritance heirarchy.
Then this class is defined:
class MyAnimals::Oyster < Animal def legs_in_oyster LEGS end end
The tutorial says that now calling MyAnimals::Oyster.new.legs_in_oyster
results in 4 and I can't figure it out. It appears to me that Oyster is a nested class in MyAnimals and as such I expected it to behave the same ways as the Birds class did above. I'm missing some key information about what declaring the class Oyster with explicit scoping means.
can anyone explain this to me? I've found hundreds of ruby class tutorials via Google but none of them address this situation.
thank you in advance...
I think this example explains it best. Ruby searches for the constant definition in this order:
EDIT
Thanks to Mark Amery for pointing out this error. The top-level is only reached in the case where there are no enclosing scopes and/or superclasses. The linked example actually makes this clear, sadly I read it wrong.
An example for this case:
FOO = 'I pity the foo!' module One FOO = 'one' class Two FOO = 'two' def self.foo FOO end end class Three < Two def self.foo FOO end end end class Four class Five < Four def self.foo FOO end end end describe FOO do it "depends where it is defined" do expect(FOO).to eq 'I pity the foo!' # top-level expect(One::FOO).to eq 'one' # module expect(One::Two.foo).to eq 'two' # class expect(One::Three.foo).to eq 'one' # outer scope (One) comes before superclass expect(Four::Five.foo).to eq 'I pity the foo!' # top-level end end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With