<?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>yonkeltron &#187; Ruby</title>
	<atom:link href="http://yonkeltron.com/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://yonkeltron.com</link>
	<description>Temporary Exile</description>
	<lastBuildDate>Fri, 16 Jul 2010 18:45:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>newhaven.rb hackfest tomorrow!</title>
		<link>http://yonkeltron.com/2010/06/30/newhaven-rb-hackfest-tomorrow/</link>
		<comments>http://yonkeltron.com/2010/06/30/newhaven-rb-hackfest-tomorrow/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 14:00:54 +0000</pubDate>
		<dc:creator>Jonathan Magen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://yonkeltron.com/?p=673</guid>
		<description><![CDATA[Tomorrow, in New Haven, CT will be the &#8220;Ruby, White and Blue&#8221; Hackfest run by newhaven.rb. We&#8217;ll be working on a few projects including the group&#8217;s site and most likely some Prawn and ScosugBot stuff. Beginners and people interested in learning are more than welcome and we hope to have some excellent projects for people ]]></description>
			<content:encoded><![CDATA[<p>Tomorrow, in New Haven, CT will be the &#8220;Ruby, White and Blue&#8221; Hackfest run by newhaven.rb. We&#8217;ll be working on a few projects including <a href="http://github.com/yonkeltron/NHV-Ruby-site">the group&#8217;s site</a> and most likely some <a href="http://github.com/sandal/prawn">Prawn</a> and <a href="http://github.com/yonkeltron/scosugbot">ScosugBot</a> stuff. Beginners and people interested in learning are more than welcome and we hope to have some excellent projects for people to get started on.</p>
<p>Fill out the <a href="http://is.gd/d9ZiB">RSVP form</a> and we&#8217;ll meet at 6pm EST at <a href="http://www.bluestatecoffee.com/">Blue State Coffee</a> on Thursday,  July 1st. Bring a computer and let&#8217;s write some code.</p>
<p><iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=Blue+State+Coffee+-+New+Haven,+New+Haven,+CT&amp;sll=41.306075,-72.931894&amp;sspn=0.009333,0.01929&amp;ie=UTF8&amp;hq=Blue+State+Coffee+-&amp;hnear=New+Haven,+Connecticut&amp;t=h&amp;cid=8790853015135628419&amp;ll=41.319076,-72.921238&amp;spn=0.022562,0.036478&amp;z=14&amp;iwloc=A&amp;output=embed"></iframe><br /><small><a href="http://maps.google.com/maps?f=q&amp;source=embed&amp;hl=en&amp;geocode=&amp;q=Blue+State+Coffee+-+New+Haven,+New+Haven,+CT&amp;sll=41.306075,-72.931894&amp;sspn=0.009333,0.01929&amp;ie=UTF8&amp;hq=Blue+State+Coffee+-&amp;hnear=New+Haven,+Connecticut&amp;t=h&amp;cid=8790853015135628419&amp;ll=41.319076,-72.921238&amp;spn=0.022562,0.036478&amp;z=14&amp;iwloc=A" style="color:#0000FF;text-align:left">View Larger Map</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://yonkeltron.com/2010/06/30/newhaven-rb-hackfest-tomorrow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Ruby DSL</title>
		<link>http://yonkeltron.com/2010/05/13/creating-a-ruby-dsl/</link>
		<comments>http://yonkeltron.com/2010/05/13/creating-a-ruby-dsl/#comments</comments>
		<pubDate>Fri, 14 May 2010 02:44:43 +0000</pubDate>
		<dc:creator>Jonathan Magen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://yonkeltron.com/?p=653</guid>
		<description><![CDATA[Tons of people in the Ruby community go on and on about domain-specific languages (abbreviated DSL) and how wonderful they are. In most cases, I agree with them. I began to wonder how I could go about leveraging Ruby&#8217;s awesomely-flexible syntax to create my own DSL. To illustrate my quest, I have written this article. ]]></description>
			<content:encoded><![CDATA[<p>Tons of people in the Ruby community go on and on about <a href="http://en.wikipedia.org/wiki/Domain_Specific_Language">domain-specific languages (abbreviated DSL)</a> and how wonderful they are. In most cases, I agree with them. I began to wonder how I could go about leveraging Ruby&#8217;s awesomely-flexible syntax to create my own DSL. To illustrate my quest, I have written this article. It assumes you know Ruby. The example details are completely fictitious and just contrived enough to be interesting. I promise, the code will be the main focus and I will link/point to other resources which might be helpful to budding DSL designers like myself.</p>
<p><strong>Problem</strong></p>
<p>The Dream Castle Architectural Firm (D-CAF, among friends) wants a tool which it can use for very high-level prototyping of custom homes. They need it to be understandable by both computers and humans. It only needs to keep track of the following things:</p>
<ul>
<li>Houses &#8211; Each house has a name</li>
<li>Floors &#8211; Each house has multiple floors. Each floor has a number</li>
<li>Rooms &#8211; Each floor has multiple rooms and each room has a type</li>
</ul>
<p>The only other requirement is that the DSL be translatable to plain English so that they can show it to customers. No problem.</p>
<p><strong>Solution</strong></p>
<p>The DSL for the high-level specification of custom houses will look like the following:</p>
<pre>CustomHouse.build :home do
  floor(1) {
    room :den
    room :kitchen
  }

  floor(2) {
    room :bedroom
    room :bathroom
  }
end</pre>
<p>That&#8217;s it. You specify that a house should be built, that it has a name, some floors and each floor has some rooms. Simple, easy and 100% pure Ruby.  Notice the cunning usage of both do/end and bracket notation for defining blocks. The outer block passed to <code>CustomHouse#build</code> uses do/end syntax while the blocks passed to <code>House#floor</code> use the bracket syntax. These could easily be reversed (or combined or whatever) but it makes it look pretty and helps to visually differentiate things so that you (the developer) and the user (the architect) can things more clearly. Plus, when you print the output (calling <code>to_s</code> on the instance of <code>House</code> which gets returned), you get the following wonderful text:</p>
<pre>House named home has 2 floors.
Floor 1 has 2 rooms (den, kitchen)
Floor 2 has 2 rooms (bedroom, bathroom)</pre>
<p>It&#8217;s a small house, don&#8217;t be a wiseacre. So, how can such a DSL be built?</p>
<p><strong>Implementation</strong></p>
<p>Let&#8217;s write the implementation for this together.  First, we&#8217;re going to start of with a module named <code>CustomHouse</code>.  In Ruby, modules are just classes so we&#8217;ll define a class method called <code>build</code> which will behave like a factory method.</p>
<pre>module CustomHouse
  def self.build(name, &amp;block)
    house = House.new(name)
    house.instance_eval(&amp;block)
    return house
  end
end</pre>
<p>As you can see, the method takes two params, a name and a block. The first thing that it does is create an instance of the House class (which we have not yet defined) passing in the name parameter. Second it calls <a href="http://ruby-doc.org/core-1.8.7/classes/Object.html#M000607">instance_eval</a> on the house passing in the block. This ventures into the territory of <a href="http://en.wikipedia.org/wiki/Metaprogramming">metaprogramming</a> which is great fun but beyond the scope of this document, though I am sure others have used it for DSL construction (coincidentally, if you are interested in Ruby metaprogramming, buy <a href="http://amzn.com/1934356476">this book</a>). Suffice it to say that it executes the supplied block in the context of the House instance. Finally, the <code>CustomHouse#build</code> method returns the instance of <code>House</code>.</p>
<p>(There are those who believe that *any* type of eval is fundamentally evil. I have been taught this many times and I try to avoid using eval on an actualy string whenever possible. Still, someone with a better understanding of Ruby internals might be able to better explain if this in any better.)</p>
<p>Next, let&#8217;s define what the code for the <code>House</code> class looks like. As a note, it will be defined in the <code>CustomHouse</code> module, technically making the fully-namespaced name of the class <code>CustomHouse::House</code>.</p>
<pre>class House
  attr_accessor :name, :floors

  def initialize(name = '')
    @name = name.to_s
    @floors = []
  end

  def floor(number, &amp;block)
    fl = Floor.new(number)
    fl.instance_eval(&amp;block)
    @floors &lt; &lt; fl
  end

  def to_s
    str = "House named #{@name} has #{@floors.length} floors.\n"
    @floors.each do |f|
      str &lt;&lt; f.to_s
    end
    str
  end
end</pre>
<p>The above code should appear relatively simple. The House class has only a few methods. First, it has a constructor function which takes a name and a block, setting the name as an instance variable and another instance variable, <code>@floors</code>, which is just an empty array. Next, it has a method called <code>floor</code> which takes a number and a block. The guts of this method should look familiar to you because it mimics almost exactly the <code>build</code> factory method defined on <code>CustomHouse</code>. Finally, it has a <code>to_s</code> method because of the requirement that the DSL be translatable to plain English for clients to check out.</p>
<p>If we can just dwell for a moment on the <code>floor</code> method, notice that, it too, takes a block and uses <code>instance_eval</code>. It then adds the newly-constructed instance of <code>Floor</code> to the array in <code>@floor</code>. Let&#8217;s look at the <code>Floor</code> class now.</p>
<pre>class Floor
  attr_accessor :number, :rooms

  def initialize(number = 0)
    @number = number
    @rooms = []
  end

  def room(type)
    @rooms &lt; &lt; Room.new(type)
  end

  def to_s
    str = "Floor #{@number} has #{@rooms.length} rooms ("
    @rooms.each do |r|
      str += "#{r.type}, "
    end
    str.chop!.chop!
    str += ")\n"
    str
  end
end</pre>
<p>There shouldn&#8217;t be anything confusing about the above code as it doesn&#8217;t use any sort of block eval. In fact, the only thing left to look at is the class for <code>Room</code> which is even less impressive.</p>
<pre>class Room
  attr_reader :type

  def initialize(type)
    @type = type
  end
end</pre>
<p>That&#8217;s it. Seriously, that&#8217;s the entire implementation of the DSL. You pass a block to <code>CustomHouse#build</code> which gets executed in the context of a new instance of <code>House</code>. The block calls the <code>House#floor</code> method with a block which in turn gets executed in the context of a new instance of <code>Floor</code>. The Floor#room method adds new <code>Room</code> instances to the class and that&#8217;s basically it.</p>
<p>Here&#8217;s all the code together with the example:</p>
<pre>module CustomHouse

  def self.build(name, &amp;block)
    house = House.new(name)
    house.instance_eval(&amp;block)
    return house
  end

  class House
    attr_accessor :name, :floors

    def initialize(name = '')
      @name = name.to_s
      @floors = []
    end

    def floor(number, &amp;block)
      fl = Floor.new(number)
      fl.instance_eval(&amp;block)
      @floors &lt;&lt; fl
    end

    def to_s
      str = "House named #{@name} has #{@floors.length} floors.\n"
      @floors.each do |f|
        str &lt;&lt; f.to_s
      end
      str
    end
  end

  class Floor
    attr_accessor :number, :rooms

    def initialize(number = 0)
      @number = number
      @rooms = []
    end

    def room(type)
      @rooms &lt;&lt; Room.new(type)
    end

    def to_s
      str = "Floor #{@number} has #{@rooms.length} rooms ("
      @rooms.each do |r|
        str += "#{r.type}, "
      end
      str.chop!.chop!
      str += ")\n"
      str
    end
  end

  class Room
    attr_reader :type

    def initialize(type)
      @type = type
    end
  end
end

h = CustomHouse.build :home do
  floor(1) {
    room :den
    room :kitchen
  }

  floor(2) {
    room :bedroom
    room :bathroom
  }
end

puts h</pre>
<p>Try running it and see what happens! Then try writing other definitions for custom houses and experience the theoretical joy of the hypothetical architectural firm.</p>
<p><strong>DSL construction techniques</strong></p>
<p>For clarification and context, I&#8217;d like to share some other, smaller examples which build on this technique and demonstrate one more.</p>
<p>Behold, a DSL for feeding Pandas:</p>
<pre>Panda.feed {
  nom :bamboo
  nom :chocolate
}</pre>
<p>The implementation of this is both simple and straightforward.</p>
<pre>class Panda
  def self.feed(&amp;block)
    panda = Panda.new
    panda.instance_eval(&amp;block)
  end

  def nom(food)
    #whatever
  end
end</pre>
<p>Since the block is evaluated in the context of the new <code>Panda</code> instance, it has access to the <code>Panda#nom</code> method. For people deathly afraid of eval, there is this alternative syntax:</p>
<pre>Panda.feed do |p|
  p.nom :bamboo
  p.nom :chocolate
end</pre>
<p>Which is implemented with <code>yield</code> instead of <code>instance_eval</code> like so:</p>
<pre>class Panda
  def self.feed
    yield Panda.new
  end

  def nom(food)
    # whatever
  end
end</pre>
<p>For a wonderful and inspiring treatment of Ruby DSLs and associated patterns, see the <a href="http://mwrc2009.confreaks.com/13-mar-2009-18-10-jive-talkin-dsl-design-and-construction-jeremy-mcanally.html">most-excellent talk on the matter given by Jeremy McAnally at the 2009 Mid West Ruby Conference</a>.</p>
<p><strong>Conclusion</strong></p>
<p>DSLs are a fantastic tool which can help to simplify complicated and repetitive tasks. Ruby is very good for creating DSLs but it is not the only good tool out there. I advise you look into the creation of DSLs with Scala and, the best DSL-creation tool there ever was, Lisp Macros.</p>
<p>I am interested in improving this tutorial for the benefit of those programmers who wish to learn about DSL construction but don&#8217;t know where to start.</p>
]]></content:encoded>
			<wfw:commentRss>http://yonkeltron.com/2010/05/13/creating-a-ruby-dsl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 has custom data attributes</title>
		<link>http://yonkeltron.com/2010/03/25/html5-has-custom-data-attributes/</link>
		<comments>http://yonkeltron.com/2010/03/25/html5-has-custom-data-attributes/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 15:16:35 +0000</pubDate>
		<dc:creator>Jonathan Magen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://yonkeltron.com/?p=627</guid>
		<description><![CDATA[So, I know that the Microformats project has has varying degrees of success in their endeavor to embed data in HTML such that it does not violate web standards.  As John Resig pointed out, others have used things like XML namespacing in XHTML to achieve similar goals. The most notable usages of this technique are ]]></description>
			<content:encoded><![CDATA[<p>So, I know that the <a href="http://microformats.org/">Microformats</a> project has has varying degrees of success in their endeavor to embed data in HTML such that it does not violate web standards.  As <a href="http://ejohn.org/blog/html-5-data-attributes/">John Resig pointed out</a>, others have used things like XML namespacing in XHTML to achieve similar goals. The most notable usages of this technique are most likely to be found in the <a href="http://www.w3.org/TR/xhtml-rdfa-scenarios/">applications</a> of <a href="http://en.wikipedia.org/wiki/RDFa">RDFa</a>. However, when looking at the new <a href="http://blog.solnic.eu/2009/09/08/unobtrusive-javascript-helpers-in-rails-3">unobtrusive JavaScript helpers</a> in the forthcoming Rails 3, I was tipped off to the huge scope of the new data- attributes in <a href="http://html5.org/">HTML5</a>. The custom data- attributes excite me.</p>
<p>In HTML5, including any arbitrary attribute may be included in any element provided that it is prefixed with data- and doesn&#8217;t interfere with the rest of the standard. Anything. So I can do the following and have it be perfectly valid:</p>
<pre>&lt;div data-panda="bamboo"&gt; Whatever &lt;div&gt;</pre>
<p>How awesome is that?</p>
]]></content:encoded>
			<wfw:commentRss>http://yonkeltron.com/2010/03/25/html5-has-custom-data-attributes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails + Merb = Rails 3</title>
		<link>http://yonkeltron.com/2010/03/17/rails-merb-rails-3/</link>
		<comments>http://yonkeltron.com/2010/03/17/rails-merb-rails-3/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 14:33:42 +0000</pubDate>
		<dc:creator>Jonathan Magen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://yonkeltron.com/?p=622</guid>
		<description><![CDATA[I&#8217;m rather excited about this. Saw this talk right here. Oh, and then there&#8217;s this]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m rather excited about this. Saw this talk <a href="http://www.infoq.com/presentations/katz-rails3">right here</a>.</p>
<p>Oh, and then there&#8217;s <a href="http://blog.rubybestpractices.com/posts/gregory/022-rbp-now-open.html">this</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://yonkeltron.com/2010/03/17/rails-merb-rails-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Talks I am willing to give</title>
		<link>http://yonkeltron.com/2009/07/20/talks-i-am-willing-to-give/</link>
		<comments>http://yonkeltron.com/2009/07/20/talks-i-am-willing-to-give/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 13:29:22 +0000</pubDate>
		<dc:creator>Jonathan Magen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://yonkeltron.com/?p=560</guid>
		<description><![CDATA[The following are possible talks I am willing to give at a future SCOSUG meeting. Emacs concurrency (or lack thereof) XSLT for fun and profit Programming with distributed objects in Ruby Unit testing JavaScript That is all]]></description>
			<content:encoded><![CDATA[<p>The following are possible talks I am willing to give at a future <a href="http://scosug.org">SCOSUG</a> meeting.</p>
<ul>
<li>Emacs concurrency (or lack thereof)</li>
<li>XSLT for fun and profit</li>
<li>Programming with distributed objects in Ruby</li>
<li>Unit testing JavaScript</li>
</ul>
<p>That is all.</p>
]]></content:encoded>
			<wfw:commentRss>http://yonkeltron.com/2009/07/20/talks-i-am-willing-to-give/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Can I get a little MapReduce from my Debian people?</title>
		<link>http://yonkeltron.com/2009/07/05/can-i-get-a-little-mapreduce-from-my-debian-people/</link>
		<comments>http://yonkeltron.com/2009/07/05/can-i-get-a-little-mapreduce-from-my-debian-people/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 20:13:17 +0000</pubDate>
		<dc:creator>Jonathan Magen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[paper]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://yonkeltron.com/?p=549</guid>
		<description><![CDATA[Debian is a world-class Linux distribution. It is used on it&#8217;s own for so many applications (desktop, laptop, workstation, handeld, server, etc.) as well as the foundation for so many wonderful projects ((U&#124;K&#124;X)buntu, Maemo, etc.). Personally, I run Debian on my laptop as well as my servers.  In fact, when I went to see about ]]></description>
			<content:encoded><![CDATA[<p>Debian is a world-class Linux distribution. It is used on it&#8217;s own for so many applications (desktop, laptop, workstation, handeld, server, etc.) as well as the foundation for so many wonderful projects ((U|K|X)buntu, Maemo, etc.). Personally, I run Debian on my laptop as well as my servers.  In fact, when I went to see about setting up a little ad-hoc cluster, I was rather disappointed. Though there are a few <a href="http://packages.debian.org/search?keywords=redhat-cluster-suite">clustering tools available</a>, as well as several distributed filesystems (<a href="http://packages.debian.org/search?keywords=gfs2">GFS</a>, <a href="http://packages.debian.org/search?keywords=gluster">GlusterFS</a>, <a href="http://packages.debian.org/search?keywords=ocfs2">OCFS2</a>, and <a href="http://packages.debian.org/search?keywords=lustre">Lustre</a>), shockingly, I could not find any implementation of MapReduce available in the Debian repositories.</p>
<p>For those who might not know, MapReduce is a novel data-processing system developed by Google for internal usage and described in their publication entitled <a href="http://labs.google.com/papers/mapreduce.html"><em>MapReduce: Simplified Data Processing on Large Clusters</em></a>. For the enlightened out there, it should be clear that the name and mechanism are derived from Lisp&#8217;s <code>map</code> and <code>reduce</code> functions. In any case, though Google&#8217;s implementation is proprietary, there have been several implementations based on their paper both written in and geared toward a variety of programming languages. Unfortunately, none of these are available in the Debian repositories. In all fairness, Debian does include <a href="http://couchdb.apache.org/">CouchDB</a> which uses map and reduce functions for generating views. However, it&#8217;s not a solution aimed at sorting and processing huge amounts of data, though it is an interesting and capable piece of software.</p>
<p>So, to try and get things moving, I have filed three Debian RFPs (Request For Package) for a few seperate MapReduce implementations.</p>
<ul>
<li><a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=535861">Hadoop</a> &#8211; Probably the most well-known of the Free/Open Source implementations. Includes a distributed filesystem (HDFS), scaleable distributed database (HBase) and tools to get you going from start to finish. Hadoop is written in Java though it can interoperate with other languages (<a href="http://scala-blogs.org/2008/09/scalable-language-and-scalable.html">Scala</a>, too). It&#8217;s a top-level project of the <a href="http://www.apache.org/">Apache Software Foundation</a> and licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache License 2.0</a> &#8211; <a href="http://hadoop.apache.org/">http://hadoop.apache.org</a></li>
<li><a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=535898">Skynet</a> &#8211; A MapReduce implementation written in Ruby. It&#8217;s designed to be fault-tolerant and distrubuted, just like the big boys. Originally written for use at <a href="http://www.geni.com">Geni.com</a> and licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT License</a> &#8211; <a href="http://skynet.rubyforge.org/">http://skynet.rubyforge.org/</a></li>
<li><a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=535891">Disco</a> &#8211; Though the implementation is itself written in Erlang, thus providing excellent distributed fault-tolerance, Disco jobs can be written in Python. It was <a href="http://research.nokia.com/">developed as an in-house tool for rapid data analysis at Nokia</a> and they seem to be quite keen on it. Disco is licensed under a modified BSD License. Page at <a href="http://discoproject.org/">http://discoproject.org/</a> and code at <a href="http://github.com/tuulos/disco/tree/master">http://github.com/tuulos/disco/tree/master</a></li>
</ul>
<p>Ok, there might be a few objections to my choices. Why did I leave out neat projects like <a href="http://www.gridgain.com/">GridGain</a>, <a href="http://mfisk.github.com/filemap/">FileMap</a> and <a href="http://blog.last.fm/2009/04/06/mapreduce-bash-script">BashReduce</a>? Well, for starters, GridGain is another Java implementation that doesn&#8217;t seem (at least to me) to have the same momentum Hadoop does. FileMap and BashReduce, while novel, useful and fascinating, are not designed for use in networked environments and are therefore unsuitable for cluster situations. So then whey not <a href="http://mapsharp.codeplex.com/">MapSharp</a>? Well, primarily because of all the <a href="http://www.itwire.com/content/view/25954/1231/">Debian Mono debates</a> going on right now (Gnome&#8217;s fail!) . I&#8217;ve done work in C# and it&#8217;s got some neat features but cool stuff doesn&#8217;t and <a href="http://www.fsf.org/news/dont-depend-on-mono">will not ensure that users are not liable from patent litigation</a>.</p>
<p>Also, it seems like those RFPs have some mistakes, so if anyone figures out how to edit them, let me know so I can clean them up.</p>
]]></content:encoded>
			<wfw:commentRss>http://yonkeltron.com/2009/07/05/can-i-get-a-little-mapreduce-from-my-debian-people/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Languages, platforms, paradigms and speed</title>
		<link>http://yonkeltron.com/2009/07/02/languages-platforms-paradigms-and-speed/</link>
		<comments>http://yonkeltron.com/2009/07/02/languages-platforms-paradigms-and-speed/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 02:13:15 +0000</pubDate>
		<dc:creator>Jonathan Magen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Politics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://yonkeltron.com/?p=545</guid>
		<description><![CDATA[Ever since the latest round of Ruby benchmarks came out and everyone got all excited, I got to thinking about the overall discussion about languages and the interpreted vs. compiled debate. To be fair, there will always be those who take a specific side for some small-but-important-to-them reason yet this has not stopped so many ]]></description>
			<content:encoded><![CDATA[<p>Ever since the <a href="http://www.infoq.com/news/2008/12/ruby-performance-shootout">latest round</a> of <a href="http://www.infoq.com/news/2009/05/performance-191-gc-compiler">Ruby benchmarks</a> came out and everyone got all excited, I got to thinking about the overall discussion about languages and the interpreted vs. compiled debate. To be fair, there will always be those who take a specific side for some small-but-important-to-them reason yet this has not stopped so many projects from bridging the gap, albeit with varying degrees of success. In many instances, it comes down to the different approaches taken by various language themselves and the payoffs they offer.</p>
<p>In my investigation, I came across some very enlightening sources of information on the overall discussion of language speed, code optimization and the tension between different paradigms. Please peruse the following:</p>
<ul>
<li><a href="http://www.youtube.com/watch?v=kKySEUrP7LA">Compiling and Optimizing Scripting Languages</a> &#8211; Google Tech Talk by one of the maintainers of <a href="http://www.phpcompiler.org/">phc</a>, the PHP compiler.</li>
<li><a href="http://www.youtube.com/watch?v=OKFeLZqLxzQ">Compiling Dynamic Languages</a> &#8211; Another Google Tech Talk focusing on optimization of Python.</li>
<li><a href="http://www.pphsg.org/cdsmith/types.html">What To Know Before Debating Type Systems</a> &#8211; From the neo-classics department, this essay by Chris Smith helped me gain a great deal of perspective with respect to type systems</li>
<li>LLVM stuff &#8211; <a href="http://www.youtube.com/watch?v=VeRaLPupGks">Google Tech Talk about LLVM 2.0</a>, tons of <a href="http://llvm.org/pubs/">LLVM-related</a> papers and presentations</li>
<li><a href="http://arxiv.org/abs/0902.2137">A formally verified compiler back-end</a> &#8211; Paper by Xavier Leroy that was too long for me to finish</li>
</ul>
<p>Something missing from this list?</p>
]]></content:encoded>
			<wfw:commentRss>http://yonkeltron.com/2009/07/02/languages-platforms-paradigms-and-speed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I have discovered Sinatra and gained enlightenment</title>
		<link>http://yonkeltron.com/2009/03/18/i-have-discovered-sinatra-and-gained-enlightenment/</link>
		<comments>http://yonkeltron.com/2009/03/18/i-have-discovered-sinatra-and-gained-enlightenment/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 23:07:35 +0000</pubDate>
		<dc:creator>Jonathan Magen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://yonkeltron.com/?p=517</guid>
		<description><![CDATA[I don&#8217;t mean Frank Sinatra, I attained enlightenment from him when I was in fifth grade and my father sat me down to teach me the way of the rat pack. That day, I learned many things and as I stayed up late, sneakily listening to one of his latest anthologies (remastered of course), the ]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t mean <a href="http://en.wikipedia.org/wiki/Special:Search/Frank_Sinatra">Frank Sinatra</a>, I attained enlightenment from him when I was in fifth grade and my father sat me down to teach me the way of the rat pack. That day, I learned many things and as I stayed up late, sneakily listening to one of his latest anthologies (remastered of course), the elegant strength of Sinatra was non-too-apparent.</p>
<p>Today, when I sat down to work on a small software project for work that was taking way too long, I realized that I should most likely just use a framework. It being a web-app, I immediately figured I should use <a href="http://en.wikipedia.org/wiki/Ruby_on_Rails">Rails</a>. After about 20 minutes, I realized that the task at hand was too simple for Rails and that something else might do me better. After seeking advice from <a href="http://twitter.com/trek">Trek</a>, I installed the <a href="http://www.sinatrarb.com">Sinatra web framework</a> and my journey began. It was fifth grade all over again.</p>
<p>With Sinatra on the back  (<a href="http://wiki.dreamhost.com/Sinatra">fully supported by Dreamhost</a>, apropros) and <a href="http://www.jquery.com">jQuery</a> on the front, I was able to advance beyond what I had accomplished in one day in just 3 hours. I had never used Sinatra before but I certainly will in the future.</p>
<p>Also, because Sinatra gives you very little policy with respect to how must do things, I had no problem writing my business logic in Sinatra, leaving me free to write my data-handling code and page generation without worry.  Just so you know, when you keep your components seperate in the way I just described, you can get all excited and call it <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a>.  For views, Sinatra supports <a href="http://haml.hamptoncatlin.com/">HAML</a>, <a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/index.html">ERB</a> (my fav) and <a href="http://builder.rubyforge.org/">Builder</a> while for models you may do pretty-much whatever you want (<a href="http://datamapper.org/doku.php">Datamapper</a>, <a href="http://ar.rubyonrails.org/">ActiveRecord</a>, <a href="http://code.google.com/p/ruby-sequel/">Sequel</a>).</p>
<p>Sinatra is really worth a look and I know that I&#8217;ll be relying on it heavily in the next few months.</p>
]]></content:encoded>
			<wfw:commentRss>http://yonkeltron.com/2009/03/18/i-have-discovered-sinatra-and-gained-enlightenment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Trouble testing timestamps</title>
		<link>http://yonkeltron.com/2009/02/25/trouble-testing-timestamps/</link>
		<comments>http://yonkeltron.com/2009/02/25/trouble-testing-timestamps/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 16:44:40 +0000</pubDate>
		<dc:creator>Jonathan Magen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://yonkeltron.com/?p=497</guid>
		<description><![CDATA[Since I&#8217;ve been encouraging myself to write more and better unit tests, I have encountered a troubling obstacle when writing tests to cover timestamp creation and updating. Let&#8217;s say I have a Record class which has a modification and creation timestamp. The ctime instance variable is created when a Record is instatiated and mtime is ]]></description>
			<content:encoded><![CDATA[<p>Since I&#8217;ve been encouraging myself to write more and better unit tests, I have encountered a troubling obstacle when writing tests to cover timestamp creation and updating. Let&#8217;s say I have a Record class which has a modification and creation timestamp. The ctime instance variable is created when a Record is instatiated and mtime is updated whenever the Record is updated. So, my test looks like this:</p>
<pre>def test_ctime
  record = Record.new
  assert_equal(Time.now, record.ctime)
end</pre>
<p>This failed because, believe it or not, the timers have <em>too high</em> a resolution! In fact, even evaluating (with the help of irb) <code>Time.now == Time.now</code> is false. This is evident by evaluating <code>5.times { puts Time.now.to_f }</code> and seeing how the output differs by a tiny amount with each iteration.</p>
<p>I response to this, I decided to generalize and adapt my assertion to accept a diminished resolution with a tolerance of one second. <code>assert_equal(Time.now.sec, record.ctime.to_i)</code>. This is still imprecise but it gets my point across.</p>
<p>I had resigned myself to accept this troublesome compromise until I went to write the test for mtime. My test for mtime updating looked like this:</p>
<pre>def test_mtime_update
  record = Record.new
  record.update
  assert_operator(Time.now, :&gt;, record.mtime)
end</pre>
<p>I feel like I am compromising because I can&#8217;t make accurate comparisons and can&#8217;t figure out how to do this properly. It seems impossible and I don&#8217;t feel as if I have adequate coverage because I can&#8217;t verify timestampt at all. Perhaps I am doing something obviously wrong or testing for the wrong things. To make myself feel better I added an <code>assert_instance_of(Time, record.ctime)</code> and the same thing for mtime. Still, this has given me much frustration and I can&#8217;t imagine no one else has encountered this before.</p>
<p>I&#8217;m writing this as part of a multithreaded application where timestamp resolution could be quite crucial and I see my tests failing to give me proper coverage. Help?</p>
]]></content:encoded>
			<wfw:commentRss>http://yonkeltron.com/2009/02/25/trouble-testing-timestamps/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Introducing RadiateFS: a networked filesystem written in Ruby</title>
		<link>http://yonkeltron.com/2009/02/15/introducing-radiatefs-a-networked-filesystem-written-in-ruby/</link>
		<comments>http://yonkeltron.com/2009/02/15/introducing-radiatefs-a-networked-filesystem-written-in-ruby/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 02:52:40 +0000</pubDate>
		<dc:creator>Jonathan Magen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[F/OSS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://yonkeltron.com/?p=480</guid>
		<description><![CDATA[After a discussion with my friend Erik and following the consumption of much pastry, I decided to try and write a networked filesystem using only Ruby and FUSE. After one iteration, I had everything documented and ready to go but I wasn&#8217;t happy with the design or the architecture. In large part, I discovered shortcomings ]]></description>
			<content:encoded><![CDATA[<p>After a discussion with my friend Erik and following the consumption of much pastry, I decided to try and write a networked filesystem using only <a href="http://en.wikipedia.org/wiki/Ruby_(programming_language)">Ruby</a> and <a href="http://en.wikipedia.org/wiki/Filesystem_in_Userspace">FUSE</a>. After one iteration, I had everything documented and ready to go but I wasn&#8217;t happy with the design or the architecture. In large part, I discovered shortcomings in my own code base as I was writing the documentation. Writing with the intent of explaining my ideas to a newcomer gave me opportunity to find the major flaws in my own creation. Documentation is a good thing, if only because it makes you think about things in a whole new way.</p>
<p>Anyway, after rewriting things and shrinking the code base down to size, I&#8217;m please to release the first version of RadiateFS, a networked filesystem written in Ruby and making use of the most-excellent FUSE bindings. Other than Ruby (tested using Ruby 1.8.7 on <a href="http://debian.org/releases/stable/">Debian Lenny</a>) and FUSE itself, it has no other external dependencies. It used the <a href="http://www.ruby-doc.org/stdlib/libdoc/drb/rdoc/index.html">DRb</a> distributed object code bundled with the standard Ruby distribution.</p>
<p>This would not have been possible without the help and inspiration of a few exceptional individuals:  Erik Ordway and the folks on freenode&#8217;s #ruby-lang channel. In particular <a href="http://segment7.net/">drbrain</a> and <a href="http://twitter.com/ra66i">raggi</a>.</p>
<p>You can download a <a href="http://static.yonkeltron.com/code/radiate/radiatefs-latest.tar.gz">tarball here (v0.2b)</a> and read the mildly-hilarious FAQ below.</p>
<p><strong>Does it work? </strong>Yes. Well, sort of. It works well enough that I feel comfortable releasing it in accordance with the principal of &#8220;release early, release often&#8221;. Now that I&#8217;ve done the &#8220;early&#8221; bit, let&#8217;s see how the &#8220;often&#8221; part goes.</p>
<p><strong>How do I install it?</strong> You&#8217;ll need a few things. On Debian-friendly systems, you can install the pre-requisites like so: <code>sudo aptitude install ruby1.8 fuse-utils libfusefs-ruby1.8</code> and that should pull in what you need. After that, you can <a href="http://static.yonkeltron.com/code/radiate/radiatefs-latest.tar.gz">download the tarball</a>, unpack it and go to town. Of course, you&#8217;ll need to do this on any system on which you want to use RadiateFS, whether it be client or server.</p>
<p><strong>How do I use it?</strong> It&#8217;s rather simple really. Once you&#8217;ve got the required packages installed and the tarball unpacked, you can share a directory on the server like so:<br />
<code>ruby radiate-server.rb -d source/ -l 0 -s host -p 54321</code> In this case, we&#8217;ere sharing a directory named &#8220;source&#8221; using a loglevel of 0 on a host named &#8220;host&#8221; listening on port 54321. In the directory you ran this in, you&#8217;ll see a log named &#8216;radiate-server.log&#8217; which, with a loglevel of 0 (debug), will have a whole lot of stuff in it. Then, on the client, you can run this to mount the remote directory: <code>ruby radiatefs.rb -d test -s host -p 54321</code> to mount the remote directory over a local directory named test.</p>
<p><strong>Why do directories act funny?</strong> Remember that whole &#8220;release early&#8221; bit? Well, it&#8217;s early and not everything works right. Right now, you can get at files for which you have a proper pathname no matter how deep in a shared directory tree you are. The problem comes when trying to get a directory listing for directories below the top level. Patches welcome.</p>
<p><strong>Is it secure?</strong> Absolutely not. I haven&#8217;t even completely implemented support for the ACL functionality which comes wit DRb. Don&#8217;t use this over the internet or any insecure network.</p>
<p><strong>Why on earth would you write this?</strong> First, I was interested by the idea of putting DRb and FUSE together. Then, it was for the challenge. Looking back, it was mostly for the lolz.</p>
<p><strong>What is your favorite food?</strong> Toss up between good olives and good curry.</p>
<p><strong>Why is it read-only?</strong> The way things are set up right now, the instance of the class which specifies the FUSE mapping is shared directly. Therefore, all methods invoked on the client are actually executed on the server. While I *could* technically get write support working, I&#8217;d rather wait and rewrite this piece to have the FUSE directory objects live on the clients and connect to a broker on the server which implements proper threading and synchronization. If I&#8217;m imagining things correctly, it&#8217;ll add a degree of scaleability as well.</p>
<p><strong>Is it documented?</strong> Yes. You can run rdoc on the source and it&#8217;ll generate the documentation. Other than that, you can certainly go source diving as this might be a neat way for people to learn about DRB and/or FUSE.</p>
<p><strong>How is it licensed?</strong> <a href="http://www.gnu.org/licenses/gpl.txt">GPL</a>.</p>
<p><strong>What&#8217;s next?</strong> Well, I&#8217;d like to fix directory support and add auto-discovery using Rinda. Should be neat to enable clients to automagically find the server and connect to it. Could be cool, right?</p>
<p><strong>I found a bug. What now?</strong> Please contact me and let me know about it so I can fix the issue. If you help me fix it, I&#8217;ll gladly give you credit for your contribution.</p>
]]></content:encoded>
			<wfw:commentRss>http://yonkeltron.com/2009/02/15/introducing-radiatefs-a-networked-filesystem-written-in-ruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
