如何在不调用原始方法的情况下修补补丁

时间:2014-10-05 03:09:22

标签: ruby arrays

我正在努力完成这项练习:

  

编写一个在Array类的实例上调用的新new_map方法。它应该使用它所调用的数组作为隐式(自身)参数,但在其他方面表现相同。

这是一个rspec:

describe Array do   describe '#new_map' do
    it "returns an array with updated values" do
      array = [1,2,3,4]
      expect( array.new_map(&:to_s) ).to eq( %w{1 2 3 4} )
      expect( array.new_map{ |e| e + 2 } ).to eq( [3, 4, 5, 6] )
    end

    it "does not call #map" do
      array = [1,2,3,4]
      array.stub(:map) { '' }
      expect( array.new_map(&:to_s) ).to eq( %w{1 2 3 4} )
    end

    it "does not change the original array" do
      array = [1,2,3,4]
      expect( array.new_map(&:to_s) ).to eq( %w{1 2 3 4} )
      expect( array ).to eq([1,2,3,4])
    end   
end

我尝试过让它发挥作用。这是我的代码:

class Array
  def new_map(&block)
    map(&block)
  end
end

我通过了rspec的两个要求,但没有通过it "does not call #map"的要求。我不明白在将块传递给它的过程中我怎么不能调用map。任何帮助或提示都将不胜感激。

2 个答案:

答案 0 :(得分:2)

如果这是某种家庭作业要求,我猜他们只是希望你实施自己的map方法

class Array
  def new_map &block
    return to_enum :new_map unless block_given? 
    arr = []
    each { |elem| arr.push block.call(elem) }
    arr       
  end
end

然而,这不是猴子补丁。这只是在运行时在Array上定义一个新的instnace方法。

答案 1 :(得分:0)

您还可以使用yield替换"block.call(elem)"

def new_map
    arr = []
    each { |item| arr << yield(item) }
    arr       
end