Ruby类方法命名冲突

时间:2013-01-28 20:48:20

标签: ruby class methods

是否可以在我的open课程中使用Parser方法?该方法似乎与IO::open

冲突
class Parser
    require 'nokogiri'

    def parse
        doc = open "someFile.html"
        # Get to parsin' ...
    end 

    def open str
        Nokogiri::HTML(open(str))
    end 
end 

parser = Parser.new
parser.parse

当我运行脚本时,我收到此错误:

$ ruby parser.rb
parser.rb:10: stack level too deep (SystemStackError)

我尝试过各种各样的事情,但唯一可行的做法是将Parser::open重命名为open以外的其他内容,例如docopen

我正在努力了解红宝石是如何工作的,所以除了答案之外的任何进一步解释都是非常赞赏!

3 个答案:

答案 0 :(得分:2)

似乎正在发生的是

def open str
  Nokogiri::HTML(open(str))
end

处于递归循环中,只会导致SystemStackError使堆栈级别过深。

你究竟想用open(str)做什么?当您将open更改为docopen时,您确切地更改了它?

答案 1 :(得分:2)

您遇到stack level too deep (SystemStackError)错误,因为您的方法是递归调用的。

def open str
  Nokogiri::HTML(open(str)) # here you call this same method over and over again
end

这是因为您定义的方法在上下文中更接近,所以它是被选中的方法。

你可以在你弄清楚的时候重命名你的方法,或者你可以做这样的事情,在一个接收器上显式调用它,这个接收器有你想要使用的open方法

def open str
  uri = URI.parse(str)
  Nokogiri::HTML(uri.open)
end

答案 2 :(得分:2)

open是模块内核上的一个方法,它包含在Object所有Ruby类的父类中。

中的open(str)会发生什么
class Parser

  def open str
    Nokogiri::HTML(open(str))
  end

以递归方式在Parser上调用已定义的open方法。如果您将方法更改为

  def open str
    Nokogiri::HTML(Kernel.open(str))
  end

您将按预期在内核上调用open方法。