【问题标题】:Trouble understanding blocks and yields in ruby无法理解 ruby​​ 中的块和产量
【发布时间】:2015-03-01 09:38:39
【问题描述】:

我是 ruby​​ 的初学者,正在学习处理块和产量的教程,特别是演示 Monkey Patching。

这是代码挑战的要求

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

这是我提交的代码

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

【问题讨论】:

    标签: ruby block yield monkeypatching


    【解决方案1】:

    但我希望有人能帮助我理解为什么我必须删除参数(数组)并因此将 array.each 更改为 self.each?

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

      new_map 数组 { 块 }

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

    【讨论】:

    • 如果解决了您的问题,请考虑标记为正确。
    【解决方案2】:

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

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

    self 是 [1,2,3],它是您的 Array 实例

    self.each do |i|  
    

    就像

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

    那么 1,2 和 3 中的每一个都会被传递给块

    new_array << yield(i)
    

    【讨论】:

    • 谢谢,本质上既然new_map方法是Array类的一个实例,那么传入一个参数作为(array)就变得多余了?
    • 确实如此。并且查看你必须通过的规范,你只需要通过一个块。
    猜你喜欢
    • 2011-03-05
    • 2012-03-29
    • 2010-11-02
    • 2017-01-01
    • 2017-12-01
    • 2014-08-01
    • 1970-01-01
    • 2011-06-28
    • 2013-08-09
    相关资源
    最近更新 更多