Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby scopes, constants precedence: lexical scope or inheritance tree

I'll show your the code snippet from rubykoans tutorial. Consider the next code:

class MyAnimals
LEGS = 2

  class Bird < Animal
    def legs_in_bird
      LEGS
    end
  end
end

def test_who_wins_with_both_nested_and_inherited_constants
  assert_equal 2, MyAnimals::Bird.new.legs_in_bird
end

# QUESTION: Which has precedence: The constant in the lexical scope,
# or the constant from the inheritance hierarchy?
# ------------------------------------------------------------------

class MyAnimals::Oyster < Animal
  def legs_in_oyster
    LEGS
  end
end

def test_who_wins_with_explicit_scoping_on_class_definition
  assert_equal 4, MyAnimals::Oyster.new.legs_in_oyster
end

# QUESTION: Now which has precedence: The constant in the lexical
# scope, or the constant from the inheritance hierarchy?  Why is it
# **different than the previous answer**?

Actually the question is in comments (I highlighted it with asteriks (though it intended to be in bold)). Can anybody explain me please? Thanks in advance!

like image 658
Paul Osadchiy Avatar asked Dec 01 '12 16:12

Paul Osadchiy


1 Answers

This is answered here: Ruby: explicit scoping on a class definition. But perhaps it's not super clear. If you read the linked article it will help you with the answer.

Basically, Bird is declared in the scope of MyAnimals, which has a higher precedence when resolving constants. Oyster is in the MyAnimals namespace, but it is not declared in that scope.

Inserting p Module.nesting into each class with show you what the enclosing scopes are.

class MyAnimals
  LEGS = 2

  class Bird < Animal

    p Module.nesting
    def legs_in_bird
      LEGS
    end
  end
end

Yields: [AboutConstants::MyAnimals::Bird, AboutConstants::MyAnimals, AboutConstants]

And

class MyAnimals::Oyster < Animal
  p Module.nesting

  def legs_in_oyster
    LEGS
  end
end

Yields: [AboutConstants::MyAnimals::Oyster, AboutConstants]

See the difference?

like image 50
Todd Avatar answered Oct 23 '22 18:10

Todd