How can I use irb the Ruby interpreter to test/debug my .rb files? - ruby

How can I use irb the Ruby interpreter to test/debug my .rb files? I want to load an .rb file, let it run, and after it ends, get back to the irb prompt so I would be able to manipulate the variables which my script has built.
I tried load, require, and irb -r, but none of them worked as I would like. After the execution, when the program terminates, I get an irb prompt, but all of the variables are inaccessible. What can I do?

Not sure exactly what you want to do, but it sounds like you may want to use the "pry" gem instead.

Install the pry gem see: http://pryrepl.org
require 'pry' at the start of your program.
put binding.pry at the end of your program (or where you want to start the interactive session)
run your program.
Using pry you will have all your variables in scope.
More information see the link above, and here:
http://banisterfiend.wordpress.com/2011/01/27/turning-irb-on-its-head-with-pry/
and:
https://github.com/pry/pry/wiki/Runtime-invocation

If the variables you want are local variables, I do not think there is a way you can access them from another file.
If you just want the return value of the whole code that is on a different file, you can eval the whole content of that file within the main code and access the return value. You can access multiple values by putting them in an array or a hash at the end of the file to be evaled.

Add following code in place where you want irb to start
require 'irb'
IRB.start(__FILE__)

binding.irb
As of Ruby 2.4, placing this in your code will drop you into an irb session in the scope where it is placed.
No additional gem installs or require statements are needed.

Related

Ruby Script that runs list of irb watir commands

I regularly use the irb for testing out cucumber watir webdriver steps on a browser. This involves opening the irb and typing in a list of the same commands. The first few commands are always
require 'watir-webdriver'
browser = Watir::Browser.new(:chrome)
b.goto 'www.foo.com'
the list of commands goes on like this. Every time I open the irb I have to go through all of these. Does anyone have any idea of a script which could be run to automate a list of commands such as the above? So that it would open the IRB and then go through the commands one by one saving me load of time.
Any help is greatly appreciated.
Probably the easiest thing to do is create a script.rb file in the root project directory (or wherever you're starting IRB), and write out the Ruby you normally run. Then when you start IRB, just load 'script.rb'
However this won't work if you need access to your browser variable after setup. In that case it would make more sense to create a class.
in ./test_browser.rb
require 'watir-webdriver'
require 'irb'
class TestBrowser < Watir::Browser
def self.build
browser = new(:chrome)
browser.goto 'www.foo.com'
# other setup steps
browser # return the browser at the end of the method
end
end
IRB.start
Then from the shell: $ ruby ./test_browser.rb
This will start up IRB with your class loaded. Then all you need to do is call the .build method and store the browser in a variable
browser = TestBrowser.build
You can always spin up irb with a particular file in mind:
irb -r./startup.rb
Where ./startup.rb is the path to whatever file you want to run first before opening the REPL shell.
It's pretty easy to make a wrapper script for this if you do it frequently enough. You can also invoke IRB manually inside a custom script of your own construction, much as rails console does.

Ruby, pry: Can I add something to the command `pry example.rb` so pry automatically goes interactive when it finishes executing the script?

Pry goes into interactive mode if it encounters an exception (eg if you just put an undefined variable 'x' at the end of the script).
(Also if, inside the script itself you require 'pry' and put binding.pry at the point you want to go interactive at.)
But I'm wondering: Is there's some kind of flag/option/argument thingy that I can add to the pry example.rb command when I enter it at the command prompt, so it will go interactive when it reaches the end of executing any example.rb script, regardless of what's inside? (Assuming no exceptions before the end, of course.)
(This would obviously be especially useful for use with editors that you can run external programs from like Notepad++, see this and this.)
Not yet, but file an issue and i'll add it :)

How can I pass STDin to IRB without it exiting after processing this input?

I'm using a short bash script to help me test an implementation of linked lists in ruby for class. I know about rspec and unit testing, and I'm certain they're better options for what I'm trying to do, but I was able to figure out this command
echo "require './nodes'" | irb
The output afterwards is
Switch to inspect mode.
require './nodes'
true
Technically a success, but the irb process ends there. So I tried
echo "require './nodes'" | irb --noinspect
Which gave me
Switch to non inspect mode.
require './nodes'
true
And it again exits the irb process.
I'm just trying to make my workflow a little bit more convenient, as I like to use irb to test my files by poking around at them and seeing what happens.
Create a simple script, the code below will land you into the irb shell with the 'nodes' gem included. If you are using Ruby 1.8.x then you'll need to add require 'rubygems' before requiring nodes gem
#!/path/to/ruby -w
require 'irb'
require 'nodes'
IRB.start

Pass ruby script file to rails console

Is there a way to pass ruby file, foo.rb to rails console. Expected results would be after console starts rails environment to run file.
Or any other way which would allow me to execute file in rails environment, triggered from command prompt.
Actually, the simplest way is to run it with load inside the rails console
load './path/to/foo.rb'
You can use
bundle exec rails runner "eval(File.read 'your_script.rb')"
UPDATE:
What we also have been using a lot lately is to load the rails environment from within the script itself. Consider doit.rb:
#!/usr/bin/env ruby
require "/path/to/rails_app/config/environment"
# ... do your stuff
This also works if the script or the current working directory are not within the rails app's directory.
In the meantime, this solution has been supported.
rails r PATH_TO_RUBY_FILE
Much simpler now.
Consider creating a rake task.
For code that I need to create records or support migrations, for example, I often create a rake task like that from this answer. For example:
In lib/tasks/example.rake:
namespace :example do
desc "Sample description you'd see if you ran: 'rake --tasks' in the terminal"
task create_user: :environment do
User.create! first_name: "Foo", last_name: "Bar"
end
end
And then in the terminal run:
rake example:create_user
script/console --irb=pry < test.rb > test.log
simple, dirty, and block the process at the end, but it does the job exactly like I wanted.
Of these approaches mentioned earlier, none seemed clean and ideal like you would expect a standalone script to run (not get eval-ed or piped via < redirection), but finally this works perfect for me:
(for Rails 3)
Insert at the top of your script:
#!/usr/bin/env ruby
APP_PATH = File.expand_path(appdir = '/srv/staging/strat/fundmgr/config/application', __FILE__)
require File.expand_path(appdir + '/../boot', __FILE__)
require APP_PATH
# set Rails.env here if desired
Rails.application.require_environment!
# your code here...
Of course, set your own Rails app path in the APP_PATH line.
That way, I can avoid having to enter any interactive irb or rails c and can test my script.rb from the shell prompt, before eg. scheduling it in crontab.
It smoothly supports command-line parameters, too, and minimizes the levels of wrappers before getting to your code.
CREDIT (also shows a Rails 2 example)
http://zerowidth.com/2011/03/18/standalone-script-runner-bin-scripts-in-rails.html
Here's the hack I'm using:
rr() {
rails_root="$(bundle exec rails runner "puts Rails.root")"
rp="$(relpath "$1" "$rails_root")"
bundle exec rails runner "eval(File.read '$rp')"
}
relpath() {python -c "import os.path; print os.path.relpath('$1','${2:-$PWD}')";}
Example:
cd ~/rails_project/app/helpers
rr my_script.rb
Based on #moritz's answer here. I changed it, since the working directory for File.read is the Rails project root.
I know this is some serious heresy, using python to help a ruby script. But I couldn't find a relpath method built into ruby.
Credit: relpath() was taken from #MestreLion, Convert absolute path into relative path given a current directory using Bash

Issue One command and Run Multiple Ruby Files

I have to run a whole bunch of ruby scripts to generate some results. In which order does not matter. I just don't want to do Ruby file1.rb, Ruby file2.rb, Ruby file3.rb...one by one.
Could I write a script that group all files together and issue command only once to run them all?
I would do it ruby-style and use rake gem.
I would create file named "rakefile.rb" and this would be its content:
task :default do
FileList['file*.rb'].each { |file| ruby file }
end
Then I would call rake in my favourite shell and I would enjoy it.
Bonus: It's multiplatform.
Assuming you are using bash and all the ruby files you want to run are in the current directory you could do:
for file in `ls ./*.rb`; do
ruby $file
done
Have runall.rb contain:
(1..3).each do |i|
`ruby file#{i}.rb`
end
and call ruby runall.rb.
You could make a sh script called startruby.sh that looks like this (this example doesn't work):
ruby ruby1.rb;
ruby ruby2.rb;
etc.
And then run
sh startruby.sh
And it will lauch all the ruby script after each other.
Offcourse you can also make it more advanced with a for loop and such, but this is the easiest/quickest way.
Depends on what you want, but if you want all the files loaded together, maybe something like ...
ruby -I. -e "ARGV.each {|f| load f}" file*.rb

Resources