我正在尝试编写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
方法。我如何实现这一目标?
答案 0 :(得分:27)
您可以明确引用该块
def discard(&block)
self - self.keep(&block)
end
或隐含地
def discard
self - self.keep(&Proc.new {})
end
在你的情况下,我会建议第一种方法。
答案 1 :(得分:1)
在第二个示例中,&Proc.new {}
没有传递一个块,而是创建了一个新的空块。应该忽略{}
并将其写为self.keep(&Proc.new)
或仅写为keep(&proc)
,因为self.
是多余的,而proc
是Proc.new
的推荐同义词: / p>
# 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
都没有使用块,则使用当前方法的块。
&proc
没有阻止, discard
将失败。因此,如果要传递块或不存在块(&nil
完全不传递块),则第一个示例是最好的。如果丢失的块是一个错误,第二个示例(根据我的更改)是最好的。
在两种情况下,每次调用“ discard”时,都会创建一个新的“ Proc”对象,并且该对象不是免费的。