Kernel#eval and class definition

Discussion in 'Ruby' started by Bertram Scharpf, Jan 11, 2005.

  1. 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
    def f ; eval "class C ; end", binding ; end

    Thanks for your answers in advance.

    Bertram

    --
    Bertram Scharpf
    Stuttgart, Deutschland/Germany
    http://www.bertram-scharpf.de
    Bertram Scharpf, Jan 11, 2005
    #1
    1. Advertising

  2. "Bertram Scharpf" <> schrieb im Newsbeitrag
    news:-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.

    HTH

    robert


    > Thanks for your answers in advance.
    >
    > Bertram
    >
    > --
    > Bertram Scharpf
    > Stuttgart, Deutschland/Germany
    > http://www.bertram-scharpf.de
    >
    >
    Robert Klemme, Jan 12, 2005
    #2
    1. Advertising

  3. Hi,

    In message "Re: Kernel#eval and class definition"
    on Wed, 12 Jan 2005 18:26:23 +0900, "Robert Klemme" <> 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.

    matz.
    Yukihiro Matsumoto, Jan 12, 2005
    #3
  4. Hi,

    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" <> 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.


    Ah, thank you both.

    Bertram

    --
    Bertram Scharpf
    Stuttgart, Deutschland/Germany
    http://www.bertram-scharpf.de
    Bertram Scharpf, Jan 12, 2005
    #4
  5. 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.
    Florian Gross, Jan 12, 2005
    #5
  6. 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
    Joel VanderWerf, Jan 12, 2005
    #6
  7. "Joel VanderWerf" <> schrieb im Newsbeitrag
    news:...
    > 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

    Kind regards

    robert
    Robert Klemme, Jan 13, 2005
    #7
  8. Bertram Scharpf

    Pit Capitain Guest

    Robert Klemme schrieb:
    > "Joel VanderWerf" <> schrieb im Newsbeitrag
    > news:...
    >>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.

    Regards,
    Pit
    Pit Capitain, Jan 13, 2005
    #8
  9. Bertram Scharpf

    ts Guest

    >>>>> "R" == Robert Klemme <> writes:

    R> That's better because then you can define methods that deal with blocks,
    R> which you can't with define_method:

    This is because you use strange name like #foo and "bar"and ruby don't
    like it :)


    uln% cat b.rb
    #!./ruby
    cl = Class.new do
    define_method:)alpha) do |&block|
    block["beta"]
    end
    end

    cl.new.alpha {|x| p x}
    uln%

    uln% b.rb
    "beta"
    uln%


    Guy Decoux
    ts, Jan 13, 2005
    #9
  10. "ts" <> schrieb im Newsbeitrag
    news:...
    > >>>>> "R" == Robert Klemme <> writes:

    >
    > R> That's better because then you can define methods that deal with

    blocks,
    > R> which you can't with define_method:
    >
    > This is because you use strange name like #foo and "bar"and ruby don't
    > like it :)


    Must be a new version of Ruby that doesn't like #foo and #bar - my 1.8.1
    has no problems with them. :))

    > uln% cat b.rb
    > #!./ruby
    > cl = Class.new do
    > define_method:)alpha) do |&block|
    > block["beta"]
    > end
    > end
    >
    > cl.new.alpha {|x| p x}
    > uln%
    >
    > uln% b.rb
    > "beta"
    > uln%


    Is this Ruby 1.9?

    robert
    Robert Klemme, Jan 13, 2005
    #10
  11. "Pit Capitain" <> schrieb im Newsbeitrag
    news:...
    > Robert Klemme schrieb:
    > > "Joel VanderWerf" <> schrieb im Newsbeitrag
    > > news:...
    > >>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!

    Kind regards

    robert
    Robert Klemme, Jan 13, 2005
    #11
  12. Bertram Scharpf

    ts Guest

    >>>>> "R" == Robert Klemme <> writes:

    R> Is this Ruby 1.9?

    yes,


    Guy Decoux
    ts, Jan 13, 2005
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jianli Shen
    Replies:
    1
    Views:
    580
    Victor Bazarov
    Mar 13, 2005
  2. yogesh
    Replies:
    3
    Views:
    584
    Kenny McCormack
    Feb 12, 2006
  3. Replies:
    3
    Views:
    166
  4. Lars Gierth
    Replies:
    6
    Views:
    217
    David Masover
    Mar 20, 2010
  5. Michael Granger
    Replies:
    0
    Views:
    439
    Michael Granger
    Jun 10, 2011
Loading...

Share This Page