クラスで結合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 ...
それを機能させる唯一の方法を削除していますか?