我之前遇到过这种情况,有些东西告诉我我一般处理它的方式不是最干净或最惯用的.
假设我有一个带块的函数,它可以依次取1或2个(比如说)参数.
def with_arguments(&block)
case block.arity
when 1
block.call("foo")
when 2
block.call("foo", "bar")
end
end
with_arguments do |x|
puts "Here's the argument I was given: #{x}"
end
with_arguments do |x, y|
puts "Here are the arguments I was given: #{x}, #{y}"
end
Run Code Online (Sandbox Code Playgroud)
打开arity看起来很漂亮.是否有更标准的Ruby方法来实现这种事情?
这是我如何将任意参数传递给lambda:
def with_arguments(&block)
args = %w(foo bar)
n = block.arity
block.call *(n < 0 ? args : args.take(n))
end
with_arguments &lambda { |foo| }
with_arguments &lambda { |foo, bar| }
with_arguments &lambda { |*args| }
with_arguments &lambda { |foo, *args| }
with_arguments &lambda { |foo, bar, *args| }
Run Code Online (Sandbox Code Playgroud)
如果n是否定的,则lambda采用任意数量的参数.准确地说(n + 1).abs,这些论点是强制性的.可以使用该信息来决定要传递的参数.
如果lambda获取有限数量的参数,那么只需传递第一个n元素args.如果它需要任意数量的参数,那么只需传递整个参数数组.
在lambda本身将处理情况下args是不够的:
with_arguments &lambda { |foo, bar, baz, *args| }
# ArgumentError: wrong number of arguments (2 for 3)
Run Code Online (Sandbox Code Playgroud)
您只需将两个参数传递给块:
def with_arguments(&block)
block.call 'foo', 'bar'
end
with_arguments { |x| puts x } # y is not used
with_arguments { |x, y| puts x, y } # All arguments are used
with_arguments { |x, y, z| puts x, y, z } # z will be nil
Run Code Online (Sandbox Code Playgroud)
将丢弃未使用的块参数,并将任何其他参数设置为nil.
这是常规块特有的,Proclambda如果给出错误的参数数量,s - s将引发错误.您实际上可以通过调用来确定是否是这种情况Proc#lambda?
此外,如果您不打算存储块,只需使用它就更简洁yield:
def with_arguments
yield 'foo', 'bar'
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1076 次 |
| 最近记录: |