Ruby 1.8.7 Lambas: syntax and scoping issue (are these bugs?

Discussion in 'Ruby' started by Charlton Wang, Dec 5, 2008.

  1. I'm seeing two odd behaviours with using lambdas:

    1. It seems as though having a lambda as a function argument with a
    block causes a syntax error. It can be mitigated by adding a semicolon
    or by using parentheses

    def foo(rest)
    puts rest.inspect
    yield
    end


    # fails syntax error
    foo :parm1=>1, :parm2=>lambda { puts "lambda" } do
    puts "In bar block"
    end

    # fails syntax error
    foo :parm1=>lambda { puts "lambda" }, :parm2=>1 do
    puts "In bar block"
    end

    # fails syntax error
    foo {:parm1=>1, :parm2=>lambda { puts "lambda" }} do
    puts "In bar block"
    end

    # succeeds???
    foo :parm1=>1, :parm2=>lambda { puts "lambda"; } do
    puts "In bar block"
    end

    # succeeds???
    foo :)parm1=>1, :parm2=>lambda { puts "lambda" }) do
    puts "In bar block"
    end

    2. I'm not understanding the scoping rules for lambda with
    instance_evals inside a class:

    # If these statements are added at the beginning the
    # the lambda will evaluate them first
    # a = 4 # stmt 1
    # b = 5 # stmt 2
    class Bar
    attr_accessor :a, :b
    def initialize
    @a = 1
    @b = 2
    end
    def foo(&block)
    instance_eval(&block)
    end
    end

    m = lambda{puts a + b}
    Bar.new.foo(&m)

    Without stmt1 and stmt2 above, the code correctly outputs 3. But if
    stmt1 and stmt2 are incommented, the output is 9 which seems to be the
    global scope rather than the scope of the instance of Bar expected
    with instance_eval.

    Am I missing something?

    Thanks,
    Charlton
    --
    Posted via http://www.ruby-forum.com/.
    Charlton Wang, Dec 5, 2008
    #1
    1. Advertising

  2. Hi --

    On Sat, 6 Dec 2008, Charlton Wang wrote:

    > I'm seeing two odd behaviours with using lambdas:


    I'm skipping to #2 if that's OK.

    > 2. I'm not understanding the scoping rules for lambda with
    > instance_evals inside a class:
    >
    > # If these statements are added at the beginning the
    > # the lambda will evaluate them first
    > # a = 4 # stmt 1
    > # b = 5 # stmt 2
    > class Bar
    > attr_accessor :a, :b
    > def initialize
    > @a = 1
    > @b = 2
    > end
    > def foo(&block)
    > instance_eval(&block)
    > end
    > end
    >
    > m = lambda{puts a + b}
    > Bar.new.foo(&m)
    >
    > Without stmt1 and stmt2 above, the code correctly outputs 3. But if
    > stmt1 and stmt2 are incommented, the output is 9 which seems to be the
    > global scope rather than the scope of the instance of Bar expected
    > with instance_eval.
    >
    > Am I missing something?


    When Ruby sees a and b, it favors the interpretation that they are
    local variables. If you want to ensure that they're interpreted as
    method calls, you can do:

    puts a() + b()


    David

    --
    Rails training from David A. Black and Ruby Power and Light:
    INTRO TO RAILS (Jan 12-15), Fort Lauderdale, FL
    See http://www.rubypal.com for details
    Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)
    David A. Black, Dec 5, 2008
    #2
    1. Advertising

  3. Charlton Wang wrote:

    > I'm seeing two odd behaviours with using lambdas:
    >
    > 1. It seems as though having a lambda as a function argument with a
    > block causes a syntax error. It can be mitigated by adding a semicolon
    > or by using parentheses
    >
    > def foo(rest)
    > puts rest.inspect
    > yield
    > end
    >
    >
    > # fails syntax error
    > foo :parm1=>1, :parm2=>lambda { puts "lambda" } do
    > puts "In bar block"
    > end


    The syntax is wrong whether or not you are passing
    a Proc object as an argument.

    def foo(rest)
    puts rest.inspect
    yield
    end
    ==>nil
    foo 'hello' { puts 'in block' }
    SyntaxError: compile error
    (irb):5: syntax error
    foo 'hello' { puts 'in block' }
    ^
    (irb):5: syntax error
    from (irb):5
    from :0
    foo( 'hello' ){ puts 'in block' }
    "hello"
    in block
    ==>nil
    foo( proc{p "I'm neither sheep nor lambda."} ){ puts 'in block' }
    #<Proc:0x02b14a5c@(irb):6>
    in block
    ==>nil
    William James, Dec 6, 2008
    #3
  4. Re: Ruby 1.8.7 Lambas: syntax and scoping issue (are these b

    Sorry, you lost me with your example.

    My block is being bound with do/end rather than {}. In your examples,
    you're using {} which has tighter binding and the syntax error is
    expected.

    foo 'hello' do puts 'in block'; end

    works just find but this isn't the same as what I'm asking. I'm binding
    the lambda function as a hash value.

    Or...maybe I'm missing something obvious.

    Charlton

    William James wrote:
    > Charlton Wang wrote:
    >
    >>
    >>
    >> # fails syntax error
    >> foo :parm1=>1, :parm2=>lambda { puts "lambda" } do
    >> puts "In bar block"
    >> end

    >
    > The syntax is wrong whether or not you are passing
    > a Proc object as an argument.
    >
    > def foo(rest)
    > puts rest.inspect
    > yield
    > end
    > ==>nil
    > foo 'hello' { puts 'in block' }
    > SyntaxError: compile error
    > (irb):5: syntax error
    > foo 'hello' { puts 'in block' }
    > ^
    > (irb):5: syntax error
    > from (irb):5
    > from :0
    > foo( 'hello' ){ puts 'in block' }
    > "hello"
    > in block
    > ==>nil
    > foo( proc{p "I'm neither sheep nor lambda."} ){ puts 'in block' }
    > #<Proc:0x02b14a5c@(irb):6>
    > in block
    > ==>nil


    --
    Posted via http://www.ruby-forum.com/.
    Charlton Wang, Dec 7, 2008
    #4
  5. Charlton Wang wrote:
    >
    > # fails syntax error
    > foo :parm1=>1, :parm2=>lambda { puts "lambda" } do
    > puts "In bar block"
    > end


    Curiously, that works in 1.9.

    I also noticed this succeeds in 1.8 (and 1.9):

    foo :parm1=>1, :parm2=>lambda { puts("lambda") } do
    puts "In bar block"
    end

    --
    Posted via http://www.ruby-forum.com/.
    The Higgs bozo, Dec 7, 2008
    #5
  6. Re: Ruby 1.8.7 Lambas: syntax and scoping issue (are these b

    The Higgs bozo wrote:
    > Charlton Wang wrote:
    >>
    >> # fails syntax error
    >> foo :parm1=>1, :parm2=>lambda { puts "lambda" } do
    >> puts "In bar block"
    >> end

    >
    > Curiously, that works in 1.9.
    >
    > I also noticed this succeeds in 1.8 (and 1.9):
    >
    > foo :parm1=>1, :parm2=>lambda { puts("lambda") } do
    > puts "In bar block"
    > end


    That's really interesting. So the parentheses as arguments to the puts
    make it work. How odd!

    --
    Posted via http://www.ruby-forum.com/.
    Charlton Wang, Dec 7, 2008
    #6
    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. Frederick Grim

    scoping issue

    Frederick Grim, Sep 12, 2003, in forum: C++
    Replies:
    4
    Views:
    409
    Gianni Mariani
    Sep 14, 2003
  2. asincero
    Replies:
    3
    Views:
    288
    Ravi Teja
    Aug 19, 2006
  3. Replies:
    3
    Views:
    417
  4. Josef 'Jupp' Schugt

    Still use 'ruby-bugs' for Ruby bugs?

    Josef 'Jupp' Schugt, Nov 4, 2004, in forum: Ruby
    Replies:
    2
    Views:
    160
    Tom Copeland
    Nov 4, 2004
  5. Philip Amadeo Saeli

    Noob Q: ruby block scoping question (ruby TK)

    Philip Amadeo Saeli, Apr 30, 2008, in forum: Ruby
    Replies:
    4
    Views:
    132
    Joel VanderWerf
    May 1, 2008
Loading...

Share This Page