Skip to content

Commit

Permalink
Added mirror for Proc#curry. Improves #3406.
Browse files Browse the repository at this point in the history
There is still a lot of cruft in the Rubinius kernel but generally we use the
mirror facility to implement methods that are not public Ruby API methods (and are
generally C functions in MRI).
  • Loading branch information
brixen committed May 25, 2015
1 parent f1f0d75 commit 93a80e0
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 18 deletions.
1 change: 1 addition & 0 deletions kernel/common/load_order.txt
Expand Up @@ -5,6 +5,7 @@ autoload.rbc
module.rbc
binding.rbc
proc.rbc
proc_mirror.rbc
enumerable_helper.rbc
enumerable.rbc
enumerator.rbc
Expand Down
20 changes: 2 additions & 18 deletions kernel/common/proc.rb
Expand Up @@ -14,23 +14,6 @@ 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 @@ -111,7 +94,8 @@ def curry(curried_arity = nil)

args = []

f = Proc.__make_curry_proc__(self, [], arity)
m = Rubinius::Mirror.reflect self
f = m.curry self, [], arity

f.singleton_class.send(:define_method, :binding) {
raise ArgumentError, "cannot create binding from f proc"
Expand Down
20 changes: 20 additions & 0 deletions kernel/common/proc_mirror.rb
@@ -0,0 +1,20 @@
module Rubinius
class Mirror
class Proc < Mirror
def curry(executable, args, arity)
args.freeze

name = executable.lambda? ? :lambda : :proc

Proc.__send__(name) do |*a, &b|
all_args = args + a
if all_args.size < arity
curry executable, all_args, arity
else
executable[*all_args]
end
end
end
end
end
end

0 comments on commit 93a80e0

Please sign in to comment.