<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Moves On Rails: Tag ruby</title>
    <link>http://www.movesonrails.com/articles/tag/ruby?tag=ruby</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>New ways to look at software</description>
    <item>
      <title>libxml-ruby and Windows</title>
      <description>&lt;p&gt;So, my first post on movesonrails.com! You might not know me, but I am one of the Nedap Healthcare developers. Usually I don't work on Moves or even with ruby on rails, but I needed some functionality...&lt;/p&gt;

&lt;p&gt;You might have seen a patch by Bart that allowed ActiveResource to be used with Libxml-ruby, with a dramatic performance increase. The downside was, you can't use libxml with Windows, limiting your applications to mac-os and linux. There was one build of libxml-ruby, which didn't really work, is an older version and missed some rather important files.&lt;/p&gt;

&lt;p&gt;But now you can use libxml-ruby in windows! Just unpack &lt;a href="http://www.movesonrails.com/files/libxml-ruby-0.5.2.0.zip"&gt;this zip&lt;/a&gt; into your ruby directory, rename ruby\lib\ruby\site_ruby\1.8\i386-msvcrt\xmlparser.so to xmlparser.s_ and you'll have libxml 0.5.2.0 !&lt;/p&gt;

&lt;p&gt;If you'd rather had libxml-ruby 0.3.8.4, you can download &lt;a href="http://www.movesonrails.com/files/libxml-ruby-0.3.8.4.zip"&gt;this zip&lt;/a&gt; instead, or even &lt;a href="http://www.movesonrails.com/files/libxml-ruby-windows.zip"&gt;0.5.1.0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To achieve this, I spent a morning compiling libxml with mingw. Just forget the following if you just want to use this, but for the sake of future version, this is what i had to do:&lt;/p&gt;

&lt;p&gt;1 . install mingw and MSYS in the standard directories (c:\mingw)&lt;/p&gt;

&lt;p&gt;2 . download the ruby source and compile, in a different directory than c:\ruby:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;code&gt;&lt;pre&gt;./configure --with-prefix=c:/mingw/ruby
    make
    make install&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;3 . download the zlib, iconv and libxml sources&lt;/p&gt;

&lt;p&gt;4 . compile all of them with :&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;code&gt;&lt;pre&gt;./configure --with-prefix=c:/mingw
    make
    make install&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;5 . download libxml-ruby&lt;/p&gt;

&lt;p&gt;6 . now, the tricky part. You won't have rake (you didn't compile it) so we have to do a trick. Go to your libxml-ruby source directory and type:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;code&gt;&lt;pre&gt;
    /c/mingw/ruby/bin/ruby ext/xml/extconf.rb
    make
    make install&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;7 . everything has been compiled. Just copy these files:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&lt;code&gt;&lt;pre&gt;
    to ruby\bin:
    c:\mingw\bin\iconv-2.dll
    c:\mingw\bin\libxml2-2.dll
    &lt;/pre&gt;&lt;/code&gt;
    &lt;code&gt;&lt;pre&gt;
    to ruby\lib\ruby\site_ruby\1.8\i386-msvcrt\xml:
    C:\MinGW\ruby\lib\ruby\site_ruby\1.8\i386-msvcrt\xml\libxml_so.o
    &lt;/pre&gt;&lt;/code&gt;
    &lt;code&gt;&lt;pre&gt;
    to ruby\lib\ruby\site_ruby\1.8\xml
    C:\MinGW\ruby\lib\ruby\site_ruby\1.8\xml\libxml.rb
    &lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;have fun with a 20 times faster XML parser :)&lt;/p&gt;

&lt;h2&gt;update! versions 0.5.2.0 and 0.3.8.4 also available!&lt;/h2&gt;

&lt;p&gt;download &lt;a href="http://www.movesonrails.com/files/libxml-ruby-0.5.2.0.zip"&gt;0.5.2.0&lt;/a&gt; or &lt;a href="http://www.movesonrails.com/files/libxml-ruby-0.3.8.4.zip"&gt;0.3.8.4&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 09 Oct 2007 14:23:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:8d7a8e6e-c1a4-4e8e-821c-4e073b714236</guid>
      <author>pieter.bos@nedap.com (Pieter Bos)</author>
      <link>http://www.movesonrails.com/articles/2007/10/09/libxml-ruby-and-windows</link>
      <category>libxml</category>
      <category>compile</category>
      <category>win32</category>
      <category>windows</category>
      <category>ruby</category>
      <category>ActiveResource</category>
      <enclosure type="application/zip" length="2296262" url="http://www.movesonrails.com/files/libxml-ruby-0.5.2.0.zip"/>
    </item>
    <item>
      <title>Working with timeranges</title>
      <description>&lt;p&gt;Everything in moves 'acts_as_placed_on_timeline'. This entails that every object has a valid_from and valid_to field, which specify when they are active.&lt;/p&gt;

&lt;p&gt;A simple example is an address, it becomes active (valid_from) when a person starts living there and is deactivated (valid_to) when the person moves to another address. &lt;/p&gt;

&lt;p&gt;Looking at the example above it is hard to see why this would ever pose a problem with code readability. Hang in there a moment longer. &lt;/p&gt;&lt;p&gt;We start with two addresses (A and B) both on the same timeline:&lt;/p&gt;

&lt;pre&gt;|------A------|-------B------|&lt;/pre&gt;

The person first lived on address A and then moved to address B. Simple. Now what if we missed an address? Say the person had an address C we didn't know about until later, and even worse: address C came between A and B.

We could just spell it our for ruby and update addresses A and B's timeline fields and add address C. But we need a more generic way that will always work, even with object that are a lot more complex and might have to update dozens of other objects.
&lt;br/&gt;&lt;br/&gt;
We decided we needed to be able to do:

&lt;pre&gt;&lt;code&gt;Address.find(A).update_on_period([start_of_c,end_of_c], attrs_of_c)&lt;/code&gt;&lt;/pre&gt;

or the equivalent:

&lt;pre&gt;&lt;code&gt;Address.find(B).update_on_period([start_of_c,end_of_c], attrs_of_c)&lt;/code&gt;&lt;/pre&gt;

This function will just iterate through each applicable address and split them accordingly. In this case the result of our method will be:

&lt;pre&gt;|------A---|-C-|-C-|---B------|&lt;/pre&gt;

The ugly splits could be merged into one but the effect is the same so we won't go into that.

At the core of this function we needed to compare periods of time in ruby. And since ruby does not have  a decent TimeRange class itself, we decided we needed to write one ourselves. (&lt;a href="http://pastie.caboo.se/92050"&gt;Period.rb&lt;/a&gt;).

The period class contains a function that determines the overlap type between two ranges of time.

&lt;pre&gt;
                     [         OTHER PERIOD          ]
         [BEFORE]               [INSIDE]                 [AFTER]
            [LEFT_OVERLAP]                     [RIGHT_OVERLAP]
      [..........................AROUND.............................]
                     [..........ENDS LATER..............................]
      [............................STARTS EARLIER....]
&lt;/pre&gt;

&lt;p&gt;Using this code we cleaned our internal code until it was sparkling, we went from checking valid_from and valid_to fields on every line to never using them at all. Which reduced the mistakes we were constantly making.&lt;/p&gt;

&lt;p&gt;I hope some of you might find the class useful, feel free to use it as you please!&lt;/p&gt;</description>
      <pubDate>Fri, 31 Aug 2007 21:01:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:53ffb19d-d3e7-4f2c-aa6a-31ce8f000919</guid>
      <author>andre.foeken@movesonrails.com (Andre Foeken)</author>
      <link>http://www.movesonrails.com/articles/2007/08/31/working-with-timeranges</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>period</category>
      <category>date</category>
      <category>time</category>
      <category>overlap</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Gettext Generators 1.2.3 Released</title>
      <description>&lt;p&gt;The longawaited update for the Gettext Generator.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First release as plugin&lt;/li&gt;
&lt;li&gt;Added svn:merge raketask&lt;/li&gt;
&lt;li&gt;Updated generated resource to mimmick scaffold_generator packaged with rails 1.2.3 tag&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So go to &lt;a href="http://rubyforge.org/projects/gettextgnrtrs/"&gt;RubyForge&lt;/a&gt; or take a look &lt;a href="/pages/gettextgenerators"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm currently getting the plugin uploaded to rubyforge. As soon as I have that figured out how that works, I'll post the link here.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ruby script/plugin install svn://rubyforge.org/var/svn/gettextgnrtrs/tags\
/Gettext-Generators-1.2.3/&lt;/code&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 28 Aug 2007 20:41:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:b5414d5b-723e-41b4-8248-a117fc4d8d2b</guid>
      <author>bart.tenbrinke@movesonrails.com (Bart ten Brinke)</author>
      <link>http://www.movesonrails.com/articles/2007/08/28/gettext-generators-1-2-3-released</link>
      <category>Project update</category>
      <category>Rails</category>
      <category>Ruby</category>
      <category>gettextgenerators</category>
      <category>rails</category>
      <category>ruby</category>
    </item>
    <item>
      <title>How to find all those stray y, puts and prints in your code</title>
      <description>&lt;p&gt;I have it all the time, I add some nasty console output to my ruby and some gets left behind. I wanted this to stop so I built a small regex to solve my problem.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    {   name = 'console.output.ruby';
        match = '^\s*(y|puts|print|printf)[ ].*';
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you add this to the ruby language def in Textmate and then update your style theme with a bright color (scope: console.output.ruby), those nasty buggers will really stand out.&lt;/p&gt;

&lt;p&gt;If you just want to get rid of them just run the regex above on your file (replace).&lt;/p&gt;</description>
      <pubDate>Tue, 28 Aug 2007 17:49:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:8da5108b-76ec-49d9-b33b-72939fcc902e</guid>
      <author>andre.foeken@movesonrails.com (Andre Foeken)</author>
      <link>http://www.movesonrails.com/articles/2007/08/28/how-to-find-all-those-stray-y-puts-and-prints-in-your-code</link>
      <category>Ruby</category>
      <category>regex</category>
      <category>y</category>
      <category>puts</category>
      <category>ruby</category>
      <category>grep</category>
      <category>textmate</category>
    </item>
    <item>
      <title>Solving some gem install problems</title>
      <description>&lt;p&gt;Lately we have been having some issues installing gem that have to compile native extensions like libxml-ruby and termios.&lt;/p&gt;

&lt;p&gt;The error we got from libxml was: "extconf failure: need libm". Strangely this was all caused by incorrect compile flags in the rbconfig.rb file.&lt;/p&gt;

&lt;p&gt;To fix this (and other issues) you can customize the rbconfig.rb file to your specific computer.&lt;/p&gt;

&lt;p&gt;Mine was located in: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt; /usr/lib/ruby/1.8/universal-darwin8.0/rbconfig.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On leopard this is universal-darwin9.0. The file contains a lot of config definitions. I removed all traces of any other architecture then i386 (like -arch x86_64, etc). I also removed the 64 flag that was included.&lt;/p&gt;

&lt;p&gt;After altering this in the entire file (quite a few replaces), everything compiled happily.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;update&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;I was also having some issues with the SQLSessionStore plugin. Seems recent changes to ruby have made it a no-no to alter constants (no surprise there). So now in stead of doing&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.
  update(:database_manager =&gt; SqlSessionStore)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You have to do:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dso = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS
dso[:database_manager] = SqlSessionStore
ActionController::CgiRequest.send(:remove_const, "DEFAULT_SESSION_OPTIONS")
ActionController::CgiRequest.const_set("DEFAULT_SESSION_OPTIONS", dso)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Which is uglier, and still should not be possible :)&lt;/p&gt;

&lt;p&gt;To make it work I also had to remove the &lt;code&gt;require 'mysql'&lt;/code&gt; line from the plugins MySqlSession.rb file. Else it would crash rails with the following error:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;warning: already initialized constant OPTIONS&lt;/code&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 29 Jul 2007 18:08:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:a95f4c46-8274-4525-a8d9-06aee7c3eed0</guid>
      <author>andre.foeken@movesonrails.com (Andre Foeken)</author>
      <link>http://www.movesonrails.com/articles/2007/07/29/solving-some-gem-install-problems</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>sqlsessionstore</category>
      <category>libxml</category>
      <category>ruby</category>
      <category>compile</category>
      <category>native</category>
      <category>libm</category>
      <category>dylib</category>
      <category>darwin8.0</category>
      <category>darwin9.0</category>
      <category>universal</category>
      <category>arch</category>
      <category>fail</category>
    </item>
    <item>
      <title>Speeding up Active Resource</title>
      <description>&lt;p&gt;As I was trying to import 12 MB of XML, it quickly became very clear that the SimpleXML used in Hash.from_xml was not going to cut it. It took nearly four minutes to convert the xml data to a hash! &lt;/p&gt;

&lt;p&gt;As Active Resource will probably be used to handle large xml files, I created a patch so that libxml is used to parse the xml. This made fetching the active resource go from 240 seconds to 12 seconds. That 20 times faster!&lt;/p&gt;

&lt;p&gt;The net override (also included) makes downloading a factor four faster.&lt;/p&gt;

&lt;p&gt;Find the patch here:
&lt;a href="http://dev.rubyonrails.org/ticket/9017"&gt;http://dev.rubyonrails.org/ticket/9017&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 19 Jul 2007 10:18:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:df8ad3e4-304c-4101-b930-a5a9219abce3</guid>
      <author>bart.tenbrinke@movesonrails.com (Bart ten Brinke)</author>
      <link>http://www.movesonrails.com/articles/2007/07/19/speeding-up-active-resource</link>
      <category>Rails</category>
      <category>ruby</category>
      <category>libxml</category>
      <category>ActiveResource</category>
      <category>slow</category>
      <category>hash</category>
      <category>from_xml</category>
    </item>
    <item>
      <title>Building a database logger</title>
      <description>&lt;p&gt;Sometimes you don't want to log to a file, but to your database. A quick and somewhat dirty way for this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; script/generate scaffold_resource LogEntry severity:string, \
  time_stamp:datetime, progname:string, msg:string
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With the following logger:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class MovesLogger &amp;lt; Logger

  def format_message(severity, timestamp, progname, msg)
    logEntry = LogEntry.new({:severity  =&amp;gt;  severity,
                           :timestamp  =&amp;gt;  timestamp,
                           :progname   =&amp;gt;  progname, 
                           :msg        =&amp;gt;  msg})
    logEntry.save
    return nil
  end  
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can use logger = MovesLogger.new($stdout) and everything will be neatly logged to the database!&lt;/p&gt;</description>
      <pubDate>Wed, 18 Jul 2007 09:26:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:a8352775-bbfa-432d-ac50-806195458c9f</guid>
      <author>bart.tenbrinke@movesonrails.com (Bart ten Brinke)</author>
      <link>http://www.movesonrails.com/articles/2007/07/18/building-a-database-logger</link>
      <category>Ruby</category>
      <category>ruby</category>
      <category>Logger</category>
      <category>format_message</category>
      <category>database</category>
    </item>
  </channel>
</rss>
