Getting my Ruby file to load into Pry? - ruby

I'm trying to edit my Ruby file with Pry. There are few variables that are set in it, and for whatever reason I can't seem to cd into them because they aren't being defined even after I 'load' the file.
Here is the code:
require 'nokogiri'
require 'open-uri'
doc = Nokogiri.XML('<foo><bar /><foo>', nil, 'UTF-8')
url = "http://superbook.eventmarketer.com/category/agencies/"
puts "Finished!"
In Pry I do:
load "./AgencyListingScraper.rb"
and then this is the output:
7] pry(main)> load './AgencyListingScraper.rb'
Finished!
=> true
[8] pry(main)>
Then when I try to do something like:
[8] pry(main)> url
NameError: undefined local variable or method `url' for main:Object
from (pry):6:in `__pry__'
[9] pry(main)> cd url
Error: Bad object path: url. Failed trying to resolve: url. #<NameError: undefined local
variable or method `url' for main:Object>
[10] pry(main)>
This is what I get.
I think I'm not loading the file correctly although I've been searching for hours and I can't figure out how to properly do this. I was doing it right months ago when I had made a scraper with Ruby, but this time I'm having trouble just getting started because of this bit.
Thanks for your help in advance!

Try it this way:
In your file include Pry and do a binding.pry:
require 'nokogiri'
require 'open-uri'
require 'pry'
doc = Nokogiri.XML('<foo><bar /><foo>', nil, 'UTF-8')
url = "http://superbook.eventmarketer.com/category/agencies/"
binding.pry
puts "Finished!"
Then run the file by executing:
ruby AgencyListingScraper.rb
That should drop you into a Pry session where you can use commands like ls to see all of the variables.
Both the way you used Pry, and this way, work. However, the reason that load may not be working in your case is that local variables don't get carried over across files, like when you require one file from another.
Try loading this file:
#test.rb
y = "i dont get carried over cause i am a local variable"
b= "i dont get carried over cause i am a local variable"
AAA= "i am a constant so i carry over"
#per = "i am an instance var so i get carried over as well"
When you load it in Pry using load "test.rb" you can see that you can't get access to the local variables from that file.

I found this question googling but the proposed solution did not work for me because the file I wanted to load was not a class nor a script but a complex ruby config file, so I was not able to inject pry in the code.
But I also found an answer in Reddit linked to this gist that was exactly what I was looking for.
Doing a
Pry.toplevel_binding.eval File.read("stuff.rb")
Will effectively execute the ruby code of the file stuff.rb in the current pry session, leaving the resulting objects for inspecting.

Related

How to use login credentials from yaml in ruby

I'm new in ruby and I can't move forward from using login cred. from a yml file for a ruby project .I have a basic yml file
login:
urls:
gmail: "https://accounts.google.com/signin"
users:
username: something
password: something_new
I've created a yml.rb with require yml ,and access the yml path & loading the file .
But I don't know how to go through users/username ... in my test.rb :( .I've added in the "it " a variable to store the yml class and at the end i'm trying with
expect data['valid_user']
expect data['login']['urls']['gmail']
expect data['login']['users']['username']
but in the terminal I receive th error "NoMethodError: undefined method `[]' for nil:NilClass "
Update
Here is my yml.rb
require 'rspec'
require 'yaml'
class YamlHelper
#env = {}
def initialize
file = "#{Dir.pwd}path of yml file"
#env = YAML.load_file(file)
end
def get_variables
#env
end
end
Here is my test.rb file
describe 'My behaviour' do
before(:each) do
#browser = Selenium::WebDriver.for :firefox
end
it 'verifies yml login' do
yaml_helper = YamlHelper.new
data = yaml_helper.get_variables
expect data['valid_user']
expect test_data['login']['urls']['gmail']
expect test_data['login']['users']['username']
expect test_data['login']['users']['password']
end
after(:each) do #browser.quit
end
Can anyone take a look ?
thanks in advance
Have a lovely day
It looks like the code is almost there. When I'm debugging this sort of thing I'll often try to distil it down to the most basic test first
Something like:
require 'yaml'
file = "#{Dir.pwd}/data.yml"
data = YAML.load_file(file)
data['valid_user']
#=> nil
data['login']['urls']['gmail']
#=> "https://accounts.google.com/signin"
data['login']['users']['username']
#=> "something"
From the above you can see there's probably a typo in your test.rb file: test_data should most likely be data. Also, your YAML file doesn't contain the valid_user key, so you probably want to remove it from the test, at least for now.
The other two keys load fine.
The error you're seeing NoMethodError: undefined method '[]' for nil:NilClass means that one of the hashes you're variables you're treating like a hash is actually nil. This sort of bug is fairly common when you're diving into nested hashes. It means one of two things:
You've correctly descended into the hash, but the data is not present in the YAML.
The data is present in the YAML, but you're not getting to it correctly.
One change you can make that will make this code a bit more resilient is to replace:
test_data['login']['users']['username']
with:
test_data.dig('login', 'users', 'username')
The latter uses dig, which delves into the data structure and tries to return the value you're after, but if it gets a nil back at any point it'll just return nil, rather than throwing an exception.
Finally, for the test you've pasted here, you don't need the before(:each) or after(:each) blocks – Selenium is only necessary for browser testing.

Ruby: cannot load such file - LoadError

I got this 'require' cannot load such file error.
I got this previously and I added
__LIB_DIR__ = File.expand_path(File.join(File.dirname(__FILE__), ".."))
unless $LOAD_PATH.include?(__LIB_DIR__)
$LOAD_PATH.unshift(__LIB_DIR__)
end
I would like to know what this does? I added this in a main 'require' file of my project.
Now I write a test case,
$:.unshift File.join(File.dirname(__FILE__), ".")
I try to run it, I get the LoadError. I also tried require_relative no luck.
Structure:
Main
Git
lib
files.rb
base.rb
test
test1.rb
I have the first code block above in base.rb where I do all 'requires'
and when i try to run the test. I get LoadError.
'Please',Explain the first and second code blocks also give me a solution
For clarity, instead of
__LIB_DIR__ = File.expand_path(File.join(File.dirname(__FILE__), ".."))
use
__LIB_DIR__ = File.expand_path('..', File.dirname(__FILE__))
What does this do?
unless $LOAD_PATH.include?(__LIB_DIR__)
$LOAD_PATH.unshift(__LIB_DIR__)
end
Consider this:
ary = %w[a b]
ary # => ["a", "b"]
ary.unshift('c')
ary # => ["c", "a", "b"]
I try to run it, I get the LoadError. I also tried require_relative no luck.
That could be for a number of reasons, but, unfortunately you didn't share the code where it occurs. require and require_relative are both used to load code, but have different syntax in the parameter passed. We'd need to know what you're trying to load, and where it is in the file hierarchy in relation to your calling script.
Perhaps one of these, or their related questions, would help:
"ruby `require': cannot load such file"
"Ruby 'require' error: cannot load such file"
"require cannot load such file"
"Cannot load files using require"

Console not ready ruby sublime text file

I'm new to programming. Just about to start learning Ruby. I already took a console class, but I am stuck here.
I'm using a mac 10.6.8. I have done a quick 1+2 in the sublime text editor. I saved it. I went over to my console typed irb and then typed ruby example.rb. I have read elsewhere here that typing require './example' would help....it didn't. I am getting the following
NameError: undefined local variable or method `example' for main:Object
from (irb):2
from /usr/local/rvm/rubies/ruby-1.9.3-p392/bin/irb:16:in `<main>'
I don't understand what I am doing wrong. Thank you for your help. I really appreciate it.
-L
I would do as below:
kirti#kirti-Aspire-5733Z:~$ irb
2.0.0p0 :001 > require 'fileutils'
=> true
2.0.0p0 :002 > FileUtils.pwd
=> "/home/kirti"
2.0.0p0 :003 > FileUtils.cd "/home/kirti/ruby"
=> nil
2.0.0p0 :004 > load "./SO.rb"
3
=> true
2.0.0p0 :005 > require "./SO.rb"
3
=> true
My SO.rb file contains the below line :
puts 1+2
May be you wanna give a try.
Step 1: Navigate to your project/file folder by using command "cd folder_name/folder_location"
Step 2: load './example.rb'
For better solution you may wanna define some function inside example.rb
Like:
def sum
1 + 2
end
And to get the output enter sum in irb after loading the example.rb file.
irb is the interactive ruby shell. Within the shell, everything you type is interpreted as Ruby code, not bash commands. So, for example:
bash> puts 1 + 2
# command not found: puts
# this happens because you're not in a Ruby shell
bash> irb
# now you're in a Ruby shell
irb> puts 1 + 2
# 3
If you wrote some code in example.rb, you have two options:
From the bash shell, run ruby example.rb (from the same directory where your example.rb file is saved.
From the irb console, you can require 'example', which will load the contents of example.rb into your interpreter. In this case, it will immediately execute the Ruby code. If you wrapped the contents of example.rb in a class, it would load the class, but not execute code within it until you instantiated/called it.
Hopefully that helps!
My guess is that you are typing (into irb):
require example.rb
When you need to type:
require './example.rb'
The first tells ruby: "require what is in a variable called example". Because you did not define a variable called example, it results in the no variable or method error.
The second tells ruby: "require a string './example.rb'". Since the require method essentially knows how to find the file name passed as a string and evaluate the file, you'll get the right output
By the way, for this example, example.rb needs to be in the same directory. If example.rb is in another directory, you'll need to use the full path (I won't expand on it here) to source it.
You'll also notice that the output will look something like this:
3
=> true
This is because the file was evaluated (executing the code: puts 1+2) and the require method returns true to indicate it evaluated the file.
If you require the file again, you'll get false because the file is already loaded.

Why am I getting NoMethodError from IRB for my own Module and method

I have taken this example exactly from the Ruby Cookbook. Unfortunately for me, like a whole lot of the examples in that book, this one does not work:
my file (Find.rb - saved both locally and to Ruby\bin):
require 'find'
module Find
def match(*paths)
matched=[]
find(*paths) { |path| matched << path if yield path }
return matched
end
module_function :match
end
I try to call it this way from IRB, according to the example the book provides:
irb(main):002:0> require 'Find'
=> false
irb(main):003:0> Find.match("./") { |p| ext = p[-4...p.size]; ext && ext.downcase == "mp3" }
It SHOULD return a list of mp3 files in my recursive directory. Instead, it does this:
NoMethodError: undefined method `match' for Find:Module
from (irb):3
from C:/Ruby192/bin/irb:12:in `<main>'
What gives? I'm new at this (although I MUST say that I'm farther along with Python, and much better at it!).
How can I get IRB to use my method?
I ran into this with irb on a Mac running Snow Leopard while using the default version of ruby (and irb of course) installed with OS X. I was able to get past it by including the module in IRB after loading the module or in the file after the module definition.
include module_name
I'm not sure if this is a defect or known behavior.
The only explanation is that the code you posted is not the code you are running, since both carefully reading it and simply cut&paste&running it shows absolutely no problems whatsoever.
What directory are you calling IRB from? Try calling it from the directory where your find.rb file is located. Also, I don't know if it makes any difference but convention is to name the file the lowercase version of the module / class. So the module would be Find and the file name would be find.rb. You shouldn't need the require call in the file itself.
So, start your command prompt window, cd into the directory that contains find.rb and run irb. In IRB you should be able to require "find" and it should return true. From there you should be able to call Find.match.
I know this question is already 3 years old, but since this is the first hit on google for the problem, and I had been banging my head against the wall all afternoon with the same problem doing the tutorial here: http://ruby.learncodethehardway.org/book/ex25.html, here goes: the function definition in the module should read
module Find
def Find.match(*paths)
...
end
end

How do I drop to the IRB prompt from a running script?

Can I drop to an IRB prompt from a running Ruby script?
I want to run a script, but then have it give me an IRB prompt at a point in the program with the current state of the program, but not just by running rdebug and having a breakpoint.
Pry (an IRB alternative) also lets you do this, in fact it was designed from the ground up for exactly this use case :)
It's as easy as putting binding.pry at the point you want to start the session:
require 'pry'
x = 10
binding.pry
And inside the session:
pry(main)> puts x
=> 10
Check out the website: http://pry.github.com
Pry let's you:
drop into a session at any point in your code
view method source code
view method documentation (not using RI so you dont have to pre-generate it)
pop in and out of different contexts
syntax highlighting
gist integration
view and replay history
open editors to edit methods using edit obj.my_method syntax
A tonne more great and original features
you can use ruby-debug to get access to irb
require 'rubygems'
require 'ruby-debug'
x = 23
puts "welcome"
debugger
puts "end"
when program reaches debugger you will get access to irb.
apparently it requires a chunk of code to drop into irb.
Here's the link (seems to work well).
http://jameskilton.com/2009/04/02/embedding-irb-into-your-ruby-application
require 'irb'
module IRB
def self.start_session(binding) # call this method to drop into irb
unless #__initialized
args = ARGV
ARGV.replace(ARGV.dup)
IRB.setup(nil)
ARGV.replace(args)
#__initialized = true
end
workspace = WorkSpace.new(binding)
irb = Irb.new(workspace)
#CONF[:IRB_RC].call(irb.context) if #CONF[:IRB_RC]
#CONF[:MAIN_CONTEXT] = irb.context
catch(:IRB_EXIT) do
irb.eval_input
end
end
end
This feature is available from Ruby 2.4. You can just use binding.irb
E.g.
require 'irb'
a = 10
binding.irb
puts a
If you run above code, you will get irb console, so that you can inspect values of local variables and anything else that is in scope.
Source: http://blog.redpanthers.co/new-binding-irb-introduced-ruby-2-4/
Ruby commit: https://github.com/ruby/ruby/commit/493e48897421d176a8faf0f0820323d79ecdf94a
Just add this line to where you want the breakpoint:
require 'ruby-debug';debugger
but i suggest use pry instead of irb, which is super handy, insert the following line instead:
require 'pry'; binding.pry
I'm quite late to the game but if you're loading a script from within irb/pry already, a simple raise also works to pop you back out to the irb/pry prompt. I use this quite often when writing one off scripts within the rails console.

Resources