How do I use instance variables initialized in my initialize method in other methods? - ruby

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.
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

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.

Related

How do I reference a method in a different class from a method in another class?

I have a module and class in a file lib/crawler/page-crawler.rb that looks like this:
require 'oga'
require 'net/http'
require 'pry'
module YPCrawler
class PageCrawler
attr_accessor :url
def initialize(url)
#url = url
end
def get_page_listings
body = Net::HTTP.get(URI.parse(#url))
document = Oga.parse_html(body)
document.css('div.result')
end
newpage = PageCrawler.new "http://www.someurl"
#listings = newpage.get_page_listings
#listings.each do |listing|
bizname = YPCrawler::ListingCrawler.new listing['id']
end
end
end
Then I have another module & class in another file lib/crawler/listing-crawler.rb that looks like this:
require 'oga'
require 'pry'
module YPCrawler
class ListingCrawler
def initialize(id)
#id = id
end
def extract_busines_name
binding.pry
end
end
end
However, when I try to run this script ruby lib/yp-crawler.rb which executes the page-crawler.rb file above and works without the YPCrawler call, I get this error:
/lib/crawler/page-crawler.rb:23:in `block in <class:PageCrawler>': uninitialized constant YPCrawler::ListingCrawler (NameError)
The issue is on this line:
bizname = YPCrawler::ListingCrawler.new listing['id']
So how do I call that other from within my iterator in my page-crawler.rb?
Edit 1
When I just do `ListingCrawler.new listing['id'], I get the following error:
uninitialized constant YPCrawler::PageCrawler::ListingCrawler (NameError)
Edit 2
Here is the directory structure of my project:
Edit 3
My yp-crawler.rb looks like this:
require_relative "yp-crawler/version"
require_relative "crawler/page-crawler"
require_relative "crawler/listing-crawler"
module YPCrawler
end
In your yp-crawler.rb file, based on the structure that you posted, you should have something like:
require 'yp-crawler/version'
require 'crawler/listing-crawler'
require 'crawler/page-crawler'
Try this, in your yp-crawler.rb add the line:
Dir["#{File.dirname(__FILE__)}/crawler/**/*.rb"].each { |file| load(file) }
That should automatically include all files in your /crawler directory at runtime. Might want to do the same for the other directories.
Let me know if that helps :)

if i remove the class name from the code and call the method direcly it will run, but using class shows me an error

If i remove the class name from the code and call the method direcly it will run, but using class shows me an error
require 'rubygems'
require 'selenium-webdriver'
require 'test/unit'
# define in setup
def setup
#driver = Selenium::WebDriver.for:firefox
#driver.navigate.to "#{#base_url}"
navigate_to_signin.click
end
class LoginValiation < Test::Unit::TestCase
def test_login_blank_validation
setup
signin_button.click
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
expected = #driver.find_element(:xpath, ".//*[#id='login_form']/div[1]").text
assert_equal("Login and/or password are wrong.", expected)
teardown
end
# Define in page objects
def signin_button
#driver.find_element(:name, "submit")
end
end
output
Error:
test_login_blank_validation(LoginValiation):
NoMethodError: undefined method `find_element' for nil:NilClass
C:/Users/Kuntal.Sugandhi/Desktop/rubyproject/ruby practice/test/login_page.rb:23:in ` signin_button'
test_login_validation.rb:19:in `test_login_blank_validation'
On removing the class and run the test directly
output
test_login_validation.rb:19:in `test_login_blank_validation': undefined method ` assert_equal' for main:Object (NoMethodError

Can't access custom helper functions made within the file - Sinatra

I have this helper within my 'app.rb' file, which is used to get the current user object.
helpers do
def get_current_user(column, value)
user = User.where(column => value).first
return user
end
end
get '/' do
user = get_current_user(:id, params[:id])
end
This is what i did in irb:
irb(main):001:0> require './app'
=> true
irb(main):007:0> user = get_current_user(:id, 2)
NoMethodError: undefined method `get_current_user' for main:Object
from (irb):7
from /usr/bin/irb:12:in `<main>'
I don't understand why i can't access the helper methods from irb. Should i explicitly include the helpers or something? If so, why? Because i put them under the same file, under the same class.
get_current_users is metaprogrammed through the helpers method to be an instance method of App. So, if app.rb looks something like this:
require 'sinatra/base'
class App < Sinatra::Base
helpers do
def get_current_user
puts "here!"
end
end
end
...then from irb you can invoke get_current_user on an instance of App like this:
>> require './app'
>> App.new!.get_current_user
here!
=> nil
>>
(If you're wondering why that's new! and not new like most sane ruby code, read this answer.)

Why do I get the error uninitialized constant Stuff::HTTParty?

I have the HTTParty gem on my system and I can use it from within rails.
Now I want to use it standalone.
I am trying:
class Stuff
include HTTParty
def self.y
HTTParty.get('http://www.google.com')
end
end
Stuff.y
but I get
$ ruby test_httparty.rb
test_httparty.rb:2:in `<class:Stuff>': uninitialized constant Stuff::HTTParty (NameError)
from test_httparty.rb:1:in `<main>'
07:46:52 durrantm Castle2012 /home/durrantm/Dropnot/_/rails_apps/linker 73845718_get_method
$
You have to require 'httparty':
require 'httparty'
class Stuff
include HTTParty
# ...
end
Its all because of the include which exists with in the class
If you include a class with a module, that means you're "bringing in" the module's methods as instance methods.
If you need more clarity on include and require
I request you to refer to this wonderful SO Posting
What is the difference between include and require in Ruby?
Here is an example which I have taken from the same posting
module A
def say
puts "this is module A"
end
end
class B
include A
end
class C
extend A
end
B.say => undefined method 'say' for B:Class
B.new.say => this is module A
C.say => this is module A
C.new.say => undefined method 'say' for C:Class

Watir / MiniTest - Undefined local variable or method 'browser'

I have 66 watir scripts that I have been creating over the past week to automate testing on the clients website.
However I have recently found out about a test framework called MiniTest which I am trying to implement now.
The reason I have set the URL as a variable is because there are 5 different sites that these tests need to run on so when they want me to run my pack on a different website I just need to update that 1 variable and not in each individual test.
require 'minitest/autorun'
require "watir-webdriver"
class MPTEST < MiniTest::Unit::TestCase
def setup()
url = "http://thewebsite.com/"
$browser = Watir::Browser.new :chrome
$browser.goto url
end
def test_myTestCase
$browser.link(:text, "Submit your CV").click
sleep(2)
$browser.button(:value,"Submit").click
assert($browser.label.text.includes?("This field is required"))
def teardown
$browser.close
end
end
When running that I receive the following output:
NameError: undefined local variable or method 'browser' for #<MPTEST:0x4cc72f8>c:/directory stuff...
Any ideas?
EDIT I have browser working however now there is an issue with my assert:
New code:
require 'minitest/autorun'
require "watir-webdriver"
class MPTEST < MiniTest::Unit::TestCase
def setup()
url ="http://thewebsite.com"
$browser = Watir::Browser.new :chrome
$browser.goto url
end
def test_myTestCase
$browser.link(:text, "Submit your CV").click
sleep(2)
$browser.button(:value,"Submit").click
assert($browser.label.text.includes?("This field is required"))
end
def teardown
$browser.close
end
end
And the error is:
NoMEthodError: undefined method 'includes?' for "":String
it seems to me you can you use #browser instead of $browser (but the problem might be not in this code)
The exception
NoMEthodError: undefined method 'includes?' for "":String
Is due to strings, in this case the value returned by $browser.label.text do not have an includes? method.
The method you actually want is include? (no plural):
assert($browser.label.text.include?("This field is required"))

Resources