Ruby script can't use gem - ruby

I have a tiny, plain (i.e. non-Rails) Ruby project that I'm trying to get to work with the addressable gem. Here's what happens:
$ ruby -r rubygems sign.rb
sign.rb:5:in `require': cannot load such file -- addressable (LoadError)
from sign.rb:5:in `<main>'
This is the Gemfile:
source "http://rubygems.org"
gem "addressable", "~> 2.3.2"
This is sign.rb:
#!/usr/bin/env ruby
require "rubygems"
require "bundler/setup"
require "addressable"
That's all there is to it. Why doesn't it want to use the gem?

There is no addressable file that you can require, just the addressable directory. You need to require the specific file under that directory you want, e.g.:
require 'addressable/uri'
uri = Addressable::URI.parse("http://example.com/path/to/resource/")
# etc ...
or
require "addressable/template"
template = Addressable::Template.new("http://example.com/{?query*}/")
# etc...
Check out the addressable docs.

Have you installed the gem previously by using $ bundle install ?
This will fetch the gems specified in your Gemfile and make them available to the working directory.

Related

ruby adds no path to gems

I use:
rvm 1.25.19 (stable)
ruby 1.9.3p545
I install gem rake command
gem install rake
I understand that $LOAD_PATH should contain the paths:
~/.rvm/rubies/ruby1.9/gems/rake/lib
~/.rvm/rubies/ruby1.9/gems/rake/bin
I execute command:
ruby -e 'puts $LOAD_PATH'
output:
/home/slip/.rvm/rubies/ruby-1.9.3-p545/lib/ruby/site_ruby/1.9.1
/home/slip/.rvm/rubies/ruby-1.9.3-p545/lib/ruby/site_ruby/1.9.1/x86_64-linux
/home/slip/.rvm/rubies/ruby-1.9.3-p545/lib/ruby/site_ruby
/home/slip/.rvm/rubies/ruby-1.9.3-p545/lib/ruby/vendor_ruby/1.9.1
/home/slip/.rvm/rubies/ruby-1.9.3-p545/lib/ruby/vendor_ruby/1.9.1/x86_64-linux
/home/slip/.rvm/rubies/ruby-1.9.3-p545/lib/ruby/vendor_ruby
/home/slip/.rvm/rubies/ruby-1.9.3-p545/lib/ruby/1.9.1
/home/slip/.rvm/rubies/ruby-1.9.3-p545/lib/ruby/1.9.1/x86_64-linux
why path to gem 'rake' don't add?
Installing a gem in Ruby doesn’t automatically add that gem’s files to the load path. When you require a file, first the existing load path is searched and if no matching file is found then Rubygems searches the installed gems for the file. If such a gem is found, then it is activated, which is when the gem’s lib directory is added to the load path.
Here’s an example using the Haml gem:
puts "Before:"
puts $LOAD_PATH
puts
require 'haml'
puts "After:"
puts $LOAD_PATH
This produces:
Before:
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/site_ruby/1.9.1
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/site_ruby/1.9.1/x86_64-darwin10.8.0
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/site_ruby
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/vendor_ruby/1.9.1
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/vendor_ruby/1.9.1/x86_64-darwin10.8.0
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/vendor_ruby
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/x86_64-darwin10.8.0
After:
/Users/matt/.rvm/gems/ruby-1.9.3-p448/gems/tilt-1.4.1/lib
/Users/matt/.rvm/gems/ruby-1.9.3-p448/gems/haml-4.0.5/lib
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/site_ruby/1.9.1
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/site_ruby/1.9.1/x86_64-darwin10.8.0
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/site_ruby
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/vendor_ruby/1.9.1
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/vendor_ruby/1.9.1/x86_64-darwin10.8.0
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/vendor_ruby
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1
/Users/matt/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/x86_64-darwin10.8.0
See how the lib directories for Tilt (which is a dependency of Haml) and Haml have been added to the start of the load path.
In the case of some gems, such as Rake, this is complicated by the fact they are part of the standard library and so are already on the load path. If you changed the example above to use require 'rake' then you wouldn’t see any change in the load path. In this situation you can specify you want to use the gem version with the gem method. This activates the gem in question, placing its lib directory at the start of the load path so when you later call require you will load the correct version.
For example, this script
require 'rake'
puts Rake::VERSION
produces 0.9.2.2 with Ruby 1.9.3, as that is the version of Rake included in the standard library. However this script:
gem 'rake'
require 'rake'
puts Rake::VERSION
produces 10.1.1, since that is the current highest version of the Rake gem installed on my system. You can also specify a particular gem version by providing a second argument to gem (this is the same syntax as used in Gemfiles). Note that the gem method doesn’t require any files, you have to do that as a separate step.

Bunder require yaml/logger

I am using bundler to require all the gems in my project. However, it's not working for yaml/logger.
If I add gem 'yaml' to my gemfile, and run bundle install, I get:
Could not find gem 'yaml (>= 0) ruby' in the gems available on this machine.
But I require it normally just fine. What am I doing wrong?
Thanks
YAML is part of the Ruby Standard Library, and not a Gem.
You do not need to add it to your Gemfile, just require it.
irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> YAML
=> Psych
The same applies for Logger.

How to reference a local gem from a ruby script?

I need to reference a local gem from a plain ruby script, without installing the gem. On the trail of How to refer a local gem in ruby?, i tried creating a Gemfile with the following setup:
%w(
custom_gem
another_custom_gem
).each do |dependency|
gem dependency, :path => File.expand_path("../../#{dependency}", __FILE__)
end
and the script looks like this:
require 'custom_gem'
CustomGem::Do.something
When I execute this with:
bundle exec ruby script.rb
I get:
script.rb:1:in `require': cannot load such file -- custom_gem (LoadError) from script.rb:1:in `<main>'
If I leave out the require 'custom_gem' , I get:
script.rb:3:in `<main>': uninitialized constant CustomGem (NameError)
I even tried without bundler, and just writing gem ... :path =>̣ ... in the script itself, but without results. Is there any other way of referencing custom gems from ruby scripts, without installing the gems locally?
Make sure that your gem name as same as in Gemfile (e.g. custom_gem)
# Gemfile
source "https://rubygems.org"
gem "custom_gem", path: "/home/username/path/to/custom_gem"
Don't forget to actually install this gem using bundler
bundle install
After that, the script should be ready to use by bundle exec ruby script.rb
# script.rb
require 'custom_gem'
CustomGem::Do.something
Without using a Gemfile, you can install a local version of a gem by running bundle exec rake install in the gem's root directory and then you can reference it just like any other installed gem.

How to install, require, and use a gem in ruby

I'm trying to use rake in my ruby script...(Ruby 1.8.6, JRuby 1.6.5)
Downloaded rake using gem install --remote rake, looks ok on install...
Fetching: rake-0.9.2.2.gem (100%)
Successfully installed rake-0.9.2.2
1 gem installed
I've got a simple ruby script which works fine, but when I import rake to using any of the following requires, it starts complaining....
require 'rake'
LoadError: no such file to load -- rake
or
require '/lib/rake'
LoadError: no such file to load -- lib/rake
After some searching, I found that adding require 'rubygems' just before rakefixes the issue....
require 'rubygems'
require 'rake'
Even though it's working, I've got some questions...
The gem spec on rake shows the require_path as lib, so why
doesn't require '/lib/rake' work? Am I misunderstanding the significance of require_path?
Why is it necessary to place require 'rubygems' before require
'rake'
Yes, you are misunderstanding the significance. The require_paths in the specification is an array of subdirectories of that gem's installation directory that should be searched for files belonging to the gem.
To find out where rake really is, try this:
$ gem which rake
You'll see that it is actually installed somewhere completely unrelated to /lib; on my system, it's under /var/lib/gems. Ruby gems, in general, live in their own directory structure; the only file in the standard Ruby include path ($:) is rubygems itself, which you used to have to explicitly require in order to make any actual gems visible. (Since Ruby 1.9, that has not been necessary.)
Gems are more complex than just libraries to load; you can have multiple versions of the same gem installed, and specify which one you want at a time, and do other things that wouldn't work if the gems were just dumped into the standard Ruby include path.
The require_path in the gemspec tells ruby where the files of this gem are located within the gem. It makes you able to type require 'rake', and ruby then knows it needs to look for /lib/rake within the gem installation folder.
In Ruby 1.8, rubygems (the mechanism responsible for making gems available to your app) is not loaded by default, and the default ruby isn't aware of any gem on your system. You need to load rubygems before being able to require any other gem. This is not the case anymore with Ruby 1.9.

How can I use Nokogiri in irb?

I am trying to:
require 'nokogiri'
in irb, without success. The Nokogiri gem is installed. From:
gem list --local
I get:
nokogiri (1.4.4, 1.4.3.1)
but when I try to "require" it in irb, I get:
LoadError: no such file to load -- nokogiri
from (irb):8:in `require'
from (irb):8
from :0
Nokogiri 'lives' in:
/opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/nokogiri-1.4.4/lib
on my system. Also, my GEM PATH (from gem env) is:
/opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8
If I go all the way into the nokogiri gem directory, I can successfully "require" it. But why can't I require it from anywhere else? I am misunderstanding something about the gem path.
Try to require 'rubygems' before requiring nokogiri. If there are no witches on your machine this could help.
Ruby prior to 1.9 didn't automatically do a require 'rubygems' for you. Post 1.9 it does. I always forget when I jump back to 1.8.7 to test something, especially in irb.
You can add require 'rubygems' to your ~/.irbrc file if you want. It won't hurt anything having it there.

Resources