From: "Mauricio Fernández" Date: 2002-12-11T19:18:49+09:00 Subject: Re: all the pretty evals... On Wed, Dec 11, 2002 at 02:05:53PM +0900, Chris Pine wrote: > 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"} } # 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 # 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 # 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. > 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