ruby – 我可以对传递给方法的块强制执行arity吗?
发布时间:2020-12-16 23:04:50 所属栏目:百科 来源:网络整理
导读:有没有办法“打开”使用Proc.new或Kernel.proc实例化的Proc的严格执行,这样它的行为就像用lambda实例化的Proc? 我的初始化方法采用块和操作并将其分配给实例变量.我希望动作严格执行arity,所以当我稍后向它应用参数时,它会引发一个ArgumentError,我可以挽救
有没有办法“打开”使用Proc.new或Kernel.proc实例化的Proc的严格执行,这样它的行为就像用lambda实例化的Proc?
我的初始化方法采用块和操作并将其分配给实例变量.我希望动作严格执行arity,所以当我稍后向它应用参数时,它会引发一个ArgumentError,我可以挽救并引发一个更有意义的异常.基本上: class Command attr_reader :name,:action def initialize(name,&action) @name = name @action = action end def perform(*args) begin action.call(*args) rescue ArgumentError raise(WrongArity.new(args.size)) end end end class WrongArity < StandardError; end 不幸的是,默认情况下,操作不会强制执行arity: c = Command.new('second_argument') { |_,y| y } c.perform(1) # => nil action.to_proc不起作用,也不起作用(& action). 还有其他想法吗?或者更好地解决问题? 谢谢! 解决方法
你的@action将是一个Proc实例,Procs有一个
arity 方法,所以你可以检查该块应该有多少个参数:
def perform(*args) if args.size != @action.arity raise WrongArity.new(args.size) end @action.call(*args) end 那应该照顾像{| a |这样的无拼接块……}和{| a,b | ……}但是随着splats事情有点复杂.如果您有像{| * a |这样的块…}然后@ action.arity将为-1和{| a,* b | ……}会给你一个-2的智商.具有arity -1的块可以使用任意数量的参数(包括无参数),具有arity -2的块至少需要一个参数但可以使用更多参数,依此类推. splatless测试的简单修改应该照顾splatful块: def perform(*args) if @action.arity >= 0 && args.size != @action.arity raise WrongArity.new(args.size) elsif @action.arity < 0 && args.size < -(@action.arity + 1) raise WrongArity.new(args.size) end @action.call(*args) end (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |