为简单起见,让我们假设以下方法:
def inner(p)
%w(a b c d).each {|x| yield("#{p} inner #{x}")}
end
我想要一个函数outer
,它与inner
相同,但是参数p
绑定到某个值,例如
def outer
inner('haha') // This is NOT correct. It's just to give you an idea.
end
这不起作用:如果我做了
outer {|q| puts q}
我得到一个 LocalJumpError:产量超出范围。
一种解决方法显然是:
def outer
inner('haha') { |x| yield(x) }
end
不是很优雅,因为一个 yield 仅产生下一个 yield 。一种更简洁的方法是显式地传递该块:
def inner(p, &block)
%w(a b c d).each {|x| block.yield("#{p} inner #{x}")}
end
def outer(&block)
inner('haha', &block)
end
尽管有人可能认为无论如何都要明确地编写block参数是更好的解决方案,因为我们可以从方法签名中看到已经预料到了一个块,但我仍然想知道是否存在一种干净的方法来实现我的目标而不用&block
参数。
更新:修复代码中缺少&
的情况。
答案 0 :(得分:1)
这很好
def inner(p)
%w(a b c d).each {|x| yield("#{p} inner #{x}")}
end
def outer(&block)
inner('haha', &block)
end
def outer(&block)
inner('haha', &block)
end
outer {|haha_and_item| puts haha_and_item}
# haha inner a
# haha inner b
# haha inner c
# haha inner d
outer
似乎只是包装方法,其唯一目的是存储字符串haha
。然后,它接受将根据Proc
方法定义相应执行的块或inner
。
如果您想使用一种方法,那么您的示例就是我所知道的唯一可用语法。但是看来您正在寻找closure
或carried one。
这里是一个例子:
def inner(parameter)
inner_closure = -> (runable) do
%w(a b c d).each { |x| runable.("#{parameter} inner #{x}") }
end
inner_closure.curry
end
parameter = 'ahah'
runable = proc {|haha_and_item| puts haha_and_item}
outer = inner(parameter)
outer[runable]
outer = inner('closure')
outer[runable]
# ahah inner a
# ahah inner b
# ahah inner c
# ahah inner d
# closure inner a
# closure inner b
# closure inner c
# closure inner d