Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

Friday, 23 September 2011

Seven in Seven - Ruby Day 3

This is the day hat the light is supposed to dawn -unfortunately I was in the pub last night and it feels like midnight in Svalbard on December the 21st. I think I'm also somewhat underwhelmed because Ruby is familiar territory, I did a little bit a few years ago and I've just carried out a project in Python so I'm just left thinking 'and...'

Exercise -extend the RubyCsv class to iterate and return CsvRow objects which you can index via 'method missing'

Again I'm not going  to post the complete code, aside from anything else there's a notice at the top saying that it can't be used in articles. For the iteration I mixed in Enumerable, changed @cvs_contents to an attr_reader and defined the 'each' method :

def each
  @csv_contents.each { |i| yield i }
end

@cvs_contents isn ow an array of CsvRow objects :

class CsvRow
        attr_accessor :contents, :index

        def initialize idx,row
                @contents = []
                @index = idx
                @contents = row.split(', ')
        end

        def method_missing name, *args
                @contents[@index.index(name.to_s)]
        end
end
created thus :

@csv_contents.push(CsvRow.new(headers,row.chomp()))
I don't really like having the header with each object, and their might be a way around this by creating the class on the fly, populating a class variable with the header list, but see the first paragraph.

What have I learned
Mixin is a powerful concept -but not unique to Ruby. method_missing is a powerful idea -and bloody dangerous. I have achieved the same thing in PHP by overriding __call() and I think that was safer.

Ruby syntax is nice, at least you don't have to scatter ':'s everywhere as you do in Python, it's more consistent than PHP and prettier than Perl5 which  generally looks as though a demented spider has been dancing on your keyboard.

Thursday, 22 September 2011

Seven in Seven, Ruby Day 2

Here we're starting to get a little deeper into Ruby, coming across a few nice features, such as code blocks (closures) and mixins. Still not really sure what the fuss is about though.

What did I learn?

Ruby is starting to look quite like python. Duck typing can catch you out : a regex pattern looks like a sting, quacks like a string, but doesn't waddle like a string. Ruby has nicked some of Perls' pattern-matching syntax, which is a good thing as it's great for rule-based input processing.

Exercise : Can we translate a hash to an array, and can we iterate over a hash?


Well, yes we can :

#!/usr/bin/ruby

numbers = {1=>'one', 2=> 'two', 3=>'three', 4 => 'four'}
num_array = []

numbers.each do |num, str|
        num_array.push([num,str])
end
p 'My class is ' + num_array.class.to_s
p 'Element class is ' + num_array[0].class.to_s
puts num_array

 Of course we could have just used numbers.flatten()

#!/usr/bin/ruby
=begin
This exercise is to print the numbers 1 to 16 in groups of 4
=end

#Old school
i = 0
ary = []
(1..16).each do |num|
        if i % 4 ==  0
                if i > 0
                        p ary
                end
                ary = []
        end
        ary.push(num)
        i = i + 1
end
p ary

# One liner -using a code block
(1..16).each_slice(4) {|ary| p ary}

Exercise 3 : Populate the Tree class from a hash.

 I'm not going to put all the code up for this, and I struggled a bit to get it going. The solution that I settled on was to have two classes,  a Tree class that took the hash argument which extended a Node class that was the basic structure.

The Node initializer looks like this :
def initialize(name, node = {})
    @children = []
    @node_name = name
    node.each { |key,child| @children.push(Node.new(key,child)) }
  end

So it just build the tree recursively.

Exercise 4 implement grep

=begin
Grep implementation, matches a string against lines from a file,
outputs the line number and contents of the matched line

usage : rb_grep pattern file
=end

i = 1
File.open(ARGV[1],"r") do |f|
        pattern = Regexp.new(ARGV[0])
        while line =  f.gets 
                line =~ pattern and printf("%d : %s", i,line)
                i = i + 1
        end 
end

Tuesday, 20 September 2011

Seven in Seven : Ruby Day 1.

Here we go, day 1, Bonus challenge -guess a number.

#!/usr/bin/ruby

guess = 1

while guess > 0
        num = rand(10)
        guess = gets.to_i
        if guess > num
                puts "Too high was : " + num.to_s
        elsif guess < num
                puts "Too Low was : " + num.to_s
        else
                puts 'Just Right'
        end
end

Bonus tip, the ruby interpreter is called irb, and doesn't necessarily come with the ruby package.

linkedin