https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112014-04-27T01:06:01ZRuby Issue Tracking SystemRuby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=463322014-04-27T01:06:01Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/46332/diff?detail_id=33431">diff</a>)</li></ul><p>Richard Schneeman wrote:</p>
<blockquote>
<p>Currently different block objects such as a lambda can be converted into to a proc: <a href="http://www.ruby-doc.org/core-1.9.3/Proc.html#method-i-to_proc" class="external">http://www.ruby-doc.org/core-1.9.3/Proc.html#method-i-to_proc</a></p>
</blockquote>
<p>It changes nothing, but returns <code>self</code> as-is, without any effects.</p> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=463332014-04-27T01:14:36Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Feedback</i></li></ul><p>Why can't you use <code>break</code> and <code>next</code>?</p> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=463532014-04-28T17:55:50Zschneems (Richard Schneeman)
<ul></ul><p>Sorry for the delayed response. I was not "watching" this issue by default.</p>
<blockquote>
<p>Why can't you use break and next?</p>
</blockquote>
<p>I wanted this to make a public api based on anonymous functions: <a href="https://github.com/opro/opro#password-token-exchange" class="external">https://github.com/opro/opro#password-token-exchange</a> (note the return used in this section towards the bottom). New developers know the semantics of <code>return</code> very well but the differences between <code>lambda</code> and <code>Proc</code> are confusing to them, they are not familiar with the <code>break</code> keyword. If i tell new developers to use this API, create a block, and use <code>break</code> many would not do so and still use <code>return</code> by accident. This is my use-case, but others may have different or better ones. As mentioned 16 people were interested in this enough to google it, find the stack overflow post and up-vote the answer.</p> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=463572014-04-29T00:36:31Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p><code>return</code> in a proc exits the defined method, unless it has returned already.<br>
Turning a proc into a lambda disappoints that expectation.<br>
It doesn't feel a good idea.</p> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=463692014-04-29T16:20:23Zavit (Andrew Vit)andrew@avit.ca
<ul></ul><p>Would it work to just wrap it inside a lambda to get the semantics you want?</p> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=463712014-04-29T19:02:22Zschneems (Richard Schneeman)
<ul></ul><p>Andrew Vit wrote:</p>
<blockquote>
<p>Would it work to just wrap it inside a lambda to get the semantics you want?</p>
</blockquote>
<p>Like <code>lambda &proc</code>? That would be fine. As Nobu mentioned Proc and lambda behave differently, sometimes I want control over the behavior of my program so I want the ability to change the object I am using from proc to lambda or lambda to proc.</p>
<p>When I made the original request I did not know that <code>lambda#to_proc</code> was basically a no-op. I thought it actually changed the behavior.</p> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=463722014-04-29T19:10:56Zavit (Andrew Vit)andrew@avit.ca
<ul></ul><p>I find that using <code>throw</code> is useful in the situation you describe. It gives a nice explicit message about what's going: it's like a multi-level return to the point where you want to <code>catch</code> it.</p> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=465762014-05-06T17:17:20Zschneems (Richard Schneeman)
<ul></ul><p>Another possible reason to convert a Proc to a lambda is to for raising error on arguments</p>
<pre><code>foo = -> { puts "hello" }
foo.call(1)
ArgumentError: wrong number of arguments (1 for 0)
from (irb):4:in `block in irb_binding'
from (irb):5:in `call'
from (irb):5
from /Users/schneems/.rubies/ruby-2.1.1/bin/irb:11:in `<main>'
bar = Proc.new { puts "hello" }
bar.call(1)
# => "hello"
</code></pre>
<p>If a user passes in a proc there will be no errors or warnings that the proc was improperly declared. Converting to a lambda would change the behavior to then raise an error.</p> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=465812014-05-07T00:08:26Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>If a user wanted to write it as a proc, then it means that he/she doesn't want it to raise error, doesn't it?</p> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=466072014-05-08T00:28:34Zkernigh (George Koehler)xkernigh@netscape.net
<ul></ul><p>Beware! The answer on Stack Overflow (<a href="http://stackoverflow.com/a/2946734" class="external">http://stackoverflow.com/a/2946734</a>) is wrong, because it does not preserve the value of <code>self</code> in the block.</p>
<p>This is better, but still wrong:</p>
<pre><code>def convert_to_lambda &block
obj = block.binding.eval('self')
Module.new do
define_method(:_, &block)
return instance_method(:_).bind(obj).to_proc
end
end
</code></pre>
<p>It preserves <code>self</code> in the block, but it fails when I pass the lambda to <code>#instance_exec</code> or <code>#module_exec</code>. I will try to post explanation to Stack Overflow.</p>
<p>There is no way to convert proc to lambda, unless Ruby adds a new feature.</p>
<p>I have no reason to support this new feature. I am not wanting libraries to convert my blocks to lambdas. I know how to use <code>next</code>. If someone converts my block to a lambda, then my block can no longer <code>return</code> from the enclosing method, or ignore extra arguments. If I want my block to be a lambda, I can write <code>&-></code>, as in</p>
<pre><code>3.times &->(_) { puts "It works!" }
</code></pre> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=473172014-06-21T07:27:46Zmyronmarston (Myron Marston)myron.marston@gmail.com
<ul></ul><p>We have a need for this feature in RSpec. Specifically, for some of the new features in RSpec 3, we use <code>Method#parameters</code> and <code>Proc#parameters</code>. However, for procs, <code>parameters</code> does not distinguish between args with defaults and args without:</p>
<pre><code>irb(main):001:0> Proc.new { |a| }.parameters
=> [[:opt, :a]]
irb(main):002:0> Proc.new { |a=1| }.parameters
=> [[:opt, :a]]
</code></pre>
<p>I understand why, because with procs you can call it without providing the args so all args are optional and it's essentailly like <code>|a=nil|</code>. Lambdas, on the other hand, do distinguish:</p>
<pre><code>irb(main):003:0> lambda { |a| }.parameters
=> [[:req, :a]]
irb(main):004:0> lambda { |a=1| }.parameters
=> [[:opt, :a]]
</code></pre>
<p>I attempted to use some code like @schneem's gem to convert a proc to a lambda for the purpose of looking at the parameters (but, importantly, not to call the lambda). Unfortunately, we ran into a ruby bug (<a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: `define_method(:name, &block)` breaks the use of the block on its own (Closed)" href="https://redmine.ruby-lang.org/issues/9967">#9967</a>) and had to back it out.</p>
<p>It would be nice for an officially supported solution to convert a proc to a lambda. I can understand the issues with calling a converted lambda, but simply using the converted lambda to get more precise info about the block parameters seems more reasonable and safe.</p> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=692822018-01-05T21:00:27Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Target version</strong> deleted (<del><i>2.2.0</i></del>)</li></ul> Ruby master - Feature #9777: Feature Proposal: Proc#to_lambdahttps://redmine.ruby-lang.org/issues/9777?journal_id=793402019-07-12T05:20:25Zakr (Akira Tanaka)akr@fsij.org
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-5 priority-4 priority-default closed" href="/issues/15973">Feature #15973</a>: Let Kernel#lambda always return a lambda</i> added</li></ul>