Archive for the ‘Ruby’ Category

Options for getting JRuby 1.6 to use Ruby 1.9 Syntax

Published by Rob on September 10th, 2012 - in Java, Ruby

In 2012 and beyond you really want to be using Ruby 1.9 syntax (as per the standard ruby implementation KRI). JRuby 1.6 uses Ruby 1.8 syntax by default, but this can be changed to be 1.9. There are a bevy of different ways to do this. I’ll outline these here, and give you my recommendation on what to do.

Command Line parameter

The first way to set the ruby syntax version is to call ruby with a –1.9 parameter thusly:

1
ruby --1.9

This I don’t like at all because it doesn’t work with irb, and you have to type different things when using KRI and JRuby.

RUBYOPT Environment variable

A second option is to set the RUBYOPT environment variable to –1.9

1
export RUBYOPT="--1.9"

This works for irb, but will actually prevent KRI from starting up as KRI doesn’t support the –1.9 parameter (KRI is Ruby 1.9 so the parameter doesn’t make sense).

JRUBY_OPTS Environment variable

Another option is to set the JRUBY_OPTS environment variable.

1
export JRUBY_OPTS=--1.9

This works great for JRuby , irb in JRuby, and KRI.

.jrubyrc file

The next useful option is in a user specific .jrubyrc file. This gets called before JRuby starts up. Keep it in ~/.jrubyrc

1
compat.version=RUBY1_9
view raw .jrubyrc This Gist is brought to you using Simple Gist Embed.

This works well if you are working in an environment where you will always be running 1.9 compatible code. It’s what I currently do.

rvm

If you are using rvm there are a number of ways to do things.

First you can use a .rvmrc and set the JRUBY_OPTS variable, or a PROJECT_JRUBY_OPTS environment variable.

The second option is to enable rvm jruby hooks.

hooks live in $rvm_path/hooks.

In rvm 1.14.3 there are a series of after_use hooks, including some after_use_jruby hooks. Inspect these to see what they do (after_use runs all the other after_use hooks, and the after_use_jruby scripts will get some JRuby magic happening). You could put one of the earlier options here to help make JRuby work.

Conclusion

In conclusion my recommendations for getting JRuby 1.6 to use Ruby 1.9 syntax are:

  1. use a .jrubyrc file wherever possible
  2. use a .rvmrc for situations where you need different versions of JRuby.

Writing Beautiful RSpec Matchers

Published by Rob on September 4th, 2012 - in Development, RSpec, Ruby

thoughtbot have created a really nice set of custom matchers for RSpec.  The Shoulda matchers make writing tests for rails models beautiful and clean.

Shoulda matchers make it possible to write specs of the form:

1 2
it {should have_many(:items).through(:order_items)}
it {should have_db_column(:description).of_type(:string)}

It’s easy to do this for yourself using the friendly matcher DSL that ships with RSpec. Let’s take a look at how.

In the simplest form, all you need to do is to call the define method, passing a name, and a block which in turn calls out to match. The simple case might be:

1 2 3 4 5
RSpec::Matchers.define :be_less_than do |expected|
match do |actual|
actual<expected
end
end

We’ve just defined a matcher :be_less_than which allows us to do the following:

1 2 3
specify "5 should be less than 10" do
5.should be_less_than 10
end

If we use the describe auto subject feature of RSpec we can also write:

1 2 3
describe 10 do
it {should be_less_than 11}
end

and

1 2 3 4
describe 10 do
it {should be_less_than 11}
it {should_not be_less_than 5}
end

With that example we can see that we are getting close to the shoulda matcher syntax.  There’s still an extra level that helps make the shoulda matchers nice, chaining. Happily this is easy to do as well. The dsl provides a chain method.  The chain methods are called before the match, so you can use the chain calls to collect up additional information to validate.  Using our example above, we might want to add in an :and_greater_than chain.

1 2 3 4 5 6 7 8 9 10
RSpec::Matchers.define :be_less_than do |expected|
match do |actual|
result = actual<expected
result &&=actual>@low_value unless @low_value.nil?
result
end
chain :and_greater_than do |low_value|
@low_value=low_value
end
end

This now will give us the ability to write:

1 2 3
describe 10 do
it {should be_less_than(11).and_greater_than(5)}
end

Unfortunately the default descriptions don’t quite work as nice when there are chains in place. You’ll find that you’ll want to write a description in the matcher definition.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
RSpec::Matchers.define :be_less_than do |expected|
match do |actual|
result = actual<expected
result &&=actual>@low_value unless @low_value.nil?
result
end
chain :and_greater_than do |low_value|
@low_value=low_value
end
description do
result = "should be less than #{expected}"
result += " and greater than #{@low_value}" if @low_value
result
end
end

Unfortunately the description doesn’t automatically get used in the error messages when the matcher fails, so you’ll want to specify a failure_message_for_should. Basing it off the description is an ok starting point.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
RSpec::Matchers.define :be_less_than do |expected|
match do |actual|
result = actual<expected
result &&=actual>@low_value unless @low_value.nil?
result
end
chain :and_greater_than do |low_value|
@low_value=low_value
end
description do
result = "be less than #{expected}"
result += " and greater than #{@low_value}" if @low_value
result
end
failure_message_for_should do |actual|
"expected #{actual} "+description
end
end

Happily RSpec does the right thing with the should not description, so with the details above the matcher will be good. There might be a case where you want a different failure_message_for_should_not, which can also be specified.

That covers how to write simple reusable RSpec matchers to make your test code look as beautiful as your production code. Go ahead and try it yourself.  I’d love to see comments or questions you might have on this.

Backbone.JS on Rails

Published by Rob on March 22nd, 2012 - in JavaScript, Ruby

A while ago I made a post Two tricks for getting Backbone.js to play well with Ruby on Rails. It was good at the time, but probably not the place you really want to be reading.

For the best information go to quora, and read the answer to the question
How well does backbone.js work with rails? by Jeremy Ashkenas, the creator of Backbone.JS. It’s the best article on the topic, and deserves all the google juice it can get.

In particular the pick function approach mentioned is useful – and would have gone a decent way to preventing the github mass assignment vulnerability.

How to get OpenSSL in Ruby 1.9.3 working on OSX 10.7 (fixing the Segmentation Fault with Ruby OpenSSL)

Published by Rob on January 20th, 2012 - in Ruby

update – this needs to have a recent version of RVM – it works with rvm 1.10 but not with 1.6 – do an rvm update first.

When using the mighty cobweb web crawler on my OSX 10.7 with Ruby 1.9.3 I was getting a seg fault in net http:

net/http.rb:799: [BUG] Segmentation fault

A bit of googling and isolation in IRB showed that this can be caused when hitting HTTPS urls using net http.

I saw a few different solutions to the problem, primarily talking about Ruby 1.9.2.Surprisingly it took me a while to end up at the RVM documentation about the problem: https://rvm.beginrescueend.com/packages/openssl/. This didn’t quite work out of the box for me, so I used the solution in the following gist.

1 2 3
rvm pkg install openssl
rvm remove 1.9.3
rvm install 1.9.3 --with-openssl-dir=$rvm_path/usr --with-gcc=clang
view raw file1.sh This Gist is brought to you using Simple Gist Embed.

and now I can happily crawl https urls.

Two tricks for getting Backbone.js to play well with Ruby on Rails

Published by Rob on November 29th, 2011 - in Ruby

Backbone.js is a great library for creating single page applications that consume RESTful JSON services. Ruby on Rails does well at generating RESTful APIs and speaking JSON. In order to get the Rails working really well with Backbone, there are two tricks to do.

First, add the following line to the application controller to make the output look like what backbone expects.

1 2 3
...
ActiveRecord::Base.include_root_in_json = false
...

Second take advantage of the : only option in to_json to limit the attributes included in the serialised json object. The documentation for this isn’t quite there in the latest rails, but the 2.3 to_json method describes it. http://apidock.com/rails/ActiveRecord/Serialization/to_json.

1 2
# code to retrieve the collection - the to_json filtering works on a collection, or a single model record
render :json => collection.to_json(:only => [ :id, :name, :another_attribute])

With these two simple tricks rails will generate the json that backbone wants, and you’ll have a happy front-end developer.

Updating RubyGems in OSX 10.5.7

Published by Rob on May 27th, 2009 - in Development, Ruby

.7When recently trying to install Sinatra via RubyGems, I got a message that RubyGems was out of date. I figured that gem would be smart enough to have an easy upgrade command, so there had to be a command to easily upgrade. Naturally there is:

1
<span style=" background-color: #ffffcc;">gem update --system</span>

I only found this when looking through google, and I got a series of pages warning to be careful when using

1
<span style=" background-color: #ffffcc;">gem update --system</span>

as it can kill existing gems (http://puctuatedproductivity.com/2007/11/01/unistalling-ruby-installed-by-source-on-os-x, http://thenoobonrails.blogspot.com/2008/06/doing-gem-update-system-might-lose-all.html) so I was a bit nervous.  Since I have a periodic use of ruby and I'm lazy enough to make Larry Wall proud, I figured I'd take a punt on just using

1
<span style=" background-color: #ffffcc;">gem update --system</span>

.  Turns out it just works, and I've kept all my old gems.  Hooray.  Given that the posts talking about issues are old, I'm either assuming that they've done things differently to me, or things have been fixed since then… so… if you need to update gems due to a message:

ERROR: Error installing sinatra:
fastthread requires RubyGems version >= 1.2

or similar, just use

1
<span style=" background-color: #ffffcc;">gem update --system</span>

© Rob@Rojotek