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”
Don’t forget
irb(main):001:0> class Foo
irb(main):002:1> end
nil
irb(main):003:0> Foo.instance_eval { define_method(“bar”) {“bar”} }
#Proc:0x402744d4
irb(main):004:0> p Foo.new.bar
“bar”
nil
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?
AFAIK yes.
klass = class << foo; self; end
irb(main):005:0> foo = Foo.new
#Foo:0x4027044c
irb(main):006:0> klass = class << foo; self; end
Foo
At first it seems you cannot get the singleton class
irb(main):007:0> def foo.fubar
irb(main):008:1> “fubar”
irb(main):009:1> end
nil
irb(main):010:0> klass = class << foo; self; end
Foo
I would have expected something magical such as
#<Class 0lx4022fe98>
But anyway we’re getting
irb(main):023:0> klass.new.fubar
TypeError: can’t create instance of virtual class
from (irb):23:in `new’
from (irb):23
irb(main):024:0> klass.instance_methods
[“fubar”]
irb(main):025:0> klass.to_s
“Foo”
.to_s is a liar 
> 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 #
> from (irb):4
> from (irb):4:in `instance_eval'
> from (irb):4:in `instance_eval'
> from (irb):4
define_method belongs to Module, you’re calling it in an instance of
Foo…
…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?
If ‘def’ were a method in Ruby, it’d belong to Module and you’d be
right, it wouldn’t work. But it’s handled at the syntactic level, so it
just works, and you’re defining a singleton method.
As for foo.class == Foo, it looks like #class (aka #type) returns the
Class the object was instanciated from, not the singleton class.
Otherwise you’d not be able to do ‘object.class.new’ or the like.
···
On Wed, Dec 11, 2002 at 02:05:53PM +0900, Chris Pine wrote:
Just trying to make sense of it all,
Chris
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_
_ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
There are 3 kinds of people: those who can count & those who can’t.
– Unknown source