Seems I am confused between the two methods though I have been using them for a while, I can't understand why the method passengers is not being added to the object in the following code:
class Bus
def number_of_seats
42
end
end
Bus.class_eval do
define_method :number_of_windows do
number_of_seats
end
def fuel_type
:diesel
end
end
Bus.instance_eval do
define_method :destination do
'Paris'
end
def passengers
12
end
end
bus = Bus.new
bus.number_of_windows # => 42
bus.fuel_type # => :diesel
bus.destination # => "Paris"
bus.passengers # => undefined method `passengers' (NoMethodError)
Notes :
instance_eval
first, just randomly used class_eval
and then it too seemed to work! instance_eval
's block: The code in the block is run with self
set to the object calling instance_eval
. class_eval
's block: The code in the block is evaluated as if its placed by opening the class of the object calling it. Hence I am puzzled at the class_eval
in the above case! I was expecting class_eval
on Bus would mean evaluating the block in the class
of Bus Class . You can refer this awesome article on class and instance_eval
as to why passengers is not being added to the object.
TL;DR:
Bus.class_eval will
create instance methods and Bus.instance_eval
will create class methods.
Now, regarding the behavior of destination (which could be called on instance)..... define method when used inside either class_eval
or instance_eval
is immune to the usual behaviour . Why?.
Because the documentation says so. As per the documentation:
define method - Defines an instance method in the receiver.
Therefore, it does not matter if you use define_method
inside class_eval
or instance_eval
it would always create an instance method.
Hope this helped :-).
Basically you can't do an instance_eval
on a class object when using def
. Here's a general way you use instance_eval
and class_eval
. http://web.stanford.edu/~ouster/cgi-bin/cs142-winter15/classEval.php
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.