Sunday, May 31, 2009

Calling method from string in Ruby

A week and a little bit has passed since the beginning of coding for Google Summer of Code 2009. I am getting more and more excited since I am learning more of advanced Ruby programming.

So I am parsing XML into objects using LibXML::XML::Reader. I had this code:

 1     def parse_events()
2 events = Events.new
3 @reader.read #go to next element
4 #read while have reached end of events
5 while not(is_end_element?('events')) do
6 if is_element?('type')
7 @reader.read
8 events.type = @reader.value
9 @reader.read
10 has_reached_end_tag?('type')
11 end
12 if is_element?('duplications')
13 @reader.read
14 events.duplications = @reader.value.to_i
15 @reader.read
16 has_reached_end_tag?('duplications')
17 end
18 if is_element?('speciations')
19 @reader.read
20 events.speciations = @reader.value.to_i
21 @reader.read
22 has_reached_end_tag?('speciations')
23 end
24 if is_element?('losses')
25 @reader.read
26 events.losses = @reader.value.to_i
27 @reader.read
28 has_reached_end_tag?('losses')
29 end
30 if is_element?('confidence')
31 events.confidence = parse_confidence
32 end
33 @reader.read
34 end
35 return events
36 end #parse_events

This was too much of code duplication, but the problem was that each time different method of the events object is called.

After some searching on interwebs, luckily, I found out that ruby has a method send, which invokes the method identified by symbol and passes any arguments.

So I created such method:

def parse_simple_element(object, name)
if is_element?(name)
@reader.read
object.send("#{name}=", @reader.value)
@reader.read
has_reached_end_tag?(name)
end
end

So now the method parse_events() can be rewritten like this:

def parse_events()
events = Events.new
@reader.read #go to next element
while not(is_end_element?('events')) do
['type', 'duplications', 'speciations', 'losses'].each { |elmt|
parse_simple_element(events, elmt)
}
if is_element?('confidence')
events.confidence = parse_confidence
end
@reader.read
end
return events
end #parse_events

Much shorter!! Now I run the unit tests and it works! No worries that I broke something while refactoring code. In cases like this I really appreciate the power of unit testing.

Monday, May 25, 2009

Hello World!

I wanted to have a blog for quite a long time, and now I have a good reason to start it: Google Summer of Code 2009.

My project is to implement phyloXML support in BioRuby and I am working for NESCent organization.

Here is the project abstract:

Phylogenetic trees are used in important applications, including phylogenomics, phylogeography, gene function prediction, cladistics and the study of molecular evolution. In order to foster successful analysis, exchange, storage and reuse of phylogenetic trees and associated data, the phyloXML format was developed. It can store all necessary information about the phylogenetic tree, like clade, sequence, name and distance. The goal of this project is to implement support for phyloXML in BioRuby.

My project page is: https://www.nescent.org/wg_phyloinformatics/PhyloSoC:PhyloXML_support_in_BioRuby

The source code is on GitHub: http://github.com/rozziite/bioruby/tree/master

I have been using Open Source software for quite a long time already and I am now excited to contribute back to community.