From: "jballanc (Joshua Ballanco)" Date: 2012-04-03T16:54:27+09:00 Subject: [ruby-core:44099] [ruby-trunk - Feature #4610] Proc#curry behavior is inconsistent with lambdas containing default argument values Issue #4610 has been updated by jballanc (Joshua Ballanco). =begin I have just tried with 2.0 and keyword args, and I think the situation is now more confusing. Now, if one wants to pass alternate values for optional arguments, the only way to do so it with the last call like so: >> l = ->(a, b, foo: 'hello', bar: 'world') { puts a, b, "#{foo}, #{bar}" } => # >> l.(1,2) 1 2 hello, world => nil >> c = l.curry => # >> c = c.(1) => # >> c.(bar: 'moon') ArgumentError: wrong number of arguments (1 for 2) from (irb):1:in `block in irb_binding' from (irb):5:in `call' from (irb):5 from ./bin/irb:12:in `
' >> c.(2) 1 2 hello, world => nil >> c.(2, bar: 'moon', foo: 'goodnight') 1 2 goodnight, moon => nil Unfortunately, there is no way to know when one is about to make the last call on a curried proc, since the arity is always reported as -1: >> l.arity => 2 >> c = l.curry => # >> c.arity => -1 >> c = c.(1) => # >> c.arity => -1 I very much like the proposal for a Proc#pass_option method. Should this be reopened or shall I file a separate bug for the implementation of Proc#pass_option? =end ---------------------------------------- Feature #4610: Proc#curry behavior is inconsistent with lambdas containing default argument values https://bugs.ruby-lang.org/issues/4610#change-25628 Author: jballanc (Joshua Ballanco) Status: Rejected Priority: Normal Assignee: mame (Yusuke Endoh) Category: Target version: If I curry a lambda with 3 arguments, then I can call three times with one argument each time to get the desired results: ruby-1.9.2-p180 :001 > l = ->(a, b, c) { puts "#{a}, #{b}, #{c}" } # ruby-1.9.2-p180 :002 > c = l.curry # ruby-1.9.2-p180 :003 > c.('one').('two').('three') one, two, three nil However, if the lambda has default values and I curry it, the entire lambda is evaluated after the first #call: ruby-1.9.2-p180 :004 > l = ->(a = 'ichi', b = 'ni', c = 'san') { puts "#{a}, #{b}, #{c}" } # ruby-1.9.2-p180 :005 > c = l.curry # ruby-1.9.2-p180 :006 > c.('one').('two').('three') one, ni, san NoMethodError: undefined method `call' for nil:NilClass This behavior seem very inconsistent. Ideally, if I wanted to use the default argument at a certain position in a currie proc, I would just #call with no arguments, like so: ruby-1.9.2-p180 :007 > c.('one').().('three') #=> Propose that this result in: "one, ni, three" -- http://bugs.ruby-lang.org/