Project

General

Profile

Feature #7314

Convert Proc to Lambda doesn't work in MRI

Added by Richard Schneeman over 3 years ago. Updated 3 months ago.

Status:
Assigned
Priority:
Normal
[ruby-core:49112]

Description

=begin

I have code where I need to convert a proc to a lambda (i need to be able to return out of the block). I would expect that passing a proc into a lambda to return a lambda. When I run this code on MRI i do not get the result I would expect

my_proc = proc { |x| x }
my_lambda = lambda &my_proc
my_lambda.lambda?

The result is (({false})) but I would expect it to be (({true}))

There is currently a way to turn a proc into a lambda in MRI like this:

def convert_to_lambda &block
obj = Object.new
obj.define_singleton_method(:, &block)
return obj.method(:
).to_proc
end

But this feels like a hack, and is not supported across other implementations. I would expect that passing a proc into a lambda to return a lambda, I believe it is a bug.

=end

History

#1 Updated by Shyouhei Urabe over 3 years ago

  • Tracker changed from Bug to Feature

Moved this to feature tracker. I think you are feeling this like a hack because, you are in fact doing something hacky (return from a block).

Anyway I'm not against that kind of feature, though I'm not sure if that can be achieved by lambda(&proc). So I feel a needs of discussion.

#2 [ruby-core:49180] Updated by Richard Schneeman over 3 years ago

I would like a standard way to turn a Proc into a lambda even if it cannot be achieved through lambda(&proc). I don't know if it will affect the outcome, but jRuby correctly returns a lambda from lambda(&proc) in 1.9 mode.

#3 [ruby-core:49946] Updated by Yusuke Endoh over 3 years ago

  • Status changed from Open to Assigned
  • Assignee set to Yukihiro Matsumoto
  • Target version set to next minor

Matz will require a use case, I guess.

--
Yusuke Endoh mame@tsg.ne.jp

#4 [ruby-core:73562] Updated by Andrew Vit 3 months ago

Use case: a stored block gets called with a "target" as first parameter, plus optional arguments. If the target object is an array, then the behaviour is unpredictable:

lm = lambda { |target, *options| puts target.inspect, options.inspect }
pr = proc   { |target, *options| puts target.inspect, options.inspect }

lm.call([1,2], 'a')  #=> [1, 2], ["a"]
pr.call([1,2], 'a')  #=> [1, 2], ["a"]

lm.call([1,2])  #=> [1, 2], []
pr.call([1,2])  #=> 1, [2]

Note how calling the block with only a single array destructures the "target" argument.
If we need to avoid destructuring, a lambda does the right thing, so converting it would be helpful.

Also available in: Atom PDF