<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5396364470982208683</id><updated>2011-07-29T04:42:07.530-04:00</updated><category term='ruby'/><category term='send'/><category term='BioRuby'/><category term='OSCON'/><category term='code profiling'/><category term='xml parsing'/><category term='funny'/><category term='GSOC 2009'/><category term='phyloXML'/><category term='object'/><category term='unit testing'/><category term='code refactoring'/><category term='google'/><category term='codejam'/><title type='text'>latvianlinuxgirl: Adventures in GSOC</title><subtitle type='html'>Ruby, BioRuby, PhyloXML, Ubuntu</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://latvianlinuxgirl.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://latvianlinuxgirl.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>latvianlinuxgirl</name><uri>http://www.blogger.com/profile/11056269222204216343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://4.bp.blogspot.com/_dN8tfKaI7Vk/SiQG95pGRCI/AAAAAAAAAAM/SCooBjB_VFI/S220/IMG_0047.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5396364470982208683.post-8116548852432169487</id><published>2009-07-21T19:20:00.003-04:00</published><updated>2009-07-21T19:26:30.471-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='codejam'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Google Code Jam 2009</title><content type='html'>Just got to know that Google Code Jam is on this year too. Definitely will participate. Last year I got past Qualification round. This year I will have to practice more and hopefully will get past Round 1.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5396364470982208683-8116548852432169487?l=latvianlinuxgirl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://latvianlinuxgirl.blogspot.com/feeds/8116548852432169487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/07/google-code-jam-2009.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/8116548852432169487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/8116548852432169487'/><link rel='alternate' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/07/google-code-jam-2009.html' title='Google Code Jam 2009'/><author><name>latvianlinuxgirl</name><uri>http://www.blogger.com/profile/11056269222204216343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://4.bp.blogspot.com/_dN8tfKaI7Vk/SiQG95pGRCI/AAAAAAAAAAM/SCooBjB_VFI/S220/IMG_0047.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5396364470982208683.post-9222531622696167721</id><published>2009-07-20T14:27:00.003-04:00</published><updated>2009-07-20T14:39:15.667-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OSCON'/><title type='text'>OSCON 2009</title><content type='html'>Just wanted to say that I am excited to be at OSCON 2009 conference. :) Also excited to meet other GSOC students at BoF session.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5396364470982208683-9222531622696167721?l=latvianlinuxgirl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://latvianlinuxgirl.blogspot.com/feeds/9222531622696167721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/07/oscon-2009.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/9222531622696167721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/9222531622696167721'/><link rel='alternate' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/07/oscon-2009.html' title='OSCON 2009'/><author><name>latvianlinuxgirl</name><uri>http://www.blogger.com/profile/11056269222204216343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://4.bp.blogspot.com/_dN8tfKaI7Vk/SiQG95pGRCI/AAAAAAAAAAM/SCooBjB_VFI/S220/IMG_0047.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5396364470982208683.post-3170760579823371753</id><published>2009-06-28T22:51:00.004-04:00</published><updated>2009-06-28T23:16:17.647-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BioRuby'/><category scheme='http://www.blogger.com/atom/ns#' term='GSOC 2009'/><category scheme='http://www.blogger.com/atom/ns#' term='code profiling'/><title type='text'>Profiling code: Breadth first search surprise</title><content type='html'>At this point in the project I am almost done with writing parser so I did some profiling of the code.&lt;br /&gt;&lt;br /&gt;My system is Ubuntu 9.04, ruby 1.8.7 [i486-linux], Intel Core 2 Duo P8600 @2.4GHz&lt;br /&gt;&lt;br /&gt;I created test_phyloxml_big.rb test file. It has test_next_tree method which calls next_tree on the phyloxml file until end of file is reached. Here follow results on the ncbi_taxonomy_mollusca.xml file which is 1.5MB large with 5632 external nodes.&lt;br /&gt;&lt;br /&gt;It takes around 7.5min to finish test_phyloxml_big.rb test.&lt;br /&gt;(Finished in 443.231507 seconds.&lt;br /&gt;Finished in 457.255576 seconds. )&lt;br /&gt;&lt;br /&gt;output of the top:&lt;br /&gt;&lt;br /&gt;  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND           &lt;br /&gt;21222 diana     20   0 29020  25m 1928 R   95  0.9   5:32.92 ruby &lt;br /&gt;&lt;br /&gt;So it looks like memory footprint is small ~ 25MBs. CPU usage is 95% (i have two processors, so it is completely using one of them).&lt;br /&gt;&lt;br /&gt;I did the same thing for tol_life_xml but it took forever to finish. (more than 3 hours)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For curiosity I created a method next_tree_dummy. All it does is to reader.read from file until it reaches &lt;/phylogeny&gt; element.&lt;br /&gt;&lt;br /&gt;tree of life xml (file size: 45.1MB) - Finished in 3.177743 seconds.&lt;br /&gt;&lt;br /&gt;mollusca xml (1.5MB) -  Finished in 0.252993 seconds.&lt;br /&gt;&lt;br /&gt;metazoa xml (32.3MB) -  Finished in 3.393467 seconds.&lt;br /&gt;&lt;br /&gt;I think this shows that libxml is really fast.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I also did profiling with ruby-prof on ncbi mollusca taxonomy file.&lt;br /&gt;&lt;br /&gt;Here is partial output:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;diana@diana-ubuntu:~/bioruby$ ruby-prof -p graph test/unit/bio/db/test_phyloxml_big.rb&lt;br /&gt;Loaded suite /usr/bin/ruby-prof&lt;br /&gt;Started&lt;br /&gt;.&lt;br /&gt;Finished in 1345.4039 seconds.&lt;br /&gt;&lt;br /&gt;1 tests, 0 assertions, 0 failures, 0 errors&lt;br /&gt;Thread ID: 3084157360&lt;br /&gt;Total Time: 1257.6&lt;br /&gt;&lt;br /&gt;[..]&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;                   1257.56      0.60      0.00   1256.96              2/2     Bio::TestPhyloXMLBig#test_next_tree&lt;br /&gt; 100.00%   0.05%   1257.56      0.60      0.00   1256.96                2     Bio::PhyloXML#next_tree&lt;br /&gt;                      0.08      0.03      0.00      0.05       8107/16210     Bio::PhyloXML#parse_attributes&lt;br /&gt;                      0.00      0.00      0.00      0.00         1/243188     String#==&lt;br /&gt;                      0.00      0.00      0.00      0.00       8104/24322     LibXML::XML::Reader#[]&lt;br /&gt;                      6.18      0.97      0.00      5.21      48616/48616     Bio::PhyloXML#parse_clade_elements&lt;br /&gt;                      0.14      0.14      0.00      0.00      48623/97244     LibXML::XML::Reader#read&lt;br /&gt;                      0.27      0.17      0.00      0.10     48644/875134     Bio::PhyloXML#is_element?&lt;br /&gt;                      0.11      0.04      0.00      0.07      16206/32442     Class#new&lt;br /&gt;                      0.04      0.04      0.00      0.00     16206/116034     Kernel#==&lt;br /&gt;                      0.00      0.00      0.00      0.00          4/72929     Bio::PhyloXML#parse_simple_elements&lt;br /&gt;                      0.07      0.01      0.00      0.06        8102/8102     Bio::Tree#add_node&lt;br /&gt;                      0.44      0.31      0.00      0.13     97243/137758     Bio::PhyloXML#is_end_element?&lt;br /&gt;                   1249.05      0.02      0.00   1249.03        8102/8102     Bio::Tree#parent&lt;br /&gt;                      0.58      0.07      0.00      0.51        8102/8102     Bio::Tree#add_edge&lt;br /&gt;-----------------------------------------------------------------------------&lt;br /&gt;                   1249.05      0.02      0.00   1249.03        8102/8102     Bio::PhyloXML#next_tree&lt;br /&gt;  99.32%   0.00%   1249.05      0.02      0.00   1249.03             8102     Bio::Tree#parent&lt;br /&gt;                   1249.03      0.13      0.00   1248.90        8102/8102     Bio::Tree#path&lt;br /&gt;                      0.00      0.00      0.00      0.00       8102/72975     Array#[]&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;                   1249.03      0.13      0.00   1248.90        8102/8102     Bio::Tree#parent&lt;br /&gt;  99.32%   0.01%   1249.03      0.13      0.00   1248.90             8102     Bio::Tree#path&lt;br /&gt;                      0.04      0.01      0.00      0.03  16204/164638052     Hash#[]&lt;br /&gt;                   1248.82      0.27      0.00   1248.55        8102/8102     Bio::Pathway#bfs_shortest_path&lt;br /&gt;                      0.03      0.03      0.00      0.00     24306/116034     Kernel#==&lt;br /&gt;                      0.01      0.01      0.00      0.00      16204/72975     Array#[]&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;                   1248.82      0.27      0.00   1248.55        8102/8102     Bio::Tree#path&lt;br /&gt;  99.30%   0.02%   1248.82      0.27      0.00   1248.55             8102     Bio::Pathway#bfs_shortest_path&lt;br /&gt;                      0.26      0.19      0.00      0.07 142736/164638052     Hash#[]&lt;br /&gt;                      0.07      0.07      0.00      0.00     75419/116034     Kernel#==&lt;br /&gt;                   1248.18    115.50      0.00   1132.68        8102/8102     Bio::Pathway#breadth_first_search&lt;br /&gt;                      0.04      0.04      0.00      0.00      67317/67330     Array#unshift&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;                   1248.18    115.50      0.00   1132.68        8102/8102     Bio::Pathway#bfs_shortest_path&lt;br /&gt;  99.25%   9.18%   1248.18    115.50      0.00   1132.68             8102     Bio::Pathway#breadth_first_search&lt;br /&gt;                    136.52     92.65      0.00     43.8765785140/164638052     Hash#[]&lt;br /&gt;                     22.53     22.53      0.00      0.0032900672/32900681     Array#shift&lt;br /&gt;                    973.59    324.56      0.00    649.0332892570/32892570     Hash#each_key&lt;br /&gt;                      0.04      0.03      0.00      0.01   24306/98702064     Hash#[]=&lt;br /&gt;[..]&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;99.32% of the total time is spent in Bio::Tree#parent method and the methods it calls.&lt;br /&gt;Bio::Tree#parent calls Bio::Tree#path which calls Bio::Pathways#bfs_shortest_path which in turn calls Bio::Pathway#breadth_first_search (99.25% of total time is spent in this method and its sub calls).&lt;br /&gt;&lt;br /&gt;This was a huge surprise for me. Why would breadth first search be needed if I just want to know the parent node of the current node.&lt;br /&gt;&lt;br /&gt;The reason I am using Bio::Tree#parent is because I have to keep track of the current node I am parsing. When I have reached &lt;/clade&gt; element i set the current_node to the parent of the node I just parsed.&lt;br /&gt;&lt;br /&gt;I see here two options.&lt;br /&gt;&lt;br /&gt;1) Keep track of the current node myself (by putting references in an array and pushing and poping accordingly). Thus I won't have to call the Bio::Tree#parent method.&lt;br /&gt;&lt;br /&gt;2) Update Bio::Tree/ Bio::Node class so that nodes contain references to their parents. (thus not needing to  call breadth first search).&lt;br /&gt;&lt;br /&gt;What do you think?&lt;br /&gt;&lt;br /&gt;(Code is available at &lt;a href="http://github.com/latvianlinuxgirl/bioruby/tree/testbig"&gt;github&lt;/a&gt; )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5396364470982208683-3170760579823371753?l=latvianlinuxgirl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://latvianlinuxgirl.blogspot.com/feeds/3170760579823371753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/06/at-this-point-in-project-i-am-almost.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/3170760579823371753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/3170760579823371753'/><link rel='alternate' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/06/at-this-point-in-project-i-am-almost.html' title='Profiling code: Breadth first search surprise'/><author><name>latvianlinuxgirl</name><uri>http://www.blogger.com/profile/11056269222204216343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://4.bp.blogspot.com/_dN8tfKaI7Vk/SiQG95pGRCI/AAAAAAAAAAM/SCooBjB_VFI/S220/IMG_0047.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5396364470982208683.post-5821014003718751373</id><published>2009-06-15T11:52:00.002-04:00</published><updated>2009-06-15T11:56:58.243-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>A quote about Microsoft</title><content type='html'>I somehow ended up reading &lt;a href="http://www.caliburn.nl/topposting.html"&gt;this site&lt;/a&gt; and read this awesome quote:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"The day Microsoft makes something that doesn't suck is probably         the day they start making vacuum cleaners." -Ernst Jan Plugge      &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;No offense to anybody, but it is funny!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5396364470982208683-5821014003718751373?l=latvianlinuxgirl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://latvianlinuxgirl.blogspot.com/feeds/5821014003718751373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/06/quote-about-microsoft.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/5821014003718751373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/5821014003718751373'/><link rel='alternate' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/06/quote-about-microsoft.html' title='A quote about Microsoft'/><author><name>latvianlinuxgirl</name><uri>http://www.blogger.com/profile/11056269222204216343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://4.bp.blogspot.com/_dN8tfKaI7Vk/SiQG95pGRCI/AAAAAAAAAAM/SCooBjB_VFI/S220/IMG_0047.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5396364470982208683.post-2295511997966790648</id><published>2009-05-31T19:09:00.009-04:00</published><updated>2009-06-04T21:40:05.497-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='xml parsing'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='object'/><category scheme='http://www.blogger.com/atom/ns#' term='phyloXML'/><category scheme='http://www.blogger.com/atom/ns#' term='send'/><category scheme='http://www.blogger.com/atom/ns#' term='GSOC 2009'/><category scheme='http://www.blogger.com/atom/ns#' term='code refactoring'/><title type='text'>Calling method from string in Ruby</title><content type='html'>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.&lt;style type="text/css"&gt;&lt;br /&gt;&lt;!-- body {color: #000000; background-color: #ffffff; font-family: Monospaced} table {color: #000000; background-color: #e9e8e2; font-family: Monospaced} .ST0 {font-family: Monospaced; font-style: italic} .LINE_COMMENT {color: #969696} .line-number {background-color: #e9e8e2} .INSTANCE_VAR {color: #009900} .QUOTED_STRING_LITERAL {color: #ce7b00} .keyword {color: #0000e6} --&gt;&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;So I am parsing XML into objects using LibXML::XML::Reader. I had this code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="line-number"&gt; 1&lt;/span&gt;     &lt;span class="keyword"&gt;def&lt;/span&gt; parse_events()&lt;br /&gt;&lt;span class="line-number"&gt; 2&lt;/span&gt;       events = &lt;span class="ST0"&gt;Events&lt;/span&gt;.new&lt;br /&gt;&lt;span class="line-number"&gt; 3&lt;/span&gt;       &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read &lt;span class="LINE_COMMENT"&gt;#&lt;/span&gt;&lt;span class="LINE_COMMENT"&gt;go to next element&lt;/span&gt;&lt;br /&gt;&lt;span class="line-number"&gt; 4&lt;/span&gt;       &lt;span class="LINE_COMMENT"&gt;#&lt;/span&gt;&lt;span class="LINE_COMMENT"&gt;read while have reached end of events&lt;/span&gt;&lt;br /&gt;&lt;span class="line-number"&gt; 5&lt;/span&gt;       &lt;span class="keyword"&gt;while&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt;(is_end_element?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;events&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)) &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;span class="line-number"&gt; 6&lt;/span&gt;         &lt;span class="keyword"&gt;if&lt;/span&gt; is_element?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;type&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span class="line-number"&gt; 7&lt;/span&gt;           &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;&lt;span class="line-number"&gt; 8&lt;/span&gt;           events.type = &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.value&lt;br /&gt;&lt;span class="line-number"&gt; 9&lt;/span&gt;           &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;&lt;span class="line-number"&gt;10&lt;/span&gt;           has_reached_end_tag?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;type&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span class="line-number"&gt;11&lt;/span&gt;         &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="line-number"&gt;12&lt;/span&gt;         &lt;span class="keyword"&gt;if&lt;/span&gt; is_element?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;duplications&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span class="line-number"&gt;13&lt;/span&gt;           &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;&lt;span class="line-number"&gt;14&lt;/span&gt;           events.duplications = &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.value.to_i&lt;br /&gt;&lt;span class="line-number"&gt;15&lt;/span&gt;           &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;&lt;span class="line-number"&gt;16&lt;/span&gt;           has_reached_end_tag?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;duplications&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span class="line-number"&gt;17&lt;/span&gt;         &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="line-number"&gt;18&lt;/span&gt;         &lt;span class="keyword"&gt;if&lt;/span&gt; is_element?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;speciations&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span class="line-number"&gt;19&lt;/span&gt;           &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;&lt;span class="line-number"&gt;20&lt;/span&gt;           events.speciations = &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.value.to_i&lt;br /&gt;&lt;span class="line-number"&gt;21&lt;/span&gt;           &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;&lt;span class="line-number"&gt;22&lt;/span&gt;           has_reached_end_tag?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;speciations&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span class="line-number"&gt;23&lt;/span&gt;         &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="line-number"&gt;24&lt;/span&gt;         &lt;span class="keyword"&gt;if&lt;/span&gt; is_element?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;losses&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span class="line-number"&gt;25&lt;/span&gt;           &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;&lt;span class="line-number"&gt;26&lt;/span&gt;           events.losses = &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.value.to_i&lt;br /&gt;&lt;span class="line-number"&gt;27&lt;/span&gt;           &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;&lt;span class="line-number"&gt;28&lt;/span&gt;           has_reached_end_tag?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;losses&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span class="line-number"&gt;29&lt;/span&gt;         &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="line-number"&gt;30&lt;/span&gt;         &lt;span class="keyword"&gt;if&lt;/span&gt; is_element?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;confidence&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span class="line-number"&gt;31&lt;/span&gt;           events.confidence = parse_confidence&lt;br /&gt;&lt;span class="line-number"&gt;32&lt;/span&gt;         &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="line-number"&gt;33&lt;/span&gt;         &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;&lt;span class="line-number"&gt;34&lt;/span&gt;       &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="line-number"&gt;35&lt;/span&gt;       &lt;span class="keyword"&gt;return&lt;/span&gt; events&lt;br /&gt;&lt;span class="line-number"&gt;36&lt;/span&gt;     &lt;span class="keyword"&gt;end&lt;/span&gt; &lt;span class="LINE_COMMENT"&gt;#&lt;/span&gt;&lt;span class="LINE_COMMENT"&gt;parse_events&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;This was too much of code duplication, but the problem was that each time different method of the events object is called.&lt;br /&gt;&lt;br /&gt;After some searching on interwebs, luckily, I found out that ruby has a method &lt;span style="font-weight: bold;"&gt;send&lt;/span&gt;, which invokes the method identified by symbol and passes any arguments.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;So I created such method:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;def&lt;/span&gt; parse_simple_element(object, name)&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; is_element?(name)&lt;br /&gt;      &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;      object.send(&lt;span class="QUOTED_STRING_LITERAL"&gt;"&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;#{&lt;/span&gt;name&lt;span class="QUOTED_STRING_LITERAL"&gt;}&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;=&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;"&lt;/span&gt;, &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.value)&lt;br /&gt;      &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;      has_reached_end_tag?(name)&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;So now the method parse_events() can be rewritten like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;def&lt;/span&gt; parse_events()&lt;br /&gt;     events = &lt;span class="ST0"&gt;Events&lt;/span&gt;.new&lt;br /&gt;     &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read &lt;span class="LINE_COMMENT"&gt;#&lt;/span&gt;&lt;span class="LINE_COMMENT"&gt;go to next element&lt;/span&gt;&lt;br /&gt;     &lt;span class="keyword"&gt;while&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt;(is_end_element?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;events&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)) &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;       [&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;type&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;, &lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;duplications&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;, &lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;speciations&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;, &lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;losses&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;].each { |elmt|&lt;br /&gt;         parse_simple_element(events, elmt)&lt;br /&gt;       }&lt;br /&gt;       &lt;span class="keyword"&gt;if&lt;/span&gt; is_element?(&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;confidence&lt;/span&gt;&lt;span class="QUOTED_STRING_LITERAL"&gt;'&lt;/span&gt;)&lt;br /&gt;         events.confidence = parse_confidence&lt;br /&gt;       &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;       &lt;span class="INSTANCE_VAR"&gt;@reader&lt;/span&gt;.read&lt;br /&gt;     &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;     &lt;span class="keyword"&gt;return&lt;/span&gt; events&lt;br /&gt;   &lt;span class="keyword"&gt;end&lt;/span&gt; &lt;span class="LINE_COMMENT"&gt;#&lt;/span&gt;&lt;span class="LINE_COMMENT"&gt;parse_events&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5396364470982208683-2295511997966790648?l=latvianlinuxgirl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://latvianlinuxgirl.blogspot.com/feeds/2295511997966790648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/05/calling-method-from-string-in-ruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/2295511997966790648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/2295511997966790648'/><link rel='alternate' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/05/calling-method-from-string-in-ruby.html' title='Calling method from string in Ruby'/><author><name>latvianlinuxgirl</name><uri>http://www.blogger.com/profile/11056269222204216343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://4.bp.blogspot.com/_dN8tfKaI7Vk/SiQG95pGRCI/AAAAAAAAAAM/SCooBjB_VFI/S220/IMG_0047.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5396364470982208683.post-3260914143905489340</id><published>2009-05-25T22:12:00.000-04:00</published><updated>2009-05-25T22:41:20.981-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BioRuby'/><category scheme='http://www.blogger.com/atom/ns#' term='phyloXML'/><category scheme='http://www.blogger.com/atom/ns#' term='GSOC 2009'/><title type='text'>Hello World!</title><content type='html'>I wanted to have a blog for quite a long time, and now I have a good reason to start it: &lt;span style="font-weight: bold;"&gt;Google Summer of Code 2009&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;My project is to implement phyloXML support in BioRuby and I am working for NESCent organization.&lt;br /&gt;&lt;br /&gt;Here is the project abstract:&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;My project page is: &lt;a href="https://www.nescent.org/wg_phyloinformatics/PhyloSoC:PhyloXML_support_in_BioRuby"&gt;https://www.nescent.org/wg_phyloinformatics/PhyloSoC:PhyloXML_support_in_BioRuby&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The source code is on GitHub: &lt;a href="http://github.com/rozziite/bioruby/tree/master"&gt;http://github.com/rozziite/bioruby/tree/master&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have been using Open Source software for quite a long time already and I am now excited to contribute back to community.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5396364470982208683-3260914143905489340?l=latvianlinuxgirl.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://latvianlinuxgirl.blogspot.com/feeds/3260914143905489340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/05/hello-world.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/3260914143905489340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5396364470982208683/posts/default/3260914143905489340'/><link rel='alternate' type='text/html' href='http://latvianlinuxgirl.blogspot.com/2009/05/hello-world.html' title='Hello World!'/><author><name>latvianlinuxgirl</name><uri>http://www.blogger.com/profile/11056269222204216343</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://4.bp.blogspot.com/_dN8tfKaI7Vk/SiQG95pGRCI/AAAAAAAAAAM/SCooBjB_VFI/S220/IMG_0047.JPG'/></author><thr:total>3</thr:total></entry></feed>
