Reputation: 13
I just don't get the answer to this question. I want to create a method dinamically with a condition enter in the moment of the instance of the object. I can create the method with other conditions that I tested, but in other circumstances it just doesn't work. Here is my code:
class Animal
def initialize(live, swim)
@live = live
@swim = swim
end
def live?
@live
end
def swim?
@swim
end
end
class Bird < Animal
def initialize(live, swim, fly)
super(live, swim)
@fly = fly
end
define_metod(:flying) {puts "flying high"} if @fly
end
Bird.new(true, true, true).flying
I tried yet to various other ways to do that. The error is that the method "flying" is not created:
Traceback (most recent call last):
main.rb:23:in `<main>': undefined method `flying' for #<Bird:0x000056382015df98 @live=true, @swim=true, @fly=true> (NoMethodError)
Upvotes: 0
Views: 70
Reputation: 110755
@fly
in define_method(:flying) {puts "flying high"} if @fly
is a class instance variable. It doesn't exist when it's referenced (when the code is parsed), so nil
is returned, resulting in the define_method
statement not being executed. The class instance variable @fly
is unrelated to the instance variables @fly
, just as @fly
for one instance is unrelated to @fly
for another instance.
See @Marcin's answer for how you can achieve your objective.
Upvotes: 1
Reputation: 5313
If you'd still like to do that, try like this (simplified example):
class A
def initialize(foo)
define_singleton_method(:flying) { "flying high" } if foo
end
end
Then:
> A.new(true).flying
=> "flying high"
> A.new(false).flying
NoMethodError: undefined method `flying' for #<A:0x0000000589a148 @foo=false>
from (irb):24
This way the define_singleton_method
is evaluated within the context of specific instance of the class, not the class itself, so you will be able to use any instance's instance variables you wish.
Upvotes: 1