2

Is it possible to use the method open on my Parser class? It seems that the method is conflicting with 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

When I run the script I get this error:

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

I've tried a variety of things, but the only thing that seems to work is to rename Parser::open to something other than open, like docopen

I'm trying to understand how ruby works, so any further explanation beyond the answer is greatly appreciated!

3 Answers 3

2

open is a method on the module Kernel that is included in Object the parent class of all Ruby classes. What happens is that open(str) in

class Parser

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

is calling your defined open method on Parser recursively. If you change your method to

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

you'll call the open method on Kernel as intended.

Sign up to request clarification or add additional context in comments.

1 Comment

YES, that is right! Very informative. I did not know about the Kernel object
2

What seems to be happening is that

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

is in a recursive loop which just causes the SystemStackError making the stack level too deep.

What exactly are you trying to do with open(str)? When you changed the open to docopen, where exactly did you change it?

6 Comments

I renamed the open method on the Parser class from open to docopen here doc = open and here def open
Yeah, that definitely would do it. The `open`` inside the Nokogiri::HTML(open(str)) was calling the open method in Parse causing it to go into infinite recursion which causes the stack to overflow.
Another probable way to fix the issue would be to do something like this Nokogiri::HTML(IO::open(str)) to have ruby access the IO method instead of the Parse one.
Yeah, that brings another question. I tried IO::open(str) and then I get the error TypeError: can't convert String into Integer
So reading the docs, apparently IO.open takes the file descriptor as argument not the filename. ruby-doc.org/core-1.9.3/IO.html#method-c-new
|
2

You are having a stack level too deep (SystemStackError) error because your method is beeing called recursively.

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

This happens because the method you defined is more close in context so it's the one picked to be called.

You can just rename your method as you figured out or you can do something like this to explicit call it on one receiver that has the open method you want to use defined

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.