Call Ruby 1.8 script from Ruby 2.0 script - ruby

I'm not sure if this belongs here or somewhere else (SuperUser?) but anyway:
I've got two Ruby scripts, one which requires Ruby 2.0 (A) and another which requires 1.8 (B). A needs to call B with a forked processes. A is something like this:
require "fileutils"
require "json"
...
`name_of_B`
B is an executable script with a shebang, starting like this:
#!/Users/user_name/.rvm/rubies/ruby-1.8.7-p374/bin/ruby
require 'rubygems'
require 'json'
...
I use RVM to manage my Ruby versions:
> rvm list
rvm rubies
ruby-1.8.7-p374 [ i686 ]
ruby-1.9.3-p448 [ x86_64 ]
=* ruby-2.0.0-p247 [ x86_64 ]
I run A with:
> ruby name_of_A
but end up with:
/Users/jacobevelyn/.rvm/gems/ruby-2.0.0-p247/gems/json-1.8.1/lib/json/ext/parser.bundle: [BUG] Segmentation fault
ruby 1.8.7 (2013-06-27 patchlevel 374) [i686-darwin12.5.0]
Any thoughts on what I can do? I don't know a whole lot about gems but it appears that B tries to look at gems installed under Ruby 2.0, rather than 1.8. (Yes, I've run gem install json under 1.8 already.) Obviously the scripts are more complicated than they appear here and absolutely cannot be ported or combined (this doesn't mean I don't want to, it means I can't for my use case), otherwise I would.

you need to change the shebang to:
#!/Users/user_name/.rvm/wrappers/ruby-1.8.7-p374/ruby
it will not only use that ruby but also its gems.
in case you use bundler (Gemfile) you might also need to wrap the command invocation in:
Bundler.with_clean_env do
...
end
which will reset loaded bundler environment

Call:
result = `\path\to\ruby_1_8 \path\to\ruby_1_8_script.rb`
This will use the correct ruby binary to execute the script that expects it. The result is saved into the var.
You can call which ruby to find the version of the ruby in your current directory. Go to your project / source dir and call it to see the version (presumably Ruby 2) that you're using for the main app. Then, go to your old project / repo (associated with the 1.8 script) and run it again. Hopefully that will show you the path to Ruby 1.8. If not, try it from root (/). Or use RVM to confidently switch to Ruby 1.8 and then call it there to get the path.
I've never used RVM much. If it is confused, and filters things through the wrong gem set, etc, then you may need instead to switch to rbenv. Also, you may need to use its own functions to display the true path to the Ruby 1.8 binary (i.e. maybe it messes with which?) Again, I don't RVM.

Related

Rubinius Syntax Errors

While working with LocomotiveCMS using Rubinius I ran into a bunch of syntax errors. All were along the lines of expecting '|'. No one was posting issues about this so I figured I would ask: How do I resolve these issues? Is this a problem with Rubinius?
First off, LocomotiveCMS only supports the "last version of Ruby" (Ruby 1.9.2 and greater). View the requirements section.
Rubinius defaults to Ruby 1.8.7 (view on rvm.io). If you look at the lines where most of these syntax errors occur like in app/models/locomotive/page.rb they are most likely in "lambdas" which aren't supported until Ruby 1.9.
To resolve, you can make Rubinius (rbx) use Ruby 1.9 in two ways:
Use rvm to reinstall rbx using Ruby 1.9 as the default:
rvm reinstall rbx --1.9
Note: if rvm complains about bad arguments upgrade rvm using rvm get master or rvm get stable.
Or, if you don't want to completely reinstall rbx, you can set an environment variable in the directory which you'll be calling Rubinius, like in the rails root directory.
export RBXOPT=-X19
You can check that the environment variable is set by using rbx -v to check the Ruby version. It should return something like:
rubinius 2.0.0.rc1 (1.9.3 release ...)
Note: If you are running Rubinius from another directory you will need to set this option again.

How to use Bundler with path specified Ruby version

I am on a VM (Lucid 64b) with a system Ruby version of 1.9.3p0.
I have a Ruby script that creates a .deb file -- The script needs to use Ruby 1.8.7 which I have installed in /foo/ruby/1.8.7.
There is an existing Gemfile to be used with Bundler
I can't use RVM and I can't install gems at the system level.
My .bashrc includes (and has been sourced)
export PATH=$PATH:/foo/ruby/1.8.7/bin
but ruby -v still gives me
ruby 1.9.3p0 (2011-10-30) [x86_64-linux]
Questions
How can I change the Ruby version for my user to use Ruby 1.8.7?
I've run: bundle install --path vendor/bundle
So in that directory (actually ./vendor/bundle/ruby/1.8/cache/gems) are all the gems I need but, when I run the Ruby script it doesn't find the required gems. I run the script like so /foo/ruby/1.8.7 script_to_gen_deb_file.rb
How can I get ruby to see/use the bundled gems?
Update
I was able to solve it. I needed to use
/foo/ruby1.8.7/bundle exec /foo/ruby1.8.7/ruby script_to_gen_deb_file.rb
I had tried this before, but I got an unrelated error and believed there was an environment problem.
Change your path so the special ruby gets precedence?
export PATH=/foo/ruby/1.8.7/bin:$PATH

Does the Bundler 1.2.0 ruby version check obviate the need for a basic .rvmrc file?

Bundler 1.2.0.pre includes a new "ruby" DSL option. According to Heroku's documentation, they use this new Gemfile syntax to control which ruby version is used when you push your app.
Being pre-release, documentation for the new Bundler option is fairly thin on the ground at the moment, and the Bundler 1.2 roadmap simply lists it as "ruby version check".
My question is: currently I use a one-line .rvmrc file in most of my projects, in which I only specify the ruby version for that project (eg. rvm ruby-1.9.3). I don't use RVM gemsets or anything else (I prefer to vendor all of the required gems within the project, and let Bundler manage the dependencies).
Given my trivial RVM config, will the new "ruby" option in Bundler's DSL mean I no longer need to specify a .rvmrc file at all? Or are they two different things?
(I do like the fact that RVM automatically switches the ruby version when I cd into my project...not sure if Bundler would do that, or if it just warns when the current version doesn't match?)
the new ruby is a function and it will allow anything that finally evaluates to a string.
Unfortunately o read it you would need to use a bundler command which assumes you already have a ruby.
Instead RVM gives you two ways to defining ruby in Gemfile:
1) ruby "1.9.3" - simple strings
2) #ruby=1.9.3-p125 - a comment when you want to use ruby code for ruby or when you want to specify patchlevel or gemset!:
#ruby=1.9.3
ruby ENV['RUBY_VERSION'] || '1.9.3'
Will allow bundler to work with any ruby loaded by RVM but by default will use 1.9.3 from #ruby=

custom_require.rb:36:in `require': no such file to load -- myapp(LoadError)

i get the above error, all i did was install rvm and update to ruby 1.9.2 from the default ruby that you get with mac.
all my gems appear in the gem list but do i need to specify a path somewhere?
cheers,
glenno.
Check that you have the gems installed gem list If not, install as usual gem install whatever or if you want a specific version gem install whatever -v 1.2.3 Or if you have bundler in your project (ie Rails), it's just bundle install
If you have all the gems, then this is probably a local file, and you're probably coming from Ruby version < 1.9, you need to either fix your $LOAD_PATH (which will depend on too many factors for me to explain here), or specify the full path to the file you want File.dirname(__FILE__) + '/myapp'
Otherwise, you need to give more info, like what version you used to be running, what myapp is, and where it is in relation to your file.
In my case it was rvm issue, I was using rvm 1.9 when i changed it to 1.8, migration worked.
rvm use 1.8
In my case I was converting to Cygwin64. The Cygwin directory name changed and Ruby upgraded to 1.9. After I fixed the Cygwin directory name, the second solution worked. Or at least got past this problem:
require File.dirname(FILE) + '/myapp.rb'

How do I add conditional rubygem requirements to a gem specification?

Is it possible to add a gem dependency only if the person is using a certain version of ruby?
Background: I'm working on a fork of a project that uses Test::Unit::Autorunner and the like. They are part of the standard library in ruby 1.8, but aren't part of the standard library in 1.9.1, and is instead in the "test-unit" gem. I want to add a dependency that says that if someone's using ruby 1.9.1 or later, install the "test-unit" gem, but if they're using 1.8 or earlier, they don't need to install anything.
If you look at the gemspec documentation for add_dependency, there isn't an option for a ruby version. Perhaps you could use the post_install_message attribute to tell the user to install the gem if they're using ruby 1.9.
I did this exact thing for a project. The trick is to add the script as an extension, which will then get executed at install time on the user's machine.
Here are code snippets and links to our github:
First, when in the gemspec (we're actually using a Rakefile to generate it, but the result ends up the same) source
# This file *needs* to be named this, there are other files
# for other extension processors
s.extensions << 'ext/mkrf_conf.rb'
And then the relevant lines in that mkrf_conf.rb source
require 'rubygems/dependency_installer.rb'
inst = Gem::DependencyInstaller.new
inst.install "test-unit" if RUBY_VERSION > "1.9"
Gem doesn't support conditional dependencies (except on gem builder's environment -as noted above), and bundler is not a viable option to solve this either - see https://github.com/carlhuda/bundler/issues/1281
hay ... i'm kind of a ruby newbie ... if this is the best way to do it.
any way ... i wish i can do that using only Ruby .... though u can use your operating system shell to do that, by using this in your program installer, just execute (works for Linux based operating systems):
$ruby --version
(u can execute that from a ruby installer file, just like: ruby --version)
and put a possibility according to output, if it's 1.9.1 add an extra line to execute:
$ sudo gem install gem_name
else, just leave it be.
Checkout this tutorial in the Ruby Programming wikibook.
Tt shows how to install different versions of dependencies depending on what version of ruby the installee is using.
(short answer--it ain't as easy as it should be)
You can't. You need to build two gems, one with
spec.required_ruby_version = '~> 1.8.6'
and one with
spec.required_ruby_version = '~> 1.9.1'
spec.add_dependency 'test-unit', '~> 2.0.5'
Gemspecs are just ruby files anyway, so you can execute any ruby code inside them, so:
spec.add_dependency = 'test-unit', '>= 2.0' if RUBY_VERSION =~ '1.9'
EDIT: Specs run only on the builders machine.

Resources