So, I've been kind of confused about all of the different ways of evaling
stuff; in particular, all the different ways to define methods in classes:
class Foo
def bar
"bar"
end
end
p Foo.new.bar # --> "bar"
...is just like...
class Foo
$binding = binding
end
eval 'def bar; "bar"; end', $binding
p Foo.new.bar # --> "bar"
...which is just like...
class Foo
end
Foo.module_eval 'def bar; "bar"; end'
p Foo.new.bar # --> "bar"
...which is just like...
class Foo
end
Foo.module_eval {define_method("bar"){"bar"}}
p Foo.new.bar # --> "bar"
So, am I right that those are all basically identical ways of doing the same
thing? Here's something slightly different: extending only one object:
class Foo
end
foo = Foo.new
foo.instance_eval 'def bar; "bar"; end'
p foo.bar # --> "bar"
...which is maybe the same as...
class Foo
end
foo = Foo.new
# Is this the only way to get this class?
klass = class << foo; self; end
klass.module_eval 'def bar; "bar"; end'
p foo.bar # --> "bar"
...however, the following does not work...
class Foo
end
foo = Foo.new
foo.instance_eval {define_method("bar"){"bar"}}
NoMethodError: undefined method `define_method' for #<Foo:0x400be61c>
from (irb):4
from (irb):4:in `instance_eval'
from (irb):4:in `instance_eval'
from (irb):4
...Well, I understand why that didn't work... I guess my question is, why
does...
foo.instance_eval 'def bar; "bar"; end'
...work? What does that even mean? Also, why (in the last working snippet)
does foo.class give Foo, rather than klass?
Just trying to make sense of it all,
Chris