Plasticx Blog

Capable of being shaped or formed

helpful Ruby idioms (to me)

Posted by Mike 08/27/2007 at 11:41AM

Before coming to Ruby I had spent a lot of time coding Java and some C/C++ . Like any programmer I spend a lot of time working with data structures (and now blocks in Ruby). I would often fall back to idioms concerning data structure size in those legacy languages but in Ruby they are bad habits.

The Enumerable module that is mixed in to Array, Hash, and others is your friend. Use its idioms to tell you the state of your data structure rather raw details as in Java that imply state. For instance in Java, we test for elements in a collection with.size() (like myhash.size() == 0), but in Ruby having elements (or not) is more statefully conveyed with .any? and .empty?

Some goodies in Enumerable :

  • any? – do we have any elements?
  • empty? (in Array class) – are we void of elements?
  • detect – return the first element that matches the criteria in the block
  • select – return all the elements that match the criteria in a block
  • each_with_index – enumerate over elements in the data structure AND automatically give me an index (which means I don’t have to predefine one)

And example in an irb session:

mike@butch 10001 ~$ irb
irb(main):001:0> a = ['hello', 'ruby-20', 'ruby']
=> ["hello", "ruby-20", "ruby"]
irb(main):002:0> a.detect{|v| v =~ /foo/}
=> nil
irb(main):003:0> a.detect{|v| v =~ /hello/}
=> "hello"
irb(main):004:0> a.detect{|v| v =~ /ruby/}
=> "ruby-20"
irb(main):005:0> a.select{|v| v =~ /ruby/}
=> ["ruby-20", "ruby"]
irb(main):006:0> a.empty?
=> false
irb(main):007:0> a.any?
=> true
irb(main):008:0> a.each_with_index{|v,i| puts "index: #{i}, val #{v}"}
index: 0, val hello
index: 1, val ruby-20
index: 2, val ruby
=> ["hello", "ruby-20", "ruby"]

Posted in |

Trackbacks<

Use the following link to trackback from your own site:
http://plasti.cx/trackbacks?article_id=659

  1. RSL
    08/27/2007 at 04:17PM

    Hash#empty? exists as well. :) Long live Enumerable though!

  2. Henrik N
    09/01/2007 at 02:49AM

    Note that any? can take a block: numbers.any? {|number| number > 42 }. I like all? too: without a block, it’ll check that all elements are true (not nil or false); or you could specify a block much like in my any? example.

  3. monde
    09/01/2007 at 10:09AM

    Nice thanks for adding your favorite idioms. If you are using ActiveRecord check out Chris at Err The Blog’s Ambition . His Ambition plugin duck types Enumerable on top of AR so you can do things such as


    User.select { |u| u.name =~ ‘monde’ }.sort_by(&:age)

  4. Frederico
    10/31/2007 at 12:19AM

    Nice man,
    I love the “each_with_index”
    it’s really dope…

    i remember old times what I had to do something like this but in C,
    ughhh… make me dizzy to think about it :D

    cheers.


Web Statistics