无法理解红宝石中的块和产量

时间:2015-01-03 07:08:29

标签: ruby block yield monkeypatching

我是ruby的初学者,并经历了一个处理块和产量的教程,特别是演示了Monkey Patching。

以下是代码质询的要求

  

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

以下是我提交的代码

class Array

  def new_map(&block)
    self.map(&block)
  end

  def new_select!(&block)
    self.replace(self.select(&block))
  end

end

以下是我必须传递的规格

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

我通过了第一次和最后一次测试,但无法通过第二次测试并收到此错误

expected: ["1", "2", "3", "4"]
     got: ""

(compared using ==)

exercise_spec.rb:14:in `block (3 levels) in <top (required)>'

根据规格,我是否假设.map方法不应该用于此特定挑战?

我甚至尝试过这个假设。但它没有通过任何规范。

def new_map(array)
  new_array =[]
  array.each do |i|
    new_array << yield(i)
  end
  new_array
end

更新

我输入了此代码并且有效

def new_map
  new_array = []
  self.each do |i|
    new_array << yield(i)
  end
  new_array
end

但我希望有人可以帮助我理解为什么我必须删除参数(array),从而将array.each更改为self.each

2 个答案:

答案 0 :(得分:0)

new_map是Array类的实例方法,使您的数组== self

[1,2,3].new_map(&:to_s)

self是[1,2,3],它是你的数组实例

self.each do |i|  

就像

[1,2,3].each do |i|

然后将1,2和3中的每一个传递给块

new_array << yield(i)

答案 1 :(得分:0)

  

但我希望有人可以帮助我理解为什么我必须删除参数(数组),从而将array.each更改为self.each?

  1. 背景:您的第一个方法是寻找一个实际上不需要传递的参数,因为数组是调用者本身;换句话说,您正在尝试将调用者(或self)作为参数传递给方法。从技术上讲,你可以做到这一点,但这不是必需的。
  2. 失败原因:但是如果运行带有先前定义的规范时出错,那是因为通过添加该参数更改了方法定义。也就是说,你必须调用方法1,如下所示:

    new_map array {block}

  3. 虽然实际上没有传递参数数组,因此会给你一个ArgumentError