Why I can not use my own blocks in 1.9?

Discussion in 'Ruby' started by Ivan Samonov, Oct 7, 2009.

  1. Ivan Samonov

    Ivan Samonov Guest

    Example:
    1.8.7:
    a = lambda {|x,y| x <=> y}
    [1,2,3].max(&a) # => 3
    1.9.1:
    z = lambda {|x,y| x <=> y}
    [3,2,1].max(&z) # => ArgumentError: wrong number of arguments (1 for 2)

    wtf?
    --
    Posted via http://www.ruby-forum.com/.
     
    Ivan Samonov, Oct 7, 2009
    #1
    1. Advertising

  2. Ivan Samonov

    Ivan Samonov Guest

    Ivan Samonov, Oct 7, 2009
    #2
    1. Advertising

  3. Ivan Samonov wrote:
    > Example:
    > 1.8.7:
    > a = lambda {|x,y| x <=> y}
    > [1,2,3].max(&a) # => 3
    > 1.9.1:
    > z = lambda {|x,y| x <=> y}
    > [3,2,1].max(&z) # => ArgumentError: wrong number of arguments (1 for 2)
    >
    > wtf?
    >

    lambda does arity checking in 1.9 as opposed to proc that doesn't (they
    aren't synonymous anymore). You can work around this problem by using
    this definition for the order predicate:

    z = proc { |x,y| x <=> y}

    1.9 obviously just passes an array to the block via rb_yield which used
    to make sense in 1.8. But now using rb_yield_values probably would be
    better to give users a hint about the expected predicate.

    --
    Florian Frank
     
    Florian Frank, Oct 7, 2009
    #3
  4. On 10/07/2009 12:48 PM, Florian Frank wrote:
    > Ivan Samonov wrote:
    >> Example:
    >> 1.8.7:
    >> a = lambda {|x,y| x <=> y}
    >> [1,2,3].max(&a) # => 3
    >> 1.9.1:
    >> z = lambda {|x,y| x <=> y}
    >> [3,2,1].max(&z) # => ArgumentError: wrong number of arguments (1 for 2)
    >>
    >> wtf?
    >>

    > lambda does arity checking in 1.9 as opposed to proc that doesn't (they
    > aren't synonymous anymore). You can work around this problem by using
    > this definition for the order predicate:
    >
    > z = proc { |x,y| x <=> y}
    >
    > 1.9 obviously just passes an array to the block via rb_yield which used
    > to make sense in 1.8. But now using rb_yield_values probably would be
    > better to give users a hint about the expected predicate.


    This has worked in 1.9.0:

    irb(main):001:0> RUBY_VERSION
    => "1.9.0"
    irb(main):002:0> l = lambda {|a,b| a <=> b}
    => #<Proc:0x9522a5c@(irb):2 (lambda)>
    irb(main):003:0> [3,2,1].sort(&l)
    => [1, 2, 3]

    Darn, I wasn't aware that the 1.9 on ubuntu is that old. Looks like I
    need to do a manual build.

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Oct 7, 2009
    #4
  5. Ivan Samonov

    7stud -- Guest

    Florian Frank wrote:
    > Ivan Samonov wrote:
    >> Example:
    >> 1.8.7:
    >> a = lambda {|x,y| x <=> y}
    >> [1,2,3].max(&a) # => 3
    >> 1.9.1:
    >> z = lambda {|x,y| x <=> y}
    >> [3,2,1].max(&z) # => ArgumentError: wrong number of arguments (1 for 2)
    >>
    >> wtf?
    >>

    > lambda does arity checking in 1.9 as opposed to proc that doesn't (they
    > aren't synonymous anymore). You can work around this problem by using
    > this definition for the order predicate:
    >
    > z = proc { |x,y| x <=> y}
    >
    > 1.9 obviously just passes an array to the block via rb_yield which used
    > to make sense in 1.8. But now using rb_yield_values probably would be
    > better to give users a hint about the expected predicate.


    How is it that both the following calls to test() work:

    def test
    yield [10, "red"]
    end

    test {|x| p x}
    puts

    test do |x, y|
    p x
    puts "--"
    p y
    end

    --output:--
    [10, "red"]

    10
    --
    "red"


    After all, this doesn't work:

    def test(x, y)
    p x
    p y
    end

    test([10, "red"])

    --output:--
    `test': wrong number of arguments (1 for 2) (ArgumentError)
    from r1test.rb:19

    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, Oct 8, 2009
    #5
  6. Hi --

    On Thu, 8 Oct 2009, 7stud -- wrote:

    > How is it that both the following calls to test() work:
    >
    > def test
    > yield [10, "red"]
    > end
    >
    > test {|x| p x}
    > puts
    >
    > test do |x, y|
    > p x
    > puts "--"
    > p y
    > end
    >
    > --output:--
    > [10, "red"]
    >
    > 10
    > --
    > "red"
    >
    >
    > After all, this doesn't work:
    >
    > def test(x, y)
    > p x
    > p y
    > end
    >
    > test([10, "red"])
    >
    > --output:--
    > `test': wrong number of arguments (1 for 2) (ArgumentError)
    > from r1test.rb:19


    Lambda-flavored Proc objects are fussier about arity than
    non-lambda-flavored ones. For example:

    def test
    yield(1)
    end

    test(&proc {|x,y| puts "Will get here in 1.9.1"})
    test(&lambda {|x,y| puts "Won't get here in 1.9.1"})

    Output:

    Will get here in 1.9.1
    -:2:in `test': wrong number of arguments (1 for 2) (ArgumentError)

    So the lambda is more method-like in this particular respect than the
    non-lambda Proc (since methods, likewise, care about arity).


    David

    --
    The Ruby training with D. Black, G. Brown, J.McAnally
    Compleat Jan 22-23, 2010, Tampa, FL
    Rubyist http://www.thecompleatrubyist.com

    David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)
     
    David A. Black, Oct 8, 2009
    #6
  7. Ivan Samonov

    7stud -- Guest

    David A. Black wrote:
    > Hi --
    >
    > On Thu, 8 Oct 2009, 7stud -- wrote:
    >
    >> p x
    >>
    >> --output:--
    >> `test': wrong number of arguments (1 for 2) (ArgumentError)
    >> from r1test.rb:19

    >
    > Lambda-flavored Proc objects are fussier about arity than
    > non-lambda-flavored ones. For example:
    >
    > def test
    > yield(1)
    > end
    >
    > test(&proc {|x,y| puts "Will get here in 1.9.1"})
    > test(&lambda {|x,y| puts "Won't get here in 1.9.1"})
    >
    > Output:
    >
    > Will get here in 1.9.1
    > -:2:in `test': wrong number of arguments (1 for 2) (ArgumentError)
    >
    > So the lambda is more method-like in this particular respect than the
    > non-lambda Proc (since methods, likewise, care about arity).
    >
    >


    Ok. I get that. What I don't understand is how a yield statement
    decides how to distribute its arguments to the parameter variables
    specified for a block. In a method call, you have to use * to 'explode'
    an array into its individual elements, which will cause the individual
    elements to be assigned to the various parameter variables. yield seems
    to act differently. In one case, it assigns a whole array to a single
    parameter variable, and in another case it explodes the array into its
    individual elements and assigns the elements to the parameter variables.

    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, Oct 8, 2009
    #7
    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. Arjen
    Replies:
    3
    Views:
    454
    Scott Allen
    Feb 27, 2005
  2. Peter Rilling
    Replies:
    2
    Views:
    405
    news.microsoft.com
    Apr 5, 2005
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,077
    Smokey Grindel
    Dec 2, 2006
  4. matt
    Replies:
    1
    Views:
    285
    George Ogata
    Aug 6, 2004
  5. Steven Taylor
    Replies:
    9
    Views:
    271
    Brian Candler
    Apr 27, 2009
Loading...

Share This Page