How to require a frozen ruby gem - ruby

I'm working on a small Ruby project and within a class I require a gem.
Now since the project has to be portable I have decided to freeze the gem so I have unpacked it.
My project now looks like
/
/lib
xml_generator.rb
/vendor
/gems
/dbf-1.7.3
How can I specify within xml_generator to use dbf-1.7.3 located locally at vendor/gems/dbf-1.7.3?
I tried several solutions, the last one is
gem "dbf", :path => "../vendor/gems/dbf-1.7.3"
require 'dbf'
but it seems it is not working.
Thanks for your help.

I think you just have to specify the exact version if dbf is installed on your system:
require 'rubygems'
gem 'dbf', '= 1.7.3'
If not you can try to require all the Ruby files under dbf-1.7.3:
Dir['./../vendor/gems/dbf-1.7.3/*.rb'].each{ |f| require f }

Related

How to include Ruby Gems on Github

So, I've created a GitHub to manage my latest Ruby project, and I want for it to utilize a couple of gems. On my PC, all I have to go is type
gem install "gemName"
and it loads it to my computer, and then all I have to do in my Ruby script is have
require "rubygems"
require "gemName"
How can I do this with GitHub? What I tried to do is create a subfolder from the main repository (called "RubyGems") and then in my main ruby script
require "/RubyGems/colorize"
require "/Rubygems/psych"
With the two gems (colorize and psych) in the "RubyGems" folder.
Is this the proper way to do this? Will this even work? What is the right way to do this? (Sorry, I'm kinda new to GitHub.)
A couple of things, unless you're using a really old version of Ruby (like 1.9) you don't need to require 'rubygems' because is already required by default, next I highly recommend you to get familiar with bundler.
Bundler is used for "bundling" the required gems you use, to so do you have to install the gem (gem install bundler) and then you create a Gemfile, like this:
source 'https://rubygems.org'
ruby '2.2.0'
gem 'colorize', git: 'https://github.com/fazibear/colorize.git'
gem 'psych'
Execute bundle install after, that will create Gemfile.lock file, make sure you push both files to your repository.
With that you would be able to bundle exec ./your-script.rb, assuming your script is something like this:
require 'psych'
require 'colorize'
# Here I do stuff with psych and colorize

Handling require in a project meant to be provided as a gem

I'm completely lost with ruby "require" (and I don't have the option for require_relative since my code is meant to run with ruby 1.8.7.
First some sample code.
requester.rb
require './column/main_column'
....
column/main_column.rb
require './helper' # helper.rb being in the root dir
....
column/segment_column
require './column/main_column'
require './helper' # helper.rb being in the root dir
....
I'm completely lost in how should I use my requires to make my code usable inside a gem and in a standalone way (without assuming a previous gem installation). I was reading at Jekyll's code and every dependencies seems to be loaded in the main rb file which to my opinion is a bit dirty and still do resolve the problem if column/segment_column.rb needs to be called independently.
Please try to argument about different approaches and why one is the best.
You should require files without the extension and relative to your gem project's lib folder.
For example, given this structure:
example-gem/
lib/
example/
gem.rb
example.rb
example-gem.gemspec
You'd require the main example module using:
require 'example'
And in the example.rb file you'd find:
require 'example/gem'
This set of conventions is adopted by the community and is documented on the RubyGems Guides. If they fail, it is often because your gem's lib directory is not in Ruby's $LOAD_PATH, which usually means the gem is not installed.
Building and installing gems during development is cumbersome. For that reason, gems like Bundler became part of the toolboxes of many Rubyists. Bundler lets you use your gem without having to build or install it locally. You can simply bundle exec a script that uses your gem or use bundle console in order to interact with it.

Created a simple gem, but irb can't see it

I created a simple gem by doing:
testgem.gemspec
Gem::Specification.new do |s|
s.name = 'testgem'
s.version = '0.0.1'
s.summary = "code generation"
s.authors = ['asdf']
end
created the following file layout:
testgem.gemspec
Gemfile
lib/
lib/testgem.rb
lib/testgem/other.rb
ran the following:
gem build testgem.gemspec
WARNING: no description specified
WARNING: no email specified
WARNING: no homepage specified
Successfully built RubyGem
Name: testgem
Version: 0.0.1
File: testgem-0.0.1.gem
installed it:
gem install ./testgem-0.0.1.gem
Successfully installed testgem-0.0.1
1 gem installed
tested to see if irb can see it:
irb
require 'testgem'
oadError: cannot load such file -- testgem
I'm using Ruby 1.9.3-p194
It seems to be installed if I do:
gem list
..
testgem (0.0.1)
..
What could be the issue?
You need to add your lib to the search path. Just add
$:.push File.expand_path("../lib", __FILE__)
on top of your .gemspec
When you use require in Ruby, you are trying to load a file, not a gem. The file could of course be contained in a gem, and by convention a gem will have a file with the same name as the gem itself so that if you wanted to use the gem foo you would use require 'foo'. This isn’t always the case though, for example to use the bcrypt-ruby gem you need to require 'bcrypt'.
Additionally a gem doesn’t necessarily have to contain any filles at all. An example of this is the rails gem, which doesn’t contain any files itself (at least in version 3.2), but has dependencies to the various Rails components, so that you can install them all in one step.
In your case, although you have a lib/testgem.rb file in your gems project directory, you are not including it in your gem. You need to specify which files should be included, the default is to not include anything.
To simply include all the files in your project directory, you can add something like:
s.files = Dir.glob '**/*'
to your gemspec.
You need to require 'rubygems' first.

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.

Add the gem I'm developing to be loaded automatically by rubygems without build/install?

I'm developing a gem with Jeweler in a custom directory.
I want to be able to require the gem within any app (and also the executables files from $PATH), and without needing to build and install the gem each time I modify it.
I thought about 2 ways:
I make a symlink to $GEM_HOME/gems and $GEM_HOME/bin
I add the bin directory to $PATH and the lib directory to rubygems to be loaded.
But I bet there is a proper way to do this.
You can specify a local path in the gem command:
gem 'your-gem', '1.2.3', :path => 'path/to/your-gem'
Update: As #Nick points out in the comments,
This is specific to using bundler. In general, it's just require '/path/to/your-gem.
I'd like to add, however, that if you're using a custom-developed gem, bundle will probably make your life easier if you're not already using it. This is because with bundler, when you're done developing the gem (or at a stable/release point) you can load a gem directly from a github repository like this:
gem 'your-gem', :git => 'git#github.com:you/your-gem.git'
No need to mess around with your Gemfile
require 'bundler/setup' will put the right gem into your $LOAD_PATH and allow you to require it on the next line.
#!/usr/bin/env ruby
require 'bundler/setup'
require '<gem-name>'

Resources