Ruby范围与yield和类有关

时间:2016-10-05 03:39:00

标签: arrays ruby class scope block

我正在尝试为数组类创建自己的每个方法。代码如下:

class Array

  def my_each
    i = 0
    while i < self.length
      yield(self[i])
      i += 1
    end
    self
  end
end

my_each {|i| puts i}



[1,2,3,4].my_each

在我看来,它应该正常工作。但是,我收到了消息

"Undefined method my_each for main: Object"

我尝试在方法下移动Array类中的块,但后来得到了以下内容:

"Undefined method my_each for Array Class"

我的块和方法具有相同的名称,所以在我看来这将是一个范围问题。在一个类中定义块如何与方法一起行为?是否可以做这样的事情或直接在我的方法中包含块?

4 个答案:

答案 0 :(得分:3)

由于您已在Array上下文中对其进行了定义,因此您也需要以这种方式调用它:

[1,2,3,4].my_each do |i|
  puts i
end

调用Array实例上定义的my_each方法。您甚至可以在代码中使用此代码,但之前的错误会阻止它。

如果你得到了第二个错误,那是因为你试过了:

Array.my_each([1,2,3,4])

这不正确,如果您希望这样做,您需要使用self.前缀定义一个类方法。

答案 1 :(得分:1)

class Array
  def my_each
    to_enum
  end
end

enum = [1,2,3,4].my_each 
  #=> #<Enumerator: [1, 2, 3, 4]:each> 
enum.to_a
  #=> [1, 2, 3, 4] 
enum.map { |n| n*2 }
  #=> [2, 4, 6, 8]
enum.next
  #=> 1 
enum.next
  #=> 2 
enum.next
  #=> 3 
enum.next
  #=> 4 
enum.next
  #=> StopIteration: iteration reached an end

Array.instance_method(:to_enum).owner
  #=> Kernel 

Kernel中记录了Object的实例方法,因此请参阅Object#to_enum

答案 2 :(得分:0)

这与范围,块或Array无关。您已在Array类中定义了您的方法,这意味着它适用于所有Array,但您没有在main上调用它,而是在Object上调用它{1}},这是Array的直接实例,而不是"Undefined method my_each for Array Class"

  

我尝试在方法下移动Array类中的块,但后来得到了以下内容:

Array

在这种情况下,您在Class上调用它,Array[1,2,3,4].my_each 的直接实例,而不是Array

  

我的块和方法具有相同的名称

块没有名称。

sudo mysql_secure_installation

在这里,您在{{1}}上调用该方法,但您的方法需要一个您忘记传递的块。因此,您将收到不同的错误消息。

答案 3 :(得分:0)

我想最好的方法就是这样做:

Array.class_eval do
  def my_each
    # do here what ever you want 
    #( you can us self if you want to handle the current object)
  end
end

[1,3,3,4].my_each

或使用this参考以获得最佳答案。希望我能帮到你