Week 1 Day 2 – Diving deeper into Ruby

I had a really great day. Gave myself a day off from working, and went to London to meet my apprentice Rohit, see a few friends and go to eXtreme Tuesday Club in the evening.

At 6pm i met with Dan in Covent Garden and we worked through a bit of #7languages7weeks Day 2 together. We came up with three ways of splitting up an array into groups of four, ending with the beautifully elegant each_slice method. You can see the result of our efforts here: week1-ruby/day2.rb

I worked through the remaining exercises on the train home. One thing really caught me out, which is how Ruby is so eager to convert hashes to arrays when you iterate. For example:

> hash = {1 => 'one', 2 => 'two', 3 => 'three'}
=> {1=>"one", 2=>"two", 3=>"three"}
> hash.each {|part| puts part.inspect }
[1, "one"]
[2, "two"]
[3, "three"]

See that?! Surprise Array!

I had originally said that you can’t convert an array to a hash, but in a case like this you can, and to solve the tree initialization exercise i found i had to. Something like this:

> hash = {1 => 'one', 2 => 'two', 3 => 'three'}
=> {1=>"one", 2=>"two", 3=>"three"}
> hash.each {|part| puts ({part.first => part.last}).inspect }

My solution to the family tree exercise can be found here: week1-ruby/tree.rb

Finally, the find-in-file exercise. I really like this one. The book said the solution was simple, and my word, it truly is.

File.open('tree.rb').each_with_index do |line, line_number|
  puts "#{line_number}: #{line}" if line =~ /tree/

That’s it! So neat. I have always liked the application of the each method on a File. Here’s the output of the program:

$ ruby read_file.rb 
13:   def initialize_with_hash(tree)
14:     tree.each_pair do |name, children|
35: ruby_tree = Tree.new('Ruby', [Tree.new('Reia'), Tree.new('MacRuby')])
38: ruby_tree.visit {|node| puts node.node_name }
41: puts 'Visiting entire tree'
42: ruby_tree.visit_all{|node| puts node.node_name }
44: family_tree = Tree.new({'grandpa' => {
50: puts 'Visiting family tree'
51: family_tree.visit_all{|node| puts node.node_name }

Very neat! Although i’ve been programming in Ruby for a long time, i am appreciating its beauty and simplicity all the more tonight!


Since looking at Alberto’s excellent solutions and checking the Ruby Hash#each documentation, i now realise that the each method is supposed to take two elements in the block. For some reason i always thought you had to use each_pair for that. So there we go, talk about failing publicly! :)