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

问题描述 投票:21回答:2

我正在尝试编写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方法。我该如何实现?

ruby block
2个回答
28
投票

您可以显式引用该块

def discard(&block)
  self - self.keep(&block)
end

或隐式

def discard
  self - self.keep(&Proc.new {})
end

您的情况,我建议第一种方法。


0
投票

在第二个示例中,&Proc.new {}没有传递一个块,而是创建了一个新的空块。应该省略{}并将其写为self.keep(&Proc.new)或仅写为keep(&proc),因为self.是多余的,并且procProc.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.newproc都没有块使用当前方法的块。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.