将传递给方法的块传递给Ruby中的另一个方法

时间:2013-12-17 21:49:30

标签: ruby block

我正在尝试编写ruby keep_ifdelete_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方法。我如何实现这一目标?

2 个答案:

答案 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.是多余的,而procProc.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.newproc都没有使用块,则使用当前方法的块。

如果&proc没有阻止,

discard将失败。因此,如果要传递块或不存在块(&nil完全不传递块),则第一个示例是最好的。如果丢失的块是一个错误,第二个示例(根据我的更改)是最好的。

在两种情况下,每次调用“ discard”时,都会创建一个新的“ Proc”对象,并且该对象不是免费的。