rubyblock

Pass block passed to method to another method in Ruby


I'm trying to write a clone of the ruby keep_if and delete_if array methods. Here is my code.

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

This works. But I want to do something like:

def discard
  self - self.keep &block
end

Desired behaviour:

[1, 2, 3].discard { |number| number < 2 }
# => [2, 3]

So I need to pass the block that is passed to the discard method, to be passed on to the keep method. How do I achieve this?


Solution

  • You can reference the block explicitly

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

    or implicitly

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

    In your case, I would suggest the first approach.