From: Robert Klemme Date: 2005-01-13T18:51:20+09:00 Subject: Re: Kernel#eval and class definition "Joel VanderWerf" schrieb im Newsbeitrag news:41E55294.2040102@path.berkeley.edu... > Florian Gross wrote: > > Yukihiro Matsumoto wrote: > > > >> |> def f ; class C ; end ; end > >> |> def f ; eval "class C ; end", binding ; end > >> | > >> |Well eval "..." is just an expression and "eval" evaluates everyhing it > >> |get's that's syntactically correct. The ruby code in the string > >> |expression is not syntactically located in method f. It's parsed at > >> |runtime while the line above is completely evaluated at compile time. > >> > >> Thanks for explanation. class definition in the method is prohibited > >> by syntax just to detect errors. And class definition in eval is > >> allowed as a back door. Besides, scope management also is a reason, > >> but it's an implementation matter. > > > > > > There's also Class.new which will create an anonymous class. You can > > assign that to a constant via Module#const_set if you need to have a > > named class for some reason. That might be a bit better than using > > eval() depending on the use case. > > Better, in the sense that it takes a block (see below). But evaling a > string to define the body of the class allows you to interpolate. > > def f(arg) > Class.new do > define_method :g do arg end > end > end > > puts f("hello").new.g # ==> hello You can even use the def syntax: irb(main):001:0> cl = Class.new do irb(main):002:1* def foo() "bar" end irb(main):003:1> end => # irb(main):004:0> cl.new.foo => "bar" That's better because then you can define methods that deal with blocks, which you can't with define_method: irb(main):005:0> cl = Class.new do irb(main):006:1* def foo() yield "bar" end irb(main):007:1> end => # irb(main):008:0> cl.new.foo {|x| p x} "bar" => nil Kind regards robert