<?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>spiral_code &#187; ruby</title>
	<atom:link href="http://blog.trydionel.com/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.trydionel.com</link>
	<description></description>
	<lastBuildDate>Fri, 27 Aug 2010 00:35:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Using 0MQ for Clojure and Ruby Interop</title>
		<link>http://blog.trydionel.com/2010/08/26/using-0mq-for-clojure-and-ruby-interop/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=using-0mq-for-clojure-and-ruby-interop</link>
		<comments>http://blog.trydionel.com/2010/08/26/using-0mq-for-clojure-and-ruby-interop/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 00:32:13 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[zeromq]]></category>

		<guid isPermaLink="false">http://blog.trydionel.com/?p=230</guid>
		<description><![CDATA[Now that you have ZeroMQ working with Clojure, some introductory examples are in order. The demonstrations below show how simple it is to bridge the gap between programming languages by using ZeroMQ, focusing on connecting Clojure and Ruby. Pub/Sub Pattern &#8230; <a href="http://blog.trydionel.com/2010/08/26/using-0mq-for-clojure-and-ruby-interop/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Now that you have <a href="http://blog.trydionel.com/2010/08/25/setting-up-0mq-for-clojure-on-osx/">ZeroMQ working with Clojure</a>, some introductory examples are in order.  The demonstrations below show how simple it is to bridge the gap between programming languages by using ZeroMQ, focusing on connecting Clojure and Ruby.</p>
<h2>Pub/Sub Pattern</h2>
<p>Our first example is the <a href="http://en.wikipedia.org/wiki/Publish/subscribe">pub/sub pattern</a>.  Our code will broadcast messages from Ruby which our Clojure process can subscribe to.  One interesting capability of 0MQ is that we can subscribe to &#8220;channels&#8221; &mdash; that is, we&#8217;ll only receive messages which start with a given query.<sup class='footnote'><a href='#fn-230-1' id='fnref-230-1'>1</a></sup></p>
<pre class="brush: ruby;">
#!/usr/bin/env ruby -wKU
# pub.rb
require 'rubygems'
require 'zmq'

zmq = ZMQ::Context.new
socket = zmq.socket(ZMQ::PUB)
socket.bind &quot;tcp://127.0.0.1:5555&quot;

# A REPL of sorts.  Messages entered here
# will get sent to our Clojure process.
while true
  '&gt; '.display

  input = gets
  break unless input

  input.each do |msg|
    socket.send(msg)
  end
end

exit 0
</pre>
<pre class="brush: clojure;">
; src/my-project/sub.clj
(ns my-project.sub
  (:use [org.zeromq.clojure :as zmq]))

(defn- string-to-bytes [s] (.getBytes s))
(defn- bytes-to-string [b] (String. b))
(defn- on-thread [f]
  (doto (Thread. #^Runnable f)
    (.start)))

(defn launch-subscriber [query]
  (on-thread
   #((let [ctx (zmq/make-context 1)
	   socket (zmq/make-socket ctx zmq/+sub+)]
       (zmq/connect socket &quot;tcp://127.0.0.1:5555&quot;)
       ; Note the dot-syntax! clojure-zmq is a bit behind
       ; on the Java API, so you have to fall back to straight
       ; Java interop to subscribe to a pub &quot;channel&quot;.
       (.subscribe socket (string-to-bytes query))
       (while true
	 (println (bytes-to-string (zmq/recv socket))))))))

; Subscribing to the &quot;foo&quot; channel.  We'll only see messages prefixed with foo.
(launch-subscriber &quot;foo&quot;)
</pre>
<p>After launching the Clojure process, hop into the shell:<sup class='footnote'><a href='#fn-230-2' id='fnref-230-2'>2</a></sup></p>
<pre class="brush: bash;">
$ ruby pub.rb
&gt; Hello There
# No entry in the Clojure output
&gt; foo Hello There
# prints &quot;foo Hello There&quot; in the Clojure output
</pre>
<h2>Request/Response Pattern</h2>
<p>The request/response technique allows us to delegate work from our master program to a worker process.  In this particular example, we&#8217;re sending lists of values from our Ruby process to our Clojure process, which adds them and sends back the result.</p>
<pre class="brush: ruby;">
#!/usr/bin/env ruby -wKU
# req.rb

require 'rubygems'
require 'zmq'

zmq = ZMQ::Context.new
socket = zmq.socket(ZMQ::REQ)
socket.bind &quot;tcp://127.0.0.1:5556&quot;

while true
  '&gt; '.display

  input = gets
  break unless input

  input.each do |msg|
    socket.send(msg)
  end
  puts socket.recv
end

exit 0
</pre>
<pre class="brush: clojure;">
; src/my-project/rep.clj
(ns my-project.rep
  (:use [org.zeromq.clojure :as zmq])
  (:use [clojure.contrib str-utils]))

(defn- string-to-bytes [s] (.getBytes s))
(defn- bytes-to-string [b] (String. b))
(defn- on-thread [f]
  (doto (Thread. #^Runnable f)
    (.start)))

(defn handler [request]
  (let [request (bytes-to-string request)
	values (map
		#(Integer/parseInt %)
		(re-seq #&quot;\d+&quot; request))
	output (str (apply + values))]
    (println (apply
	      str
	      (str-join &quot; + &quot; values)
	      &quot; = &quot;
	      output))
    output))

(defn make-adder []
  (on-thread
   #((let [ctx (zmq/make-context 1)
	   socket (zmq/make-socket ctx zmq/+rep+)]
       (zmq/connect socket &quot;tcp://127.0.0.1:5556&quot;)
       (while true
	 (let [request (zmq/recv socket)
	       result (handler request)]
	   (zmq/send- socket (string-to-bytes result))))))))

(make-adder)
</pre>
<p>Fire up the Clojure process, and hop back into the shell:</p>
<pre class="brush: bash;">
$ ruby req.rb
&gt; 2 2
4
# The Clojure process will print &quot;2 + 2 = 4&quot;
&gt; 8 8
16
# The Clojure process will print &quot;8 + 8 = 16&quot;
</pre>
<p>You can find more ZeroMQ patterns on the <a href="http://www.zeromq.org/docs:cookbook">official cookbook page</a>.</p>
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-230-1'>This could be useful for using 0MQ for method dispatch, e.g. this socket will accept &#8220;add&#8221; messages and sum the terms in a message, whereas another socket will accept &#8220;log&#8221; messages and log the message to file. <span class='footnotereverse'><a href='#fnref-230-1'>&#8617;</a></span></li>
<li id='fn-230-2'>If you launched the process through lein and swank-clojure, your output will appear in the console which started <code>lein swank</code>. <span class='footnotereverse'><a href='#fnref-230-2'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2010/08/26/using-0mq-for-clojure-and-ruby-interop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Easy code reloading with FSSM</title>
		<link>http://blog.trydionel.com/2010/08/22/easy-code-reloading-with-fssm/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=easy-code-reloading-with-fssm</link>
		<comments>http://blog.trydionel.com/2010/08/22/easy-code-reloading-with-fssm/#comments</comments>
		<pubDate>Sun, 22 Aug 2010 19:40:21 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[fssm]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sinatra]]></category>
		<category><![CDATA[unicorn]]></category>

		<guid isPermaLink="false">http://blog.trydionel.com/?p=185</guid>
		<description><![CDATA[After a several month hiatus (filled with such activities as getting married and honeymooning), I&#8217;m finally getting back into the swing of &#8220;normal&#8221; life. I&#8217;ve been working on a pet project using Sinatra and Unicorn (doing some long-polling stuff, so &#8230; <a href="http://blog.trydionel.com/2010/08/22/easy-code-reloading-with-fssm/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After a several month hiatus (filled with such activities as getting married and honeymooning), I&#8217;m finally getting back into the swing of &#8220;normal&#8221; life.</p>
<p>I&#8217;ve been working on a pet project using Sinatra and Unicorn (doing some long-polling stuff, so I needed to support multiple connections even in dev).  Unfortunately, this combination makes code reloading tricky to tackle, as it rules out <a href="http://rtomayko.github.com/shotgun/">shotgun</a> entirely, and seems to also bust <a href="http://github.com/rkh/sinatra-reloader">Sinatra::Reloader</a>.</p>
<p>After a couple hours of HUPping unicorns manually, I decided that I needed a more robust solution. <a href="http://github.com/chriseppstein/compass/blob/stable/lib/compass/commands/watch_project.rb#L61">Some digging</a> led me to the  <a href="http://github.com/ttilley/fssm"><abbr title="File System State Monitor">FSSM</abbr> gem by ttilley</a>.  This library will watch your file system for events and runs a registered callback when they occur.  A few minutes of hacking and my reloading woes are solved!</p>
<pre class="brush: ruby;">
#!/usr/bin/env ruby -wKU

require 'rubygems'
require 'fssm'

puts &quot;Monitoring #{File.expand_path(File.dirname(__FILE__))} for changes...&quot;
FSSM.monitor(File.dirname(__FILE__), ['**/*.rb', '**/*.ru', '**/*.yml']) do
  update { system &quot;kill -HUP `cat pids/unicorn.pid`&quot; }
end

exit 0
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2010/08/22/easy-code-reloading-with-fssm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Meet Rack::UpsideDownTernet</title>
		<link>http://blog.trydionel.com/2010/03/31/meet-rackupsidedownternet/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=meet-rackupsidedownternet</link>
		<comments>http://blog.trydionel.com/2010/03/31/meet-rackupsidedownternet/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 02:17:48 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[rack]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[upsidedownternet]]></category>

		<guid isPermaLink="false">http://blog.trydionel.com/?p=170</guid>
		<description><![CDATA[One of my coworkers recently tweeted his interested in a Rack-compliant version of the upside-down-ternet. Inspired by the upcoming April Fools&#8217; Day, I took the challenge and created Rack::UpsideDownTernet. Check it out at GitHub! Fun Stuff Just like the original, &#8230; <a href="http://blog.trydionel.com/2010/03/31/meet-rackupsidedownternet/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One of my coworkers recently <a href="http://twitter.com/jasonnoble/status/11389845850">tweeted</a> his interested in a Rack-compliant version of <a href="http://www.ex-parrot.com/pete/upside-down-ternet.html">the upside-down-ternet</a>.  Inspired by the upcoming April Fools&#8217; Day, I took the challenge and created Rack::UpsideDownTernet. <a href="http://github.com/trydionel/rack-upside-down-ternet">Check it out at GitHub!</a></p>
<h2>Fun Stuff</h2>
<p>Just like the original, this middleware downloads all the images on a page, transforms them with ImageMagick (<code>-flip</code> is the default transformation) and renders out the updated images.  Pure.  Simple.  Fun.</p>
<p>Setup is just like any other middleware.  Bonus: set your own image transformations!</p>
<pre class="brush: ruby;">
# environment.rb
require 'rack_upside_down_ternet'
config.middleware.use Rack::UpsideDownTernet, '-blur 10 -flip'
</pre>
<h2>Broken Stuff</h2>
<ul>
<li>Uses curl instead of just grabbing the file out of the images directory</li>
<li>Doesn&#8217;t even kinda work with remote/absolute URL images</li>
<li>Requires unicorn (or any multi-worker setup).  Make sure you have at least 2 workers running, as your first request will block curl from downloading images</li>
<li>Requires that you create <code>PROJECT_DIR/tmp</code> and <code>PROJECT_DIR/images/mod</code></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2010/03/31/meet-rackupsidedownternet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some Unicode tips for Ruby</title>
		<link>http://blog.trydionel.com/2010/03/23/some-unicode-tips-for-ruby/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=some-unicode-tips-for-ruby</link>
		<comments>http://blog.trydionel.com/2010/03/23/some-unicode-tips-for-ruby/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 01:54:01 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://blog.trydionel.com/?p=141</guid>
		<description><![CDATA[I recently released a <a href="http://japanese.trydionel.com">Japanese word search builder</a> (see the discussion in the <a href="http://news.ycombinator.com/item?id=1191826">Hacker News post</a>).  This was my first foray into the world of multibyte characters, and I quickly discovered the pain involved in simply printing "ありがと" to the screen.  Below are some of the details I found to help me through this trial. <a href="http://blog.trydionel.com/2010/03/23/some-unicode-tips-for-ruby/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<style>
.italic { font-style: italic; }
</style>
<p>I recently released a <a href="http://japanese.trydionel.com">Japanese word search builder</a> (see the discussion in the <a href="http://news.ycombinator.com/item?id=1191826">Hacker News post</a>).  This was my first foray into the world of multibyte characters, and I quickly discovered the pain involved in simply printing &#8220;ありがと&#8221; to the screen.  Below are some of the details I found to help me through this trial.</p>
<h3>Tips to make your Unicode+Ruby experience easier</h3>
<ol start=0>
<li>Read James Edward Gray&#8217;s <a href="http://blog.grayproductions.net/articles/understanding_m17n">Understanding m17n</a> series.  Every word. Period.</li>
<li>If at all possible, use Ruby 1.9+.  As James describes, Unicode support is <span class="italic">far</span> better than in 1.8.x.</li>
<li>In spite of Ruby 1.9&#8242;s superior Unicode support, it still doesn&#8217;t read files as UTF8 by default.  This means that loading any files which include Unicode characters will cause Ruby to lash out at you with complaints about multi-byte characters.  To get around this, set the file&#8217;s encoding type at the start of the file.
<pre class="brush: bash;">
# encoding: UTF-8
... unicode goes here ...
</pre>
</li>
<li>If you can&#8217;t use 1.9, make sure you use the Jcode library.  It&#8217;s included with Ruby and adds lots of useful Unicode-oriented features to String and Regexp.  The only disadvantage is that the original methods remain in place (e.g., you&#8217;ll have to make sure you call String#jsize rather than String#size).
<pre class="brush: ruby;">
require 'jcode'
&quot;ありがと&quot;.size
# =&gt; 12
&quot;ありがと&quot;.jsize
# =&gt; 4
</pre>
</li>
<li>If you plan for your Ruby file to be run directly, make sure you add the <code>-KU</code> flag to your shabang line.  This will tell Ruby to be open to UTF8 data.
<pre class="brush: bash;">
#!/usr/local/bin/env ruby -KU
... Ruby goes here ...
</pre>
</li>
<li>Familiarize yourself with <code>iconv</code> &mdash; both the Ruby library and the command line tool.  This tool will allow you to translate data easily between various character encodings.</li>
<li>While not strictly required these days, it&#8217;s still recommended when serving HTML with Unicode data to set the content type both in a meta tag on the page <span class="italic">and</span> the in HTTP header.
<pre class="brush: xml;">
HTTP/1.1 200 OK
Server: nginx/0.6.39
Date: Wed, 24 Mar 2010 00:39:47 GMT
Content-Type: text/html; charset=utf-8
...

&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot;  content=&quot;text/html; charset=utf-8&quot; /&gt;
...
</pre>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2010/03/23/some-unicode-tips-for-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lightning-Quick Redis Viewer</title>
		<link>http://blog.trydionel.com/2010/02/27/lightning-quick-redis-viewer/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=lightning-quick-redis-viewer</link>
		<comments>http://blog.trydionel.com/2010/02/27/lightning-quick-redis-viewer/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 21:34:10 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sinatra]]></category>

		<guid isPermaLink="false">http://blog.trydionel.com/?p=135</guid>
		<description><![CDATA[I&#8217;ve had the opportunity to work with the Redis datastore this week. If you&#8217;re not familiar with it, Redis is a blindingly-fast, in-memory key-value store. It supports several nice features such as string, list and set support (complete with set &#8230; <a href="http://blog.trydionel.com/2010/02/27/lightning-quick-redis-viewer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had the opportunity to work with the Redis datastore this week.  If you&#8217;re not familiar with it, Redis is a blindingly-fast, in-memory key-value store.  It supports several nice features such as string, list and set support (complete with set operations) and the ability to persist data to disk.  Check out the <a href="http://code.google.com/p/redis/">official site</a> for lots more info.</p>
<p>My project revolved around data collection, and I pretty quickly ran into the need to see what I was actually shoving into the database.  After 10 minutes and only ~50 lines, I came up with a Sinatra backed Redis viewer.  See the code below, or check out <a href="http://gist.github.com/316957">my gist on Github</a>!</p>
<pre class="brush: ruby;">
# app.rb
require 'rubygems'
require 'haml'
require 'sinatra'
require 'redis'

helpers do
  def redis
    @redis ||= Redis.new
  end
end

get &quot;/&quot; do
  @keys = redis.keys(&quot;*&quot;)
  haml :index
end

get &quot;/:key&quot; do
  @key = params[:key]
  @data = case redis.type(@key)
  when &quot;string&quot;
    Array(redis[@key])
  when &quot;list&quot;
    redis.lrange(@key, 0, -1)
  when &quot;set&quot;
    redis.set_members(@key)
  else
    []
  end
  haml :show
end

# views/index.haml
%html
%body
  %h1 Current Keys
  %ul
    - @keys.each do |key|
      %li
        %a{:href =&gt; &quot;/#{key}&quot;}= key

# views/show.haml
%html
%body
  %h1= &quot;Data stored in '#{@key}'&quot;
  %ul
    -@data.each do |data|
      %li
        %p= data
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2010/02/27/lightning-quick-redis-viewer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing Git Pivotal</title>
		<link>http://blog.trydionel.com/2010/01/30/announcing-git-pivotal/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=announcing-git-pivotal</link>
		<comments>http://blog.trydionel.com/2010/01/30/announcing-git-pivotal/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 21:30:48 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[git pivotal]]></category>
		<category><![CDATA[pivotal tracker]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.trydionel.com/?p=103</guid>
		<description><![CDATA[<p>I'm pleased to release the (highly alpha) Git Pivotal gem!  This gem contains a toolkit to smooth the integration between git and Pivotal Tracker. <a href="http://github.com/trydionel/git-pivotal">Learn more at github.</a></p> <a href="http://blog.trydionel.com/2010/01/30/announcing-git-pivotal/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2>Using git effectively</h2>
<p>Like most of the developer blogosphere, I was thoroughly excited to read Vincent Driessen&#8217;s post on <a href="http://nvie.com/archives/323">branch management in git.</a>  It captured a simple and repeatable methodology for extracting a great deal of power from git without having to really dive down into its belly.  Given that Vincent&#8217;s methodology relies heavily on feature and bugfix branches, I began looking for techniques on combining <a href="http://www.pivotaltracker.com">Pivotal Tracker</a> &mdash; which I&#8217;ve been using recently for all of my project management needs &mdash; with git.  I found some advice in Rein Henrichs&#8217; article which suggests <a href="http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html">using Pivotal Tracker story ids as branch identifiers</a>, but not much else on how to really tighten the two together.</p>
<h2>Moving towards smoother integration</h2>
<p>Further Googling didn&#8217;t reveal any tools to aide my new objective, so I set out to create my own toolkit.  After a few evenings digging through Pivotal Tracker&#8217;s API (which actually changed from v2 to v3 while I worked <img src='http://blog.trydionel.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ), I&#8217;m ready to announce my work: <a href="http://github.com/trydionel/git-pivotal">Git Pivotal</a>.  It&#8217;s a very alpha release currently, but I have some work in development that will (hopefully) stabilize it soon.</p>
<h2>Git Pick</h2>
<p>The first (and currently only) tool is <code>git pick</code>.  After <a href="http://github.com/trydionel/git-pivotal#config">some simple configuration</a>, this will grab your top-most available feature story from Pivotal Tracker, display some simple info about it and offer to create a feature branch for it off of your current branch.</p>
<h2>What&#8217;s coming</h2>
<p>I plan to add some additional commands for marking current feature branches as finished, managing bugs and bugfix branches and possibly integrating release stories as well.  If you&#8217;re a fan of git and Pivotal Tracker, keep an eye on this project!</p>
<p>So what do you think?  Is this useful?  Share your thoughts below!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2010/01/30/announcing-git-pivotal/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>List Comprehensions in Ruby</title>
		<link>http://blog.trydionel.com/2009/10/27/list-comprehensions-in-ruby/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=list-comprehensions-in-ruby</link>
		<comments>http://blog.trydionel.com/2009/10/27/list-comprehensions-in-ruby/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 00:12:14 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[lists]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://trydionel.wordpress.com/?p=11</guid>
		<description><![CDATA[I think list comprehensions are one of the neatest features of Python. They&#8217;re extremely readable, and are pretty simple to learn. They take verbose, loop-based array handlers and compact them into one elegant line. As an example, the list comprehension &#8230; <a href="http://blog.trydionel.com/2009/10/27/list-comprehensions-in-ruby/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I think <a href="http://en.wikipedia.org/wiki/List_comprehension">list comprehensions</a> are one of the neatest features of Python.  They&#8217;re extremely readable, and are pretty simple to learn.  They take verbose, loop-based array handlers and compact them into one elegant line.  As an example, the list comprehension below produces the primes between 1 and 10:</p>
<pre class="brush: python;">
# suppose isPrime(n) returns the primality of n
[x for x in range(1,10) if isPrime(x)]
# =&amp;gt; [2, 3, 5, 7]
</pre>
<p>When I migrated from Python to Ruby recently, I was disappointed to find that there was no simple replacement for list comprehensions.  Top that with everyone in the Ruby community saying &#8220;Ruby doesn&#8217;t do list comprehensions,&#8221; and I basically gave up on my hope of finding a suitable analogue.  Fortunately though, I stumbled upon <a href="http://www.ruby-forum.com/topic/89416">a thread in Ruby-Forum</a> recently showing how to quickly add the capability onto any array!</p>
<p>The meat of the trick is this:</p>
<pre class="brush: ruby;">
module Enumerable
  def comprehend( &amp;amp;amp;block )
    block ? map( &amp;amp;amp;block ).compact : self
  end
end
</pre>
<p>With this monkey patch, I&#8217;m now able to write:</p>
<pre class="brush: ruby;">
# Likewise, is_prime?(n) returns primality of n
(1..9).comprehend { |x| x if is_prime?(x) }
# =&amp;gt; [2, 3, 5, 7]
</pre>
<p>While this isn&#8217;t a direct replacement of Python&#8217;s implementation, it&#8217;s at least enough to prove that Ruby is surprisingly powerful!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2009/10/27/list-comprehensions-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
