Determine ruby version from within Rails - ruby-on-rails

Is there a way to determine what version of Ruby is running from within Rails (either on the web or through script/console)? I have Ruby 1.8.6 installed but I've also installed Ruby Enterprise Edition 1.8.7-20090928 and want to ensure that it's using the right installation.

Use this global constant:
RUBY_VERSION
Other relevant global constants include:
RUBY_PATCHLEVEL
RUBY_PLATFORM
RUBY_RELEASE_DATE
Usage example via irb session:
irb(main):001:0> RUBY_VERSION
=> "1.8.7"

Try the constant RUBY_VERSION. I use this extensively to determine whether I'm running under 1.8 or JRuby.
Also, if you're not in production mode, you can do a quick check by hitting the URL "/rails/info/properties"

Use RUBY_VERSION as mentioned by others.
You can then use Gem::Version to do version string comparison:
require 'rubygems' # Only needed for ruby pre-1.9.0 but it's safe for later versions (evaluates to false).
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('1.9.0')
extend DL::Importable
else
extend DL::Importer
end

In addition to the RUBY_VERSION constant and friends you may also want to check out Config::CONFIG. This hash contains not only the version numbers but also a ton of other useful runtime information, like the path to the binary, the hostname, ...

Related

Rails REPL that is more than irb/pry but less than rails console

I frequently want to try out small code snippets, often much smaller than classes, and even functions, just to make sure it works by itself so I don't need to test it by running a bunch of scripts, simply to fix small errors in a line of code or so.
Besides irb/pry, I want to test Rails-specific code, such as Object.blank?. So with that, I want to have the Rails library loaded, but I don't need the full functionality that Rails console gives me. Especially when the application is not in a working state, the REPL will not open at all, and merely present a stack trace of the failure at hand.
If anybody knew how to achieve this middle ground, maybe through the use of a particular gem path and require statement to load one of the other REPLs I have mentioned, could you illustrate those commands?
I am working inside of a project using RVM to manage the gemset, and would like to not modify that environment at all, maybe only my general terminal environment, if possible.
.blank? is from ActiveSupport. You can actually just load ActiveSupport without the rest of Rails:
irb(main):001:0> require 'active_support/all'
irb(main):002:0> [].blank?
=> true
The all.rb file loads all of ActiveSupport.
The same can be done with ActiveRecord and other rails components; for example:
irb(main):001:0> require 'active_record'
=> true
irb(main):002:0> class NewModel < ActiveRecord::Base; end
=> nil
irb(main):003:0> NewModel.new
ActiveRecord::ConnectionNotEstablished: No connection pool for NewModel
This gives an error because I didn't bother setting up a database, but it shows that Rails is pretty modular. I've used ActiveRecord in projects without Rails (the rails gem is actually an empty gem which just defines the various active_* gems as dependencies).
Most of the Rails "magic" come from Active Support Core Extensions. You can include that in a regular irb session to get most of the connivence methods like blank?.
Start an IRB session and run
require 'active_support'
require 'active_support/core_ext'

Initializer being called before gem in Ruby 2.1

I have a Rails 3.2 app running on Ruby 1.9.3, and I was asked to update it to Ruby 2.1 and, later, Rails 4.1. I'm having a problem upgrading to Ruby 2.1 though:
Our company have a gem that's used by our systems and defines some global constants. The application has to overwrite these constants in development (we know it's hacky, but it's temporary until we can get our staging server back on), so I have an Initializer file that overwrites these constants. That worked fine so far, I get some warnings on the server console (warning: already initialized constant ...) but it worked.
Now, however, Rails seems to be calling my custom initializer before the gem, does anyone know of a change in Ruby 2.0 or 2.1 that may induce this change of behaviour? Note that I'm still using Rails 3.2, I just updated a few gems to make it compatible with the new Ruby.
This is how I set the constant in the initializer and gem (both files have the same name and are basically the same). The constant that needs to be overwritten is URL_PORTAL:
module Portal
module Sso
URL_PORTAL_PRODUCTION = "(URL1)"
URL_PORTAL_DEVELOPMENT = "(URL2)" # I overwrite this in the initializer
URL_PORTAL_TEST = "(URL3)"
URL_PORTAL = case Rails.env
when "production" then URL_PORTAL_PRODUCTION
when "test" then URL_PORTAL_TEST
else URL_PORTAL_DEVELOPMENT
end
end
end
You can add require 'portal/seo' (or other appropriate filename) in the begining of the file.

String.encode() alternative in Ruby 1.8.7 for cleaning input to UTF-8

I just discovered that the String.encode method is only available from Ruby -v 1.9.3 and upwards. I'm working in a Rails environment were I cannot change this. I used this method to correct invalid UTF-8 input.
The only good alternative I've found was through the iconv.conv() method, however iconv is deprecated in newer ruby versions and I would like my code to be smelling like flowers even if/when my sysadmin decides to upgrade.
For reference, the alternative I found from Here:
ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
valid_string = ic.iconv(untrusted_string + ' ')[0..-2]
Thanks!
Take a look at the charlock_holmes gem, that covered most of our pre 1.9 needs in encoding.

Returning a hash from a subprocess in Ruby using IO.popen

I'm using IO.popen("cmd") in my Ruby script to run an Ironruby subroutine. In my Ironruby script, I am getting some data and storing it in a hash. In my Ruby script, I then use x=IO.popen("Iron ruby script") to retrieve the hash. Problem is, I can't seem to get the hash to show up in my Ruby script. I've tried x.gets, x.read, etc etc.
What would be the best way to get the hash from this pipe using IO.popen?
Thanks
In the subproccess:
require "yaml"
puts YAML.dump(theHash)
In the parent:
require "yaml"
x=IO.popen(...)
theHash=YAML.load(x.read)
Ruby ships with dRuby, a distributed object system for Ruby. It may be overkill in this case. Demo:
#test1.rb
require 'drb/drb' # in standard lib
the_hash = Hash[:key1,'value1',:key2, 'value2']
DRb.start_service("druby://localhost:8787", the_hash)
DRb.thread.join
#test2.rb
require 'drb/drb'
DRb.start_service
p DRbObject.new_with_uri("druby://localhost:8787")
#=>{:key1=>"value1", :key2=>"value2"}

Active Merchant - uninitialized constant ActiveSupport::XmlMini_REXML::StringIO

I have activemerchant 1.16.0 and rails 3.0.5.
I am trying to build a basic code to communicate with PayPal's gateway using active merchant.
if credit_card.valid?
# or gateway.purchase to do both authorize and capture
response = gateway.authorize(1000, credit_card, :ip => "127.0.0.1")
if response.success?
gateway.capture(1000, response.authorization)
puts "Purchase complete!"
else
puts "Error: #{response.message}"
end
else
puts "Error: credit card is not valid. #{credit_card.errors.full_messages.join('. ')}"
end
I get the following error:
/Library/Ruby/Gems/1.8/gems/activesupport-3.0.9/lib/active_support/xml_mini/rexml.rb:20:in `parse': uninitialized constant ActiveSupport::XmlMini_REXML::StringIO (NameError)
This error propagates from the gateway.authorize() call.
Any idea what's wrong with my setup?
Thanks.
According to the question, it doesn't work when the code is by itself, but works when require "stringio" is added.
My suspicion is that ActiveMerchant is unit-tested, but for some reason the dependency on StringIO isn't detected by those unit tests, possibly because other parts of the unit testing code indirectly requires stringio.
One thing I recently found out was that require 'yaml' gives you the stringio library as a side effect:
StringIO.new
# NameError: uninitialized constant StringIO
# from (irb):1
require "yaml"
# => true
StringIO.new
# => #<StringIO:0x7fb7d48ce360>
RUBY_VERSION
# => "1.8.7"
and it wouldn't be hard to imagine unit tests for ActiveMerchant (or other parts of Rails) requiring yaml.
However, this is only speculation. I haven't checked, as I don't use Rails.
Andrew Grimm pretty much hit the nail on the head with his original comment on this question. The missing require 'stringio' is indeed the issue. But it is a bug with Rails, more specifically ActiveSupport 3.0.9 (which is where the error seems to be coming from). We can trace it down using the git commit history of rails.
First we need to check out rails and switch to the v3.0.9 tag. If we now look at activesupport/lib/active_support/xml_mini/rexml.rb we see that require 'stringio' is not there. In and of itself this is not significant, but bear with me. We can now switch to the next tag (v3.0.10.rc1), and we'll see that the file hasn't been updated (it is likely that this version of rails will have the same issue). Next tag in line is v3.1.0.beta1, notice that this time around there is a require 'stringio' at the top of the file.
We can check out the commit that brought in this change (this one here from Jan 19th 2011). The commit message says:
fixed a missing require that causes trouble when using AS in a
non-rails env
This would indicate that as long as you're in a rails environment this issue wouldn't surface. So, my guess is something about the environment caused the issue to come up, may have something to do with the fact that the OP says they are using rails 3.0.5, but the error is coming from activesupport-3.0.9. Perhaps the code was called from a rake task that forgot to inherit from :environment (difficult to say without more info). Either way, putting require 'stringio' at the top of the code is definitely the fix, until you can upgrade to Rails 3.1 (once it comes out) at which point the require will no longer be needed.

Resources