Why I can not use my own blocks in 1.9?

I

Ivan Samonov

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?
 
F

Florian Frank

Ivan said:
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.
 
R

Robert Klemme

Ivan said:
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
 
7

7stud --

Florian said:
Ivan said:
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
 
D

David A. Black

Hi --

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

7stud --

David said:
Hi --



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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top