Skip to content

Commit

Permalink
ported over jruby's fix for Proc#curry, this closes #2951
Browse files Browse the repository at this point in the history
  • Loading branch information
tak1n committed May 23, 2015
1 parent 621953b commit e5def49
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
29 changes: 18 additions & 11 deletions kernel/common/proc.rb
Expand Up @@ -14,6 +14,23 @@ def self.__from_block__(env)
end
end

def self.__make_curry_proc__(proc, passed, arity)
is_lambda = proc.lambda?
passed.freeze

__send__((is_lambda ? :lambda : :proc)) do |*argv, &passed_proc|
my_passed = passed + argv
if my_passed.length < arity
if !passed_proc.nil?
warn "#{caller[0]}: given block not used"
end
__make_curry_proc__(proc, my_passed, arity)
else
proc.call(*my_passed)
end
end
end

def self.new(*args)
env = nil

Expand Down Expand Up @@ -94,17 +111,7 @@ def curry(curried_arity = nil)

args = []

my_self = self
m = lambda? ? :lambda : :proc
f = __send__(m) {|*x|
call_args = args + x
if call_args.length >= my_self.arity
my_self[*call_args]
else
args = call_args
f
end
}
f = Proc.__make_curry_proc__(self, [], arity)

f.singleton_class.send(:define_method, :binding) {
raise ArgumentError, "cannot create binding from f proc"
Expand Down
16 changes: 13 additions & 3 deletions spec/ruby/core/proc/curry_spec.rb
Expand Up @@ -59,17 +59,17 @@
l = lambda { |*a| }
l.curry.arity.should == -1
end

it "produces Procs that raise ArgumentError for #binding" do
lambda do
@proc_add.curry.binding
end.should raise_error(ArgumentError)
end

it "produces Procs that return [[:rest]] for #parameters" do
@proc_add.curry.parameters.should == [[:rest]]
end

it "produces Procs that return nil for #source_location" do
@proc_add.curry.source_location.should == nil
end
Expand All @@ -79,6 +79,16 @@

instance_exec(3, &curried).should == 6
end

it "combines arguments and calculates incoming arity accurately for successively currying" do
l = lambda{|a,b,c| a+b+c }
l1 = l.curry.call(1)
# the l1 currying seems unnecessary, but it triggered the original issue
l2 = l1.curry.call(2)

l2.curry.call(3).should == 6
l1.curry.call(2,3).should == 6
end
end

describe "Proc#curry with arity argument" do
Expand Down

0 comments on commit e5def49

Please sign in to comment.