Correct way to require files within a RubyGem? - ruby

I used Bundler to generate a Gem skeleton for me. Within lib/foo.rb, I have the following:
require 'foo/client'
require 'foo/other'
Those two lines are supposed to require lib/foo/client.rb and lib/foo/other.rb, respectively. It builds without a problem, but when I go to test it with irb, I get a file not found error.
ruby-1.9.2-head :003 > require 'foo'
LoadError: no such file to load -- foo/client
from /home/ethan/.rvm/rubies/ruby-1.9.2-head/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /home/ethan/.rvm/rubies/ruby-1.9.2-head/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /home/ethan/.rvm/gems/ruby-1.9.2-head/gems/foo-0.1.0/lib/foo.rb:3:in `<top (required)>'
from /home/ethan/.rvm/rubies/ruby-1.9.2-head/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /home/ethan/.rvm/rubies/ruby-1.9.2-head/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from (irb):3
from /home/ethan/.rvm/rubies/ruby-1.9.2-head/bin/irb:16:in `<main>'
ruby-1.9.2-head :004 >
What is the correct way to require files within the same Gem? There must be something simple that I'm overseeing...

If your gem is called 'foo', then all you need to do is use bundle exec:
bundle exec your-script.rb
Without bundle exec, the load paths are not set up correctly.
Using irb, you use the bundle command bundle console.
chris#chris:~/oss/pp-adaptive$ irb
irb(main):001:0> AdaptivePayments
NameError: uninitialized constant Object::AdaptivePayments
from (irb):1
from /home/chris/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
irb(main):002:0>
chris#chris:~/oss/pp-adaptive$ bundle console
irb(main):001:0> AdaptivePayments
=> AdaptivePayments
irb(main):002:0>
Note that once the gem is installed on your system, you may use it without bundler.

The current directory is not in the load path in Ruby 1.9. Try one of these:
require './client'
or
require_relative 'client'

If you are in IRB itself you may have to
require "rubygems"
require "foo"
if the library is a gem. Alternatively you can require the full path of the gem, but I wouldn't advise it since rubygems does require magic so reload! works in irb ( at least it does for rails console ).

Related

How to require ActiveRecord In IRB

I would like to load the ActiveRecord gem in my IRB session, but the following is not working:
require 'activerecord'
2.4.1 :004 > require 'activerecord'
LoadError: cannot load such file -- activerecord
from /Users/robskrob/.rvm/rubies/ruby-2.4.1/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /Users/robskrob/.rvm/rubies/ruby-2.4.1/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from (irb):4
from /Users/robskrob/.rvm/rubies/ruby-2.4.1/bin/irb:11:in `<main>'
and Neither is this one:
2.4.1 :018 > require 'activerecord-5.1.2'
LoadError: cannot load such file -- activerecord-5.1.2
from /Users/robskrob/.rvm/rubies/ruby-2.4.1/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:120:in `require'
from /Users/robskrob/.rvm/rubies/ruby-2.4.1/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb:120:in `require'
from (irb):18
from /Users/robskrob/.rvm/rubies/ruby-2.4.1/bin/irb:11:in `<main>'
This is my Gem path in irb:
2.4.1 :012 > Gem.path
=> [
"/Users/robskrob/.rvm/gems/ruby-2.4.1",
"/Users/robskrob/.rvm/gems/ruby-2.4.1#global
]
and here are my active record gems:
ls /Users/robskrob/.rvm/gems/ruby-2.4.1/gems/activere
activerecord-4.2.10/ activerecord-5.1.2/ activerecord-5.1.4/ activerecord-5.1.6/
activerecord-5.0.0.1/ activerecord-5.1.3/ activerecord-5.1.5/ activeresource-5.0.0/
How do I load one of those ActiveRecord gems into my IRB session?
I have looked at this post and this post, but I could not source a solution from either the questions or the answers.
Try require('active_record')
If you take a look at the gem Github repo the actual file name is active_record.rb so the above code should work.
https://github.com/rails/rails/tree/master/activerecord/lib

Ruby require not finding all files

I've done some research and nothing quite hits on my issue...
I'm building a gem so I have a directory structure like this
root/ - lib/ - mygem/ - cli.rb
- version.rb
- xmltemplates.rb
- mygem.rb
- bin/
It's a thor app so in cli.rb I have:
require 'thor'
require 'mygem/version'
require 'mygem/xmltemplates'
module MyGem
#STUFF
end
And in vesrion.rb:
module MyGem
VERSION = '0.1.0'
end
and in xmltemplates.rb:
module MyGem
MY_TEMPLATE = 'TEST'
end
I was getting errors when trying to compile with as a gem so I decided to play with it in irb.
So for this test I did cd lib to make myself local to the lib directory.
1.9.3-p392 :001 > require 'rubygems'
=> false
1.9.3-p392 :003 > require 'mygem'
=> true
1.9.3-p392 :005 > require 'mygem/cli'
LoadError: cannot load such file -- mygem/xmltemplates
from /Users/user/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /Users/user/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /Users/user/.rvm/gems/ruby-1.9.3-p392/gems/mygem-0.1.0/lib/mygem/cli.rb:3:in `<top (required)>'
from /Users/user/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /Users/user/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from (irb):5
from /Users/user/.rvm/rubies/ruby-1.9.3-p392/bin/irb:16:in `<main>'
1.9.3-p392 :007 > require 'mygem/xmltemplates'
LoadError: cannot load such file -- mygem/xmltemplates
from /Users/user/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /Users/user/.rvm/rubies/ruby-1.9.3-p392/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from (irb):7
from /Users/user/.rvm/rubies/ruby-1.9.3-p392/bin/irb:16:in `<main>'
1.9.3-p392 :009 > require 'mygem/version'
=> true
1.9.3-p392 :010 > MyGem::VERSION
=> "0.1.0"
So it boils down to this: Is there any reason that mygem/version would load find and mygem.xmltemplates would not? I've checked permissions on the files as well and they are all identical.
Some of the previous posts I've read mentioned require_relative, but that didn't work for me and it seems like if that was it I would not have been able to load cli.rb or version.rb.
When working with gems it's important that your .gemspec file is up to date. The gem loader uses this to find files. Perhaps you haven't added xmltemplates to that spec yet?
If you're trying to diagnose loading problems, always check $LOAD_PATH to be sure your lib/ is in there. If it isn't, you will get LoadError type exceptions due to missing files.

What could cause a LoadError when requiring taglib-ruby in IRB?

Have gone through similar questions here, but have not been able to get this working.
I have RVM installed, and am trying to use a gemset I've set up for a Rails project to run a simple .rb file. After loading the gemset, I can load some of the gems through IRB, but not others.
1.9.2p290 :003 > require 'json'
=> true
1.9.2p290 :004 > require 'taglib-ruby'
LoadError: no such file to load -- taglib-ruby
from /Users/amoodie/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /Users/amoodie/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from (irb):4
from /Users/amoodie/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
1.9.2p290 :005 > require 'dropbox-sdk'
LoadError: no such file to load -- dropbox-sdk
from /Users/amoodie/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /Users/amoodie/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from (irb):5
from /Users/amoodie/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
1.9.2p290 :006 > require 'pg'
=> true
1.9.2p290 :007 > require 'rails'
=> true
All the above gems are in the same gemset. Trying to load rubygems returns false. I have no issue using accessing them through the Rails app, through.
Using the Wrong Module Names
You're probably requiring the wrong module names. For example, try require 'taglib' instead of using the name of the gem or system package. If that works, you will probably need to do something similar with the require statement for the Dropbox library, too.

ruby LoadError: cannot load such file

When I require a file, for example (called st.rb):
require 'rubygems'
require 'mongrel'
class TestHandler < Mongrel::HttpHandler
def process(request, response)
response.start(200) do |head, out|
head["Content-Type"] = "text/html"
out.write "Hello, World!\n"
end
end
end
in irb I get:
>> require 'st.rb'
LoadError: cannot load such file -- st.rb
from /usr/local/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from /usr/local/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
from (irb):3
from /usr/local/bin/irb:12:in `<main>'
I might have a clue, but it's just a guess. My ruby version/install location is:
/usr/local/bin/ruby and ruby 1.9.3p0
yet, ruby gems is in /usr/local/lib/ruby/1.9.1 and it's talking about version 1.9.1. Could this possibly be the reason?
Thanks!
UPDATE
Weird, when I type 'puts RUBY_VERSION' in IRB, I get this:
puts RUBY_VERSION
1.9.3
NoMethodError: undefined method `write' for nil:NilClass
from /usr/local/lib/ruby/1.9.1/irb.rb:311:in `printf'
from /usr/local/lib/ruby/1.9.1/irb.rb:311:in `output_value'
from /usr/local/lib/ruby/1.9.1/irb.rb:160:in `block (2 levels) in eval_input'
from /usr/local/lib/ruby/1.9.1/irb.rb:273:in `signal_status'
from /usr/local/lib/ruby/1.9.1/irb.rb:156:in `block in eval_input'
from /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:243:in `block (2 levels) in each_top_level_statement'
from /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop'
from /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in each_top_level_statement'
from /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch'
from /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `each_top_level_statement'
from /usr/local/lib/ruby/1.9.1/irb.rb:155:in `eval_input'
from /usr/local/lib/ruby/1.9.1/irb.rb:70:in `block in start'
from /usr/local/lib/ruby/1.9.1/irb.rb:69:in `catch'
from /usr/local/lib/ruby/1.9.1/irb.rb:69:in `start'
from /usr/local/bin/irb:12:in `<main>'
Maybe IRB bug!
>>
The directory where st.rb lives is most likely not on your load path.
Assuming that st.rb is located in a directory called lib relative to where you invoke irb, you can add that lib directory to the list of directories that ruby uses to load classes or modules with this:
$: << 'lib'
For example, in order to call the module called 'foobar' (foobar.rb) that lives in the lib directory, I would need to first add the lib directory to the list of load path. Here, I am just appending the lib directory to my load path:
irb(main):001:0> require 'foobar'
LoadError: no such file to load -- foobar
from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `require'
from (irb):1
irb(main):002:0> $:
=> ["/usr/lib/ruby/gems/1.8/gems/spoon-0.0.1/lib", "/usr/lib/ruby/gems/1.8/gems/interactive_editor-0.0.10/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", "."]
irb(main):004:0> $: << 'lib'
=> ["/usr/lib/ruby/gems/1.8/gems/spoon-0.0.1/lib", "/usr/lib/ruby/gems/1.8/gems/interactive_editor-0.0.10/lib", "/usr/lib/ruby/site_ruby/1.8", "/usr/lib/ruby/site_ruby/1.8/i386-cygwin", "/usr/lib/ruby/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i386-cygwin", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i386-cygwin", ".", "lib"]
irb(main):005:0> require 'foobar'
=> true
EDIT
Sorry, I completely missed the fact that you are using ruby 1.9.x. All accounts report that your current working directory has been removed from LOAD_PATH for security reasons, so you will have to do something like in irb:
$: << "."
The problem shall have solved if you specify your path. For example,
require 'st.rb' --> require './st.rb'
See if your problem get solved or not.
For security & other reasons, ruby does not by default include the current directory in the load_path. You may want to check this for more details - Why does Ruby 1.9.2 remove "." from LOAD_PATH, and what's the alternative?
I created my own Gem, but I did it in a directory that is not in my load path:
$ pwd
/Users/myuser/projects
$ gem build my_gem/my_gem.gemspec
Then I ran irb and tried to load the Gem:
> require 'my_gem'
LoadError: cannot load such file -- my_gem
I used the global variable $: to inspect my load path and I realized I am using RVM. And rvm has specific directories in my load path $:. None of those directories included my ~/projects directory where I created the custom gem.
So one solution is to modify the load path itself:
$: << "/Users/myuser/projects/my_gem/lib"
Note that the lib directory is in the path, which holds the my_gem.rb file which will be required in irb:
> require 'my_gem'
=> true
Now if you want to install the gem in RVM path, then you would need to run:
$ gem install my_gem
But it will need to be in a repository like rubygems.org.
$ gem push my_gem-0.0.0.gem
Pushing gem to RubyGems.org...
Successfully registered gem my_gem
I just came across a similar problem. Try
require './st.rb'
This should do the trick.

Ruby gem install and "No such file to load"

I'm scripting with Ruby 1.9.2dev in Backtrack 5 but I'm having some problems when try to parse html entities with the library "htmlentities".
I cannot load the library although I have installed it with gem.
I'll show you the problems I'm having in the console:
root#bt:~# gem list -d htmlentities
*** LOCAL GEMS ***
htmlentities (4.3.1)
Author: Paul Battley
Homepage: https://github.com/threedaymonk/htmlentities
Installed at: /var/lib/gems/1.9.2
A module for encoding and decoding (X)HTML entities.
root#bt:~# irb irb(main):001:0> require 'htmlentities' LoadError: no such file to load -- htmlentities
from (irb):1:in `require'
from (irb):1
from /usr/bin/irb:12:in `<main>'
This is the same problem I'm having with nokogiri. I installed the library with
gem install htmlentities
Do you have any idea why I'm having this problem?
Thank you.
EDITED:
I tried also with require 'rubygems' previously to any other require, but happens the same:
I tried require 'rubygems' but is happening the same:
irb(main):001:0> require 'rubygems'
=> false
irb(main):002:0> require 'htmlentities'
LoadError: no such file to load -- htmlentities
from (irb):2:in `require'
from (irb):2
from /usr/bin/irb:12:in `<main>'
Try to require 'rubygems' before the rest of your gems requirements.
rubygems is actually redefining the Kernel#require method to look for gems on your gempath. Whitout it ruby will just look for local/on path files.
It took me a lot but now I know how to fix it. It's about GEM_PATH.
# echo "export GEM_PATH=/var/lib/gems/1.9.2/" >> ~/.bashrc
# source ~/.bashrc
Now if I run irb:
# irb
irb(main):003:0> require 'htmlentities'
=> true
irb(main):004:0>
WOOT!

Resources