Ruby keep_if
およびdelete_if
配列メソッドのクローンを作成しようとしています。これが私のコードです。
module Strain
def keep
self.inject([]) do |extracts, element|
yield(element) ? extracts << element : extracts
end
end
def discard
self.inject([]) do |extracts, element|
!yield(element) ? extracts << element : extracts
end
end
end
class Array
include Strain
end
これは機能します。しかし、私は次のようなことをしたいと思います。
def discard
self - self.keep &block
end
望ましい行動:
[1, 2, 3].discard { |number| number < 2 }
# => [2, 3]
したがって、discard
メソッドに渡されるブロックを、keep
メソッドに渡す必要があります。どうすればこれを達成できますか?
ブロックを明示的に参照できます
def discard(&block)
self - self.keep(&block)
end
または暗黙的に
def discard
self - self.keep(&Proc.new {})
end
あなたの場合、私は最初のアプローチを提案します。
2番目の例では、_&Proc.new {}
_はブロックを渡さず、新しい空のブロックを作成します。 _{}
_を省略して、self.keep(&Proc.new)
または単にkeep(&proc)
と書く必要があります。_self.
_は冗長であり、proc
は_Proc.new
_:
_# passes on the block or the absence of a block
def discard(&block)
self - keep(&block)
end
# passes on the block and fails if no block given
def discard
self - keep(&proc)
end
_
ブロックのない_Proc.new
_とproc
はどちらも、現在のメソッドのブロックを使用します。
discard
がブロックを取得しない場合、_&proc
_は失敗します。したがって、最初の例は、ブロックを渡す場合、またはブロックがない場合に最適です(_&nil
_はブロックをまったく渡しません)。 2番目の例(私が変更したもの)は、欠落しているブロックがエラーである場合に最適です。
どちらの場合も、「discard」が呼び出されるたびに、新しい「Proc」オブジェクトが作成され、それは無料ではありません。