Ruby 1.9.1, The Stuff It Gives Us
We’re still kicking the Ruby hardcore. We’ve just been massively busy locked in the Kinetic Barn HQ this winter. Anyway, here is a list of the latest things we’ve found interesting about the first stable 1.9.x release of MRI Ruby.
Note: Some of these have been in the 1.9 branch for awhile, I’m just taking the moment to get you all acquainted.
Newlines allowed before ternary colon operator (:) and method call dot operator (.)
Before this you might note that you could do this in Ruby, and it was valid.
Person.
set_first_name('Ben').
capitalize.
to_a
# or...
dog = Person.first_name == 'Ben' ?
'Cookie' :
'pookie'You won’t see the former very often, but you can do it if you keep to coding standards of 80-100 columns of text in your source.
I’ve seen and used the latter numerous times, however I usually don’t put a newline after the colon. Eithercase, Ruby makes things a bit more clearer in 1.9 (though these are bad examples of their use cases).
Person
.set_first_name('Ben')
.capitalize
.to_a
# or...
dog = Person.first_name == 'Ben' ?
'Cookie'
: 'pookie'Kernel#methods and #singleton_methods used to return an array of strings but now they return an array of symbols.
I use this daily within Irb to see what methods are in my objects. You used to receive an Array of Strings, of all the methods on the object you ran this against. Now you will get this.
>> String.methods.sort
=> [:, :, :=>, :, :, :, :, :, :__id__, :__send__, :allocate, :ancestors, :autoload,
:autoload?, :class, :class_eval, :class_variable_defined?, :class_variables, :clone,
:const_defined?, :const_get, :const_missing, :const_set, :constants, :display,
:dup, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :id, :include?,
:included_modules, :inspect, :instance_eval, :instance_method,
:instance_methods, :instance_of?, :instance_variable_defined?,
:instance_variable_get, :instance_variable_set, :instance_variables, :is_a?,
:kind_of?, :method, :method_defined?, :methods, :module_eval, :name, :new,
:nil?, :object_id, :po, :poc, :pretty_inspect, :pretty_print, :pretty_print_cycle,
...]If you know anything about Ruby low level you might guess someone got smart and decided it was better to utilize the Symbol table instead of building these lists of anonymous String instances.
Hash; preserving item insertion order
Yes, Hashes are now ordered… which is pretty odd if you’ve been writing Ruby for awhile now. We all used to utilize Arrays, and I hope we still do. But Hashes are now ordered by the pattern in which you insert keys/values into them.
[1,2,3,4,5].inject({}) { |hash, value| hash["name_#{value}"] = value; hash }
# Ruby 1.8
=> {"name_4"=>4, "name_5"=>5, "name_1"=>1, "name_2"=>2, "name_3"=>3}
# Ruby 1.9
=> {"name_1"=>1, "name_2"=>2, "name_3"=>3, "name_4"=>4, "name_5"=>5}As a community, let’s not go nuts and start replacing our usage of Array’s with Hashes when we needed to persist order. I’m fairly certain the speed of an Array will always trump a Hash.
Named/Coroutine style Regexp
Dave Thomas can give you a better description than I can…
sentence = %r{
(?<subject> cat | dog | gerbil ){0}
(?<verb> eats | drinks| generates ){0}
(?<object> water | bones | PDFs ){0}
(?<adjective> big | small | smelly ){0}
(?<opt_adj> (\g<adjective>\s)? ){0}
The\s\g<opt_adj>\g<subject>\s\g<verb>\s\g<opt_adj>\g<object>
}x
md = sentence.match("The cat drinks water")
puts "The subject is #{md[:subject]} and the verb is #{md[:verb]}"Dir.exists?/.exist?
This one annoyed quite a few people, because before you had to do File.exists?(”/tmp”) to test the existance of a directory. Odd, but fixed.
Negative operators such as ”!”, ”!=” and ”!~” are now overloadable
OOOHHH… more fun for the DSL writers out there! dm-core, I’m looking at you! :)
Rake and RubyGems Made Core
Both Rake and Rubygems are now included in the core library. Hopefully it’s still as easy to upgrade them both!
Thats Not All
Of course this isn’t it, and the entire list is a great read. If anyone else has anything feel free to post… like the difference between proc and lambda now, new Hash key syntax {apple: 1, pear: 2} or anything else… feel free to comment.
