Hello,
i just wondered where the difference between the following code parts is?
---- code ----
class << Array
p self.inspect
define_method :foo do
p "inside foo"
end
end
Array.class.module_eval do
p self.inspect
define_method :bar do
p "inside bar"
end
end
Array.foo
Array.bar
---- output ----
"#<Class:Array>"
"Class"
"inside foo"
"inside bar"
---- end ----
it obviously makes a difference because self.inspect returns two different values. but how is this practically relevant?
Greetings,
Niklas
"class << Array" opens the eigenclass of the Array object.
Thus the foo method is only defined for the Array object itself.
"Array.class" returns the class of the Array object, which is Class.
Defining a method with module_eval in there means that it
is defined for _all_ class objects.
To demonstrate this, try to call the methods on another class:
irb(main):017:0> String.foo
NoMethodError: undefined method `foo' for String:Class
from (irb):17
irb(main):018:0> String.bar
"inside bar"
Stefan
···
2008/8/21 Niklas Baumstark <niklas.baumstark@googlemail.com>:
Hello,
i just wondered where the difference between the following code parts is?
---- code ----
class << Array
p self.inspect
define_method :foo do
p "inside foo"
end
end
Array.class.module_eval do
p self.inspect
define_method :bar do
p "inside bar"
end
end
Array.foo
Array.bar
---- output ----
"#<Class:Array>"
"Class"
"inside foo"
"inside bar"
---- end ----
it obviously makes a difference because self.inspect returns two different values. but how is this practically relevant?
Hello,
i just wondered where the difference between the following code parts is?
---- code ----
class << Array
p self.inspect
define_method :foo do
p "inside foo"
end
end
Array.class.module_eval do
p self.inspect
define_method :bar do
p "inside bar"
end
end
Array.foo
Array.bar
---- output ----
"#<Class:Array>"
"Class"
"inside foo"
"inside bar"
Array.class is equal to Class -- all classes are instances of Class. So, the
second one actually adds an instance method :bar to Class, so *all* classes
get that method:
String.bar
#=> "inside bar"
If you only want to modify Array, leave out the '.class'
Array.module_eval do
p self.inspect #=> "Array"
def self.bar
"inside class method bar"
end
def bar
"inside instance method bar"
end
end
Array.bar
#=> "inside class method bar"
.bar
#=> "inside instance method bar"
or try the following...
(class << Array; self; end).module_eval do
p self.inspect
define_method :bar do
p "inside bar"
end
end