0

This is what my class looks like:

require 'oga'
require 'net/http'
require 'pry'

module YPCrawler
  class PageCrawler
    def initialize(url)
      @url = 'http://www.someurl.com'
    end

    def get_page_listings
      body = Net::HTTP.get(URI.parse(@url))
      document = Oga.parse_html(body)    
      bizlistings = document.css('div.result')
      binding.pry    
    end

  end
end

Yet when I get thrown into pry, I see this:

[1] pry(YPCrawler::PageCrawler)> @url
=> nil
[2] pry(YPCrawler::PageCrawler)> body
NameError: undefined local variable or method `body' for YPCrawler::PageCrawler:Class
from (pry):2:in `<class:PageCrawler>'
[3] pry(YPCrawler::PageCrawler)> document
NameError: undefined local variable or method `document' for YPCrawler::PageCrawler:Class
from (pry):3:in `<class:PageCrawler>'
[4] pry(YPCrawler::PageCrawler)> bizlistings
NameError: undefined local variable or method `bizlistings' for YPCrawler::PageCrawler:Class
from (pry):4:in `<class:PageCrawler>'
[5] pry(YPCrawler::PageCrawler)> url
NameError: undefined local variable or method `url' for YPCrawler::PageCrawler:Class
Did you mean?  URI
from (pry):5:in `<class:PageCrawler>'
[6] pry(YPCrawler::PageCrawler)> @url
=> nil

Why can I not access @url that was initialized in my def initialize method?

Edit 1

Added Screenshots of what my code and the terminal PRY session really look like, since there was some disbelief about the position of my binding.pry.

code terminal

Edit 2

My main lib/yp-crawler.rb file looks like this:

require_relative "yp-crawler/version"
require_relative "yp-crawler/page-crawler"
require_relative "yp-crawler/listing-crawler"

module YPCrawler
end

So the code that is run above is my yp-crawler/page-crawler.rb file, which I included in my lib/yp-crawler.rb file.

Edit 3

Here is a recording of my entire workflow. Please tell me what I am missing:

https://www.dropbox.com/s/jp1abthfkiplb4p/Pry-not-cooperating.webm?dl=0

marcamillion
  • 32,933
  • 55
  • 189
  • 380
  • 1
    you can create an attr_accessor for url e.g `attr_accessor :url` this will give you `url` and `url=(val)` methods in the class for gettting and setting the instance variable `@url`. The other items like body, document, etc. are just local variables to `get_page_listings` method and will not be accessible from a class or instance perspective. – engineersmnky Sep 28 '16 at 13:14
  • 1
    Are you **sure** that's what your code looks like? Or did you place the `binding.pry` *below* the `end`, instead of above it? – Tom Lord Sep 28 '16 at 13:17
  • @engineersmnky intuitively what you says makes sense. I wasn't trying to access `body` and `document` outside of the `get_page_listings` method. So they should be accessible. I am pretty sure that it should be accessible where the `binding.pry` is. Also, I tried adding `attr_accessor :url` right above my `initialize` method and I still can't access `url` from my pry command line....aka...that still doesn't work. – marcamillion Sep 28 '16 at 13:19
  • @agree that most likely `binding.pry` is put before the last `end` – Andrey Deineko Sep 28 '16 at 13:20
  • @TomLord I am 100% sure. The pry binding is in the right place, i.e. within the `get_page_listings` method...which is why I am so confused. Although, to be fair....I am sure the main issue is that `@url` is nil, within `get_page_listings`. Once that's true, then everything else won't work. So I am trying to figure out why that is nil. – marcamillion Sep 28 '16 at 13:20
  • 1
    but this `NameError: undefined local variable or method 'url' for YPCrawler::PageCrawler:Class` does not look like binding is in the right place.. – Andrey Deineko Sep 28 '16 at 13:22
  • `NameError: undefined local variable or method 'document' for YPCrawler::PageCrawler:Class` also looks like the `binding.pry` is in the wrong place. Not only is the variable undefined (?!), but the stack trace is odd. Perhaps you have a **second** `binding.pry` in that file, which the actually the one being picked up??? – Tom Lord Sep 28 '16 at 13:26
  • (Because in answer to your original question, the code *should* work perfectly fine. `@url` is defined in the initializer, and can be accessed in the method.) – Tom Lord Sep 28 '16 at 13:27
  • Guys, I updated the question with screenshots of both my code and the Terminal. Refresh. – marcamillion Sep 28 '16 at 13:28
  • 1
    @marcamillion i see you screenshots and the first one looks right but the second one is wrong and you can tell by the fact that the bindings are in different places. They might be on the same "line" but it is clear in the second screenshot that the binding is on the class and not inside the method just by looking at the end tags – engineersmnky Sep 28 '16 at 13:29
  • @engineersmnky I agree. Not sure why the binding is appearing there. That's very bizarre. – marcamillion Sep 28 '16 at 13:30
  • did you load this in pry and then make changes without reloading pry? – engineersmnky Sep 28 '16 at 13:31
  • No, so the structure is I have a `lib/yp-crawler.rb`, that requires the `page-crawler.rb`. The `binding.pry` is within the `page-crawler.rb` file, but to run this program I simply do `ruby lib/yp-crawler.rb` at the command line and it auto halts execution at the `binding.pry`. – marcamillion Sep 28 '16 at 13:33
  • 1
    @marcamillion Look at your second screenshot: The `binding.pry` **was** in the wrong place. You need to reload `pry` when making changes to the code. – Tom Lord Sep 28 '16 at 13:34
  • How do I 'reload pry'? I am not loading it in the first place. I simply just hit `exit` when I am in pry, and then retype `ruby lib/yp-crawler.rb`. How do I manually reload pry if not by doing that? – marcamillion Sep 28 '16 at 13:35
  • Save the file. Hit exit. Re-run it. It will now work. – Tom Lord Sep 28 '16 at 13:35
  • I updated the question with a link to a video of my entire workflow. Please tell me what I am missing. – marcamillion Sep 28 '16 at 13:44

1 Answers1

2

I bet your code looks as follows:

module YPCrawler
  class PageCrawler
    attr_reader :url
    def initialize(url)
      @url = 'http://www.someurl.com'
    end

    def get_page_listings
      body = Net::HTTP.get(URI.parse(@url))
      document = Oga.parse_html(body)    
      bizlistings = document.css('div.result')
    end
    binding.pry    
  end
end

Even though you might have moved the binding.pry into method, most likely you did not reload the console, so it executes the "wrong" version.

From your screenshots it is clear that either file is not reloaded or you just made changes to wrong file.

Andrey Deineko
  • 51,333
  • 10
  • 112
  • 145
  • Refresh the question to see a screenshot of my code. Also see my last comment on the question to see how I execute the code. It's not the wrong version. – marcamillion Sep 28 '16 at 13:34
  • @marcamillion may it be you just run the wrong file? Because there is no magic in programming. – Andrey Deineko Sep 28 '16 at 13:36
  • Refresh the question again. I put more details about my code structure and layout. – marcamillion Sep 28 '16 at 13:42
  • 2
    I'm 99.9% sure you are either not saving the file, or running the wrong file, or not restarting the `pry` session. – Tom Lord Sep 28 '16 at 13:43
  • LOL...this is gonna be HILARIOUS when someone else discovers it wasn't that :D. I added a video of my workflow. Refresh the question and tell me what I am missing please. – marcamillion Sep 28 '16 at 13:44
  • Btw, you guys could be right. I just can't see it or see how I should be doing something different. Is it the way I am requiring 'pry'? – marcamillion Sep 28 '16 at 13:45
  • @marcamillion can you run `self.class` while you're in console? if that returns `Class` (and it would) - it is what's in my answer :) And thus I won't help you - you'll just have to see step by step where you have duplicated file or whatsoever... – Andrey Deineko Sep 28 '16 at 13:48
  • It does return `Class`, but your comment is unhelpful to helping me figure it out. I am not running this within a 'console'. I am running it within a fully self-contained ruby instance, which I do exit and restart on each time. It is very possible that I am not loading pry properly, but obviously I don't know how to fix that which is why I am asking here. – marcamillion Sep 28 '16 at 13:53
  • @marcamillion but hitting `binding.pry` puts you into console, that what i meant. Can you scan your whole project on `binding.pry` occurrences? Might be helpful – Andrey Deineko Sep 28 '16 at 13:54
  • Oooohh....you are correct. It seems that my path in my main file was incorrect, and there was a duplicate file. Thanks! – marcamillion Sep 28 '16 at 14:01
  • @marcamillion glad you've found it (you did, right?) – Andrey Deineko Sep 28 '16 at 14:03
  • I did find it. The issue I am now having is that now my `get_page_listings` method doesn't seem to get triggered. Should I be able to just call `get_page_listings` outside of that method, within the class, and it should call it and trigger my `binding.pry`? – marcamillion Sep 28 '16 at 14:04
  • 1
    @marcamillion you should add `PageCrawler.new.get_page_listings` to the end of your file to call the method – Andrey Deineko Sep 28 '16 at 14:07
  • Aka...I am now doing this: `get_page_listings` and am getting `undefined method `get_page_listings' `. – marcamillion Sep 28 '16 at 14:07
  • @marcamillion yea, you can not do this inside the class, because the reciever is class itself, and it is an instance method – Andrey Deineko Sep 28 '16 at 14:07
  • Ahh perfect. Your suggestion re: `PageCrawler.new.get_page_listings` works. So I guess I should call this method from within another file, eh? – marcamillion Sep 28 '16 at 14:08
  • @marcamillion you can call it from within anywhere as long as this anywhere is aware of `PageCrawler` class :) – Andrey Deineko Sep 28 '16 at 14:09
  • 1
    Ahh ok. That makes sense. Thanks much! – marcamillion Sep 28 '16 at 14:10