"Bertram Scharpf" <lists@bertram-scharpf.de> schrieb im Newsbeitrag
news:20050111144155.GA19812@homer.bertram-scharpf...
Hi,
I try to understand more deeply what Ruby does.
Why here is the first line forbidden, the second allowed?
def f ; class C ; end ; end
This is a syntax error. The construct "class ... end" is simply
syntactically not allowed in a method. IMHO it doesn't make much sense
also, but that's another story.
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.
In message "Re: Kernel#eval and class definition" on Wed, 12 Jan 2005 18:26:23 +0900, "Robert Klemme" <bob.news@gmx.net> writes:
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.
Am Mittwoch, 12. Jan 2005, 18:43:42 +0900 schrieb Yukihiro Matsumoto:
In message "Re: Kernel#eval and class definition" > on Wed, 12 Jan 2005 18:26:23 +0900, "Robert Klemme" <bob.news@gmx.net> writes:
>> def f ; class C ; end ; end
>> def f ; eval "class C ; end", binding ; end
>
>The ruby code in the string
>expression is not syntactically located in method f.
class definition in the method is prohibited
by syntax just to detect errors.
>> 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.
>> 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
"Joel VanderWerf" <vjoel@PATH.Berkeley.EDU> 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
=> #<Class:0x10186208>
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
=> #<Class:0x10172468>
irb(main):008:0> cl.new.foo {|x| p x}
"bar"
=> nil
"Joel VanderWerf" <vjoel@PATH.Berkeley.EDU> schrieb im Newsbeitrag
news:41E55294.2040102@path.berkeley.edu...
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
=> #<Class:0x10186208>
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
=> #<Class:0x10172468>
irb(main):008:0> cl.new.foo {|x| p x}
"bar"
=> nil
The def syntax lets you define methods with blocks, but it doesn't let you use objects from the defining scope, as Joel has been doing in his example. Note that he passes an object into the defining method and accesses this very object from the new class. You can't do that with the def syntax AFAIK.
"Pit Capitain" <pit@capitain.de> schrieb im Newsbeitrag
news:41E64CD5.6010703@capitain.de...
Robert Klemme schrieb:
> "Joel VanderWerf" <vjoel@PATH.Berkeley.EDU> schrieb im Newsbeitrag
> news:41E55294.2040102@path.berkeley.edu...
>>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
> => #<Class:0x10186208>
> 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
> => #<Class:0x10172468>
> irb(main):008:0> cl.new.foo {|x| p x}
> "bar"
> => nil
The def syntax lets you define methods with blocks, but it doesn't let
you use
objects from the defining scope, as Joel has been doing in his example.
Note
that he passes an object into the defining method and accesses this very
object
from the new class. You can't do that with the def syntax AFAIK.
Yeah, true. So then both have their pros and cons. Thanks for the
reminder!