Charlie Harvey

Ruby — Day Two

The second day of Ruby picks up the pace a bit, mostly focussing on the nice bits of sugar that Ruby provides and the excercises give you a chance to play with them a bit.


Find out how to access files with and without blocks.

#!/usr/bin/ruby -w # without block counter = 1 file ="eg_file.txt", "r") while (line = file.gets) puts "#{counter}: #{line}" counter = counter + 1 end file.close # with block counter = 1"eg_file.txt", "r") do |infile| while (line = infile.gets) puts "#{counter}: #{line}" counter = counter + 1 end end # with Exception Handling counter = 1 begin file ="eg_file.txt", "r") while (line = file.gets) puts "#{counter}: #{line}" counter = counter + 1 end file.close rescue => err puts "Exception: #{err}" err end # using each block counter = 1 f ="eg_file.txt","r") f.each do |line| puts "#{counter}: #{line}" counter = counter + 1 end f.close


How would you translate a hash to an array? Can you translate arrays to hashes

Wow this was a bit of a killer. There is a function called in ruby 1.9 that does what I would do to convert a hash into an array — unrolling it. But Debian Squeeze's ruby is still at 1.8. So I had to make a flatten. #!/usr/bin/ruby # in 1.9 you can just # h.flatten # => [1, "one", 2, [2, "two"], 3, "three"] # Here I have to roll my own. class Hash def flatten() arr = [] { |k,v| arr.push(k); v.class=="Hash" ? arr.push(v.flatten) : arr.push(v); } arr end end h = {1=> "one", 2 => [2,"two"], 3 => "three"} a = h.flatten puts a.join(', ');


Print the contents of an array of sixteen numbers, four numbers at a time using just each. Now do the same with each slice in Enumerable.

I wasn’t sure that this was the most compelling bit of syntax to illustrate the Poppins-like magic of Ruby, but had a crack anyway. #!/usr/bin/ruby # print array of 16 numbers, 4 at a time a = [] 16.times {|i| a[i]=i} # using only each [0,4,8,12].each{|i| puts a[i..i+3].join(', ')} # same thing using each_slice a.each_slice(4){|x| puts x.join(", ") }


The Tree class was interesting, but it did not allow you to specify a new tree with a clean user interface. Let the initializer accept a nested structure with hashes and arrays. You should be able to specify a tree like this

I spent a while regretting that I wasn’t doing this excercise in Perl, mostly due to the rustiness of my Ruby skills. #!/usr/bin/ruby class Tree attr_accessor :children, :node_name def initialize (h={}) @node_name = h.keys.first @children = [] h[@node_name].each {|node,value| @children.push{node=>value}) } end def visit_all(&block) visit &block @children.each{|n| n.visit_all &block} end def visit(&block) self end end # class { 'Ruby' => {'sub1' => {}, 'sub2' => {} } } ) puts "Tree first node visit" t.visit {|node| puts node.node_name} puts puts "Tree visit all nodes" t.visit_all {|node| puts node.node_name}

Write a simple grep that will print the lines of a file having any occurences of a phrase anywhere in that line. … If you want include line numbers.

After faffing to make the Tree code in the previous excercise run as expected, this excercise seemed rather straightforward. #!/usr/bin/ruby # # prints lines of file which match a regexp given as an argument unless ARGV.length == 2 puts "Two arguments required" exit 1 end f =[1],"r") counter = 1 f.each do |line| puts "#{ARGV[1]} #{counter}: #{line}" if (line =~ /#{ARGV[0]}/) counter = counter + 1 end f.close


  • Be respectful. You may want to read the comment guidelines before posting.
  • You can use Markdown syntax to format your comments. You can only use level 5 and 6 headings.
  • You can add class="your language" to code blocks to help highlight.js highlight them correctly.

Privacy note: This form will forward your IP address, user agent and referrer to the Akismet, StopForumSpam and Botscout spam filtering services. I don’t log these details. Those services will. I do log everything you type into the form. Full privacy statement.