<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ary Boretc.</title>
	<atom:link href="http://weblogs.manas.com.ar/ary/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblogs.manas.com.ar/ary</link>
	<description>Programando una manzana</description>
	<lastBuildDate>Thu, 31 Mar 2011 01:45:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Nuntium: exponential backoff and new xmpp library</title>
		<link>http://weblogs.manas.com.ar/ary/2011/03/30/nuntium-exponential-backoff-and-new-xmpp-library/</link>
		<comments>http://weblogs.manas.com.ar/ary/2011/03/30/nuntium-exponential-backoff-and-new-xmpp-library/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 14:51:42 +0000</pubDate>
		<dc:creator>ary</dc:creator>
				<category><![CDATA[Nuntium]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://weblogs.manas.com.ar/ary/?p=234</guid>
		<description><![CDATA[This week we've updated nuntium to version 2.8, yay! Aside from some minor bug fixes, nuntium now implements an exponential backoff strategy when a message delivery fails. Previously, it worked like this: A message failed to be delivered. If the cause was the message itself (for example it contains invalid data), it was discarded. If [...]]]></description>
			<content:encoded><![CDATA[<p>This week we've updated <a href="http://instedd.org/technologies/nuntium/">nuntium</a> to version 2.8, yay!</p>
<p>Aside from some minor bug fixes, nuntium now implements an exponential backoff strategy when a message delivery fails. Previously, it worked like this:</p>
<ol>
<li>A message failed to be delivered.</li>
<li>If the cause was the message itself (for example it contains invalid data), it was discarded.</li>
<li>If the cause was an authentication problem, for example an SMTP server's password changed, the channel responsible for delivering the message was disabled and an alert was sent to the administrator.</li>
<li>Otherwise, the cause was a temporary one, maybe a connection timeout. In that case, delivery through that channel was suspended for five minutes with an alert being sent to the administrator.</li>
</ol>
<p>In this last point, sometimes the cause was in fact an invalid message for which the other side expecting to get the message wasn't correctly prepared to handle. This caused all subsequent valid messages to be suspended for five minutes.</p>
<p>We changed this behavior to just suspend this message for some time (using an exponential backoff strategy) but allowing next messages to be sent. The message is marked as "delayed" an you can see it in the UI. We think this is a much more resilient solution.</p>
<p>The other big thing is that we changed the library we used to receive and send XMPP messages. Previously we used <a href="http://home.gna.org/xmpp4r/">xmpp4r</a>, which works quite well but sometimes it would raise unexpected exceptions which we couldn't understand. Also, it wasn't based on event machine. We switched to the excelent <a href="http://blather.squishtech.com/">blather</a> library and so far it didn't let us down.</p>
<p>What's next? Having implemented delayed messages on failure cases we are only a small step away from implementing delayed messages just for the sake of it. Imagine sending a message to nuntium and telling it to send it on a specific date. With this you could implement things as simple as birthday reminders to pregnancy checks reminders or messages sent today or tomorrow afternoon of a given time zone.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblogs.manas.com.ar/ary/2011/03/30/nuntium-exponential-backoff-and-new-xmpp-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New office, ruby cake</title>
		<link>http://weblogs.manas.com.ar/ary/2011/02/22/new-office-ruby-cake/</link>
		<comments>http://weblogs.manas.com.ar/ary/2011/02/22/new-office-ruby-cake/#comments</comments>
		<pubDate>Tue, 22 Feb 2011 23:01:21 +0000</pubDate>
		<dc:creator>ary</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://weblogs.manas.com.ar/ary/?p=227</guid>
		<description><![CDATA[Two weeks ago, Friday, was the last day in our old office. The mood was pretty nice since the new office has direct sun light and is much more comfortable, and also because every Friday, in a round-robin fashion, each one of us brings some delicious for dessert. It was my turn. I'm not much [...]]]></description>
			<content:encoded><![CDATA[<p>Two weeks ago, Friday, was the last day in our old office. The mood was pretty nice since the new office has direct sun light and is much more comfortable, and also because every Friday, in a round-robin fashion, each one of us brings some delicious for dessert. It was my turn.</p>
<p>I'm not much of a cook. I checked some online recipes and finally settled on a Chocotorta, a somewhat famous pie here in Argentina that you can prepare with chocolate cookies, coffee, dulce de leche and white cheese. I wanted it to be special for this last day so I thought about decorating it with powder chocolate that would read either "Friday" or "Manas". But those words were too long and they wouldn't fit. So the closest thing that meant happiness to me but was shorter was "Ruby". <img src='http://weblogs.manas.com.ar/ary/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<p>Here's a picture of it. The "R" is not very clear...</p>
<div id="attachment_229" class="wp-caption alignnone" style="width: 160px"><a href="http://weblogs.manas.com.ar/ary/files/2011/02/2011-02-11-14.05.43.jpg"><img src="http://weblogs.manas.com.ar/ary/files/2011/02/2011-02-11-14.05.43-150x150.jpg" alt="The rubycake" width="150" height="150" class="size-thumbnail wp-image-229" /></a><p class="wp-caption-text">The rubycake</p></div>
<p>So here's the recipe I used:</p>
<p>Ingredients:</p>
<ul>
<li>3 packs of <a href="http://images.google.com/images?q=chocolinas">Chocolinas</a></li>
<li>500 grams of dulce de leche</li>
<li>300 grams of <a href="http://images.google.com/images?q=mendicrim">white cheese</a></li>
<li>1 cup of hot chocolate milk (can also be coffee)</li>
<li>Chocolate powder</li>
<li>1 <a href="http://images.google.com/images?q=pionono">pionono</a> (can be replaced with chocolinas)</li>
<li>1 peach</li>
</ul>
<p>Mix the dulce the leche and the white cheese. I also added some chocolate powder to it. We'll call this the stuffing.</p>
<p>Wet some chocolinas in the hot chocolate milk and with them form a rectangle, like a platform. Then put some of the stuffing on it. Then put either another platform of chocolinas or pionono. Continue until your formed three or four platforms. On top of the final platform put more sutffing. Sprinkle the chocolate powder to form the word "Ruby". Chop the peach in tiny sliced and put them around. Don't forget to put one slice in the "R"'s hole and two on the "B"'s circle. Put on the fridge. You are done!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblogs.manas.com.ar/ary/2011/02/22/new-office-ruby-cake/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>rgviz-rails updated to Rails 3</title>
		<link>http://weblogs.manas.com.ar/ary/2010/12/11/rgviz-rails-updated-to-rails-3/</link>
		<comments>http://weblogs.manas.com.ar/ary/2010/12/11/rgviz-rails-updated-to-rails-3/#comments</comments>
		<pubDate>Sat, 11 Dec 2010 17:26:03 +0000</pubDate>
		<dc:creator>ary</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Visualization]]></category>

		<guid isPermaLink="false">http://weblogs.manas.com.ar/ary/?p=221</guid>
		<description><![CDATA[I just updated the rgviz-rails gem to work with Rails 3. It was pretty easy, following the instructions of this site. I also moved the code from Google Code to github, so i can have all my projects under a single tree, and to start using git more frequently. Here are the new URLs: http://github.com/asterite/rgviz [...]]]></description>
			<content:encoded><![CDATA[<p>I just updated the rgviz-rails gem to work with Rails 3. It was pretty easy, following the instructions of <a href="http://boldr.net/upgrade-plugins-gems-rails-3">this site</a>.</p>
<p>I also moved the code from Google Code to github, so i can have all my projects under a single tree, and to start using git more frequently.</p>
<p>Here are the new URLs:</p>
<p><a href="http://github.com/asterite/rgviz">http://github.com/asterite/rgviz</a><br />
<a href="http://github.com/asterite/rgviz-rails">http://github.com/asterite/rgviz-rails</a></p>
]]></content:encoded>
			<wfw:commentRss>http://weblogs.manas.com.ar/ary/2010/12/11/rgviz-rails-updated-to-rails-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing cukecooker: writing cucumber scenarios with aid</title>
		<link>http://weblogs.manas.com.ar/ary/2010/12/08/introducing-cukecooker-writing-cucumber-scenarios-with-aid/</link>
		<comments>http://weblogs.manas.com.ar/ary/2010/12/08/introducing-cukecooker-writing-cucumber-scenarios-with-aid/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 02:15:05 +0000</pubDate>
		<dc:creator>ary</dc:creator>
				<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Utilities]]></category>

		<guid isPermaLink="false">http://weblogs.manas.com.ar/ary/?p=201</guid>
		<description><![CDATA[In our development team we want our testers to start writing cucumber features. I know, BDD, the features should be written before the code, but a tester could later add scenarios which we haven't previously thought or regression features for bugs. For writing the scenarios she could learn the steps from other features or just [...]]]></description>
			<content:encoded><![CDATA[<p>In our development team we want our testers to start writing cucumber features. I know, BDD, the features should be written before the code, but a tester could later add scenarios which we haven't previously thought or regression features for bugs.</p>
<p>For writing the scenarios she could learn the steps from other features or just browse the step definition files, but I felt it was a little uncomfortable, specially having to deal with regular expressions. So we thought about writing a script that lists all step definitions in a project: then she could browse the list, copy what she needed and fill in the parameters.</p>
<p>I went a step further: why not generating a page that allows her to browse steps, select one, fill in the parameters and then write it to a scenario? After doing this for many steps he could copy and paste the resulting scenario to the feature file. Autocompletion, no need to deal with regular expressions, just one copy and paste, nice colors (well, this last point might not be true).</p>
<p>And so <a href="https://github.com/asterite/cukecooker/" target="_blank">cukecooker</a> was born. You can think of it as a Cucumber IDE. To install it:</p>
<pre>
gem install cukecooker
</pre>
<p>To run it:</p>
<pre>
cukecooker
</pre>
<p>or</p>
<pre>
cukecooker path/to/your/project
</pre>
<p>This will generate an HTML file. Open it and start writing cucumber scenarios. Here are some screenshots.</p>
<p>This is the step selection part, where typing in the input above filters the steps, you can navigate them using the arrow keys and choose one pressing enter (or using the mouse):</p>
<p><a href="http://weblogs.manas.com.ar/ary/files/2010/12/filter.png"><img src="http://weblogs.manas.com.ar/ary/files/2010/12/filter-300x179.png" alt="cukecooker filter steps" width="300" height="179" class="alignnone size-medium wp-image-206" /></a></p>
<p>Once you select a step you can fill in the parameters:<br />
<a href="http://weblogs.manas.com.ar/ary/files/2010/12/build.png"><img src="http://weblogs.manas.com.ar/ary/files/2010/12/build-300x181.png" alt="cukecooker complete parameters" width="300" height="181" class="alignnone size-medium wp-image-207" /></a></p>
<p>For steps which require a table or a multiline string I just put a big "TODO: complete this"... maybe in a future I'll include an editor for that.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblogs.manas.com.ar/ary/2010/12/08/introducing-cukecooker-writing-cucumber-scenarios-with-aid/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rails Rumble is over: welcome GithubDamper!</title>
		<link>http://weblogs.manas.com.ar/ary/2010/10/18/rails-rumble-is-over-welcome-githubdamper/</link>
		<comments>http://weblogs.manas.com.ar/ary/2010/10/18/rails-rumble-is-over-welcome-githubdamper/#comments</comments>
		<pubDate>Mon, 18 Oct 2010 14:09:21 +0000</pubDate>
		<dc:creator>ary</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://weblogs.manas.com.ar/ary/?p=191</guid>
		<description><![CDATA[This past weekend, together with Emmanuel Oga, we've been coding a Ruby on Rails application for this year's Rails Rumble. The idea: in github you can watch some repositories, but later you can't make a search over those watches. The only search github provides is one over all repositories. When your watches reaches a big [...]]]></description>
			<content:encoded><![CDATA[<p>This past weekend, together with <a href="http://emmanueloga.wordpress.com/">Emmanuel Oga</a>, we've been coding a Ruby on Rails application for this year's <a href="http://railsrumble.com/">Rails Rumble</a>.</p>
<p>The idea: in <a href="http://github.com">github</a> you can <b>watch some repositories</b>, but later <b>you can't make a search over those watches</b>. The only search github provides is one over all repositories. When your watches reaches a big number it's defeats its purpose. So <b>we decided to let users tag their watches and then be able to search them by tags</b>.</p>
<p>(Well, actually the original idea was a lot bigger: github generates a big feed for your watches, including commits, comments and gists, and we wanted to filter that feed in a smart way, but in just 48 hours, having to install a server from scratch it was a little ambitious)</p>
<p>What we wanted is the tags to be a <b>community effort</b>: if I tag a project with "java", let that tag be shown to other users. On the other side, we also wanted the users to have personal tags. But we didn't want the user to choose, when tagging, wheter it's personal or global, because that's a burden on him. So we came up with the following idea: <b>if more than five users put the same tag on a give repository, that tag becomes automatically available to all users</b>.</p>
<p>We also wanted to start out with some tags, like for programming languages or common software terms, so when a user logs in she starts with some tags on her repositories. So we have a <b>background process</b> that imports a user's watches and <b>put tags on them if their description contains one of those common words</b>. That list gets expanded as tags become automatically available to all users, as described in the previous paragraph. For instance, if the initial tags list didn't contains "orm" as a tag, but more than five users tagged the same repository as "orm", all repositories whose description contain "orm" will now contain that tag. That makes the community effort a lot easier.</p>
<p>On the other hand, <b>the automatic tagging might not be perfect</b> and a repository might get tagged with an incorrect word. So, <b>if more than five users remove the same tag from a repository, that tag gets automatically removed from that repository to all users</b>.</p>
<p>Unfortunately, we forgot to put this behavior on our web site so users might think they must tag their watches without the system ever helping them. We hope to spread that knowledge with blogs and tweets, since we will get disqualified if we make changes after those 48 hours.</p>
<p>It was a really fun experience. I couldn't install the necessary software to deploy it on my computer so I used Emmanuel's one, with Arch Linux and using gvim. I learned a lot!</p>
<p>Emmanuel's brother-in-law helped us out with the design and the logo, which we really like. It seems that octocat had some troubles keeping his watches organized and got tired of it. <img src='http://weblogs.manas.com.ar/ary/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Finally, here's the website: <a href="http://www.githubdamper.com/">http://www.githubdamper.com</a>. We hope you find it useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblogs.manas.com.ar/ary/2010/10/18/rails-rumble-is-over-welcome-githubdamper/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Even more powerful Goolge Visualizations for Ruby on Rails</title>
		<link>http://weblogs.manas.com.ar/ary/2010/08/19/even-more-powerful-goolge-visualizations-for-ruby-on-rails/</link>
		<comments>http://weblogs.manas.com.ar/ary/2010/08/19/even-more-powerful-goolge-visualizations-for-ruby-on-rails/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 11:16:15 +0000</pubDate>
		<dc:creator>ary</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Visualization]]></category>

		<guid isPermaLink="false">http://weblogs.manas.com.ar/ary/?p=180</guid>
		<description><![CDATA[Ok, now you can easily implement a Google Visualization API data source on rails. But... are you still using javascript to render them? Well, you don't need to do that anymore. Now rgviz-rails supports a pretty simple and powerful way to do it. In your views templates you now have an rgviz function. You use [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, now you can <a href="http://weblogs.manas.com.ar/ary/2010/08/17/173/">easily implement a Google Visualization API data source on rails</a>. But... are you still using javascript to render them?</p>
<p>Well, you don't need to do that anymore. Now rgviz-rails supports a pretty simple and powerful way to do it. In your views templates you now have an rgviz function. You use it like this:</p>
<p><code><br />
&lt;%= rgviz :id =&gt; 'my_visualization',<br />
  :kind =&gt; 'BarChart',<br />
  :url =&gt; '/some_endpoint',<br />
  :query =&gt; 'select country_name, sum(age) group by country_name',<br />
  'options' =&gt; {:width =&gt; 640, :height =&gt; 480, :is3D =&gt; true}<br />
  %&gt;<br />
</code></p>
<p>Not a single line of javascript code.</p>
<p>Yes, I know. You have a combo box and when the users changes its value you need to refresh the visualization, right? You can do it with what I call "magic names", hehe.</p>
<p><a href="http://github.com/asterite/rgviz-rails/wiki/Showing-a-visualization-in-a-view">Read more about this</a>. <img src='http://weblogs.manas.com.ar/ary/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://weblogs.manas.com.ar/ary/2010/08/19/even-more-powerful-goolge-visualizations-for-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Powerful Google Visualizations for Ruby on Rails</title>
		<link>http://weblogs.manas.com.ar/ary/2010/08/17/173/</link>
		<comments>http://weblogs.manas.com.ar/ary/2010/08/17/173/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 02:11:09 +0000</pubDate>
		<dc:creator>ary</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Visualization]]></category>

		<guid isPermaLink="false">http://weblogs.manas.com.ar/ary/?p=173</guid>
		<description><![CDATA[So we have this project in Ruby on Rails where we keep track of several reports. Now we need to do some visualizations with all those reports. We analyzed several solutions. One was using Google Fusion Tables but we soon realized it was not an easy task: we need to keep our records synchronized with [...]]]></description>
			<content:encoded><![CDATA[<p>So we have this project in <a href="http://rubyonrails.org/">Ruby on Rails</a> where we keep track of several reports. Now we need to do some visualizations with all those reports.</p>
<p>We analyzed several solutions. One was using <a href="http://tables.googlelabs.com">Google Fusion Tables</a> but we soon realized it was not an easy task: we need to keep our records synchronized with Google. Well, maybe not very hard: have a background process that keeps track of the last date of synchronization and gets all the records whose updated_at date is greater then that, and synchronize. The problem is that some of our records can be deleted, so we would need to mark them as deleted or think of something else, which complicates the main logic of our application. Also our application is pretty simple and complicating it with background processes wasn't our ideal solution.</p>
<p>Then we though about just using the <a href="http://code.google.com/apis/visualization/documentation/">Google Visualization API</a>. It works by sending a query to an endpoint which returns some javascript code that includes, amongst other things, a <a href="http://code.google.com/apis/visualization/documentation/reference.html#dataparam">table</a> to be used in the visualization. The query can be anything that the end-point understands but Google has it's own <a href="http://code.google.com/apis/visualization/documentation/querylanguage.html">query language</a>, which is used by <a href="http://spreadsheets.google.com/">Google Spreadsheets</a>, for example.</p>
<p>So we started by making one endpoint that just ignores the query and sends what we needed for one of our visualizations. We basically issued an ActiveRecord query, with some sums, custom selects, groups by and joins, and transformed the results into the necessary javascript code. But then we needed another visualization and we had to write another endpoint with yet another query. Soon we realized it would really be nice to have just one endpoint that supports receiving a query, and much better if that query comes in Google's query language syntax, since people should be familiar with it and we can give the documentation URL to our developers and tell them "This is how you can query our endpoint".</p>
<p>This is how <a href="http://github.com/asterite/rgviz">rgviz</a> and <a href="http://github.com/asterite/rgviz-rails">rgviz-rails</a> were born. The first one just implements a query language parser. The second one executes queries with ActiveRecord. So if you have a model named Person and you want to provide an endpoint to query Person data, you just need to write this in a method of your controller:</p>
<pre>render :rgviz =&gt; Person</pre>
<p>One of the nicest things about this is that you can also use associations in your query. So for example if a Person belongs to a City, you could write a query like:</p>
<pre>select city_name, avg(age) group by city_name</pre>
<p>Another nice thing is that the <a href="http://code.google.com/apis/visualization/documentation/querylanguage.html#Pivot">pivot clause</a> is fully supported. And the endpoint will always execute your query in just one SQL query, and an efficient one.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblogs.manas.com.ar/ary/2010/08/17/173/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building an application to track expenses in one hour using GeoChat</title>
		<link>http://weblogs.manas.com.ar/ary/2010/06/17/154/</link>
		<comments>http://weblogs.manas.com.ar/ary/2010/06/17/154/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 03:33:30 +0000</pubDate>
		<dc:creator>ary</dc:creator>
				<category><![CDATA[GeoChat]]></category>
		<category><![CDATA[Nuntium]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://weblogs.manas.com.ar/ary/?p=154</guid>
		<description><![CDATA[Whenever one of our team member travels to another country we tell her to track expenses like food, transportation and accomodation so that later that money can be refunded. Each of us does it in a different way: we write it in a notes application in a cellphone, or in a text file in our [...]]]></description>
			<content:encoded><![CDATA[<p>Whenever one of our team member travels to another country we tell her to track expenses like food, transportation and accomodation so that later that money can be refunded. Each of us does it in a different way: we write it in a notes application in a cellphone, or in a text file in our computer, or maybe in a web application. The problem with the two first approaches is that the information might be lost: the machine might crash or be lost. The last approach is ok, but then you need to remember to connect to the internet to track the expense, and that can happen several hours after having paid, and our memory is not very good.</p>
<p>So I wanted to simply send an sms message to some number to track my expenses. I carry my cellphone all the time so I can send an sms immediately after paying something. Such an application seems very hard to do at first, specially because of the messaging component: receiving sms, configuring a number, etc. Doesn't it?</p>
<p>Well, we have <a href="http://geochat.instedd.org">GeoChat</a>! GeoChat is an application that lets you  create groups of people to stay in touch with them. When a message is sent to a group it will be broadcasted to every member. And not necessarily to their mobile phone: each user can decide to receive emails, twitter updates, an instant message to their jabber client, etc. The original use case is for people in the field to report emergency and disaster situations to recover from them as quickly as possible. But that doesn't mean we can use it for other purposes.</p>
<p>For example, one thing that you can do is configure a group in GeoChat to forward some or all of the messages to an <a href="http://geochathelp.com/doku.php?id=advanced:datasetservices&amp;s[]=dataset">external service</a>. You can also configure GeoChat not to broadcast its messages.</p>
<p>So here's the idea: we'll create a group and we'll configure it to send every message to an external service. This service will receive messages like "shopping $20" or "accomodation $300".</p>
<p>So I started coding it and in one hour I got it working! This new tool is called <a href="http://xpenz.heroku.com/">Xpenz</a>.</p>
<p>That shows us how easy is to build some applications on top of GeoChat. In fact, here we are not using much of GeoChat's power, mainly the messaging component. For this you could instead use <a href="http://nuntium.googlecode.com/">Nuntium</a>, but I decided to use GeoChat since a lot of messaging is already configured for me and I also had the authentication problem solved.</p>
<p>The code is in <a href="http://code.google.com/p/xpenz/">Google Code</a>, so it's open source. Let's review the main logic:</p>
<pre>
class TrackController &lt; ApplicationController
  def expense
    name = params[:sender]
    if name.blank?
      head 'bad_request'
    else
      User.track :user =&gt; name, :message =&gt; request.raw_post
      head 'ok'
    end
  end
end
</pre>
<p>So basically we are getting the sender query parameter, which is the GeoChat login name, and if it is present we track the expense by using the request raw post body. And here's User#track:</p>
<pre>
def self.track(options)
    user = User.find_or_create_by_name options[:user]
    pieces = options[:message].split(' ')
    pieces.map!{|x| x.start_with?('$') ? x[1 .. -1] : x}

    numbers = pieces.select{|x| x.float?}
    texts = pieces.select{|x| !x.float?}
    text = texts.join(' ')

    if numbers.length == 0
      user.currency = text
      user.save!
    else
      if numbers.length == 1
        amount = numbers[0].to_f
      else
        amount = numbers.last
        numbers[0 .. -2].reverse.each{|n| text = "#{n} #{text}"}
      end
      Expense.create! :user =&gt; user, :amount =&gt; amount, :reason =&gt; text, :currency =&gt; user.currency
    end
  end
</pre>
<p>So the first line finds or create the user in xpenz for the GeoChat user. Then we split the message in spaces and do some logic do termine whether it's a currency change or an expense track.</p>
<p>The main point here is that I just had to write about 20 lines of code to make it work. Well, maybe 50 because <a href="http://code.google.com/p/xpenz/source/browse/test/functional/track_controller_test.rb">I tested it</a>. <img src='http://weblogs.manas.com.ar/ary/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://weblogs.manas.com.ar/ary/2010/06/17/154/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick way to test many values in ruby</title>
		<link>http://weblogs.manas.com.ar/ary/2010/04/15/quick-way-to-test-many-values-in-ruby/</link>
		<comments>http://weblogs.manas.com.ar/ary/2010/04/15/quick-way-to-test-many-values-in-ruby/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 15:36:13 +0000</pubDate>
		<dc:creator>ary</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://weblogs.manas.com.ar/ary/?p=139</guid>
		<description><![CDATA[Many times we end up having similar tests: same logic but different inputs and expected outputs. For example, suppose we need to test our brand new sqrt function: test "sqrt 1" do assert_equals 1, sqrt(1) end test "sqrt 4" do assert_equals 2, sqrt(4) end test "sqrt 9" do assert_equals 3, sqrt(9) end Here we are [...]]]></description>
			<content:encoded><![CDATA[<p>Many times we end up having similar tests: same logic but different inputs and expected outputs. For example, suppose we need to test our brand new sqrt function:</p>
<pre>
test "sqrt 1" do
  assert_equals 1, sqrt(1)
end

test "sqrt 4" do
  assert_equals 2, sqrt(4)
end

test "sqrt 9" do
  assert_equals 3, sqrt(9)
end
</pre>
<p>Here we are dupplicating code, since "assert_equals X, sqrt(Y)" is written all over the place. The naive way to refactor this is:</p>
<pre>
def assert_sqrt(input, output)
  assert_equals output, sqrt(input)
end

test "sqrt 1" do
  assert_sqrt 1, 1
end

test "sqrt 4" do
  assert_sqrt 4, 2
end

test "sqrt 9" do
  assert_sqrt 9, 3
end
</pre>
<p>Much better.</p>
<p>Some languages provide tools to deal with this problem in a nicer way. In C# you can do this:</p>
<pre>
[Test]
public void TestSqrt(
  Values(
    new int[] { 1, 1 },
    new int[] { 4, 2 },
    new int[] { 9, 3 }
    ) int[] values) {
  Assert.Equals(values[1], Sqrt(values[0]));
}
</pre>
<p>So here we are supplying a set of values for our test. (maybe not much nicer, but the code duplication is gone)</p>
<p>The thing I like most about ruby is that the language gives you the tools to get the most out of your code so you don't end up inventing classes, attributes or whatever just to make something as simple as supplying many values to a test.</p>
<p>Here's a better way to do it in ruby:</p>
<pre>
[[1, 1], [4, 2], [9, 3]].each do |values|
  test "sqrt #{values[0]}"
    assert_equal values[1], sqrt(values[0])
  end
end
</pre>
<p>Very good!</p>
<p>What makes this possible?</p>
<ol>
<li>Ruby lets you define code that will be executed at the class definition level</li>
<li>Ruby lets you define methods dynamically (here the test function defines a "test_..." method)</li>
</ol>
<p>Those two particularities makes the language really nice to work with.</p>
<p>Oh, but wait, there's one more thing. I just found out I can do |input, output| in that last piece of code. It seems that if you iterate an array of arrays, you can specify many arguments to the given block and the i-th argument will match the i-th element of the array, so you don't end up doing values[0] and values[1], which obfuscates the meaning of our code. Thanks again, ruby!</p>
<p>So, here's the final code:</p>
<pre>
[[1, 1], [4, 2], [9, 3]].each do |input, output|
  test "sqrt #{input}"
    assert_equal output, sqrt(input)
  end
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://weblogs.manas.com.ar/ary/2010/04/15/quick-way-to-test-many-values-in-ruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>String concatenation in ruby</title>
		<link>http://weblogs.manas.com.ar/ary/2010/02/22/string-concatenation-in-ruby/</link>
		<comments>http://weblogs.manas.com.ar/ary/2010/02/22/string-concatenation-in-ruby/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 14:16:01 +0000</pubDate>
		<dc:creator>ary</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://weblogs.manas.com.ar/ary/?p=133</guid>
		<description><![CDATA[I just found out the difference between += and &#60;&#60; when used for a string. irb(main):001:0&#62; str = 'chan' =&#62; "chan" irb(main):002:0&#62; str.object_id =&#62; 69952758899780 irb(main):003:0&#62; str += 'ged' =&#62; "changed" irb(main):004:0&#62; str.object_id =&#62; 69952758848800 irb(main):005:0&#62; str &#60;&#60; ', now not' =&#62; "changed, now not" irb(main):006:0&#62; str.object_id =&#62; 69952758848800 So I think that basically you [...]]]></description>
			<content:encoded><![CDATA[<p>I just found out the difference between += and &lt;&lt; when used for a string.</p>
<pre>irb(main):001:0&gt; str = 'chan'
=&gt; "chan"
irb(main):002:0&gt; str.object_id
=&gt; 69952758899780
irb(main):003:0&gt; str += 'ged'
=&gt; "changed"
irb(main):004:0&gt; str.object_id
=&gt; 69952758848800
irb(main):005:0&gt; str &lt;&lt; ', now not'
=&gt; "changed, now not"
irb(main):006:0&gt; str.object_id
=&gt; 69952758848800</pre>
<p>So I think that basically you should never use += for strings, unless you really want to hurt the garbage collector.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblogs.manas.com.ar/ary/2010/02/22/string-concatenation-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

