Ryan Bigg

⟵ Posts

Ruby 1.9.1 & Friends

31 Jan 2009

I have made a followup postto this which contains more up-to-date information. This post is left here as an example of the state of Ruby 1.9 in January-July 2009.

Last updated: July 11th, 2009

For changes between Ruby 1.8 and Ruby 1.9, look here

So this morning I sat down to give Ruby 1.9.1 a shot with my goal being to get at least the very, very basic Rails application running on it. I’ve run this guide on Mac OS X. Your mileage may vary.

Ruby 1.9.1

Download it from the ruby-lang.org website, install it using autoconf && ./configure –with-readline-dir=/usr/local –program-suffix=1.9 && make && sudo make install and everything should be peachy. I’ve gone about installing Ruby 1.9.1 alongside my current installation of Ruby. If you wish to go the “whole hog” (and I don’t recommend that you do, unless you know how to revert it) don’t run the configure command with the –program-suffix option specified.

Rubygems

Since Ruby 1.9.1 comes with Rubygems now, and this has been confirmed to Just Work (tm). The command used was gem1.9.

Rails

gem1.9 install rails rack sqlite3-ruby works too, which is nice to see. The versions of the things installed were:

  • Rails: 2.3.2
  • Rack: 1.0.0
  • Sqlite3 Ruby: 1.2.4

You need the rack gem for running your Rails app and of course the sqlite3-ruby gem because, by default, Rails applications use sqlite3.

The Rails App

We’ll generate a Rails application by typing rails onepointnine and we’ll head into this directory.

Because I’ve installed 1.9.1 alongside 1.8, the version that Rails will try to use by default is 1.8. To fix this, we’ll be running our commands with a ruby1.9 prefix.

We launch our server by ruby1.9 script/server and then go to http://localhost:3000. Welcome aboard! Clicking on “About your application’s environment” should give you something like this. If you don’t see Ruby 1.9.1, you’re using the wrong version of Ruby. Ensure that you launched the server with ruby 1.9 script/server

In another tab, we run ruby1.9 script/generate scaffold blog title:string text:text to get our scaffold and rake1.9 db:migrate to put some tables in our sqlite3 database. Now go to http://localhost:3000/blogs and play around a bit. Everything at this point should be working.

Tests

So now I’ll try a real app, rBoard.

Upon trying to run rake1.9 spec it gives:

frozenplague:rboard radar (master)$ rake1.9 spec --trace
(in /Users/radar/Sites/rboard)
rake aborted!
undefined method `>=' for nil:NilClass
/Users/radar/Sites/rboard/config/boot.rb:86:in `load_rubygems'
/Users/radar/Sites/rboard/config/boot.rb:52:in `load_initializer'
/Users/radar/Sites/rboard/config/boot.rb:38:in `run'
/Users/radar/Sites/rboard/config/boot.rb:11:in `boot!'
/Users/radar/Sites/rboard/config/boot.rb:109:in `<top (required)>'
/Users/radar/Sites/rboard/Rakefile:2:in `require'
/Users/radar/Sites/rboard/Rakefile:2:in `<top (required)>'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2383:in `load'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2383:in `raw_load_rakefile'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2017:in `block in load_rakefile'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2016:in `load_rakefile'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2000:in `block in run'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:1998:in `run'
/usr/local/bin/rake1.9:31:in `
' </pre> To fix this we find the rubygems_version on line 69 and (even though I can't explain how this happens), putting the following code above all the code inside this method makes it magically work:
puts Gem::RubyGemsVersion.inspect
I'm serious. Go figure. Now we'll run it again and we'll get a slightly better error:
frozenplague:rboard radar (master)$ rake1.9 spec --trace
(in /Users/radar/Sites/rboard)
"1.3.1" <-- RubyGems Version
"1.3.1" <-- RubyGems Version, the return
"1.3.1" <-- RubyGems Version, the reckoning
rake aborted!
Could not find RubyGem test-unit (= 1.2.3) <--- BINGO!
/usr/local/lib/ruby1.9/1.9.1/rubygems.rb:636:in `report_activate_error'
/usr/local/lib/ruby1.9/1.9.1/rubygems.rb:141:in `activate'
/usr/local/lib/ruby1.9/1.9.1/rubygems.rb:49:in `gem'
/Users/radar/Sites/rboard/lib/tasks/rspec.rake:1:in `<top (required)>'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:145:in `load'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:145:in `block in load_with_new_constant_marking'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:521:in `new_constants_in'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:145:in `load_with_new_constant_marking'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rails-2.3.2/lib/tasks/rails.rb:8:in `block in <top (required)>'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rails-2.3.2/lib/tasks/rails.rb:8:in `each'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rails-2.3.2/lib/tasks/rails.rb:8:in `<top (required)>'
/Users/radar/Sites/rboard/Rakefile:7:in `require'
/Users/radar/Sites/rboard/Rakefile:7:in `<top (required)>'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2383:in `load'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2383:in `raw_load_rakefile'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2017:in `block in load_rakefile'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2016:in `load_rakefile'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2000:in `block in run'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/usr/local/lib/ruby1.9/gems/1.9.1/gems/rake-0.8.7/lib/rake.rb:1998:in `run'
/usr/local/bin/rake1.9:31:in `
' </pre> Annotated the output a little bit. This just tells us we're missing test-unit, version 1.2.3. Usually we would go ahead and do sudo gem1.9 install test-unit, but this installs 2.0.2! Never fear, just a quick edit of lib/tasks/rspec.rake's first line and we're off and racing.

Misbehaving Gems

  Generally gems will not install because they are using functions in Ruby that no longer exist. Upon suggestion from the first comment on this blog post and from another blog on the interwebs I replace occurrences ofRARRAY(blah)->ptr with RARRAYPTR(blah), RARRAY(blah)->len with RARRAYLEN(blah), and commented out all the places where it said rb_thread_start_timer() and rb_thread_stop_timer() and this generally fixes the gem so I can install it.

MySQL

To install mysql I first attempted gem1.9 install mysql (for Mac OS X, you need to specify additional parameters for this command: -- --with-mysql-dir=/usr/local/mysql --with-mysql-lib=/usr/local/mysql/lib --with-mysql-include=/usr/local/mysql/include) and it failed epically:
Building native extensions.  This could take a while...
ERROR:  Error installing mysql:
	ERROR: Failed to build gem native extension.

/usr/local/bin/ruby1.9 extconf.rb install mysql -- --with-mysql-dir=/usr/local/mysql --with-mysql-lib=/usr/local/mysql/lib --with-mysql-include=/usr/local/mysql/include
checking for mysql_query() in -lmysqlclient... yes
checking for mysql_ssl_set()... yes
checking for mysql.h... yes
creating Makefile

make
gcc -I. -I/usr/local/include/ruby1.9-1.9.1/i386-darwin9.7.0 -I/usr/local/include/ruby1.9-1.9.1/ruby/backward -I/usr/local/include/ruby1.9-1.9.1 -I. -DHAVE_MYSQL_SSL_SET -DHAVE_MYSQL_H -I/usr/local/mysql/include -I/usr/local/mysql/include  -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE   -fno-common  -O2 -g -Wall -Wno-parentheses -pipe -fno-common  -o mysql.o -c mysql.c
mysql.c:6:21: error: version.h: No such file or directory
mysql.c: In function "make_field_obj":
mysql.c:185: warning: unused variable "hash"
mysql.c: In function "escape_string":
mysql.c:267: error: "struct RString" has no member named "len"
mysql.c:268: error: "struct RString" has no member named "len"
mysql.c:268: error: "struct RString" has no member named "ptr"
mysql.c:268: error: "struct RString" has no member named "ptr"
mysql.c:268: error: "struct RString" has no member named "len"
mysql.c: In function "real_escape_string":
mysql.c:401: error: "struct RString" has no member named "len"
mysql.c:402: error: "struct RString" has no member named "len"
mysql.c:402: error: "struct RString" has no member named "ptr"
mysql.c:402: error: "struct RString" has no member named "ptr"
mysql.c:402: error: "struct RString" has no member named "len"
mysql.c: In function "query":
mysql.c:710: error: "struct RString" has no member named "ptr"
mysql.c:710: error: "struct RString" has no member named "len"
mysql.c:729: error: "struct RString" has no member named "ptr"
mysql.c:729: error: "struct RString" has no member named "len"
mysql.c: In function "query_with_result_set":
mysql.c:882: warning: implicit declaration of function "TypeError"
mysql.c: In function "fetch_field_direct":
mysql.c:960: warning: implicit declaration of function "Raise"
mysql.c: In function "fetch_hash2":
mysql.c:1032: error: "struct RString" has no member named "ptr"
mysql.c:1033: error: "struct RString" has no member named "ptr"
mysql.c: In function "field_inspect":
mysql.c:1157: error: "struct RString" has no member named "len"
mysql.c:1158: error: "struct RString" has no member named "ptr"
mysql.c:1158: error: "struct RString" has no member named "ptr"
mysql.c: In function "stmt_bind_result":
mysql.c:1284: error: "struct RString" has no member named "ptr"
mysql.c: In function "stmt_execute":
mysql.c:1346: error: "struct RString" has no member named "ptr"
mysql.c:1347: error: "struct RString" has no member named "len"
mysql.c:1348: error: "struct RString" has no member named "len"
mysql.c:1359: error: "struct RArray" has no member named "ptr"
mysql.c:1360: error: "struct RArray" has no member named "ptr"
mysql.c:1361: error: "struct RArray" has no member named "ptr"
mysql.c:1362: error: "struct RArray" has no member named "ptr"
mysql.c:1363: error: "struct RArray" has no member named "ptr"
mysql.c:1364: error: "struct RArray" has no member named "ptr"
mysql.c:1316: warning: unused variable "false"
mysql.c: In function "stmt_prepare":
mysql.c:1584: error: "struct RString" has no member named "ptr"
mysql.c:1584: error: "struct RString" has no member named "len"
make: *** [mysql.o] Error 1


Gem files will remain installed in /usr/local/lib/ruby1.9/gems/1.9.1/gems/mysql-2.7 for inspection.
Results logged to /usr/local/lib/ruby1.9/gems/1.9.1/gems/mysql-2.7/gem_make.out
The solution above fixes this problem, also using my own fixed version of the gem works too, but throws an error when trying to install the documentation. Just use --no-ri --no-rdoc options until this is fixed.

Hpricot

Once upon a time reported as a failing gem, now passes! Good work!

pg (postgresql gem)

Another one previously reported as failing, now succeeds. Previous attempt was with the postgres gem.

thin (1.2.2)

Confirmed working.

mongrel

Lost cause, use Rack instead.

passenger (2.2.4)

Tested with passenger 2.2.4. As stated here, passenger is compatible with Ruby 1.9.1. This has been used to run a Rails 2.3 test application without issue.

nokigiri & ruby-xslt

Mac users apparently do not need to install ruby-xslt. Everyone else is not so lucky. To install this on Ubuntu, we first need to do this: sudo apt-get install libxml-ruby1.8 libxslt1-dev and then we do sudo gem1.9 install ruby-xslt but we encounter:
/usr/local/bin/ruby extconf.rb install ruby-xslt
checking for xmlParseDoc() in -lxml2... yes
checking for xsltParseStylesheetFile() in -lxslt... yes
checking for exsltRegisterAll() in -lexslt... yes
creating extconf.h
creating Makefile

make
gcc -I. -I/usr/local/include/ruby-1.9.1/i686-linux -I/usr/local/include/ruby-1.9.1/ruby/backward -I/usr/local/include/ruby-1.9.1 -I. -DRUBY_EXTCONF_H=\"extconf.h\"  -D_FILE_OFFSET_BITS=64  -fPIC -g -Wall -I/usr/include/libxml2 -I/usr/include/libxml2  -O2 -g -Wall -Wno-parentheses -DUSE_ERROR_HANDLER -DUSE_EXSLT  -o extfunc.o -c extfunc.c
In file included from xslt.h:25,
                 from extfunc.c:19:
/usr/local/include/ruby-1.9.1/ruby/backward/rubyio.h:2:2: warning: #warning use "ruby/io.h" instead of "rubyio.h"
In file included from rb_utils.h:25,
                 from xslt.h:51,
                 from extfunc.c:19:
/usr/local/include/ruby-1.9.1/ruby/backward/rubyio.h:2:2: warning: #warning use "ruby/io.h" instead of "rubyio.h"
extfunc.c: In function "value2xpathObj":
extfunc.c:141: error: "struct RArray" has no member named "len"
make: *** [extfunc.o] Error 1


Gem files will remain installed in /usr/local/lib/ruby/gems/1.9.1/gems/ruby-xslt-0.9.6 for inspection.
So we use the solution above and we patch this gem to work by editing the /usr/local/lib/ruby/gems/1.9.1/gems/ruby-xslt-0.9.6/ext/xslt_lib/extfunc.c, line 141. We'll also need to edit /usr/local/lib/ruby/gems/1.9.1/gems/ruby-xslt-0.9.6/ext/xslt_lib/extfunc.c, lines 504, 533 (two occurrences), parameters.c lines 42 and 43. Then run sudo ruby extconf.rb && sudo make && sudo make install and this gem should install. To install nokogiri, ensure you have followed the steps above and then sudo gem1.9 install nokogiri. Tested with nokogiri 1.2.3 and ruby-xslt 0.9.6.

haml (2.2.0)

haml works right out of the box too, throws some errors for --inline-source and has recently attained Ruby 1.9 compatibility.

Further Notes

I tried rboard and that worked on this setup (with a few minor tweaks to the paperclip plugin and the script commands). I also had to freeze rails to vendor/rails.

Conclusion

My original summary was that you should hold off completely from using Ruby 1.9.1, but that was back in January. Whilst "important" things such as the mysql gem and ruby-xslt are broken, there's no real dealbreakers stopping you from running your applications on Ruby 1.9.1. As reassurance of this, wikipedia's mobile site is a merb application, running Ruby 1.9.1 and was launched last month and handles a fair bit of traffic.