Reputation: 11890
If a child inherits from the parent, it inherits the parents methods as well.
So how come an inherited method can't access the child's constants?
Example -
class Parent
def my_method
puts "Value of FOO is #{FOO}"
end
end
class Child < Parent
FOO = "bar"
end
Child.new.my_method #=> NameError: uninitialized constant Parent::FOO
Doesn't the inherited method run "inside" the child class?
How can I get around this?
Upvotes: 3
Views: 1854
Reputation: 795
No it doesn't. When you call Child.new.my_method
it looks for the FOO
constant in Parent
and upwards.
I'm not going to question your approach and just provide you with a way to do what you want:
class Parent
def self.inherited(other)
other.define_singleton_method(:my_method) do
puts "Value of FOO is #{other.const_get(:FOO)}"
end
end
end
Now whenever you inherit from Parent
the inherited hook will define a method my_method
on the subclass. Notice that the scope of the block in the inherited
method is still the class level scope of Parent
. That's why I'm directly referencing the subclass (other
) to get the constant.
A way around this would be to use other.instance_exec { ... }
.
@maxpleaner pointed out (with the explanation provided by @CarySwoveland) that you could also retrieve the class via self
and then retrieve the constant from it.
I.e., just do
class Parent
def my_method
puts "Values of FOO is #{self.class.const_get(:FOO)}"
end
end
That works because when calling child = Child.new; child.my_method
the value of self
within my_method
will be child
. And the class of child
is obviously Child
which knows the constant FOO
.
Upvotes: 4