When running ruby scripts as such
ruby some-script.rb
How would I include a file (e.g. configuration file) in it dynamically?
As you have found, the -r option is your friend. It also works with IRB:
irb -ropen-uri
Will do the same as require 'open-uri'
FWIW, the most common thing I need to include via the command line is rubygems. And since newer versions of ruby come with gems built in I don't want to edit the file, but include it for testing. Luckily the folks who created gems added a little alias sugar.
You can do the following:
ruby -rubygems myscript.rb
Instead of the ugly:
ruby -rrubygems myscript.rb
OK, so it is one character, but thought it was extra polish to make me happier.
Actually, I found it. It's the -r command line entry.
-r <library_name>
This causes Ruby to load the library using require.
It is useful when used in conjunction with -n or -p.
You can use:
require 'some_ruby_file'
in some-script.rb. It will load some_ruby_file.rb.
Before you call require "somefile.rb" you must navigate to the folder that the file is located or you must provide the full path. In example: require "~/Documents/Somefolder/somefile.rb"
Related
I am using Mac OS X. I have two versions (2.1.5 and 2.0.0) of Ruby installed. The former installed at /another/.path/to/ruby (there is a dot before "path" to mimic the fact that the path contains a dot-headed directory in between), in addition to the default system one (version 2.0.0) at /usr/bin/ruby. I used rbenv to install Ruby.
After I manually set the PATH environment variable so the default ruby command will be found in another directory: /another/.path/to/ruby. Now I check
which -a ruby
It is using correct ruby first, as output.
/another/.path/to/ruby
/usr/bin/ruby
Now I create a script, rbs, with the first line of shebang specifying the ruby to use.
#!/usr/bin/env ruby
puts 'hey there'
Then I run
./rbs
it outputs 'hey there'. Good. Meanwhile, the Ruby is using the correct version.
/usr/bin/env ruby --version
as well as
ruby --version
both output 2.1.5. So it does great job to use the new version.
However, here is where the problem occurs: now I update rbs file to be:
#!/another/.path/to/ruby
puts 'hey there'
Note that I updated the shebang to use the absolute path to the desired ruby. then I run
./rbs
It outputs:
./rbs: line 2: puts: command not found
which is too weird;
but if I run
ruby ./rbs
it outputs 'hey there' as normal. It looks like the shebang works perfect using /usr/bin/env ruby, but not for absolute path for the newly install ruby?
Why is this? Is there a way to fix it so the updated script can still work by typing the following?
./rbs
Thanks!
The puts: command not found message indicates that your script is not being run by Ruby, but by the shell instead. So first, I would double-check your shebang line's syntax and path.
Second, note that rbenv uses shims that dynamically find and run the right version of ruby (and associated programs like gem, etc). But the shims are scripts, and scripts can't themselves be shebang interpreters; you have to find and use the actual path to the ruby executable (as output by rbenv which ruby).
On the other hand, since /usr/bin/env is an executable, you can always use something like #!/usr/bin/env ruby, which will work even if the ruby it finds in the path is itself a script.
I can't comment, (otherwise I'd add as a comment) but I think its worthwhile to add that the
#!/usr/bin/env ruby
MUST be the first line of the file. This tripped me up for a while.
source
I am trying to make a command line tool. I already have a ruby script (one file). But I want to project it as a normal command line command.
Right now I have to go into the directory where the script is and type ruby script.rb for it to function but i want to make a command such as script [option] from directory and it should process the required option in the script.
Do I need to make an independent ruby gem for this? I have read about some gems like thor and commander but I am not able to use them properly.
How can I make this command line tool?
PS: An example can be the twitter gem and a command line tool 't' which is also a gem.
Ruby, because it's a general-programming language, makes it easy to create command-line scripts. Here's a basic script you can build upon:
#!/usr/bin/env ruby
require 'optparse'
args = {}
OptionParser.new do |opt|
opt.on('-i', '--input FILE', 'File to read') { |o| args[:file_in] = o }
opt.on('-o', '--output FILE', 'File to write') { |o| args[:file_out] = o }
end.parse!
abort "Missing input or output file" unless (args[:file_in] && args[:file_out])
File.write(args[:file_out], File.read(args[:file_in]))
Here's what's happening:
#!/usr/bin/env ruby is commonly called a "bang line". The shell will look for this line at the top of a file to determine what application can read the file and execute/interpret it. env is an application that will look through the user's PATH environment variable and return the first Ruby found as the Ruby to execute the script. Using this makes the script work with Rubies in the normal /usr/bin, /usr/local/bin or when managed by rbenv or RVM.
require 'opt parse' pulls in Ruby's command-line parser class OptionParser, which makes it easy to set up traditional flags, such as -i path/to/file/to/read, -o path/to/file/to/write, or long parameters, like --input or --output. It also automatically supplies the -h and --help flags to return formatted help text for the script. OptionParser is a bit of a learning-curve, so play with the complete example and you'll figure it out.
The rest should be pretty self-explanatory.
Traditionally, executables that are installed by the system go in /usr/bin. Executables we write, or add, go in /usr/local/bin, and I highly recommend sticking with that.
Some OSes don't automatically supply an entry for /usr/local/bin in the PATH, so you might need to modify your PATH setting in your ~/.bashrc, ~/.bash_profile or ~/.profile to allow the shell to locate the script.
Executable scripts need to have their executable flag set: chmod +x /path/to/executable is the basic command. See man chmod for more information.
I tend to leave the script's extension in place; Ruby scripts are "foo.rb", Python are "bar.py", etc. I do that because I prefer to have that extension as a hint of the language it's written in, but YMMV. The extension isn't necessary so go with what works for you.
Beyond all that, you might want to provide logging output, or output to the system's syslog. In the first case use Ruby's built-in Logger class, or the Syslog class in the second case.
Actually there's two great gems for command line apps in Ruby.
First is methadone which is for simpler command line apps.
Another is gli which is for apps with multiple commands, for example something like bundler.
If you want to know more, you can check out book about creating command line apps build awesome command-line apps in ruby by author of these gems.
You do not need to make it a gem, the following suffices:
Change its name from script.rb to script
Add #!/usr/bin/env ruby as the first line of script
Put it somewhere in PATH (e.g. $HOME/bin, making sure it is in PATH), or execute by giving path explicitly, e.g. $HOME/myscriptdir/script
I am using IRB (interactive ruby console) to learn how to program with Ruby. How do I load a file into the console if I write my programs in a text editor first?
If you only need to load one file into IRB you can invoke it with irb -r ./your_file.rb if it is in the same directory.
This automatically requires the file and allows you to work with it immediately.
Using ruby 1.9.3 on Ubuntu 14.04, I am able to load files from the current directory into irb with the following command line:
irb -I . -r foo.rb
where foo.rb is the file I want to load from my current directory. The -I option is necessary to add the current directory (.) to ruby's load path, as explained in the ruby man page. This makes it possible to require files from the current directory, which is what the -r option to irb accomplishes.
The key piece that wasn't obvious for me when I had this problem is the -I option. Once you do that, you can call require 'foo.rb' from within irb for any files in the current directory. And of course, you can specify any directory you want, not just . with the -I option. To include multiple directories on the load path, separate them with a colon (:), e.g.:
irb -I foo/:bar/:baz/
This command will add the directories foo, bar, and baz to ruby's load path.
The final alternative is to use the relative or absolute path to the file when using require or -r to load a file:
irb -r ./foo.rb
or from within irb:
> require './foo.rb'
Type in irb
And then
require './ruby_file.rb'
This is assuming that ruby_file.rb is in the same directory. Adjust accordingly.
Two ways:
to load source without running the program -- this gives access to all variables and functions:
source("filename.rb")
to run program and then drop into interactive mode -- this only gives access to functions, not variables:
require("filename.rb")
It depends on your ruby. Ruby 1.8 includes your current path, while ruby 1.9 does not. Evaluate $: to determine if your path is included or not. So in ruby 1.9 you must use the entire path, which is always a safe bet.
Then you can use require or load to include the file.
require does not require you to add the suffix of the file when trying to find it and will only include the file once. require should be used instead of load most of the time.
Check out Adding a directory to $LOAD_PATH (Ruby) if you are going to be using ruby 1.8
Type the ruby codes in the text editor
Save it with the extension .rb (for example: demo.rb).
In linux, open your terminal then change directory to the current location of that file (cd command is used to change directory).
After that,type irb and your filename(don't forget to include your extension(.rb)).
In that image,I loaded a simple ruby file which only prints "ruby".
Another way to load the path into irb is just type require then drag and drop the file into the terminal.🙂
-tested using Linux Mint.
For those, who want to load .rb file from the different directory. Just add a string representer of the directory to $: variable.
> $: << "/directory/to/the/required/rb/file"
> require "file"
I'm using ruby v1.9.1 in combination with vim and I execute my scripts with:
:!ruby "%"
my scripts are running fine if I add:
$:.unshift File.dirname(__FILE__)
to add the path of this file to the LOAD_PATH of ruby. If I omit this line my require statements to local scripts aren't working anymore.
Is there a way to pass the path of the file to rubys LOAD_PATH? Something like (completly fictional):
:!ruby "%" --add-to-load-path
I did some research before and stubled upon require_relative, but this has the same effect as require and is not working.
You can use the -I option of the ruby executable and write something like the following:
:!ruby -I%:p:h. %
See ruby --help for further information and file modifiers.
Edited: see comments.
Might sound like a newbie question (and it is since I am new to Ruby and IRB) but is there a way to save the commands you did in IRB to file? I am playing with WATIR and would love to save all my inputs to file instead of copying and pasting each.
Thanks for the help!
On my machine I can put this in my .irbrc file (located in your home directory):
Kernel.at_exit {
File.open("irb.log", "w") do |f|
f << Readline::HISTORY.to_a.join("\n")
end
}
It creates a file irb.log that contains your readline history. Irb uses readline for command input. It might be configured not to use readline for some people, I don't know. And maybe the history will be truncated at some point, or maybe it'll be modified by certain commands you do in your irb session... but try it out and see if it works.
If you want the irb prompt and the result of each command to be included in the log, then just use tee to record the output of irb:
$ irb | tee irb.log
You can run vim in irb:
http://vimcasts.org/episodes/running-vim-within-irb/
Take a look at watir-console.
I found this question when looking to do the same thing. I ended up switching from IRB to Pry; it is a separate REPL project for Ruby that has a whole host of advanced features not supported in IRB.
Well worth a look.
Pry