I have a gem installed but require 'gemname' does not work. Why?
There is no standard for what the file you need to include is. However there are some commonly followed conventions that you can can follow try and make use of:
- Often the file is called the same
name as the gem. Sorequire mygem
will work. - Often the file is
the only .rb file in the lib
subdirectory of the gem, So if you
can get the name of the gem (maybe
you are itterating through
vendor/gems in a pre 2.1 rails
project), then you can inspect#{gemname}/lib
for .rb files, and
if there is only one, its a pretty
good bet that is the one to require
If all of that works, then all you can do is look into the gem's directory (which you can find by running gem environment | grep INSTALLATION | awk '{print $4}'
and looking in the lib directory, You will probably need to read the files and hope there is a comment explaining what to do
Ruby: Getting a gem's name for require
It seems like that should be part of the gem spec., so I've been nosing around in some of the rubygems
gem's modules to see if there was a way to programmatically find out the right require
string. So far I haven't found anything. It seems like a hole to me; I've run into the problem you're talking about, and it's a pain. The gem-writers are the ones who know the string, so it should be in the *.gemspec file.
My recommendation is to run gem env
at the command-line, and cd
into the directories displayed for "GEM PATHS", then into the gems
directory, followed by the directory for the gem in question. Inside that directory look for README or similar files and see what they say. If nothing is found run:
grep -r require *
then look through the results for likely candidate strings. If there's a "test" directory, change the "*
" to "test
" first, to reduce the results to more-likely hits.
For instance, the Net::SSH gem is called "net-ssh", but it's gem is required using net/ssh
. Searching with grep showed a lot of instances of require 'net/ssh'
.
Ruby - Cannot use locally installed gem
There are potentially two issues. The first is how you are starting Ruby and the second is how you are requiring your module.
First, if you are starting Ruby by running ruby password_reset.rb
then you are ignoring the Gemfile
. The Gemfile
is only used when you're using bundler
, so you want to make sure you are starting Ruby by running bundle exec ruby password_reset.rb
. This causes bundler to read your Gemfile and execute Ruby in that context.
Second, you're not properly including your module in your Ruby file. Just because you've added the gem to your Gemfile and started Ruby using bundler doesn't mean that the Ruby process knows you intend to use that gem's module; it just makes the module available for use. You might wonder, "Why don't I have to do that in Rails?" Because Rails does that for you automatically via config/application.rb
.
Given these two issues, the correct way to accomplish your goal is to configure your app as follows:
First, create your Gemfile
:
# Gemfile
gem 'password_generator', path: '~/workspace/gems/password_generator'
Second, create your password_reset.rb
file:
# password_reset.rb
# Manually require any libraries that this app will use, even if defined in Gemfile
require 'password_generator'
# Call `puts` so something is printed to the console when this app runs
puts PasswordGenerator.generate
Third, run bundle install
to ensure your Gemfile
is properly formatted and to generate your Gemfile.lock
:
⇒ bundle install
Using bundler 1.16.5
Using password_generator 0.1.0 from source at `../../gems/password_generator`
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Fourth, run bundle exec ruby password_reset.rb
and observe the output:
⇒ bundle exec ruby password_reset.rb
kpiDfyTxtdAsKmYuZqmK
Everything works because:
- Ruby is started with Bundler
- Bundler reads your Gemfile and makes the gems available to Ruby
- Your app requires the module from the gem before attempting to use the module
Ruby loadError when running require 'gemname' on irb
Problem solved.
First I create, on gemname folder, Gemfile
. Inside looks like:
# A sample Gemfile
source "https://rubygems.org"
gemspec
# gem "rails"
Reinstalled the gem, Gemfile.lock
was created.
Then I ran irb via bundle exec irb
instead of typing irb
.
require 'gemname'
works.
Using gems in rails -- require 'gemname' results in No File Found
I just installed this gem and made a new rails 3 app, added it to the Gemfile and I can access it fine from 'rails console' and from within the app when running 'rails server' and also from 'irb'. Are you sure you've typed the gem name correctly? I confused myself by typing 'twitter_oath' a few times and not 'twitter_oauth'...
Have you got the latest rubygems? perhaps try:
$ sudo gem install rubygems-update
$ sudo gem update --system
$ sudo gem update
Are you using rails 3? What OS & ruby are you using?
How to rescue from a require gem_name when the gem is not installed
require
raises a LoadError
exception if it can't load the required library. However, you never rescue from LoadError
anywhere, you rescue from StandardError
.
If you want to rescue from LoadError
, you have to say so:
begin
require 'some_gem'
rescue LoadError
puts 'please install some_gem first!'
end
Even better yet, make sure that you are actually printing the correct missing dependency:
begin
require 'some_gem'
rescue LoadError => e
raise unless e.message =~ /some_gem/
puts 'please install some_gem first!'
end
(This re-raises the exact same exception that was rescued from, in case that the exception was actually caused by some other missing library somewhere else. You wouldn't want to print misleading information, right?)
Depending on what the intended target audience for the library is and whether or not they might be scared away by a backtrace being dumped to their console, you might want to re-raise the exception in any case, instead of just swallowing it:
begin
require 'some_gem'
rescue LoadError => e
puts 'please install some_gem first!' if e.message =~ /some_gem/
raise
end
Or, you could skip the puts
and instead raise an exception with the message set to what you want to say:
begin
require 'some_gem'
rescue LoadError => e
raise e.exception('please install some_gem first!') if e.message =~ /some_gem/
raise
end
Except now the exception is raised in the wrong place and thus has the wrong line number and stacktrace and thus is misleading, but that is easily fixed:
begin
require 'some_gem'
rescue LoadError => e
raise unless e.message =~ /some_gem/
friendly_ex = e.exception('please install some_gem first!')
friendly_ex.set_backtrace(e.backtrace)
raise friendly_ex
end
Now you print pretty much the same thing that you would have printed with the puts
, but you have a "proper" exception that for example allows better debugging or allows a consumer of your library to rescue that exception and handle it their way, both of which would have been impossible or at least hard with your solution that just swallows the exception.
Requiring a gem using internally a different name
require 'google/search'
is correct for your gem
The return value of false
means that Ruby found your gem library file google/search.rb
but has already parsed and loaded it. It would return true
only if the library had not already been loaded.
Reference: http://www.ruby-doc.org/core-2.1.1/Kernel.html#method-i-require
It is possible that the require has found a conflicting file - anything in the gem search path matching google/search.rb
could in theory be loaded, the gem name itself is not relevant other than .../gemname/lib
gets added to the search path. It is this potential for gems to claim file names from each other which drives conventions such as naming your main library file identically to the gem, but as long as one derives reasonably directly and/or uniquely from the other, it should be fine to use different names.
For a gem called google-search
, the advice on Rubygems says users should expect to use the require as you want it, so you are following normal Ruby convention here.
(...)in `require': no such file to load -- 'gemname' (LoadError)
You could invoke you ruby script with
ruby -rubygems script.rb
or add rubygems to RUBYOPT
$ export RUBYOPT="rubygems"
If a gem is not listed using the following command, does that mean it's not installed?
To see if it's installed:
gem list bundler
Gives:
*** LOCAL GEMS ***
bundler (1.1.3)
To find the gem source code:
gem which bundler
Gives:
/path/to/directory/.rvm/gems/ruby-1.9.3-p125@global/gems/bundler-1.1.3/lib/bundler.rb
Related Topics
How to Set Up Cascade Deleting in Rails
Get Last Day of the Month in Ruby
Skip Over Iteration in Enumerable#Collect
How Does Defining [Square Bracket] Method in Ruby Work
Rails 3. How to Add a Helper That Activeadmin Will Use
Changing Field Separator/Delimiter in Exported CSV Using Ruby CSV
Ruby Rails - Select Only Few Columns from the Data Base
Is There an Equivalent to 'Array::Sample' for Hashes
Rails Erb Form Helper Options_For_Select :Selected
Ruby - Determining Method Origins
Bundler Could Not Find Compatible Versions for Gem "Bundler":
How to Write Columns Header to a CSV File with Ruby
How to Access (Devise) Current_User in a Rspec Feature Test
Rake Assets:Precompile Attempting to Connect to Database