<?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/"
	>

<channel>
	<title>Machines</title>
	<atom:link href="http://www.trampolinesystems.com/blog/machines/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.trampolinesystems.com/blog/machines</link>
	<description>Ideas, thoughts and observations from Trampoline's technical brains</description>
	<pubDate>Mon, 17 Aug 2009 15:29:18 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Open source term extraction</title>
		<link>http://www.trampolinesystems.com/blog/machines/2009/08/17/open-source-term-extraction/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2009/08/17/open-source-term-extraction/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 09:27:20 +0000</pubDate>
		<dc:creator>david</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=194</guid>
		<description><![CDATA[This is just a quick announcement to let people know that we&#8217;ve open sourced our JRuby library for term extraction. You can get the code from my github page.
Unlike a lot of term extraction libraries, this doesn&#8217;t take any stance as to the &#8220;significance&#8221; of the terms it extracts. It&#8217;s purely about looking at the [...]]]></description>
			<content:encoded><![CDATA[<p>This is just a quick announcement to let people know that we&#8217;ve open sourced our JRuby library for term extraction. You can get the code from <a href="http://github.com/DRMacIver/term-extractor">my github page</a>.</p>
<p>Unlike a lot of term extraction libraries, this doesn&#8217;t take any stance as to the &#8220;significance&#8221; of the terms it extracts. It&#8217;s purely about looking at the syntax and determining where good boundaries for terms are. There are a couple reasons for this, but basically we&#8217;ve found that it&#8217;s more effective to separate the two steps and makes it easier to tinker around with them independently. The criteria for &#8220;interestingness&#8221; of terms seem to be largely distinct from those for terms which simply make sense linguistically. So we have a two stage pipeline, one which extracts semantically meaningful terms and one which determines what terms are actually interesting in the context of the document. The second step is much more complicated, and we&#8217;re not open sourcing that (yet? probably not any time soon, if ever. Even if we wanted to, it relies on a lot more global information across the document corpus and so is very tied in with how SONAR operates, making it much harder to isolate).</p>
<p>So, how does it work? Black magic and voodoo!</p>
<p>Actually, no. It&#8217;s pretty straightforward. It builds on top of the excellent <a href="http://opennlp.sourceforge.net/">OpenNLP</a> library, using its tools for part of speech tagging, sentence splitting (a much harder problem than you&#8217;d imagine) and phrase chunking. It&#8217;s currently a rules based system on top of there, as while you&#8217;re figuring things out it makes much more sense to stick with something so easily fine tunable. Our expectation is that we&#8217;ll gradually start replacing bits of it with machine learning based techniques as we start to hit the limitations of a rules based system, but for now it&#8217;s working pretty well. </p>
<p>Let&#8217;s have an example. If we feed the second paragraph of this post into the term extractor, we get the following terms back:</p>
<pre>
term extraction libraries
stance
terms
syntax
good boundaries
couple reasons
two steps
steps
criteria
interestingness
sense
two stage pipeline
stage pipeline
semantically meaningful terms
context
context of the document
document
second step
open sourcing
time
document corpus
SONAR
</pre>
<p>Hope you find this useful. Let us know if you build anything cool with it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2009/08/17/open-source-term-extraction/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Open sourcing Pearson&#8217;s Correlation calculations</title>
		<link>http://www.trampolinesystems.com/blog/machines/2009/04/22/open-sourcing-pearsons-correlation-calculations/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2009/04/22/open-sourcing-pearsons-correlation-calculations/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 16:44:01 +0000</pubDate>
		<dc:creator>david</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=192</guid>
		<description><![CDATA[As you might recall, I did some articles on calculating Pearson&#8217;s in SQL.
It turns out that this is a hilariously bad idea. The performance you get for it is terrible when the numbers get large. Switching to PostgreSQL seemed to help a bit here, but even then the numbers are not great (and we still [...]]]></description>
			<content:encoded><![CDATA[<p>As you might recall, I did some articles on calculating Pearson&#8217;s in SQL.</p>
<p>It turns out that this is a hilariously bad idea. The performance you get for it is <em>terrible</em> when the numbers get large. Switching to PostgreSQL seemed to help a bit here, but even then the numbers are not great (and we still aren&#8217;t planning on a port to PostgreSQL anyway). So we needed to find a better solution. Doing it in memory would be fast, but it would just fall over on a large dataset.</p>
<p>Anyway, after some tinkering around I came up with a slightly unholy solution. It&#8217;s a mix of bash, awk, standard unix tools and Java (the Java parts may be rewritten in something else later). The design is such that much of the heavy lifting is offloaded to sort, which is offline so doesn&#8217;t need to load the whole dataset into memory, and processes things in a line oriented manner. This lets it get by with a very reasonable memory usage and, in my fairly informal tests, to perform about 50 times faster than the SQL version.</p>
<p>We&#8217;re releasing the code under a BSD license and making it  <a href="http://github.com/DRMacIver/binary-pearsons/tree/master">available on github.</a> It&#8217;s in a bit of a rough state at the moment, but is usable as is.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2009/04/22/open-sourcing-pearsons-correlation-calculations/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ActiveRecord-JDBC plugin for working with MySQL master-slave configurations</title>
		<link>http://www.trampolinesystems.com/blog/machines/2009/03/20/activerecord-jdbc-plugin-for-working-with-mysql-master-slave-configurations/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2009/03/20/activerecord-jdbc-plugin-for-working-with-mysql-master-slave-configurations/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 12:35:16 +0000</pubDate>
		<dc:creator>mccraig</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=186</guid>
		<description><![CDATA[here&#8217;s a little plugin for ActiveRecord-JDBC which enables simple use of MySQL master-slave configurations
active-record-jdbc-mysql-master-slave
]]></description>
			<content:encoded><![CDATA[<p>here&#8217;s a little plugin for ActiveRecord-JDBC which enables simple use of MySQL master-slave configurations</p>
<p><a href="http://github.com/mccraigmccraig/active-record-jdbc-mysql-master-slave">active-record-jdbc-mysql-master-slave</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2009/03/20/activerecord-jdbc-plugin-for-working-with-mysql-master-slave-configurations/feed/</wfw:commentRss>
		</item>
		<item>
		<title>type discussion on irc (my eyez)</title>
		<link>http://www.trampolinesystems.com/blog/machines/2009/02/05/type-discussion-on-irc/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2009/02/05/type-discussion-on-irc/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 18:07:14 +0000</pubDate>
		<dc:creator>jan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=163</guid>
		<description><![CDATA[A java programmer, a scala dev and a ruby guy meet on #irc. Says the java guy to the&#8230; wait, this is not the beginning of a joke.

jan: Map&#60;String,Map&#60;String,String&#62;&#62;  argggghh
thepete: mmm, readable code, yummy
David: Map&#60;String, Map&#60;String, String&#62;&#62; is perfectly reasonable. :)
       The real problem is that Java makes [...]]]></description>
			<content:encoded><![CDATA[<p>A java programmer, a scala dev and a ruby guy meet on #irc. Says the java guy to the&#8230; wait, this is not the beginning of a joke.</p>
<pre>
jan: Map&lt;String,Map&lt;String,String&gt;&gt;  argggghh
thepete: mmm, readable code, yummy
David: Map&lt;String, Map&lt;String, String&gt;&gt; is perfectly reasonable. :)
       The real problem is that Java makes you declare it twice.
jan: Map&lt;String, Map&lt;String, Object&gt;&gt; m =
       new HashMap&lt;String, Map&lt;String, Object&gt;&gt;();
mccraig: stop that !
mccraig: my eyez
David: val m = new HashMap[String, Map[String, Object]]
thepete: ze goggles;
David: or val m = ne wHashMap[(String, String), Object] if you prefer. :)
jan: what type will m have? Map?
David: val m : Map[(String, String), Object] = new HashMap
mccraig: m = {}
David: m["1"] = "stuff"; m[1] # Why is this returning nil??? :(
mccraig: yeah i know, but whatever
jan: MapWithIndifferentAccess
mccraig: my eyez hurt less
David: my eyez weep
mccraig: u can get eyedrops for that
David: You can get gogglez. :-)
jan: can i blog this? :)
</pre>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/uE9Dgp4zlPg&#038;hl=en&#038;fs=1&#038;autoplay=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/uE9Dgp4zlPg&#038;hl=en&#038;fs=1&#038;autoplay=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2009/02/05/type-discussion-on-irc/feed/</wfw:commentRss>
		</item>
		<item>
		<title>PFY Wanted!</title>
		<link>http://www.trampolinesystems.com/blog/machines/2009/01/29/pfy-wanted/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2009/01/29/pfy-wanted/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 18:39:43 +0000</pubDate>
		<dc:creator>jon</dc:creator>
		
		<category><![CDATA[Business]]></category>

		<category><![CDATA[Job]]></category>

		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=158</guid>
		<description><![CDATA[Trampoline are looking to hire a PFY! Working as part of our engineering team, you&#8217;ll be helping us grow our infrastructure and supporting a mixture of sales staff, executives and developers in their day-to-day operations. This is a junior-to-mid-level position that would be ideal for a graduate with 1-2 yrs experience who&#8217;s keen to learn [...]]]></description>
			<content:encoded><![CDATA[<p>Trampoline are looking to hire a PFY! Working as part of our engineering team, you&#8217;ll be helping us grow our infrastructure and supporting a mixture of sales staff, executives and developers in their day-to-day operations. This is a junior-to-mid-level position that would be ideal for a graduate with 1-2 yrs experience who&#8217;s keen to learn quickly.</p>
<p>For more details and how to apply, check out http://www.trampolinesystems.com/jobs</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2009/01/29/pfy-wanted/feed/</wfw:commentRss>
		</item>
		<item>
		<title>java signed types fail</title>
		<link>http://www.trampolinesystems.com/blog/machines/2009/01/29/java-signed-types-fail/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2009/01/29/java-signed-types-fail/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 18:16:19 +0000</pubDate>
		<dc:creator>jan</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[fail]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=142</guid>
		<description><![CDATA[Ok, another fail post, this time regarding java.
Remember, Java has only signed types (int, byte, short, long) - char is the only exception.
WTF?
James Gosling says (source):
Quiz any C developer about unsigned, and pretty soon you discover that almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is.
Things like that made C [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, another fail post, this time regarding java.</p>
<p>Remember, Java has only signed types (int, byte, short, long) - char is the only exception.</p>
<p>WTF?</p>
<p>James Gosling says (<a href="http://www.gotw.ca/publications/c_family_interview.htm">source</a>):</p>
<blockquote><p>Quiz any C developer about unsigned, and pretty soon you discover that almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is.<br />
Things like that made C complex. The language part of Java is, I think, pretty simple.</p></blockquote>
<p>Ok, so he is basically saying that J. Random Developer is too stupid to care about differences in signedness, and decided to make them all signed, maybe for consistency reasons or who knows. Sometimes you don&#8217;t care about signed variables. Say for example you&#8217;re dealing with any sort of  decoding/encoding problems (like network protocols). Now you have to make sure that you don&#8217;t trip over sign problems (esp. with implicit casts). Here&#8217;s a snippet from the JRuby codebase (base64 decoding routines):</p>
<pre>   private static byte safeGet(ByteBuffer encode) {
     return encode.hasRemaining() ? encode.get() : 0;
   }
   ...
   int s = safeGet(encode);
   while (((a = b64_xtable[s]) == -1) &amp;&amp; encode.hasRemaining()) {
      // do something
   }</pre>
<p>In Java, a byte can have a value from -128 to 127. This code above works fine, except when you feed it data which is not just in the range of displayable ascii characters, because the variable &#8220;s&#8221; will then potentially be negative and cause an ArrayOutOfBoundsException. So the general recommendation is to use the next bigger signed type (short instead of byte, long instead of int). If you&#8217;re using someone else&#8217;s API (java.nio.ByteBuffer in this case) you don&#8217;t have the choice and therefore you have to be extra careful when using it. In this case the right thing to do is a bitwise AND with 0xFF to strip the signed part of the int.</p>
<pre>  while (((a = b64_xtable[s &amp; 0xff]) == -1) &amp;&amp; encode.hasRemaining()) { // do something }</pre>
<p>Here&#8217;s the JRuby <a href="http://jira.codehaus.org/browse/JRUBY-3340">bug report</a> and a general <a href="http://www.darksleep.com/player/JavaAndUnsignedTypes.html">introduction</a> to java sign issues by Sean R. Owens.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2009/01/29/java-signed-types-fail/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Porting Pearsons to Postgres. Performance?</title>
		<link>http://www.trampolinesystems.com/blog/machines/2009/01/29/porting-pearsons-to-postgres-performance/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2009/01/29/porting-pearsons-to-postgres-performance/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 14:53:52 +0000</pubDate>
		<dc:creator>david</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=140</guid>
		<description><![CDATA[I&#8217;ve uploaded a version of the Pearson&#8217;s Coefficient code which runs on postgresql. You can download it here.I wrote this as an experiment to see if Postgres could help us with some of our MySQL performance woes.
Some brief experimentation suggests that once you fix PostgreSQL&#8217;s ridiculous default configuration the performance story is relatively happy. At [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve uploaded a version of the <a href="http://www.trampolinesystems.com/blog/machines/2008/11/23/calculating-pearsons-corellation-coefficient-in-sql/">Pearson&#8217;s Coefficient code</a> which runs on postgresql. You can download it <a href="http://code.trampolinesystems.com/pearsons_pg.rb">here</a>.I wrote this as an experiment to see if Postgres could help us with some of our MySQL performance woes.</p>
<p>Some brief experimentation suggests that once you fix PostgreSQL&#8217;s ridiculous default configuration the performance story is relatively happy. At small sizes MySQL is moderately faster, but as the sizes get large PostgreSQL seems to take the lead. I don&#8217;t have any sort of formal benchmark yet: This needs much more testing before I can definitively claim either is faster than the other, but for now the signs in favour of PostgreSQL are promising.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2009/01/29/porting-pearsons-to-postgres-performance/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Has Many + non default primary key loads incorrect data in Rails 2.2.2</title>
		<link>http://www.trampolinesystems.com/blog/machines/2009/01/29/has-many-non-default-primary-key-loads-incorrect-data-in-rails-222/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2009/01/29/has-many-non-default-primary-key-loads-incorrect-data-in-rails-222/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 12:16:34 +0000</pubDate>
		<dc:creator>emma</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[activerecord]]></category>

		<category><![CDATA[association]]></category>

		<category><![CDATA[habtm]]></category>

		<category><![CDATA[has_many]]></category>

		<category><![CDATA[preload]]></category>

		<category><![CDATA[primary_key]]></category>

		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=135</guid>
		<description><![CDATA[ 
I found an interesting bug in Rails 2.2.2 yesterday. I couldn&#8217;t find a similar bug on the rails lighthouse so created a new ticket. What was most interesting though, was how quick the rails core team picked up the bug and assigned it to  someone. 
It turns out that the bug had already been fixed in [...]]]></description>
			<content:encoded><![CDATA[<p> </p>
<p>I found an interesting bug in Rails 2.2.2 yesterday. I couldn&#8217;t find a similar bug on the rails lighthouse so created a new <a href="http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1809-has-many-non-default-primary-key-loads-incorrect-data#ticket-1809-3">ticket</a>. What was most interesting though, was how quick the rails core team picked up the bug and assigned it to  someone. </p>
<p>It turns out that the bug had already been fixed in the current master branch of the rails git repo, though apparently no one had noticed it&#8217;s existence because I can&#8217;t find any references to this anywhere. I guess the fix in activerecord, which is almost identical to my fix below, will form part of the next release whenever that is.</p>
<p>I assume this is probably also the case for other has_* relationships, but have not verified.</p>
<p>I have a has_many association from class <strong>Foo</strong> to class <strong>Bar</strong>, where, for this specific relationship, the primary key on <strong>Foo</strong> is not <em>id</em>, nor is the foreign key on <strong>Bar</strong> <em>id</em>.</p>
<pre><code><span class="keywords">class</span> Foo
  has_many, <span class="symbol">:bars</span>, <span class="symbol">:primary_key</span> =&gt; <span class="string">'a_non_standard_key_name'</span>, <span class="symbol">:foreign_key</span> =&gt; <span class="string">'another_non_standard_key_name'</span>
<span class="keywords">end</span>
</code></pre>
<p>The relationship is one way, I have no need to navigate from <strong>Bar</strong> back to <strong>Foo</strong>, but only call <em>a_foo.bars</em>.</p>
<p>This works fine when working with a single object, but breaks down when you want to do eager association preloading to avoid n+1 query problem of loading <em>bars</em> for many <em>foos</em>.</p>
<p>When performing the following you find that</p>
<pre><code>f = Foo.find <span class="symbol">:all</span>, <span class="symbol">:include</span> =&gt; <span class="symbol">:Bar</span>
f.bars = [SOMETHING_UNEXPECTED]
</code></pre>
<p>The reason is that ActiveRecord creates the preloading query based on the default primary key of <strong>Foo</strong> (normally <em>id</em>).</p>
<p>It queries for <strong>Bar</strong>.<em>another_non_standard_key_name</em> matching <strong>Foo</strong>.<em>id</em> not <strong>Foo</strong>.<em>a_non_standard_key_name</em></p>
<p>This causes seriously unexpected behaviour, and could easily go unnoticed since no errors are thrown.</p>
<p>I have found the hook in ActiveRecord where this functionality should be included and monkey patched for my system, because I need it now. I can&#8217;t vouch for it&#8217;s correctness, but we have many many specs for our product and none of them have broken because of this.</p>
<p>I&#8217;m running frozen rails 2.2.2</p>
<p>vendor/activerecord/lib/active_record/association_preload.rb, line 221</p>
<p>Change</p>
<pre><code>primary_key_name = reflection.through_reflection_primary_key_name
</code></pre>
<p>to</p>
<pre><code>primary_key_name = reflection.through_reflection_primary_key_name || reflection.options[<span class="symbol">:primary_key</span>]</code></pre>
<pre></pre>
<p>Hope this helps someone!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2009/01/29/has-many-non-default-primary-key-loads-incorrect-data-in-rails-222/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Yet another MySQL Fail</title>
		<link>http://www.trampolinesystems.com/blog/machines/2009/01/26/yet-another-mysql-fail/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2009/01/26/yet-another-mysql-fail/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 15:20:39 +0000</pubDate>
		<dc:creator>david</dc:creator>
		
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=125</guid>
		<description><![CDATA[mysql&#62; create table stuff (name varchar(32));
Query OK, 0 rows affected (0.24 sec)
mysql&#62; insert into stuff values (&#8217;foo&#8217;), (&#8217;1&#8242;), (&#8217;0&#8242;);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql&#62; select * from stuff;
+&#8212;&#8212;+
&#124; name &#124;
+&#8212;&#8212;+
&#124; foo  &#124;
&#124; 1    &#124;
&#124; 0    &#124;
+&#8212;&#8212;+
3 rows in set (0.00 sec)
mysql&#62; delete from stuff where name = 0;
Query OK, [...]]]></description>
			<content:encoded><![CDATA[<p>mysql&gt; create table stuff (name varchar(32));<br />
Query OK, 0 rows affected (0.24 sec)</p>
<p>mysql&gt; insert into stuff values (&#8217;foo&#8217;), (&#8217;1&#8242;), (&#8217;0&#8242;);<br />
Query OK, 3 rows affected (0.00 sec)<br />
Records: 3  Duplicates: 0  Warnings: 0</p>
<p>mysql&gt; select * from stuff;<br />
+&#8212;&#8212;+<br />
| name |<br />
+&#8212;&#8212;+<br />
| foo  |<br />
| 1    |<br />
| 0    |<br />
+&#8212;&#8212;+<br />
3 rows in set (0.00 sec)</p>
<p>mysql&gt; delete from stuff where name = 0;<br />
Query OK, 2 rows affected (0.09 sec)</p>
<p>mysql&gt; select * from stuff;<br />
+&#8212;&#8212;+<br />
| name |<br />
+&#8212;&#8212;+<br />
| 1    |<br />
+&#8212;&#8212;+<br />
1 row in set (0.00 sec)</p>
<p>mysql&gt; create table stuff (name varchar(32));<br />
Query OK, 0 rows affected (0.24 sec)</p>
<p>mysql&gt; insert into stuff values (&#8217;foo&#8217;), (&#8217;1&#8242;), (&#8217;0&#8242;);<br />
Query OK, 3 rows affected (0.00 sec)<br />
Records: 3  Duplicates: 0  Warnings: 0</p>
<p>mysql&gt; select * from stuff;<br />
+&#8212;&#8212;+<br />
| name |<br />
+&#8212;&#8212;+<br />
| foo  |<br />
| 1    |<br />
| 0    |<br />
+&#8212;&#8212;+<br />
3 rows in set (0.00 sec)</p>
<p>mysql&gt; delete from stuff where name = 0;<br />
Query OK, 2 rows affected (0.09 sec)</p>
<p>mysql&gt; select * from stuff;<br />
+&#8212;&#8212;+<br />
| name |<br />
+&#8212;&#8212;+<br />
| 1    |<br />
+&#8212;&#8212;+<br />
1 row in set (0.00 sec)</p>
<p>mysql&gt; WTF????<br />
-&gt; ;<br />
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near &#8216;WTF????&#8217; at line 1</p>
<p>So, what&#8217;s going on here? I said to delete everything where the name was 0, but it deleted the row &#8216;foo&#8217;.</p>
<p>The following might help:</p>
<p>mysql&gt; create table more_stuff(id int);<br />
Query OK, 0 rows affected (0.19 sec)</p>
<p>mysql&gt; insert into more_stuff values(&#8217;foo&#8217;);<br />
Query OK, 1 row affected, 1 warning (0.00 sec)</p>
<p>mysql&gt; select * from more_stuff;<br />
+&#8212;&#8212;+<br />
| id   |<br />
+&#8212;&#8212;+<br />
|    0 |<br />
+&#8212;&#8212;+<br />
1 row in set (0.00 sec)</p>
<p>When you try to use a string as an integer in MySQL, it takes non numeric strings and turns them into zero. So when you test name = 0, it converts name into an integer and turns that into 0. Consequently strings which can&#8217;t be parsed as an integer result in true for this test.</p>
<p>At this point I would rant about how mindbogglingly stupid this behaviour is, but I don&#8217;t think I can really be bothered.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2009/01/26/yet-another-mysql-fail/feed/</wfw:commentRss>
		</item>
		<item>
		<title>JRuby + Clojure&#8217;s Immutable Data Structures = Easy to maintain, application data-model.</title>
		<link>http://www.trampolinesystems.com/blog/machines/2009/01/22/jruby-clojure/</link>
		<comments>http://www.trampolinesystems.com/blog/machines/2009/01/22/jruby-clojure/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 15:57:44 +0000</pubDate>
		<dc:creator>daniel</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.trampolinesystems.com/blog/machines/?p=51</guid>
		<description><![CDATA[Implementing an application with rich data-model which can be updated by multiple UI controls, many concurrent threads with undo/redo functionality may be somewhat cumbersome. In order to ease this task, the functional programming paradigm with the immutable data structures turned out to be useful.
Because all good developers are lazy, one should seek for reuse rather [...]]]></description>
			<content:encoded><![CDATA[<p>Implementing an application with rich data-model which can be updated by multiple UI controls, many concurrent threads with undo/redo functionality may be somewhat cumbersome. In order to ease this task, the functional programming paradigm with the immutable data structures turned out to be useful.</p>
<p>Because all good developers are lazy, one should seek for reuse rather than reinventing required tools, especially when there is good existing one. I tried to follow that path. Since we are using JRuby as our language of choice here at Trampoline, I decided to look more closely at clojure’s immutable data structures. It is straightforward to use Java classes from JRuby which is described in many places on the web already (<a title="Calling Java from JRuby" href="http://wiki.jruby.org/wiki/Calling_Java_from_JRuby">here</a>, <a title="Using Java Classes in JRuby" href="http://blogs.sun.com/coolstuff/entry/using_java_classes_in_jruby">here</a> &amp; <a title="JRuby and the Java Platform" href="http://java.sun.com/developer/technicalArticles/scripting/jruby/">here</a>). The unknown to me was how can I use clojure’s objects from Jruby. Apparently clojure data structures are delivered as pre-compiled java classes and no runtime interpretation/compilation of clojure scripts is needed. The task turned out to be very easy.</p>
<p>The simple implementation of graph data structure with no deletion functionality looks as simple as:</p>
<div>
<div style="background-color: #0D1020">
<a href="http://www.trampolinesystems.com/blog/machines/wp-content/uploads/2009/01/basic_graph1.png"><img class="alignleft size-medium wp-image-122" title="basic_graph1" src="http://www.trampolinesystems.com/blog/machines/wp-content/uploads/2009/01/basic_graph1-300x288.png" alt="basic_graph1" width="300" height="288" /></a>
</div>
<p> <br />
 </p>
<p>In order to have Clojure collections look more like Ruby ones one can define aliases for their methods:</p>
<p><a href="http://www.trampolinesystems.com/blog/machines/wp-content/uploads/2009/01/persistent_map.png"></a></p>
<div style="background-color: #0D1020"><a href="http://www.trampolinesystems.com/blog/machines/wp-content/uploads/2009/01/persistent_map.png"><img class="alignnone size-medium wp-image-93" title="persistent_map" src="http://www.trampolinesystems.com/blog/machines/wp-content/uploads/2009/01/persistent_map-300x276.png" alt="persistent_map" width="300" height="276" /></a></div>
</div>
<p> </p>
<p>Unfortunately (or fortunately due to different contract) we can not do it with all the methods. Particularly with mutating ones. That’s because Ruby’s <code>=</code> (assign operator) semantics is to return the value being assign. It is analogous to <code>[]=</code> method as well. So even if we redefine the <code>[]=(key, val)</code> method so that the method returns the updated version of the collection, the Ruby interpreter will step into the scene and wrap the whole method, so that it eventually returns val. Anyway, whether this is good or bad is the topic for a whole other post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.trampolinesystems.com/blog/machines/2009/01/22/jruby-clojure/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
