Why I can not use my own blocks in 1.9?

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?

z = lambda {|x| x[0] <=> x[1]}
[3,2,1].max(&z) # => 3

it works in 1.9!

Ivan S. 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.

On 10/07/2009 12:48 PM, Florian F. wrote:

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:[email protected](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

Florian F. wrote:

Ivan S. 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

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

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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs