我正在尝试在类上定义合取Proc#*
和析取。当接收者和参数的数量不同时,它应该引发错误。否则,它应该分别返回一个联合/析取的 proc 对象。我实现它们如下:Proc#+
Proc
class Proc
def * other
raise ArgumentError, "Arity does not match" unless arity == other.arity
->(*args){call(*args) and other.call(*args)}
end
def + other
raise ArgumentError, "Arity does not match" unless arity == other.arity
->(*args){call(*args) or other.call(*args)}
end
end
这适用于简单的过程:
p = ->x{x % 2 == 0} * ->x{x % 3 == 0}
p.call(2) # => false
p.call(6) # => true
但是当我进一步尝试构建这些方法的结果时,它会引发错误:
q = p * ->x{x % 5 == 0}
# => Error, Arity does not match
这是因为 is 的 arity ,而->x{x % 5 == 0}
is的arity在我的实现中。1
p
-1
call(*args)
有什么好的方法可以使方法Proc#*
和Proc#+
递归工作吗?
如果我
raise ...
从定义中删除 ,那么它将起作用,但是,当具有不同 arity 的 proc 结合/分离时,它将返回误导性错误消息。例如,假设raise ...
从上面的定义中删除了该部分,我这样做:
p = ->x{x % 2 == 0} * ->x, y, z{x % 3 == 0}
thenProc#*
不会引发错误,但会返回一个有效的 proc 对象。但是,由于它的一部分需要一个参数,而另一部分需要三个参数,因此无法以p
有效的方式将参数传递给。
p.call(2) # => error
会提出一个ArgumentError
,说:
Wrong number of arguments
但是错误实际上是在创建p
不能满足任何数量的参数时发生的,并且错误消息会产生误导。这就是我添加raise ...
支票的原因。删除是raise ...
使其工作的唯一方法吗?