クラスで結合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
これは、のアリティが->x{x % 5 == 0}is1であるのに対し、のアリティはp私の実装-1によるものであるためです。call(*args)
メソッドを作成して再帰的Proc#*に動作させる良い方法はありますか?Proc#+
定義からを削除する
raise ...と機能しますが、アリティが異なるプロシージャが結合/分離されたときに、誤解を招くエラー メッセージが返されます。たとえば、raise ...上記の定義からパーツが削除されたとします。
p = ->x{x % 2 == 0} * ->x, y, z{x % 3 == 0}
その後Proc#*、エラーは発生しませんが、有効な proc オブジェクトが返されます。pただし、その一部は 1 つの引数を必要とし、別の部分は 3 つの引数を必要とするため、有効な方法で引数を渡す方法がありません。
p.call(2) # => error
を発生させ、次のようArgumentErrorに言います。
Wrong number of arguments
しかし、作成時に実際に発生した間違いはp、任意の数の引数で満たすことができず、エラー メッセージが誤解を招く可能性があります。そのため、raise ...チェックを追加しました。raise ...それを機能させる唯一の方法を削除していますか?