<?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>Tender Lovemaking &#187; Aaron Patterson</title>
	<atom:link href="http://tenderlovemaking.com/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://tenderlovemaking.com</link>
	<description>The act of making love, tenderly.</description>
	<lastBuildDate>Sat, 26 Jun 2010 02:57:12 +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>Event based JSON and YAML parsing</title>
		<link>http://tenderlovemaking.com/2010/04/17/event-based-json-and-yaml-parsing/</link>
		<comments>http://tenderlovemaking.com/2010/04/17/event-based-json-and-yaml-parsing/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 23:41:58 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=432</guid>
		<description><![CDATA[Let&#8217;s use Ruby 1.9.2 and Psych to build an event based twitter stream parser. Psych is a YAML parser that I wrote and is in the standard library in 1.9.2. Eventually, it will replace the current YAML parser, but we can still use it today! But you said YAML and JSON! wtf? I know! In [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s use Ruby 1.9.2 and <a href="http://github.com/tenderlove/psych">Psych</a> to build an event based twitter stream parser.  Psych is a YAML parser that I wrote and is in the standard library in 1.9.2.  Eventually, it will replace the current YAML parser, but we can still use it today!</p>
<p><strong>But you said YAML <em>and JSON</em>!  wtf?</strong></p>
<p>I know!  In the YAML 1.2 spec, <a href="http://www.yaml.org/spec/1.2/spec.html">JSON is a subset of YAML</a>.  Psych supports YAML 1.1 right now, so *much* (but not all) JSON is supported.  Once libyaml is upgraded to YAML 1.2, it will have full JSON support!</p>
<h3>Why do we want to do an event based parser?</h3>
<p><a href="http://apiwiki.twitter.com/Streaming-API-Documentation">Twitter streams</a> are a never ending flow of user status updates, and if we want a process to live forever consuming these updates, it would be nice if that process kept a low memory profile.  Psych is built in such a way that we can hand it an IO object, it will read from the IO object, then call callback methods as soon as possible.  It buffers as little as possible, sending events as soon as possible.  If you are familiar with SAX based XML parsing, this will be familiar to you.  Plus it is a fun problem!</p>
<p>Let&#8217;s start by writing an event listener for some sample JSON.</p>
<h3>Event Listener</h3>
<p>Our event listener is only going to listen for scalar events, meaning that when Psych parses a string, it will send that string to our listener.  There are many different events that can happen, so Psych ships with <a href="http://github.com/tenderlove/psych/blob/master/lib/psych/handler.rb">a handler from which you can inherit</a>.  If you check out the source for the <a href="http://github.com/tenderlove/psych/blob/master/lib/psych/handler.rb">base class handler</a>, you can see what types of events your handler can intercept.</p>
<p>For now, let&#8217;s write our scalar handler, and try it out.</p>
<pre class="brush: ruby;">
require 'psych'

class Listener &lt; Psych::Handler
  def scalar(value, anchor, tag, plain, quoted, style)
    puts value
  end
end

listener = Listener.new
parser   = Psych::Parser.new listener
parser.parse DATA

__END__
{&quot;foo&quot;:&quot;bar&quot;}
</pre>
<p>If you run this code, you should see the strings &#8220;foo&#8221; and &#8220;bar&#8221; printed.</p>
<p>In this example, our handler simply prints out every scalar value encountered.  We created a new instance of the listener, pass that listener to a new instance of the parser, and tell the parser to parse DATA.  We can hand the parser an IO object or a String object.  This is important because we&#8217;d like to hand the parser our socket connection, that way the parser can deal with reading from the socket for us.</p>
<h3>Hooking up to Twitter</h3>
<p>It would be convenient for us if Twitter&#8217;s stream was one continuous JSON document.  Why?  If it was, we could feed the socket straight to our JSON parser and start consuming events immediately.  Unfortunately, Twitter&#8217;s stream is not so kind for us event based consumers.  We&#8217;ll need to trick our JSON parser to think the feed is one continuous document.  We&#8217;ll get tricky with our data in a minute, but first let&#8217;s deal with authentication.</p>
<p><strong>Authentication</strong></p>
<p>Twitter requires us to authenticate before we can consume a feed.  <a href="http://apiwiki.twitter.com/Streaming-API-Documentation#Authentication">Stream authentication</a> is done via Basic Auth.  Let&#8217;s write a class that can authenticate and read from the stream.  Once we do that, we&#8217;ll concentrate on parsing the stream.</p>
<pre class="brush: ruby;">
require 'socket'

class StreamClient
  def initialize user, pass
    @ba = [&quot;#{user}:#{pass}&quot;].pack('m').chomp
  end

  def listen
    socket = TCPSocket.new 'stream.twitter.com', 80
    socket.write &quot;GET /1/statuses/sample.json HTTP/1.1\r\n&quot;
    socket.write &quot;Host: stream.twitter.com\r\n&quot;
    socket.write &quot;Authorization: Basic #{@ba}\r\n&quot;
    socket.write &quot;\r\n&quot;

    # Read the headers
    while((line = socket.readline) != &quot;\r\n&quot;); puts line if $DEBUG; end

    # Consume the feed
    while line = socket.readline
      puts line
    end
  end
end

StreamClient.new(ARGV[0], ARGV[1]).listen
</pre>
<p>This class takes a username and password and calculates the basic auth signature.  When &#8220;listen&#8221; is called, it opens a connection, authorizes, reads the response headers, and starts consuming the feed.</p>
<h3>Processing the Feed</h3>
<p>If we look at the output from the previous script, we&#8217;ll see that the Twitter stream looks something like this:</p>
<pre>
512
{"in_reply_to_screen_name":null,...}

419
{"in_reply_to_screen_name":"tenderlove"...}
</pre>
<p>Which isn&#8217;t valid JSON.  Instead, it&#8217;s a header (the number) indicating the length of the JSON chunk, the JSON chunk, then a trailing &#8220;\r\n&#8221;.  We would <em>like</em> the stream to look something like this:</p>
<pre>
---
{"in_reply_to_screen_name":null,...}
...
---
{"in_reply_to_screen_name":"tenderlove"...}
...
</pre>
<p>This chunk is two valid YAML documents.  If the stream looked like this, we could feed it straight to our YAML processor no problem.  How can we modify the stream to be suitable for our parser?</p>
<h3>Fun with Thread and IO.pipe</h3>
<p>If we create a pipe, we can have have one thread process input from Twitter and feed that in to the pipe.  We can then give the other end of the pipe to our JSON processor and let it read from our processed feed.  Let&#8217;s modify the &#8220;listen&#8221; method in our client to munge the feed to a pipe, and hand that off to our YAML processor.  I only care about the text of people&#8217;s tweets, so let&#8217;s modify our listener too.</p>
<p>Here is our completed program:</p>
<pre class="brush: ruby;">
require 'socket'
require 'psych'

class StreamClient
  def initialize user, pass
    @ba = [&quot;#{user}:#{pass}&quot;].pack('m').chomp
  end

  def listen listener
    socket = TCPSocket.new 'stream.twitter.com', 80
    socket.write &quot;GET /1/statuses/sample.json HTTP/1.1\r\n&quot;
    socket.write &quot;Host: stream.twitter.com\r\n&quot;
    socket.write &quot;Authorization: Basic #{@ba}\r\n&quot;
    socket.write &quot;\r\n&quot;

    # Read the headers
    while((line = socket.readline) != &quot;\r\n&quot;); puts line if $DEBUG; end

    reader, writer = IO.pipe
    producer = Thread.new(socket, writer) do |s, io|
      loop do
        io.write &quot;---\n&quot;
        io.write s.read s.readline.strip.to_i 16
        io.write &quot;...\n&quot;
        s.read 2 # strip the blank line
      end
    end

    parser = Psych::Parser.new listener
    parser.parse reader

    producer.join
  end
end

class Listener &lt; Psych::Handler
  def initialize
    @was_text = false
  end

  def scalar value, anchor, tag, plain, quoted, style
    puts value if @was_text
    @was_text = value == 'text'
  end
end

StreamClient.new(ARGV[0], ARGV[1]).listen Listener.new
</pre>
<p>Great!  In 30 lines, we&#8217;ve been able to provide an event based API for consuming Twitter streams.  Were it not for the feed munging, we could reduce that by 9 lines!</p>
<h3>Problems</h3>
<p>So far, there have only been two problems for me with this script.  The first is that we are forced to buffer the response from Twitter, but we cannot help that.  The second is that sometimes the JSON emitted from Twitter is not parseable by Psych.  I think this is just due to Psych only supporting YAML 1.1.</p>
<h3>Conclusion</h3>
<p>It&#8217;s true that we could have implemented this same interface without a pipe and a thread.  Rather than munging the stream, we could create a new parser instance for each status update.  But why create so many objects for parsing the stream when we only need one?</p>
<p>Anyway, have fun playing with this code, and I encourage you to try out Ruby 1.9.2.  I think it&#8217;s really fun!  PEW PEW PEW!  HAPPY SATURDAY!</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2010/04/17/event-based-json-and-yaml-parsing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>RDoc on your iPad</title>
		<link>http://tenderlovemaking.com/2010/04/12/rdoc-on-your-ipad/</link>
		<comments>http://tenderlovemaking.com/2010/04/12/rdoc-on-your-ipad/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 03:49:18 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=422</guid>
		<description><![CDATA[Oh snap! I haven&#8217;t posted here in a long time. My day job and my night jobs have been keeping me too busy! Hopefully I&#8217;ll have more time to blog in the future. I have a bunch of ideas, I just need to find the time to write! Anyway, let&#8217;s talk RDoc, iPad, and epub! [...]]]></description>
			<content:encoded><![CDATA[<p>Oh snap!  I haven&#8217;t posted here in a long time.  My <a href="http://atti.com/">day job</a> and my <a href="http://redmine.ruby-lang.org/account/show/73">night</a> <a href="http://nokogiri.org/">jobs</a> have been keeping me too busy!  Hopefully I&#8217;ll have more time to blog in the future.  I have a bunch of ideas, I just need to find the time to write!</p>
<p>Anyway, let&#8217;s talk <a href="http://rdoc.rubyforge.org/">RDoc</a>, <a href="http://www.apple.com/ipad/">iPad</a>, and <a href="http://en.wikipedia.org/wiki/EPUB">epub</a>!  I like documentation.  I especially like consuming documentation.  I thought it would be neat if I could read documentation on my iPad.  As it turns out, getting RDoc documentation on your iPad isn&#8217;t that hard!</p>
<p><a href="http://www.flickr.com/photos/aaronp/4516263901/" title="Nokogiri on iPad by tenderlovemaking, on Flickr"><img src="http://farm5.static.flickr.com/4034/4516263901_f65ec66ba2.jpg" width="500" height="375" alt="Nokogiri on iPad" /></a></p>
<p>According to Wikipedia, <a href="http://en.wikipedia.org/wiki/EPUB">iBooks is an EPUB reader</a>.  EPUB is a standard format for making books.  The EPUB format is <a href="http://www.hxa.name/articles/content/epub-guide_hxa7241_2007.html">basically a zip file that contains a bunch of XHTML and XML documents</a>.  The XHTML documents are the &#8220;meat&#8221; of your book, where the XML documents tell the reader where to find everything, and the order in which to put things.  RDoc already emits HTML, so our job is to make sure it emits XHTML along with the special XML files.  How do we do that?</p>
<p>RDoc supports a plugin system where we can hook in and emit anything we want.  To hook in to RDoc, we just add a special file to our gem (&#8220;lib/rdoc/discover.rb&#8221;), and <a href="http://github.com/tenderlove/paddle/blob/master/lib/rdoc/generator/paddle.rb#L9">register with the RDoc plugin system</a>. So I wrote a gem called <a href="http://github.com/tenderlove/paddle">paddle</a> that plugs in to RDoc, emits the documentation as XHTML along with the supporting XML files.  It even comes with a nice Ruby logo!  I encourage you to <a href="http://github.com/tenderlove/paddle/blob/master/lib/rdoc/generator/paddle.rb">take a look at the source</a>.  The code is quite short, but could be refactored even smaller!</p>
<h3>Using the Paddle</h3>
<p>Creating your own books with Paddle is really easy.  First, install paddle:</p>
<pre>
  $ sudo gem install paddle
</pre>
<p>Then find a project for which you want to create a book.  For this example, I&#8217;ll generate a book for one of my gems called <a href="http://github.com/tenderlove/texticle">texticle</a>.  From the project root, use the rdoc command.  Make sure to tell rdoc to use the &#8220;paddle&#8221; formatter, and <strong>supply a title</strong> (very important to supply a title!):</p>
<pre>
  $ cd git/texticle
  $ rdoc -f paddle -t 'Texticle Documentation' -o epub lib
</pre>
<p>Now there should be an &#8220;epub&#8221; directory that contains your book.  But we&#8217;re not quite done yet.  There is one more step.  The book must be in a zipfile, and the zipfile requires a particular format.  Let&#8217;s create the zipfile now using the &#8220;zip&#8221; command:</p>
<pre>
  $ cd epub
  $ zip -Xr9D texticle.epub mimetype *
</pre>
<p>You should end up with a file named &#8220;texticle.epub&#8221;.  Just drag that file to iTunes, sync up your iPad, and boom!</p>
<h3>Problems</h3>
<p>I hacked this out in an evening, so there are a few problems.  I&#8217;ll mention them here, just so you&#8217;re not surprised, and to give you ideas for patches to submit!  <img src='http://tenderlovemaking.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<ul>
<li>Right now, the links don&#8217;t work:</li>
<p>  I haven&#8217;t figured out why, but they don&#8217;t.  That will come soon.</p>
<li>The author field isn&#8217;t filled out in the book:</li>
<p>  I need to teach RDoc to take more command line options so we can tell Paddle what to use for the book&#8217;s author field</p>
<li>Only classes, modules, and the things they contain are documented:</li>
<p>  Right now, your README file won&#8217;t show up in the book.  That is just missing right now.  It should be easy to add, I just haven&#8217;t done it.
</ul>
<h3>A couple books to get you started</h3>
<ul>
<li>Here&#8217;s the <a href="/rails.epub">Rails Documentation</a></li>
<li>Here&#8217;s the <a href="/nokogiri.epub">Nokogiri Documentation</a></li>
</ul>
<h3>THE END!</h3>
<p>Thanks for reading!  Have fun making books for your iPad, and don&#8217;t forget to send patches back to me!  <img src='http://tenderlovemaking.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2010/04/12/rdoc-on-your-ipad/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Compiling with Clang</title>
		<link>http://tenderlovemaking.com/2010/01/03/compiling-with-clang/</link>
		<comments>http://tenderlovemaking.com/2010/01/03/compiling-with-clang/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 00:05:00 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>
		<category><![CDATA[nokogiri]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=414</guid>
		<description><![CDATA[HI EVERYONE AND HAPPY SUNDAY! Lately I&#8217;ve been trying to compile my ruby extensions with Clang. One reason I like trying out my extensions with Clang is because it catches some errors that GCC doesn&#8217;t. If you know the right things to set, it&#8217;s pretty easy to get your extension to compile with Clang. Unfortunately [...]]]></description>
			<content:encoded><![CDATA[<p>HI EVERYONE AND HAPPY SUNDAY!</p>
<p>Lately I&#8217;ve been trying to compile my ruby extensions with <a href="http://clang.llvm.org/">Clang</a>.  One reason I like trying out my extensions with Clang is because it catches some errors that GCC doesn&#8217;t.  If you know the right things to set, it&#8217;s pretty easy to get your extension to compile with Clang.  Unfortunately finding the right thing isn&#8217;t always easy, but I found the right bits to flip and I want to share!</p>
<p>Here&#8217;s how to do it.  Add this line to your extconf.rb right after you require mkmf:</p>
<pre class="brush: ruby;">
require 'mkmf'

RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']

# ... rest of your extconf goes here
</pre>
<p>Then when you compile your extension, just set CC to point at clang:</p>
<pre><code>$ CC=/Developer/usr/bin/clang rake compile</code></pre>
<p>You can see it in action in the <a href="http://github.com/tenderlove/nokogiri/blob/master/ext/nokogiri/extconf.rb#L7">nokogiri extconf</a>.  You can even see where <a href="http://github.com/tenderlove/nokogiri/commit/6321c97963f657e8b4ece1783a6a25ca21504fda">clang helped me shake out some bugs</a>, and I think that&#8217;s pretty cool.</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2010/01/03/compiling-with-clang/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Writing Ruby C extensions: Part 1</title>
		<link>http://tenderlovemaking.com/2009/12/18/writing-ruby-c-extensions-part-1/</link>
		<comments>http://tenderlovemaking.com/2009/12/18/writing-ruby-c-extensions-part-1/#comments</comments>
		<pubDate>Sat, 19 Dec 2009 05:06:27 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=410</guid>
		<description><![CDATA[Writing Ruby C extensions: Part 1 I like writing C extensions for Ruby. In this series of blog posts we&#8217;re going to explore writing C extensions. I will cover topics including setting up the development environment, TDD, debugging techniques, dealing with Ruby&#8217;s garbage collector, cross compiling for windows, and more. By the end of this [...]]]></description>
			<content:encoded><![CDATA[<h1>Writing Ruby C extensions: Part 1</h1>
<p>I like writing C extensions for Ruby.  In this series of blog posts we&#8217;re<br />
going to explore writing C extensions. I will cover topics including setting<br />
up the development environment, TDD, debugging techniques, dealing with<br />
Ruby&#8217;s garbage collector, cross compiling for windows, and more.</p>
<p>By the end of this series, we should end up with a Ruby C extension that wraps<br />
<a href="http://www.icir.org/christian/libstree/">libstree</a>.  libstree is a <a href="http://en.wikipedia.org/wiki/Suffix_tree">Suffix tree</a> implementation written in C.</p>
<p>In this part, we&#8217;re going to set up our development environment, examine the<br />
layout of a typical C extension, and implement our first method in C.  Of<br />
course we will be doing this TDD, so we&#8217;ll also get autotest running.</p>
<h2>Prerequisite gems</h2>
<p>First up, we need to install a few gems to make building our extension easier.<br />
Install the following three gems, and while they install, you should read about<br />
why we need them:</p>
<pre><code>$ sudo gem install ZenTest hoe rake-compiler
</code></pre>
<h3>ZenTest</h3>
<p>ZenTest contains autotest, which we&#8217;ll be using to automatically run the tests<br />
while we&#8217;re developing</p>
<h3>hoe</h3>
<p>Hoe abstracts gem specifications for us.  It knows how to properly build a<br />
gemspec, and provides us with a few rake tasks that make development simple.</p>
<h3>rake-compiler</h3>
<p>This gem provides us with compilation tasks, and generally makes building<br />
native gems easier.  We&#8217;ll be looking further in to rake-compiler&#8217;s<br />
capabilities in later articles.</p>
<h2>Create the project</h2>
<p>We&#8217;re going to call this gem &#8220;stree&#8221;.  The first thing we&#8217;ll do is use the &#8220;sow&#8221;<br />
command supplied by Hoe to create the initial project structure.</p>
<pre><code>$ sow stree
</code></pre>
<p>You should now have an initial project tree set up under the &#8220;stree&#8221; directory.<br />
Remove the &#8220;bin&#8221; directory, as we won&#8217;t need that.  I rename all of my<br />
documentation files to end in &#8220;rdoc&#8221;, but that is just my personal preference.</p>
<h2>Writing our first test</h2>
<p>First thing we need to do is write our first failing test.  Open up<br />
&#8220;test/test_stree.rb&#8221; and make it look like this:</p>
<pre><code>require "test/unit"
require "stree"

class TestStree &lt; Test::Unit::TestCase
  def test_hello_world
    assert_equal 'hello world', Stree.hello_world
  end
end
</code></pre>
<p>This test is very simple.  The trick though, is that the &#8220;hello_world&#8221; method<br />
will be implemented in C.  At this point, you should be able to run &#8220;rake&#8221; and<br />
see a failing test.</p>
<h2>Native extension project layout</h2>
<p>Native extension layouts look very similar to normal pure ruby layouts.  We just<br />
add one more directory called &#8220;ext&#8221;.  Under the &#8220;ext&#8221; directory we&#8217;ll add<br />
another directory that is the same name as our gem, &#8220;stree&#8221;.  Under<br />
&#8220;ext/stree&#8221; is where we&#8217;ll keep all of our C code.  Make those directories,<br />
and you should have a file list that looks similar to this:</p>
<pre><code>$ tree
.
|-- CHANGELOG.rdoc
|-- Manifest.txt
|-- README.rdoc
|-- Rakefile
|-- ext
|   `-- stree
|-- lib
|   `-- stree.rb
`-- test
    `-- test_stree.rb
</code></pre>
<p>The next step is to modify our Rakefile.</p>
<h2>Modifying the Rakefile</h2>
<p>The next step is to modify the Rakefile to teach it how to compile our<br />
extension.  Once we get done with this step, our Rakefile will have a task<br />
called &#8220;compile&#8221;.</p>
<p>Modify your Rakefile so that it looks similar to this:</p>
<pre><code>require 'rubygems'
require 'hoe'

Hoe.spec 'stree' do
  developer('Aaron Patterson', 'aaron@tenderlovemaking.com')
  self.readme_file   = 'README.rdoc'
  self.history_file  = 'CHANGELOG.rdoc'
  self.extra_rdoc_files  = FileList['*.rdoc']
  self.extra_dev_deps << ['rake-compiler', '>= 0']
  self.spec_extras = { :extensions => ["ext/stree/extconf.rb"] }

  Rake::ExtensionTask.new('stree', spec) do |ext|
    ext.lib_dir = File.join('lib', 'stree')
  end
end

Rake::Task[:test].prerequisites << :compile
</code></pre>
<p>I've modified the readme and history file sections to use custom named files.<br />
The important parts are the "spec_extras", the "Rake::ExtensionTask" line and<br />
the "Rake::Task" line.</p>
<p>The "spec_extras" line modifies the gemspec.  When someone installs our gem,<br />
this line tells the gem command to execute the "ext/stree/extconf.rb" file.<br />
We'll talk a little bit more about the extconf.rb file later.</p>
<p>The "Rake::ExtensionTask" is the line where we get our "compile" task.  It comes<br />
from the rake-compiler gem.  This block also configures rake-compiler to tell<br />
it where to copy the compiled extension when it's finished.  We want our<br />
compiled extension to end up in "lib/stree/".  This is my convention, and I'll<br />
explain why this convention is good in later posts.</p>
<p>The final line tells Rake to always compile our extension before the tests run.<br />
Some people might not want to use this, but I like compiling my extension<br />
before every test run.</p>
<h2>Configuring autotest</h2>
<p>Autotest doesn't use the normal rake tasks when running your tests.  That means<br />
we need to teach autotest to compile our extension before running the tests.<br />
We're going to hook in to the autotest run command and have it build our<br />
extension before running the tests.</p>
<p>While we're at it, we'll also teach autotest to run the tests after any .c<br />
files get modified.</p>
<p>Open up ".autotest" and make it look like this:</p>
<pre><code>require 'autotest/restart'

Autotest.add_hook :initialize do |at|
  at.add_mapping(/.*\.c/) do |f, _|
    at.files_matching(/test_.*rb$/)
  end
end

Autotest.add_hook :run_command do |at|
  system "rake clean compile"
end
</code></pre>
<p>Start up autotest and let it run in the background.  By the end of this blog<br />
post, autotest should show one passing test.</p>
<p>At this point, we should see Rake complaining with a message:</p>
<pre><code>rake aborted!
Don't know how to build task 'ext/stree/extconf.rb'
</code></pre>
<p>Let's deal with that error now.</p>
<h2>extconf.rb</h2>
<p>The responsibility of the extconf.rb file is generate a Makefile that will<br />
be used to build your extension.  Eventually, we will need to teach extconf.rb<br />
how to examine the target system to make sure that the libstree library is<br />
installed.</p>
<p>Right now, we don't need to do any inspection of the system.  We simply want<br />
to create a Makefile.  To build our Makefile, we're going to use a library<br />
that ships with ruby called "mkmf".  Open up "ext/stree/extconf.rb" and<br />
modify it to look like this:</p>
<pre><code>require 'mkmf'
create_makefile('stree/stree')
</code></pre>
<p>That is the minimum code required to get our Makefile generated.</p>
<p>As I mentioned earlier, the extconf.rb file is executed by the RubyGems system<br />
when installing our gem.  While we're developing our gem, rake-compiler will<br />
take care of executing that file for us.</p>
<h2>Our first C code</h2>
<p>Great!  Our environment knows how to compile things, but we don't have anything<br />
to compile!  Let's write our first bit of C code.</p>
<p>We are going to write the file named "ext/stree/stree.c".  The name of this<br />
file is important.  It corresponds to the "create_makefile" line from our<br />
extconf.rb.  After our extension is built, we'll end up with a file<br />
"lib/stree/stree.dylib" (or .so depending on your system).  This convention is<br />
important, but I'm going to talk about <em>why</em> it's important in a later post.</p>
<p>When Ruby loads the dynamic library we're building, it must supply us with<br />
some way to define our native methods.  The way it does this is with another<br />
naming convention using the dynamic library's file name.  When "stree.dylib"<br />
is loaded, ruby will automatically try to call a function called "Init_stree".<br />
The second part matches the name of the file it loaded.  In the Init_stree<br />
function is where we'll do our native extension initialization.</p>
<p>In stree.c, define the Init_stree function to look like this:</p>
<pre><code>#include &lt;ruby.h&gt;
void Init_stree()
{
  VALUE mStree = rb_define_module("Stree");
  rb_define_singleton_method(mStree, "hello_world", hello_world, 0);
}
</code></pre>
<p>This function does two things, defines the "Stree" module, and the "hello_world"<br />
method on the Stree module.</p>
<p>The first line actually defines the module, the second line tells ruby to<br />
define the singleton method "hello_world", and when that method gets called,<br />
to call the "hello_world" C function pointer.  The 0 indicates the number of<br />
arguments.</p>
<p>Let's actually add the hello_world C function now:</p>
<pre><code>static VALUE hello_world(VALUE mod)
{
  return rb_str_new2("hello world");
}
</code></pre>
<p>We declare this function as static because it's not needed outside this file.<br />
All ruby methods must return a VALUE.  The first argument to the C function is<br />
always the recipient of the message, in this case it will be the Stree module.</p>
<p>We create a new ruby string with rb_str_new2() and return it.</p>
<p>The final stree.c file should look like this:</p>
<pre><code>#include &lt;ruby.h&gt;

static VALUE hello_world(VALUE klass)
{
  return rb_str_new2("hello world");
}

void Init_stree()
{
  VALUE mStree = rb_define_module("Stree");
  rb_define_singleton_method(mStree, "hello_world", hello_world, 0);
}
</code></pre>
<h3>A note on types.</h3>
<p>When we write ruby, everything is an object.  When we write ruby in C,<br />
everything is a VALUE.  We'll learn more about the VALUE type in later posts.</p>
<h2>Finishing up</h2>
<p>We've written our C code, everything should now compile and copy in to the<br />
right place, but our tests are still failing.  What gives?</p>
<p>We've got one more tiny modification to make.  We need to actually require<br />
the dynamic library that we built.  Open up "lib/stree.rb" and modify it to<br />
look like this:</p>
<pre><code>require 'stree/stree'

module Stree
  VERSION = '1.0.0'
end
</code></pre>
<p>We've now told ruby to load the dynamic library we built, and changed the<br />
definition of Stree to a module in our ruby code.  At this point, our test<br />
should be passing.  Congratulations!  You have now successfully mixed C and<br />
Ruby code.</p>
<p>If you were successful, your project tree should look like this:</p>
<pre><code>$ tree -I tmp
.
|-- CHANGELOG.rdoc
|-- Manifest.txt
|-- README.rdoc
|-- Rakefile
|-- ext
|   `-- stree
|       |-- extconf.rb
|       `-- stree.c
|-- lib
|   |-- stree
|   |   `-- stree.bundle
|   `-- stree.rb
`-- test
    `-- test_stree.rb
</code></pre>
<p>The "tmp" directory is where rake-compiler stashes your .o files when<br />
compiling your extension.  I've omitted that from the tree to keep it short.</p>
<h2>Last notes</h2>
<p>I've <a href="http://github.com/tenderlove/stree">posted the code for stree here</a> in case you're having troubles.  I've<br />
made tags for each post so you can follow along.</p>
<p>Next time, we'll tackle making sure libstree is installed, compiling and<br />
linking against libstree, and making a few calls in to libstree from Ruby.</p>
<p>In the mean time, your homework is to <a href="http://github.com/shyouhei/ruby/blob/trunk/README.EXT">read through README.EXT</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2009/12/18/writing-ruby-c-extensions-part-1/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Rubyconf 2009 Slides</title>
		<link>http://tenderlovemaking.com/2009/12/07/rubyconf-2009-slides/</link>
		<comments>http://tenderlovemaking.com/2009/12/07/rubyconf-2009-slides/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 01:05:48 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=405</guid>
		<description><![CDATA[I&#8217;ve posted the slides for the talk that Ryan and I gave at Rubyconf 2009. You can grab the pdf here. I&#8217;ve also put them on slideshare here. I replaced the videos in the slides with links to youtube. If you want to jump straight to the videos though, you can find them here, here, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve posted the slides for the <a href="http://www.rubyconf.org/talks/60-worst-ideas-ever-">talk that Ryan and I gave</a> at Rubyconf 2009.</p>
<p>You can grab the <a href="http://tenderlovemaking.com/ZOMG_Horrible.pdf">pdf here</a>.</p>
<p>I&#8217;ve also <a href="http://www.slideshare.net/tenderlove/worst-ideas-ever">put them on slideshare here</a>.</p>
<p>I replaced the videos in the slides with links to youtube.  If you want to jump straight to the videos though, you can find them <a href="http://www.youtube.com/watch?v=MXERy8Y2eVo">here</a>, <a href="http://www.youtube.com/watch?v=ar2eqEoMUTw">here</a>, and <a href="http://www.youtube.com/watch?v=lsWKjS6Vufw">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2009/12/07/rubyconf-2009-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Full Text Search on Heroku</title>
		<link>http://tenderlovemaking.com/2009/10/17/full-text-search-on-heroku/</link>
		<comments>http://tenderlovemaking.com/2009/10/17/full-text-search-on-heroku/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 23:29:50 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>
		<category><![CDATA[texticle]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=369</guid>
		<description><![CDATA[YA!! IT&#8217;S SATURDAY NIGHT! YOU ALL KNOW WHAT THAT MEANS! Time to get krunk and do some full text searching. OW! I&#8217;d like to share with my tens of loyal readers how I&#8217;m doing Full Text Search on Heroku. Heroku&#8217;s documentation lists two ways to get full text indexing working with your Heroku application. They [...]]]></description>
			<content:encoded><![CDATA[<p>YA!!  IT&#8217;S <strong>SATURDAY NIGHT</strong>!  YOU ALL KNOW WHAT THAT MEANS!  Time to get krunk and do some <strong>full text searching</strong>.  OW!  I&#8217;d like to share with my tens of loyal readers how I&#8217;m doing Full Text Search on Heroku.</p>
<p>Heroku&#8217;s documentation <a href="http://docs.heroku.com/full-text-indexing">lists two ways</a> to get full text indexing working with your Heroku application.  They talk about using <a href="http://www.davebalmain.com/">Ferret</a> and <a href="http://lucene.apache.org/solr/">Solr</a> for full text indexes.  The Ferret option looks OK, but it requires you to rebuild your indexes every time you push.  Solr would work, but it requires an EC2 instance or some third party server.  Since my budget is precisely $0, using Solr is out of the picture.</p>
<p>But there is a third option.  A very <em>secret</em> option.  A devious but fun option.  You see, <a href="http://docs.heroku.com/database">Heroku runs PostgreSQL</a> for each rails application database.  They&#8217;re running a version new enough (Version 8.3) to have full text index support built in.  If we&#8217;re willing to throw out database agnosticism, we can take advantage of the database&#8217;s indexing capability.  For this article, I&#8217;d like to hop on the Postgres train and show you how to get full text indexes working with Postgres in your rails application.  I&#8217;ll also show you how to get those indexes on Heroku so we can use them &#8220;in the cloud&#8221; (Heroku is in the cloud, right?).</p>
<p>For the rest of this article, I&#8217;m going to assume you have PostgreSQL version 8.3 or higher installed already and can get your rails application working with Postgres.  Installing postgres is outside the scope of this article, but I found <a href="http://www.gregbenedict.com/2009/08/31/installing-postgresql-on-snow-leopard-10-6/">these instructions</a> to be very helpful.</p>
<h3>Step 1: Go get some coffee</h3>
<p>I love it when instructions tell me to go get some coffee because I always do.  I have to follow the instructions right?</p>
<h3>Step 2: Install Texticle</h3>
<p><a href="http://texticle.rubyforge.org/">Texticle</a> is a gem I wrote to help you define your text indexes on a per model basis.  To install texticle, we just do the normal gem install:</p>
<pre>
  $ sudo gem install texticle
</pre>
<p>The gem is pure ruby and isn&#8217;t very long, so I encourage you to <a href="http://github.com/tenderlove/texticle">peek through the source</a>.</p>
<p>While we&#8217;re at it, we should configure rails to load the texticle gem.  We need to add it to our envoronment.rb file.  Here&#8217;s what mine looks like:</p>
<pre class="brush: ruby;">
RAILS_GEM_VERSION = '2.3.4' unless defined? RAILS_GEM_VERSION

require File.join(File.dirname(__FILE__), 'boot')

Rails::Initializer.run do |config|
  config.time_zone = 'UTC'

  config.gem 'texticle'
end
</pre>
<p>Texticle also comes with some handy rake tasks (which we&#8217;ll talk about later).  In order to get those we&#8217;ll need update the rails Rakefile:</p>
<pre class="brush: ruby;">
require(File.join(File.dirname(__FILE__), 'config', 'boot'))

require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'

require 'tasks/rails'

require 'rubygems'

## Our texticle rake tasks
require 'texticle/tasks'
</pre>
<h3>Step 3: Configuring your index</h3>
<p>Let&#8217;s pretend we have an Article model.  The Article model has a &#8220;title&#8221; field and a &#8220;body&#8221; field:</p>
<pre class="brush: ruby;">
class CreateArticles &lt; ActiveRecord::Migration
  def self.up
    create_table :articles do |t|
      t.string :title
      t.text   :body

      t.timestamps
    end
  end

  def self.down
    drop_table :articles
  end
end
</pre>
<p>To index those two fields, we just create an index block in the model and list the fields we want to index:</p>
<pre class="brush: ruby;">
class Article &lt; ActiveRecord::Base
  index do
    title
    body
  end
end
</pre>
<p>Declaring this index automatically defines a &#8220;search&#8221; method on the model that we can use to search our articles:</p>
<pre class="brush: ruby;">
&gt;&gt; Article.search('coffee instruction')
=&gt; [#&lt;Article id: 4, title: &quot;coffee&quot;, body: &quot;I like getting coffee to be in instructions&quot;, created_at: &quot;2009-10-17 21:42:13&quot;, updated_at: &quot;2009-10-17 21:42:13&quot;&gt;]
&gt;&gt; Article.create(:title =&gt; 'kittens', :body =&gt; 'kitten poop smells bad, but I still like kittens.')
=&gt; #&lt;Article id: 5, title: &quot;kittens&quot;, body: &quot;kitten poop smells bad, but I still like kittens.&quot;, created_at: &quot;2009-10-17 21:42:33&quot;, updated_at: &quot;2009-10-17 21:42:33&quot;&gt;
&gt;&gt; Article.search('kittens')
=&gt; [#&lt;Article id: 5, title: &quot;kittens&quot;, body: &quot;kitten poop smells bad, but I still like kittens.&quot;, created_at: &quot;2009-10-17 21:42:33&quot;, updated_at: &quot;2009-10-17 21:42:33&quot;&gt;]
&gt;&gt;
</pre>
<p>Great!  We can search our records.  There&#8217;s just one catch: we haven&#8217;t indexed our data.  Doing these types of searches will be slow against large sets of data unless we add an index.  Writing these indexes is a PITA, so texticle comes with a handy rake task for generating a migration to create your indexes:</p>
<pre>
  $ rake texticle:migration
  $ rake db:migrate
</pre>
<p>After running this, Postgres can use the prebuilt indexes when searching your data.</p>
<p>Just remember: every time you modify columns in your index block, or add new index blocks, you should create a new migration to updated the indexes.  If you don&#8217;t update the indexes, searches will still work as expected, they just might be kind of slow.</p>
<h3>Step 4: Integrating With Heroku</h3>
<p>This part is pretty easy.  First we update our <a href="http://blog.heroku.com/archives/2009/3/10/gem_manifests/">heroku gem manifest</a>:</p>
<pre>
  $ echo "texticle" >> .gems
  $ git add .gems
  $ git commit -m'updating gem manifest'
  $ git push origin master
</pre>
<p>Once your code is up on heroku, just tell heroku to migrate the database:</p>
<pre>
  $ heroku rake db:migrate
</pre>
<p>It&#8217;s just that easy!  Your indexes should be available on the Heroku database server and your application can use them.</p>
<h3>Advanced Texticle Usage</h3>
<p>Texticle has a few more features I&#8217;d like to briefly mention.  The first one is search ranking.  We can tell Postgres which field has a higher priority.  For example, we can tell Postgres to weigh matches in the article&#8217;s title higher than matches in the body:</p>
<pre class="brush: ruby;">
class Article &lt; ActiveRecord::Base
  index do
    title 'A'
    body  'B'
  end
end
</pre>
<p>The ranks are &#8216;A&#8217; through &#8216;D&#8217;, and multiple fields can have the same rank.</p>
<p>We can also group indexes.  The index we&#8217;ve seen so far will search all columns listed.  We can add another index so that we only search the &#8220;title&#8221; field:</p>
<pre class="brush: ruby;">
class Article &lt; ActiveRecord::Base
  index do
    title 'A'
    body  'B'
  end

  index('title') { title }
end
</pre>
<p>This gives us a &#8220;search_title&#8221; method in addition to the &#8220;search&#8221; method:</p>
<pre class="brush: ruby;">
&gt;&gt; Article.search_title('kittens')
=&gt; [#&lt;Article id: 5, title: &quot;kittens&quot;, body: &quot;kitten poop smells bad, but I still like kittens.&quot;, created_at: &quot;2009-10-17 21:42:33&quot;, updated_at: &quot;2009-10-17 21:42:33&quot;&gt;]
&gt;&gt;
</pre>
<p>The last thing I want to mention is &#8220;rank&#8221;.  When you perform a search, texticle adds an extra field to your model called &#8220;rank&#8221;.  The rank indicates how well your record matched the search criteria:</p>
<pre class="brush: ruby;">
&gt;&gt; Article.search('like').map { |x| x.rank }
=&gt; [&quot;0.4&quot;, &quot;0.4&quot;]
&gt;&gt; Article.search('coffee').map { |x| x.rank }
=&gt; [&quot;1.4&quot;]
&gt;&gt;
</pre>
<p>Search results are already returned sorted by rank in descending order, so no need to worry about sorting.</p>
<h3>Conclusion</h3>
<p>I hope you enjoy tickling text with texticle as much as I do.  So far, I&#8217;ve been pretty happy with this solution.</p>
<p>Things I like:</p>
<ul>
<li>It&#8217;s the right price for use with Heroku (namely $0)</li>
<li>Easy to configure and deploy</li>
<li>No need to rebuild indexes on pushes</li>
<li>Postgres can be configured to use different dictionaries, so you aren&#8217;t stuck with English</li>
</ul>
<p>The only drawbacks I&#8217;ve found so far are:</p>
<ul>
<li>INSERTs and UPDATEs are slower</li>
<li>It&#8217;s database specific</li>
</ul>
<p>Inserts and updates will be slower, but that comes with the territory of adding database indexes.  My data is mostly doing reads, so it doesn&#8217;t bother me.  Texticle <strong>is</strong> database specific, but other databases are starting to have full text search support.  I think texticle could be extended to support other databases, but I&#8217;m quite happy with postgres.</p>
<p>Anyway, thanks for reading.  The final step is that you should go get another cup of coffee.</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2009/10/17/full-text-search-on-heroku/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Ruby and RFID tags</title>
		<link>http://tenderlovemaking.com/2009/09/19/ruby-and-rfid-tags/</link>
		<comments>http://tenderlovemaking.com/2009/09/19/ruby-and-rfid-tags/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 05:52:26 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>
		<category><![CDATA[nfc]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=358</guid>
		<description><![CDATA[It&#8217;s been forever since I&#8217;ve written a blog entry, so LETS DO THIS. I want to talk about reading RFID tags with Ruby. I am a nerd, so even though I can&#8217;t think of a good application, I am compelled to be able to read RFID tags. I love programming Ruby, so of course, I [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been forever since I&#8217;ve written a blog entry, so <strong>LETS DO THIS</strong>.  I want to talk about reading RFID tags with Ruby.  I am a nerd, so even though I can&#8217;t think of a good application, I am <em>compelled</em> to be able to read RFID tags.  I love programming Ruby, so of course, I have to do this with Ruby.</p>
<h3>Getting an RFID Reader</h3>
<p>First thing to do, is buy an RFID reader.  After searching around, I found the <a href="http://www.touchatag.com/">touchatag reader</a>.  I bought the <a href="http://store.touchatag.com/usshop/acatalog/touchatag_starter_pack.html">touchatag starter pack</a>.  It&#8217;s only $40, USB, and comes with 10 RFID tags.  Most importantly, it works well with <a href="http://www.libnfc.org/">libnfc</a> (more about that later).</p>
<p><a href="http://www.flickr.com/photos/aaronp/3935563715/" title="IMG_0315 by fakebeard, on Flickr"><img src="http://farm4.static.flickr.com/3436/3935563715_1f799ab95b.jpg" width="500" height="333" alt="IMG_0315" /></a></p>
<p>The tags that come with the reader have an adhesive back, so you can stick them to stuff.  They also have the unique identifier printed on them so that you can make sure your program output is correct.</p>
<p><a href="http://www.flickr.com/photos/aaronp/3936348912/" title="IMG_0317 by fakebeard, on Flickr"><img src="http://farm4.static.flickr.com/3529/3936348912_36d1b2fe2a_m.jpg" width="240" height="160" alt="IMG_0317" /></a><a href="http://www.flickr.com/photos/aaronp/3936350030/" title="IMG_0318 by fakebeard, on Flickr"><img src="http://farm3.static.flickr.com/2471/3936350030_ea34963cb7_m.jpg" width="240" height="160" alt="IMG_0318" /></a></p>
<h3>Interfacing with the reader</h3>
<p>Now that we&#8217;ve got the reader, let&#8217;s do something with it!  I mentioned earlier that the touchatag reader works with <a href="http://libnfc.org/">libnfc</a>.  Libnfc is a C library that knows how to work with NFC devices (nerd talk for &#8220;RFID readers&#8221;).  I&#8217;ve written a gem called <a href="http://github.com/tenderlove/nfc">nfc</a> that wraps up the C library in to something we can use in Ruby.</p>
<p>First thing we need to do is install libnfc.  I use macports with OS X.  With macports, installing libnfc is quite easy:</p>
<pre>
    $ sudo port install libnfc
</pre>
<p>Installing on linux should be just as easy, but you&#8217;ll need to consult your package manager.  Make sure to install the devel packages too!</p>
<p>After that, simply install the nfc Ruby gem:</p>
<pre>
    $ sudo gem install nfc
</pre>
<p>Now that that is out of the way, we can actually read an RFID tag.  Here is our code:</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'nfc'
# Find a tag
NFC.instance.find do |tag|
  # Print out the tag we find
  p tag
end
</pre>
<p>That&#8217;s it!  Run the code, then touch a tag to the reader, and boom!  We have output.  With the tag I&#8217;m using, the output looks like this:</p>
<pre>
$ ruby -I lib test.rb
(NFC) ISO14443A Tag
 ATQA (SENS_RES): 00  44
    UID (NFCID1): 04  D7  62  91  21  25  80
   SAK (SEL_RES): 00
</pre>
<p>The important part of this output is the UID field.  That field is the unique identifier for this tag.  The identifier comes back as a list of integers, but they are printed on the tag as hex.  We can adjust the program just a little bit to see that list, or to get the same string that&#8217;s printed on the tag:</p>
<pre class="brush: ruby;">
# Find a tag
NFC.instance.find do |tag|
  # Examine the raw numbers
  p tag.uid
  # Get just the UID as a string
  puts tag.to_s
end
</pre>
<p>The output looks like this:</p>
<pre>
$ ruby -I lib test.rb
[4, 215, 98, 145, 33, 37, 128]
04D76291212580
</pre>
<p>That&#8217;s pretty much it.  Unfortunately, I can&#8217;t think of anything fun to do with my tags, but maybe you can!  <a href="http://www.flickr.com/photos/aaronp/3804698617/">I hooked my tags up to the &#8220;say&#8221; command that comes with OS X and made each tag say something different</a>.</p>
<h3>Non-Blocking NFC interaction</h3>
<p>Our previous example blocked until an RFID tag was read.  If you run the program without having an RFID tag on the reader, it will just sit there until it can read a tag.  Sometimes we might want to tell whether or not there is a tag on the reader <em>right now</em>.  In other words, we <em>don&#8217;t</em> want our program to block.</p>
<p>Calling find without providing a block will return immediately:</p>
<pre class="brush: ruby;">
p NFC.instance.find.to_s
</pre>
<p>You&#8217;ll get a return value immediately.  The tag returned will either contain a blank uid, or an actual UID.  Here is the output run once with a tag sitting on the reader, and once without a tag:</p>
<pre>
$ ruby -I lib test.rb
"04D76291212580"
$ ruby -I lib test.rb
""
</pre>
<h3>Conclusion</h3>
<p>That&#8217;s pretty much it.  Interacting with the touchatag reader is quite simple and straight forward.  Currently the nfc gem supports reading ISO1443A tags (the tags that come with the reader).  The reader should be able to read other tag types, but I haven&#8217;t had a chance to get other tags to test.</p>
<p>Touchatag provides an <a href="http://www.touchatag.com/developer/docs/guide">official API</a> for their readers.  But the API seems difficult and is dependent on a network connection.</p>
<p><a href="http://www.flickr.com/photos/aaronp/3804698617/">Here is a video of me reading some tags</a>.<br />
<a href="http://gist.github.com/164896">Here is the code from the video</a>.<br />
<a href="http://www.flickr.com/photos/aaronp/tags/touchatag/">Here you can find more photos of the reader</a>.<br />
Finally, <a href="http://github.com/tenderlove/nfc">here is the source of the NFC gem</a>.</p>
<p>Have fun reading some RFID tags!</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2009/09/19/ruby-and-rfid-tags/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>String Encoding in Ruby 1.9 C extensions</title>
		<link>http://tenderlovemaking.com/2009/06/26/string-encoding-in-ruby-1-9-c-extensions/</link>
		<comments>http://tenderlovemaking.com/2009/06/26/string-encoding-in-ruby-1-9-c-extensions/#comments</comments>
		<pubDate>Fri, 26 Jun 2009 15:48:54 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>
		<category><![CDATA[nokogiri]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=315</guid>
		<description><![CDATA[One of the challenges of developing nokogiri has been dealing with String encodings in C. I would like to present one of the problems encountered, along with a solution. I will be using RubyInline in the examples below, but the C code presented should be easy to port to your own C extensions. Examining the [...]]]></description>
			<content:encoded><![CDATA[<p>One of the challenges of <a href="http://github.com/tenderlove/nokogiri">developing nokogiri</a> has been dealing with String encodings in C.  I would like to present one of the problems encountered, along with a solution.  I will be using <a href="http://rubyforge.org/projects/rubyinline/">RubyInline</a> in the examples below, but the C code presented should be easy to port to your own C extensions.</p>
<h2>Examining the Encoding</h2>
<p>If you&#8217;ve developed a C extension before, you&#8217;re probably familiar with <b>rb_str_new2</b> and friends.  They all basically turn a <b>char *</b> in to a string <b>VALUE</b>.  But in Ruby 1.9, what is the encoding of the returned Ruby String?  Well, using RubyInline, it&#8217;s easy enough to see by calling the &#8220;encoding&#8221; method.  Here is a script that works in Ruby 1.8 and Ruby 1.9:</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'inline'

class HelloWorld
  inline do |builder|
    builder.c '
      static VALUE test() {
        return rb_str_new2(&quot;Hello world&quot;);
      }
    '
  end
end

string = HelloWorld.new.test

if string.respond_to? :encoding
  puts string.encoding
else
  puts string
end
</pre>
<p>In Ruby 1.8, this outputs the string, and in 1.9 we see the encoding.  In 1.9, the encoding returned is <b>ASCII-8BIT</b>.  Now <b>ASCII-8BIT</b> may be the encoding that you want, but then again, it may not.  In Nokogiri, the strings coming from libxml2 are already encoded according to the document declaration.  So strings returned must be marked with the appropriate encoding.  How can we update the encoding?</p>
<h2>Changing the Encoding</h2>
<p>In Ruby 1.9, we get a few new functions specifically for dealing with encoding.  These functions are defined in <b>&lt;ruby/encoding.h&gt;</b>.  We&#8217;re going to be dealing with two of them: <b>rb_enc_find_index</b> and <b>rb_enc_associate_index</b>.</p>
<p>The first function, <b>rb_enc_find_index</b>, given a <b>char *</b> will look up the index of your encoding.  The function takes a string like &#8220;UTF-8&#8243; and returns a magic index number for that encoding.</p>
<p>The second function, <b>rb_enc_associate_index</b>, will associate a string held in a <b>VALUE</b> with the encoding index returned from the first function.</p>
<p>Armed with this knowledge, we can modify our original program to return a string encoded with UTF-8.  The only modifications are to include <b>&lt;ruby/encoding.h&gt;</b>, get the index for the desired encoding, then associate the <b>VALUE</b> with the returned index:</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'inline'

class HelloWorld
  inline do |builder|
    builder.include &quot;&lt;ruby/encoding.h&gt;&quot;

    builder.c '
      static VALUE test() {
        VALUE string = rb_str_new2(&quot;Hello World&quot;);
        int enc = rb_enc_find_index(&quot;UTF-8&quot;);
        rb_enc_associate_index(string, enc);
        return string;
      }
    '
  end
end

string = HelloWorld.new.test

if string.respond_to? :encoding
  puts string.encoding
else
  puts string
end
</pre>
<p>Great!  When this is run under Ruby 1.9, the encoding returned is UTF-8.  Unfortunately, this example is now specific for Ruby 1.9.  Ruby 1.8 does not ship with the correct header files, and definitely does not include the functions for looking up and assigning encoding.  This code will just not work under Ruby 1.8.  Luckily, this code can be refactored to work under either version of Ruby.</p>
<h2>Refactoring for 1.8 Support</h2>
<p>Both Ruby 1.8 and 1.9 provide a <b>&lt;ruby.h&gt;</b> header file.  The Ruby 1.9 version of that file defines a constant <b>HAVE_RUBY_ENCODING_H</b> that lets us determine whether the proper header file exists.  Our final attempt tests for the encoding constant, then defines a macro to wrap <b>rb_str_new2</b>.  If the version of Ruby we compile against has encoding support, the macro can add the encoding to the string, otherwise, it just ignores the encoding:</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'inline'

class HelloWorld
  inline do |builder|

    builder.prefix &lt;&lt;-eoc
#include &lt;ruby.h&gt;

#ifdef HAVE_RUBY_ENCODING_H

#include &lt;ruby/encoding.h&gt;

#define ENCODED_STR_NEW2(str, encoding) \
  ({ \
    VALUE _string = rb_str_new2((const char *)str); \
    int _enc = rb_enc_find_index(encoding); \
    rb_enc_associate_index(_string, _enc); \
    _string; \
  })

#else

#define ENCODED_STR_NEW2(str, encoding) \
  rb_str_new2((const char *)str)

#endif
    eoc

    builder.c '
      static VALUE test() {
        return ENCODED_STR_NEW2(&quot;Hello world&quot;, &quot;UTF-8&quot;);
      }
    '
  end
end

string = HelloWorld.new.test

if string.respond_to? :encoding
  puts string.encoding
else
  puts string
end
</pre>
<p>In 1.8, the macro just returns the new string.  In 1.9, the macro returns the string and additionally sets the encoding.  Now if we use this macro wherever we create new strings, we&#8217;ll be working well with 1.8 and 1.9!</p>
<h2>Final Notes</h2>
<p>This example was slightly simplified.  Since the encoding index is determined at runtime, there could be problems.  If <b>rb_enc_find_index</b> cannot find the requested encoding, it simply returns a <b>-1</b>.  The macro should handle that case.</p>
<p>Also, if you&#8217;re playing along at home, remember to save the file between running it with 1.8 and 1.9.  RubyInline examines the mtime of the ruby file, and will only recompile when the rb file has been written to.  That means if you run it with 1.8, then immediately run again with 1.9, it won&#8217;t recompile it for 1.9.  I suppose I should send in a patch.  <img src='http://tenderlovemaking.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>One last thing&#8230;  There may be better ways to do this.  I needed to determine the encoding at runtime because XML files declare their encoding scheme.  If you parse an XML file that declares it&#8217;s encoding as EUC-JP, it would make sense that the strings you pull our are encoded in EUC-JP, right?  If you know that you&#8217;re <i>always</i> going to be returning UTF-8 strings from your C extensions, it could be a different story.  Either way, using macros and checking for constants should make sure your code works with 1.8 or 1.9.</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2009/06/26/string-encoding-in-ruby-1-9-c-extensions/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Easy Markup Validation</title>
		<link>http://tenderlovemaking.com/2009/06/12/easy-markup-validation/</link>
		<comments>http://tenderlovemaking.com/2009/06/12/easy-markup-validation/#comments</comments>
		<pubDate>Sat, 13 Jun 2009 00:24:01 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>
		<category><![CDATA[nokogiri]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=302</guid>
		<description><![CDATA[I wanted a test helper that would assert that my XHTML was valid XHTML. So I wrote one and called it &#8220;markup_validity&#8220;. You can use it too, and I will show you how. First, install the gem: $ sudo gem install markup_validity Then, use it in your tests: require 'test/unit' require 'rubygems' require 'markup_validity' class [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted a test helper that would assert that my XHTML was valid XHTML.  So I wrote one and called it &#8220;<a href="http://github.com/tenderlove/markup_validity/tree/master">markup_validity</a>&#8220;.  You can use it too, and I will show you how.</p>
<p>First, install the gem:</p>
<pre>
  $ sudo gem install markup_validity
</pre>
<p>Then, use it in your tests:</p>
<pre class="brush: ruby;">
require 'test/unit'
require 'rubygems'
require 'markup_validity'

class ValidHTML &lt; Test::Unit::TestCase
  def test_i_can_has_valid_xhtml
    assert_xhtml_transitional xhtml_document
  end
end
</pre>
<p>Oh.  You use RSpec?  It supports that too:</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'markup_validity'

describe &quot;my XHTML document&quot; do
  it &quot;can has transitional xhtml&quot; do
    xhtml_document.should be_xhtml_transitional
  end
end
</pre>
<p>Debugging invalid markup can be a pain.  MarkupValidity tries to give you helpful errors to make your life easier.  Say you have an invalid piece of XHTML like this:</p>
<pre class="brush: plain;">
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
  &lt;head&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;
      &lt;p&gt;
        Hello
      &lt;/p&gt;
    &lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The error output from MarkupValidity will be this:</p>
<pre class="brush: plain;">
.Error on line: 2:
Element 'head': Missing child element(s). Expected is one of ( script, style, meta, link, object, isindex, title, base ).

1: &lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
2:   &lt;head&gt;
3:   &lt;/head&gt;
4:   &lt;body&gt;
5:     &lt;p&gt;

Error on line: 6:
Element 'p': This element is not expected. Expected is one of ( a, br, span, bdo, object, applet, img, map, iframe, tt ).

5:     &lt;p&gt;
6:       &lt;p&gt;
7:         Hello
8:       &lt;/p&gt;
9:     &lt;/p&gt;
</pre>
<p>MarkupValidity provides a few assertions for test/unit:</p>
<ul>
<li><b>assert_xhtml_transitional(xhtml)</b> for asserting valid transitional XHTML</li>
<li><b>assert_xhtml_strict(xhtml)</b> for asserting valid strict XHTML</li>
<li><b>assert_schema(schema, xml)</b> for asserting that your xml validates against a schema</li>
<li><b>assert_xhtml</b> which is an alias for assert_xhtml_transitional</li>
</ul>
<p>The methods provided for RSpec are quite similar:</p>
<ul>
<li><b>be_xhtml_transitional</b> for asserting valid transitional XHTML</li>
<li><b>be_xhtml_strict</b> for asserting valid strict XHTML</li>
<li><b>be_valid_with_schema(schema)</b> for asserting that your xml validates against a schema</li>
<li><b>be_xhtml</b> which is an alias for be_xhtml_transitional</li>
</ul>
<p>MarkupValidity even works well with rails.  Here is an example rails controller test:</p>
<pre class="brush: ruby;">
require 'test_helper'
require 'markup_validity'

class AwesomeControllerTest &lt; ActionController::TestCase
  test &quot;valid markup&quot; do
    get :new
    assert_xhtml_transitional @response.body
  end
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2009/06/12/easy-markup-validation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Autotest and Vim integration</title>
		<link>http://tenderlovemaking.com/2009/05/18/autotest-and-vim-integration/</link>
		<comments>http://tenderlovemaking.com/2009/05/18/autotest-and-vim-integration/#comments</comments>
		<pubDate>Tue, 19 May 2009 02:13:39 +0000</pubDate>
		<dc:creator>Aaron Patterson</dc:creator>
				<category><![CDATA[computadora]]></category>

		<guid isPermaLink="false">http://tenderlovemaking.com/?p=289</guid>
		<description><![CDATA[Yay! I got vim and autotest integration working. When I run autotest, if there is an error, I can have Vim read the errors from autotest and jump me to the right place. Here is a video of me using it: Please note that I&#8217;m not copying and pasting anything. In vim, I hit a [...]]]></description>
			<content:encoded><![CDATA[<p>Yay!  I got vim and autotest integration working.  When I run autotest, if there is an error, I can have Vim read the errors from autotest and jump me to the right place.</p>
<p>Here is a video of me using it:</p>
<p><object type="application/x-shockwave-flash" width="641" height="250" data="http://www.flickr.com/apps/video/stewart.swf?v=71377" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"><param name="flashvars" value="intl_lang=en-us&#038;photo_secret=5516478afb&#038;photo_id=3543914385"></param><param name="movie" value="http://www.flickr.com/apps/video/stewart.swf?v=71377"></param><param name="bgcolor" value="#000000"></param><param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/video/stewart.swf?v=71377" bgcolor="#000000" allowfullscreen="true" flashvars="intl_lang=en-us&#038;photo_secret=5516478afb&#038;photo_id=3543914385" height="250" width="641"></embed></object></p>
<p>Please note that I&#8217;m not copying and pasting anything.  In vim, I hit a command and Vim automatically picks up errors from autotest and jumps me to the line where the error occurred.  </p>
<p>You too can impress your friends with this trick!  Here&#8217;s how:</p>
<ol>
<li>Make sure you have <a href="http://vim-ruby.rubyforge.org/">vim-ruby</a> installed</li>
<li>Use this as your .autotest file:
<pre class="brush: ruby;">
require 'autotest/restart'

Autotest.add_hook :initialize do |at|
  at.unit_diff = 'cat'
end

Autotest.add_hook :ran_command do |at|
  File.open('/tmp/autotest.txt', 'wb') { |f|
    f.write(at.results.join)
  }
end
</pre>
</li>
<li>Add this to your .vimrc:<br />
<code><br />
compiler rubyunit<br />
nmap &lt;Leader>fd :cf /tmp/autotest.txt&lt;cr> :compiler rubyunit&lt;cr><br />
</code></li>
</ol>
<p>Now when you get an error in autotest, just type &#8220;\fd&#8221; in Vim to jump straight to your first error.</p>
<p>The contents of /tmp/autotest.txt will be used in your errorfile.  In Vim do &#8220;:help quickfix&#8221; for more info on what you can do with your new found power.</p>
<p>Caveat: You don&#8217;t get unit_diff.  I&#8217;m working on that.  Any help would be much appreciated (I suck at errorformat in Vim).</p>
]]></content:encoded>
			<wfw:commentRss>http://tenderlovemaking.com/2009/05/18/autotest-and-vim-integration/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
