2

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

我正在尝试了解 ruby​​ 的工作原理,因此非常感谢答案之外的任何进一步解释!

4

3 回答 3

2

似乎正在发生的是

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

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

你到底想用 open(str) 做什么?当你改变opento时docopen,你到底在哪里改变它?

于 2013-01-28T20:57:22.443 回答
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
于 2013-01-28T20:57:46.960 回答
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将按预期调用内核上的方法。

于 2013-01-28T21:18:32.727 回答