Bundler issue when running a ruby script - ruby

I am trying to run some older ruby script (with old ruby version) from within a ruby script. Here is a program:
old_ruby187.rb
#!/usr/ruby/1.8.7/bin/ruby
puts "Hello"
new_ruby230.rb
#!/usr/ruby/2.3.0/bin/ruby
require "rubygems"
require "bundler"
Bundler.setup # Code works if I comment this line
puts `old_ruby187.rb`
I get bundler load error. If I execute ./new_ruby230.rb, it gives an error for the last puts command line.:
'require': no such file to load -- rubygems (LoadError)
If I comment just Bundler.setup and run it, it works fine. Not sure if Bundler.setup tries to load something for system call. I need bundler for other gems used in new_ruby230.rb script.
Any help is appreciated.
Update (02/22/2018):
I ended up using ssh when calling old ruby script. Something like:
new_ruby230.rb
#!/usr/ruby/2.3.0/bin/ruby
require "rubygems"
require "bundler"
require "socket"
Bundler.setup
puts `ssh #{Socket.gethostname} old_ruby187.rb` # this worked!

Pretty sure you're not supposed to require rubygems like that. Bundler is there to manage your gems. Remove that require statement (require "rubygems") and you should be good to go.

Related

Require files from gem in Ruby script without bundle exec

I have a script that needs to require specific files out of gems defined in the project Gemfile.
#!/usr/bin/env ruby
require 'some_gem/helpers/some_helper'
... rest of script
When I run the script, I get an error about not being able to load some_helper.rb. If I run with bundle exec command... then everything works.
I understand that bundle exec exposes the Gems to the $LOAD_PATH which lets require work. Is there a way to move that capability into the script so users don't have to type bundle exec?
Do I just need to add require "bundler/setup" to the script before I require the gem files?
http://bundler.io/v1.12/#getting-started
:)
#!/usr/bin/env ruby
require 'rubygems' # because reasons.. most probably it is not needed unless you are using really old ruby where it is not loaded by default
# also at the moment rubygems and bundler are being merged :)
require 'bundler/setup' # for things installed with bundler
require 'some_gem/helpers/some_helper'
You can also check e.g. http://mislav.net/2013/01/understanding-binstubs/

How to write a batch script to install ruby gem

I'm writing a batch script as a setup for a ruby program I'm writing. It needs to be able to
a. Make sure Ruby is installed on the user's computer (and if not point them to the ruby download page)
b. make sure the ruby "yaml" gem is installed, which is a prerequisite for it. I've tried
gem install yaml
in the batch script to no avail. How can I write a batch script that will do these two things?
As far as I know, there is no yaml gem. Although it must be required in code that uses it, it is distributed as part of a Ruby installation. Try this:
ruby -ryaml -e"puts 'YAML found'"
It should work; and if you change the -r token to some nonexistent gem, you'll see an exception raised.
Instead of writing your own script, you could use bundler and create a gemfile. This way people can install all the gems on any operating system.
Example:
require 'rubygems'
require 'bundler/setup'
require 'nokogiri'
require 'rest-client'
#require all your gems like normal
def parse(site)
Nokogiri::HTML(RestClient.get(site))
end
And for the gem file:
source: "https://rubygems.org"
gem 'nokogiri', '~> 1.6.7.2' #<= you can specify which version
gem 'rest-client' #<= you don't have to specify a version though
After you've got everything set up, cd to the directory that has the gemfile and run bundle install this will install all the gems

Requiring Gems With CGI And lighttpd

I have configured lighttpd for CGI. Things are basically working except for requiring gems with Ruby. For example this script
#!/usr/bin/env ruby
require 'cgi'
require 'rubygems'
require 'mysql2'
cgi = CGI.new
print "Content-Type: text/plain\n\n"
print "Hello, world!"
gives me cannot load such file -- mysql2 (LoadError). If I remove the require 'mysql2' it works fine. I installed mysql2 as root, and other users can require it without issue.
What is also odd is that Gem.available? 'mysql2' is true in the CGI script, so it seems that the gem is being detected in some way.
I fixed it, but I'm still not sure what the issue was. As root, I did
gem update --system
gem install --no-user-install mysql2
For some reason the permissions ended up wrong so I had to do
chmod -R o+rX /usr/local/share/gems1.9
Then everything worked again. Also require 'rubygems' ended up being unnecessary in the CGI script.

Rackup: cannot load such file 'sinatra'

I already installed sinatra gem and in irb, if I type,
require 'sinatra'
It returns true.
But when I do
rackup -d config.ru
It tells me
nil
Exception `LoadError' at /usr/local/lib/ruby/1.9.1/rubygems/custom_require.rb:36 - cannot load such file -- sinatra
Here is my config.ru
require './app'
set :environment, ENV['RACK_ENV'].to_sym
set :app_file, 'app.rb'
disable :run
run Sinatra::Application
app.rb
require 'rubygems'
require 'sinatra'
get '' do
'Hello World'
end
I don't know what is going wrong.
$ which ruby
/usr/local/bin/ruby
$ which rackup
/usr/local/bin/rackup
$ ruby -v
ruby 1.9.3p374 (2013-01-15 revision 38858) [x86_64-linux]
$ rackup -v
Rack 1.2 (Release: 1.5)
I think this is just the verbose output from setting the -d option. Does the server actually start (after producing a load of output)?
What’s happening is this. Using -d sets Ruby’s $DEBUG flag to true. Rack then tries to load the app through the config.ru, which in turn loads your app.rb. The first thing in app.rb is require 'sinatra'.
Rubygems replaces the original require method with its own. When you call require it tries to load the file normally using the existing load path and the original require method. If the gem hasn’t been loaded this will raise a LoadError, which Rubygems catches before loading the gem.
With the $DEBUG flag set, Ruby will produce a message when an exception is raised even though it is rescued and dealt with, and this is what you’re seeing.
To avoid this simply omit the -d flag to your call to rackup (perhaps enabling warnings with -w would give you a sufficiently verbose output without swamping you in too much detail).
If the server isn’t starting then it will be a different issue rather than not finding Sinatra. If that is the case you’ll need to check the rest of the output for clues.
(Note that I originally thought something else was happening, and that’s what my questions int he comments were about.)
my guess is that your rackup script is a binstub of a 'rack' gem
installed in a diff ruby1.9x vm
maybe earlier version of ruby1.9.2
so it can't see the sinatra installed
I'd try 'which rackup' on the command line
This is definitely issue of load path. Anyway try to setup required ruby and gems via RVM and Bundler. It makes sure that Ruby interpreter and load paths are consistent.

require 'rubygems'

I have seen many samples of Ruby code with this line (for example, http://www.sinatrarb.com/). What is purpose of this require?
# require 'rubygems'
require 'sinatra'
get '/hi' do
"Hello world!"
end
In all cases the code works without this line.
require 'rubygems' will adjust the Ruby loadpath allowing you to successfully require the gems you installed through rubygems, without getting a LoadError: no such file to load -- sinatra.
From the rubygems-1.3.6 documentation:
When RubyGems is required, Kernel#require is replaced with our own
which is capable of loading gems on demand.
When you call require 'x', this is what happens:
If the file can be loaded from the existing Ruby loadpath, it
is.
Otherwise, installed gems are searched for a file that
matches. If it's found in gem 'y', that gem is activated
(added to the loadpath).
The normal require functionality of returning false if that file
has already been loaded is preserved.
See the documentation for Kernel#require to understand why this is necessary.
It is often superfluous. It will allow you to require specific versions of particular gems though, with the gem command.
https://guides.rubygems.org/patterns/#requiring-rubygems
As an addition to prior (and correct answers): Ruby 1.9 and newer ship with RubyGems built-in, so there is no real need to require 'rubygems'. Source here

Resources