I'm confused as to when I should be using instance_eval
and class eval
.
I should or shouldn't use them?
Answer with simple examples on how to use them.
Thanks a lot.
The class_eval
and instance_eval
are both used to reopen an object and define additional behaviour.
They follows the open/closed principle .
class_eval
is used to define additional behaviour in the context of a class.
Let's use the following Person
class:
class Person
def initialize(name)
@name = name
end
end
Person.class_eval do
def say_hello
puts "Hello! I'm #{@name}"
end
end
j = Person.new "John"
j.say_hello # Hello! I'm John
r = Person.new "Robert"
r.say_hello # Hello! I'm Robert
Both j
and p
can use a new method called say_hello
that wasn't defined in the definition of the class Person
, but on an extension of it.
instance_eval
is used to define additional behavior in the context of a receiving object.
The previous example could be rewritten as:
class Person
def initialize(name)
@name = name
end
end
j = Person.new "John"
j.instance_eval do
def say_hello
puts "Hello! I'm #{@name}"
end
end
j.say_hello # Hello! I'm John
Since we used instance_eval
on j
, only the behavior of j
has been redefined, in fact we can't use say_hello
on another instance:
r = Person.new "Robert"
r.say_hello # undefined method `say_hello' for #<Person:0x00007fac43c15b28 @name="Robert"> (NoMethodError)
This is the opposite of class_eval
.
class_eval
allows you to open and redefine the behavior of a class in order to extend all instances of the class instance_eval
allows you to open and redefine the behavior of just an instance of a class I'm of the idea that you shouldn't use them, because this can lead to code fragmentation.
But you have to use them when you want to add behavior on third parties code or when you want to add behavior dynamically.
Use ClassName.instance_eval to define a class method (one associated with the class object but not visible to instances). Use ClassName.class_eval to define an instance method (one that applies to all of the instances of ClassName).
Source: RubyMonk
One of the major differences between eval and instance_eval is that with instance_eval you have the choice of explicitly handling the context of self. As instance_eval is a method on Object it is scoped by the object you specify.
class_eval is much simpler than instance_eval which works on metaclasses (or the singleton object). It works on the class as if you were opening it in a text editor and adding new state or behaviour to it.
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.