<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Data Noise - Home</title>
  <id>tag:www.datanoise.com,2007:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://www.datanoise.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.datanoise.com/" rel="alternate" type="text/html"/>
  <updated>2007-05-10T04:59:32Z</updated>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-05-10:413</id>
    <published>2007-05-10T04:59:00Z</published>
    <updated>2007-05-10T04:59:32Z</updated>
    <category term="ruby-debug"/>
    <link href="http://www.datanoise.com/articles/2007/5/10/ruby-debug-basics-screencast" rel="alternate" type="text/html"/>
    <title>ruby-debug basics screencast</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://brian.maybeyoureinsane.net/blog/2007/05/07/ruby-debug-basics-screencast/&quot;&gt;Brian Donovan&lt;/a&gt; shows the basics of using ruby-debug. This is very nice addition to my already outdated &lt;a href=&quot;http://datanoise.com/articles/2006/7/12/tutorial-on-ruby-debug&quot;&gt;tutorial&lt;/a&gt;. He also announced that his next screencast will cover debugging of a Rails application. &lt;/p&gt;

&lt;p&gt;One the same note, the next version of Rails comes with the native ruby-debug support. The relevant changeset is &lt;a href=&quot;http://dev.rubyonrails.org/changeset/6611&quot;&gt;here&lt;/a&gt;. &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-04-03:203</id>
    <published>2007-04-03T06:14:00Z</published>
    <updated>2007-05-28T23:20:29Z</updated>
    <category term="ruby-debug"/>
    <link href="http://www.datanoise.com/articles/2007/4/3/ruby-debug-version-0-9-1-has-been-released" rel="alternate" type="text/html"/>
    <title>ruby-debug version 0.9.1 has been released!</title>
<summary type="html">&lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;As usual:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ sudo gem in ruby-debug
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Changes&lt;/h2&gt;

&lt;p&gt;This is mainly a maintenance release, which includes several important bugfixes related to frame calculations. &lt;/p&gt;

&lt;p&gt;In particular,&lt;/p&gt;</summary><content type="html">
            &lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;As usual:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ sudo gem in ruby-debug
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Changes&lt;/h2&gt;

&lt;p&gt;This is mainly a maintenance release, which includes several important bugfixes related to frame calculations. &lt;/p&gt;

&lt;p&gt;In particular,&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;As usual:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ sudo gem in ruby-debug
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Changes&lt;/h2&gt;

&lt;p&gt;This is mainly a maintenance release, which includes several important bugfixes related to frame calculations. &lt;/p&gt;

&lt;p&gt;In particular,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;All native (implemented in C) methods that take a block will create a new frame. What that means is that in the following code in order to reach line 2:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1  (1..10).each do |i|
2    puts i
3  end
4  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;you have to &lt;strong&gt;step&lt;/strong&gt; into the &lt;code&gt;each&lt;/code&gt; method. The &lt;strong&gt;next&lt;/strong&gt; command will move you to line 4 skipping the block.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;next&lt;/strong&gt; command is now 'true' step-over operation. Which means that in the following code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1 def f; 1 end
2 def b; 2 end
3 f; b
4
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;if you are on line 3 you have to call &lt;strong&gt;next&lt;/strong&gt; command twice in order to move to line 4.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Previous change has a subtle side effect when you are debugging ERB templates. You probably already know that you can do that, right? Just set a breakpoint somewhere in your template:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rdebug ./script/server 
./script/server:2 require File.dirname(__FILE__) + '/../config/boot'
[-3, 6] in ./script/server
   1  #!/usr/local/bin/ruby
=&amp;gt; 2  require File.dirname(__FILE__) + '/../config/boot'
   3  require 'commands/server'
(rdb:1) break list.rhtml:1
Set breakpoint 1 at list.rhtml:1


(rdb:1) cont
...
Breakpoint 1 at list.rhtml:1
script/../config/../app/views/bug/list.rhtml:1 &amp;lt;% @title = &quot;Task List&quot; -%&amp;gt;
[-4, 5] in script/../config/../app/views/bug/list.rhtml
=&amp;gt; 1  &amp;lt;% @title = &quot;Task List&quot; -%&amp;gt;
   2  &amp;lt;center&amp;gt;
   3  &amp;lt;% if @list_action and session['filter'] -%&amp;gt;
   4  &amp;lt;div id=&quot;filter&quot;&amp;gt;Applied filter:&amp;amp;nbsp;
   5  &amp;lt;select name=&quot;filters&quot; onchange=&quot;javascript:filterChanged(this);&quot;&amp;gt;


(rdb:6) next
script/../config/../app/views/bug/list.rhtml:2 &amp;lt;center&amp;gt;
[-3, 6] in script/../config/../app/views/bug/list.rhtml
   1  &amp;lt;% @title = &quot;Task List&quot; -%&amp;gt;
=&amp;gt; 2  &amp;lt;center&amp;gt;
   3  &amp;lt;% if @list_action and session['filter'] -%&amp;gt;
   4  &amp;lt;div id=&quot;filter&quot;&amp;gt;Applied filter:&amp;amp;nbsp;
   5  &amp;lt;select name=&quot;filters&quot; onchange=&quot;javascript:filterChanged(this);&quot;&amp;gt;
   6    &amp;lt;option value=&quot;all&quot;&amp;gt;-- Show All --&amp;lt;/option&amp;gt;


(rdb:6) eval @title
&quot;Task List&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and the debugger will stop at the first line of &lt;code&gt;list.rhtml&lt;/code&gt; template file when Rails renders it.&lt;/p&gt;

&lt;p&gt;Stepping through your template works relatively well. The only problem is that sometimes ERB generates several instructions for a single line of template code, so that you have to use &lt;strong&gt;next&lt;/strong&gt; command several times in order to move to the next line. That is where you can find the &lt;em&gt;force (+)&lt;/em&gt; modifier for &lt;strong&gt;step&lt;/strong&gt; and &lt;strong&gt;next&lt;/strong&gt; commands useful. What that means is that &lt;strong&gt;next+&lt;/strong&gt; and &lt;strong&gt;step+&lt;/strong&gt; commands will force the debugger to move to another line.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Disclaimer&lt;/strong&gt;: If you find yourself debugging your templates too often, consider revisiting your development approach. Your code does not belong there.  Also, Ruby provides &lt;a href=&quot;http://rspec.rubyforge.org&quot;&gt;top-of-the-art&lt;/a&gt; &lt;a href=&quot;http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/index.html&quot;&gt;unit-test&lt;/a&gt; libraries for you. Use them!&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And, finally, starting from this version you can pass the &lt;strong&gt;cont&lt;/strong&gt;-inue command a numerical parameter which makes the debugger to continue until it reaches a specific line of code. This is sort of &lt;em&gt;'Run to Cursor'&lt;/em&gt; command found in modern GUI debuggers. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-03-23:174</id>
    <published>2007-03-23T06:39:00Z</published>
    <updated>2007-03-23T15:33:54Z</updated>
    <category term="Rails"/>
    <link href="http://www.datanoise.com/articles/2007/3/23/acts_as_sphinx-plugin" rel="alternate" type="text/html"/>
    <title>acts_as_sphinx plugin</title>
<summary type="html">&lt;p&gt;We can't imagine a web site without at least a rudimentary search functionality. What a frustration when we shop for a particular product or looking for an answer on a community web site and can't find exactly what we are looking for. The search is the paramount for any online business. If a customer can't find a product she's looking for, she would go somewhere else and you lose a sale. &lt;/p&gt;

&lt;p&gt;Unfortunately, most of the databases don't provide full-text search capabilities or provide a minimal support which is not enough in most of the cases. &lt;/p&gt;</summary><content type="html">
            &lt;p&gt;We can't imagine a web site without at least a rudimentary search functionality. What a frustration when we shop for a particular product or looking for an answer on a community web site and can't find exactly what we are looking for. The search is the paramount for any online business. If a customer can't find a product she's looking for, she would go somewhere else and you lose a sale. &lt;/p&gt;

&lt;p&gt;Unfortunately, most of the databases don't provide full-text search capabilities or provide a minimal support which is not enough in most of the cases. &lt;/p&gt;
&lt;p&gt;We can't imagine a web site without at least a rudimentary search functionality. What a frustration when we shop for a particular product or looking for an answer on a community web site and can't find exactly what we are looking for. The search is the paramount for any online business. If a customer can't find a product she's looking for, she would go somewhere else and you lose a sale. &lt;/p&gt;

&lt;p&gt;Unfortunately, most of the databases don't provide full-text search capabilities or provide a minimal support which is not enough in most of the cases. &lt;/p&gt;

&lt;p&gt;There are several options for Ruby developer to choose from. First of all is wonderful &lt;a href=&quot;http://ferret.davebalmain.com/trac/&quot;&gt;Ferret&lt;/a&gt;. This library rocks! I've already written an &lt;a href=&quot;http://datanoise.com/articles/2006/9/5/fun-with-ferret&quot;&gt;article&lt;/a&gt; of how to use it to index your &lt;code&gt;ri&lt;/code&gt; database. It provides a very reach API that is based on &lt;a href=&quot;http://lucene.apache.org/java/docs/&quot; title=&quot;Apache Lucene - Overview&quot;&gt;Apache Lucene&lt;/a&gt; library. And it is considered the one of the fastest implementations of &lt;a href=&quot;http://en.wikipedia.org/wiki/Information_retrieval&quot;&gt;IR library&lt;/a&gt; out there. So, if you really need to add a functionality that goes beyond plain search capabilities, like adding the highlighting to your search results, using a specific analyzer, or keeping the real data along with your index, you should definitely consider this library. The integration becomes even simpler, because of the work being done by Jens Kramer with his &lt;a href=&quot;http://projects.jkraemer.net/acts_as_ferret/wiki&quot;&gt;&lt;code&gt;acts_as_ferret&lt;/code&gt;&lt;/a&gt; plugin. There is also very informative and detailed &lt;a href=&quot;http://www.railsenvy.com/2007/2/19/acts-as-ferret-tutorial&quot;&gt;article&lt;/a&gt; by guys from RailsEnvy blog.&lt;/p&gt;

&lt;p&gt;But there is another solution for the same problem and, from my prospective, it is much easier to use and install.&lt;/p&gt;

&lt;h1&gt;Introducing sphinx&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://www.sphinxsearch.com&quot;&gt;Sphinx&lt;/a&gt;&lt;/strong&gt; is being developed by a Russian programmer Andrew Aksyonoff. It's a general purpose IR library. What makes it so special is the incredible, jaw-dropping speed of searching and indexing. There are several posts written by developers of &lt;a href=&quot;http://www.mysqlperformanceblog.com/&quot;&gt;MySQL Performance Blog&lt;/a&gt; that advertise sphinx as a powerful search engine software. In &lt;a href=&quot;http://www.mysqlperformanceblog.com/2006/11/29/boardreader-forum-search-engine/&quot;&gt;this post&lt;/a&gt; they describe how sphinx is being used in one of their commercial projects. I've been using it in one of my projects for several months already and it proved to be very fast and stable.&lt;/p&gt;

&lt;p&gt;What makes it so fast, I think, besides of cause the genius of Andrew, is that sphinx provides the tradeoff of the available functionality in favor of speed. There is just not so much you can tweak with the provided API. But, mind you, the API covers more than 95% of all cases that you need for a general purpose search functionality required by most web sites. Also the latest versions come with the &quot;extended&quot; search mode, that moves this library closer to its competitors.&lt;/p&gt;

&lt;p&gt;OK, in order to use it, you need to install it first. Let's see how we do it:&lt;/p&gt;

&lt;h2&gt;Installation procedure&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You can download it from &lt;a href=&quot;http://www.sphinxsearch.com/downloads.html&quot;&gt;the Andrew's website&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ wget http://www.sphinxsearch.com/downloads/sphinx-0.9.7-rc2.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the standard installation procedure.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; sudo make install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By completing these steps you have installed three applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;searchd&lt;/code&gt;&lt;/strong&gt; is a daemon process that serves incoming search requests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;indexer&lt;/code&gt;&lt;/strong&gt; is an application that builds your index.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;search&lt;/code&gt;&lt;/strong&gt; is an application for testing your queries.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In order to make it all work you need to create a configuration file. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Sphinx configuration file&lt;/h2&gt;

&lt;p&gt;I'm going to demonstrate how to create an example configuration file based on a simple database called &lt;code&gt;mydatabase&lt;/code&gt; that has two tables: &lt;em&gt;products&lt;/em&gt; and &lt;em&gt;brands&lt;/em&gt;. &lt;em&gt;products&lt;/em&gt; table has a foreign key to &lt;em&gt;brands&lt;/em&gt; table. &lt;/p&gt;

&lt;p&gt;First of all, we define a data source for our index:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    source products
    {
        type                = mysql
        sql_host            = localhost
        sql_user            = root
        sql_pass            = myrootpwd
        sql_db              = mydatabase
        sql_sock            = /tmp/mysql.sock

        sql_query           = \
         SELECT products.id, products.name, brands.name, products.description \
         FROM products INNER JOIN brands ON products.brand_id = brands.id
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can use either &lt;em&gt;Mysql&lt;/em&gt; or &lt;em&gt;Postgres&lt;/em&gt; databases. There is also an option to use plain files for your datasource, please refer to the &lt;em&gt;sphinx&lt;/em&gt; documentation. The &lt;code&gt;type&lt;/code&gt; parameter defines what type of the database you are using and the rest of &lt;code&gt;sql_*&lt;/code&gt; parameters define how to access your database. The &lt;code&gt;sql_query&lt;/code&gt; parameter provides a query which &lt;em&gt;sphinx&lt;/em&gt; will be using for indexing. As you can see, our data has four fields. The first field must always be &lt;em&gt;the document id&lt;/em&gt;, which sphinx returns as the result of a query. All other three fields will be used in your searches and you can assign a specific relevance weight to each of them.&lt;/p&gt;

&lt;p&gt;Now we define our index itself:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    index products
    {
        source          = products
        path            = ../sphinx/products

        # morphology
        morphology          = stem_en
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here we specify the data source for our index that we previously defined and where to store index files. Optionally, you can set several other attributes. Here, for example, I decided to use a particular morphology algorithm. For more options, consult the &lt;em&gt;sphinx&lt;/em&gt; documentation.&lt;/p&gt;

&lt;p&gt;In our last step, we provide options for the &lt;code&gt;indexer&lt;/code&gt; application and &lt;code&gt;searchd&lt;/code&gt; server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    indexer
    {
        # memory limit
        mem_limit           = 32M
    }

    searchd
    {
        address             = 127.0.0.1
        port                = 3312
        log                 = ../log/searchd.log
        query_log           = ../log/searchd_query.log
        read_timeout        = 5
        max_children        = 30
        pid_file            = ../log/searchd.pid
        max_matches         = 1000
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These are more or less self-explanatory. You can find the whole configuration file here: &lt;a href=&quot;http://datanoise.com/assets/2007/3/23/sphinx.conf&quot;&gt;sphinx.conf&lt;/a&gt;.
Move this file to your &lt;code&gt;&amp;lt;rails-app&amp;gt;/config&lt;/code&gt; directory.&lt;/p&gt;

&lt;h2&gt;Introducing acts_as_sphinx plugin&lt;/h2&gt;

&lt;p&gt;You can install this plugin by running this command from the top directory of your Rails application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ ./script/plugin install http://svn.datanoise.com/acts_as_sphinx
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This plugin extends your &lt;code&gt;ActiveRecord&lt;/code&gt; model classes by adding sphinx search methods. This plugin uses &lt;code&gt;sphinx.rb&lt;/code&gt; API library developed by Dmytro Shteflyuk that now is included with the sphinx package. Read &lt;a href=&quot;http://feeds.feedburner.com/~r/kpumuk/~3/54123360/&quot;&gt;Dmytro's post&lt;/a&gt; for more details about it.&lt;/p&gt;

&lt;p&gt;Here is how you use this plugin:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We create a model class for each of our tables:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./script/generate model product
$ ./script/generate model brand
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since we defined &lt;em&gt;products&lt;/em&gt; index in our configuration file, we are going to extend the corresponding &lt;code&gt;Product&lt;/code&gt; model. Open &lt;code&gt;app/model/product.rb&lt;/code&gt; and modify it as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Product &amp;lt; ActiveRecord::Base
   belongs_to :brand
   acts_as_sphinx
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;acts_as_sphinx&lt;/code&gt; macro modifies our Product class and introduces two methods: &lt;code&gt;Product.ask_sphinx&lt;/code&gt; and &lt;code&gt;Product.find_with_sphinx&lt;/code&gt;. By default, it uses the name of the table associated with the model class as the name of the index. So in this case, &lt;code&gt;Product.find_with_sphinx&lt;/code&gt; will be using our &lt;em&gt;products&lt;/em&gt; index. Refer to &lt;code&gt;acts_as_sphinx&lt;/code&gt; source code for the detailed documentation of these methods.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now we need to prepare our index data. &lt;code&gt;acts_as_sphinx&lt;/code&gt; introduces several rake tasks in &lt;code&gt;sphinx:&lt;/code&gt; namespace: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sphinx:index&lt;/strong&gt;  - creates/rebuilds all indexes defined in &lt;code&gt;&amp;lt;rails-app&amp;gt;/config/sphinx.conf&lt;/code&gt; file. &lt;em&gt;Note that &lt;code&gt;searchd&lt;/code&gt; daemon must be stopped when you run this task!&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sphinx:start&lt;/strong&gt;  - starts &lt;code&gt;searchd&lt;/code&gt; daemon using settings from &lt;code&gt;&amp;lt;rails-app&amp;gt;/config/sphinx.conf&lt;/code&gt; file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sphinx:stop&lt;/strong&gt;   - stops &lt;code&gt;searchd&lt;/code&gt; daemon&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sphinx:rotate&lt;/strong&gt; - rebuilds all indexes and sends &lt;code&gt;searchd&lt;/code&gt; daemon a signal to read new index files. &lt;em&gt;Note that &lt;code&gt;searchd&lt;/code&gt; must be running when using this task!&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This way, in order to build our initial index data, we use these commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ make sphinx
$ rake sphinx:index
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OK, we are ready to start sphinx server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rake sphinx:start
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now let's test our new search engine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./script/console
&amp;gt;&amp;gt; res = Product.find_with_sphinx 'ipod'
=&amp;gt; ...
&amp;gt;&amp;gt; res.total
=&amp;gt; 3
&amp;gt;&amp;gt; res.time
=&amp;gt; &quot;0.00&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Basic query functionality&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;find_with_sphinx&lt;/code&gt; method takes all parameters that you can pass to &lt;code&gt;ActiveRecord::Base#find&lt;/code&gt; method plus a special :sphinx key. This key points to a hash of sphinx specific parameters. These are some of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;:mode&lt;/code&gt;       defines the search mode (:all, :any, :boolean, :extended)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;:limit&lt;/code&gt;      restricts result to a specified number of objects, default is 20&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;:offset&lt;/code&gt;     returns results from a specific offset, default is 0&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;:page&lt;/code&gt;       can be used instead of :offset option to specify the page number&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;:index&lt;/code&gt;      overrides the default index name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;:weight&lt;/code&gt;     is an array of weights for each index component (used in the relevance algorithm)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, to make product and brand names more preferable than the product description:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    Product.find_with_sphinx query, :sphinx =&amp;gt; {:width =&amp;gt; [100, 100, 50]}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Pagination with acts_as_sphinx&lt;/h2&gt;

&lt;p&gt;It's quite easy to use Rails pagination with this plugin. Following the example from &lt;code&gt;acts_as_ferrent&lt;/code&gt; article:&lt;/p&gt;

&lt;p&gt;add to your &lt;code&gt;app/controllers/application.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    PER_PAGE = 10 unless defined? PER_PAGE

    def pages_for(size, options = {})
      default_options = {:per_page =&amp;gt; PER_PAGE}
      options = default_options.merge(options)
      Paginator.new self, size, options[:per_page], (options[:page] || 1)
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;add to &lt;code&gt;app/controllers/product_controller.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    @products = Product.find_with_sphinx query, :include =&amp;gt; :brand,
      :sphinx =&amp;gt; {:limit =&amp;gt; PER_PAGE, :page =&amp;gt; @page}
    @product_pages = pages_for @products.total, :page =&amp;gt; @page
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and you are good to go.&lt;/p&gt;

&lt;h2&gt;Index live updates&lt;/h2&gt;

&lt;p&gt;This is probably not a good idea to update your index on every change to your model objects. That's why &lt;code&gt;acts_as_sphinx&lt;/code&gt; doesn't provide any callback methods. Instead, I would recommend to schedule your index updates once or several times a day depending on your needs. It all depends on your particular case, the size of your database, and the frequency of updates. If you have a huge database you can use &lt;a href=&quot;http://www.sphinxsearch.com/doc.html#live-updates&quot;&gt;&lt;em&gt;main+delta&lt;/em&gt; update schema&lt;/a&gt; as described in the sphinx documentation. Personally I am using cron job to rotate my index every three hours using &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ rake sphinx:rotate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;command. &lt;/p&gt;

&lt;p&gt;Also &lt;strong&gt;sphinx&lt;/strong&gt; provides a very nice feature where you can partition your index and serve each part from a separate server. In order to query all this parts at the same time you define an index of a special &lt;strong&gt;distributed&lt;/strong&gt; type. This way you can have the main infrequently modified index on one server and keep deltas on another. Once again, refer to the sphinx documentation for more information.&lt;/p&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Sphinx&lt;/strong&gt; library is a very powerful tool and useful addition to your website. &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-03-19:160</id>
    <published>2007-03-19T18:16:00Z</published>
    <updated>2007-03-20T21:47:53Z</updated>
    <category term="TextMate"/>
    <link href="http://www.datanoise.com/articles/2007/3/19/textmate-and-quick-searches" rel="alternate" type="text/html"/>
    <title>TextMate and Quick Searches</title>
<content type="html">
            &lt;p&gt;I've been using &lt;strong&gt;&lt;a href=&quot;http://macromates.com/&quot;&gt;TextMate&lt;/a&gt;&lt;/strong&gt; since probably the first public version. At least my license dialog shows &lt;em&gt;October 6th 2004, Serial Number #60&lt;/em&gt;. And, oh boy, I've been a happy user. I can't declare that this is the best editor out there, and I don't want to start another editor vs war. I've been using Vi(m)/emacs for such a long time that I can't even remember and I'm not going to give up on them just yet. But I can say that &lt;strong&gt;TextMate&lt;/strong&gt; is definitely a unique piece of software that sets a high mark for other editors to follow.&lt;/p&gt;

&lt;p&gt;I think the most innovative feature of this editor is the way it represents the document structure with &lt;a href=&quot;http://macromates.com/textmate/manual/scope_selectors#scope_selectors&quot;&gt;scopes&lt;/a&gt;. Everything else is built around this structure: shortcuts, snippets, commands, code highlighting, etc. This very feature makes it so much easier to customize your editor, than anything I've seen so far. (Whatever I've tried I couldn't make mmm-mode package work for me).&lt;/p&gt;

&lt;p&gt;Another thing that I'd love to have from any editor is a desktop integration. Don't get me wrong, I'm an avid terminal and CLI proponent, but I've access to the most powerful desktop out there and it would be sad if I can't enjoy it when I'm writing my documents. And &lt;strong&gt;TextMate&lt;/strong&gt; allows me enjoying both of these worlds.&lt;/p&gt;

&lt;p&gt;OK, enough of &lt;strong&gt;TextMate&lt;/strong&gt; praises, there are still some areas where this editor needs some love. One of them is the search capability. The regular and incremental searches are fine, I'm talking about the &lt;em&gt;Find in Project&lt;/em&gt; search. First of all, it's quite slow and it used to take a lot of your RAM. Second of all, I've found that in about 95% of all cases, I need to search in a particular directory of my project. So I did what everyone else does, I created my own command, which I am about to share with you.&lt;/p&gt;

&lt;div&gt;&lt;/div&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-03-16:152</id>
    <published>2007-03-16T02:24:00Z</published>
    <updated>2007-03-17T04:54:06Z</updated>
    <category term="Rails"/>
    <category term="TextMate"/>
    <link href="http://www.datanoise.com/articles/2007/3/16/entering-fixtures-with-textmate" rel="alternate" type="text/html"/>
    <title>Entering fixtures with TextMate</title>
<summary type="html">&lt;p&gt;Probably the most boring task when writing Rails test cases is entering new fixtures. With a little help from TextMate this process can be made more pleasant. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open &lt;strong&gt;Bundle Editor&lt;/strong&gt; and create a new command.&lt;/li&gt;
&lt;li&gt;Name it, for example, 'rails: new fixture'&lt;/li&gt;
&lt;li&gt;Use this script as the command body:&lt;/li&gt;
&lt;/ul&gt;</summary><content type="html">
            &lt;p&gt;Probably the most boring task when writing Rails test cases is entering new fixtures. With a little help from TextMate this process can be made more pleasant. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open &lt;strong&gt;Bundle Editor&lt;/strong&gt; and create a new command.&lt;/li&gt;
&lt;li&gt;Name it, for example, 'rails: new fixture'&lt;/li&gt;
&lt;li&gt;Use this script as the command body:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Probably the most boring task when writing Rails test cases is entering new fixtures. With a little help from TextMate this process can be made more pleasant. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open &lt;strong&gt;Bundle Editor&lt;/strong&gt; and create a new command.&lt;/li&gt;
&lt;li&gt;Name it, for example, 'rails: new fixture'&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use this script as the command body:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/local/bin/ruby
require ENV['TM_SUPPORT_PATH'] + &quot;/lib/exit_codes&quot;
unless ENV['TM_FILEPATH'] =~ /\/test/
  TextMate.exit_show_tool_tip  &quot;you're not in the context of a rails project&quot;
  exit 1
else
  rails_dir = $`
  tbl_name = File.basename(ENV['TM_FILEPATH'], '.yml')
end


require 'rubygems'
require 'active_record'
eval &quot;class #{tbl_name.classify} &amp;lt; ActiveRecord::Base; end&quot;, TOPLEVEL_BINDING
model = tbl_name.classify.constantize


conf = YAML.load(File.read(rails_dir + &quot;/config/database.yml&quot;))
db_conf = conf['development']
ActiveRecord::Base.establish_connection db_conf


unless model.table_exists?
  TextMate.exit_show_tool_tip  &quot;there is no table called #{tbl_name}&quot;
  exit 1
end


columns = model.columns.map{|clm| clm.name}
puts '${1:fixture_name}:'
idx = 2
columns.each do |c|
  puts &quot;  #{c}: ${#{idx}}&quot;
  idx += 1
end
puts '$0'
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;strong&gt;None&lt;/strong&gt; for the &lt;em&gt;Command Input&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Insert as Snippet&lt;/strong&gt; for the &lt;em&gt;Command Output&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Activation&lt;/em&gt; should be set to &lt;strong&gt;Tab Trigger&lt;/strong&gt; with the &lt;strong&gt;fix&lt;/strong&gt; as the activation sequence.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Source Selector&lt;/em&gt; must be set to &lt;strong&gt;source.yaml&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, when the command is created, open your fixture file and enter &lt;strong&gt;fix&lt;/strong&gt; followed by Tab key. TextMate will insert the template your new fixture with all column names specified. You can enter values for the first column and move to the next one by pressing Tab key.&lt;/p&gt;

&lt;div&gt;&lt;/div&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-03-15:150</id>
    <published>2007-03-15T20:17:00Z</published>
    <updated>2007-03-15T20:19:04Z</updated>
    <category term="ruby-debug"/>
    <link href="http://www.datanoise.com/articles/2007/3/15/ruby-debug-version-0-8-has-been-released" rel="alternate" type="text/html"/>
    <title>ruby-debug version 0.8 has been released!</title>
<summary type="html">&lt;p&gt;This is mostly a maintenance release. The major change is that &lt;strong&gt;ruby-debug&lt;/strong&gt; has been split in two parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ruby-debug-base&lt;/strong&gt; gem contains the debugger core API written in C. Use this gem if you want to create your own interface to the debugger and don't want to depend on changes to the ruby-debug CLI. The API is considered somewhat stable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ruby-debug&lt;/strong&gt; gem depends on &lt;strong&gt;ruby-debug-base&lt;/strong&gt; and provides CLI interface.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;</summary><content type="html">
            &lt;p&gt;This is mostly a maintenance release. The major change is that &lt;strong&gt;ruby-debug&lt;/strong&gt; has been split in two parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ruby-debug-base&lt;/strong&gt; gem contains the debugger core API written in C. Use this gem if you want to create your own interface to the debugger and don't want to depend on changes to the ruby-debug CLI. The API is considered somewhat stable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ruby-debug&lt;/strong&gt; gem depends on &lt;strong&gt;ruby-debug-base&lt;/strong&gt; and provides CLI interface.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is mostly a maintenance release. The major change is that &lt;strong&gt;ruby-debug&lt;/strong&gt; has been split in two parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ruby-debug-base&lt;/strong&gt; gem contains the debugger core API written in C. Use this gem if you want to create your own interface to the debugger and don't want to depend on changes to the ruby-debug CLI. The API is considered somewhat stable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ruby-debug&lt;/strong&gt; gem depends on &lt;strong&gt;ruby-debug-base&lt;/strong&gt; and provides CLI interface.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The idea is that if you are working on an integration with ruby-debug and find that the command set provided by &lt;em&gt;ruby-debug&lt;/em&gt; is too limited for your purposes, you create a new gem and make it depended on &lt;strong&gt;ruby-debug-base&lt;/strong&gt;. The only requirement is that you provide and register &lt;code&gt;Debugger.handler&lt;/code&gt; like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    class MyHandler
      def at_line(context, file, line)...

      def at_breakoint(context, breakpoint)...

      def at_catchpoint(context, exception)...

      def at_tracing(context, file, line)...
    end
    Debugger.handler = MyHandler.new
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The handler implements four callback methods that are invoked by the debugger. Each method receives the current context (&lt;code&gt;Debugger::Context&lt;/code&gt;) as the first parameters. Please refer to the &lt;strong&gt;rdoc&lt;/strong&gt; bundled with ruby-debug-base gem for the description of debugger API and consider ruby-debug gem as an example of such interface implementation.&lt;/p&gt;

&lt;p&gt;One interesting example of such alternative interfaces could be the &lt;a href=&quot;http://xdebug.org/docs-dbgp.php&quot;&gt;DBGP&lt;/a&gt; protocol that is &lt;a href=&quot;http://www.eclipse.org/proposals/dltk/&quot;&gt;becoming common&lt;/a&gt; in the field of dynamic languages.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-03-09:137</id>
    <published>2007-03-09T21:22:00Z</published>
    <updated>2007-03-11T02:29:25Z</updated>
    <category term="OSX"/>
    <category term="Ruby"/>
    <link href="http://www.datanoise.com/articles/2007/3/9/macfuse-and-ruby-fusefs-extension" rel="alternate" type="text/html"/>
    <title>MacFuse and Ruby fusefs extension</title>
<content type="html">
            &lt;p&gt;Lately I've been playing with &lt;a href=&quot;http://code.google.com/p/macfuse/&quot;&gt;MacFuse&lt;/a&gt; project and all I could say is that this is a fantastic effort of bringing the well-known user-space(&lt;a href=&quot;http://fuse.sourceforge.net/&quot;&gt;fuse&lt;/a&gt;) file system to the OSX land. The latest versions of &lt;strong&gt;fuse&lt;/strong&gt; work well with FreeBSD and &lt;strong&gt;MacFuse&lt;/strong&gt; extends this functionality to OSX platform. &lt;/p&gt;

&lt;p&gt;My goal was to make Ruby's &lt;a href=&quot;http://rubyforge.org/projects/fusefs&quot;&gt;fusefs&lt;/a&gt; extension play along with it. The major stumbling point was that &lt;strong&gt;MacFuse&lt;/strong&gt; requires using the new fuse API, so I had to make several modifications to &lt;strong&gt;fusefs&lt;/strong&gt; in order to make it possible at least to compile it.&lt;/p&gt;

&lt;p&gt;OK. If you are a braveheart type and not afraid that it might damage your computer, these are the steps you need to do in order to install this extension:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download the latest version of &lt;a href=&quot;http://code.google.com/p/macfuse/&quot;&gt;&lt;strong&gt;MacFuse&lt;/strong&gt;&lt;/a&gt; and use the installer that it comes with.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check out my version of fusefs from http://svn.datanoise.com/fusefs-osx and use the standard procedure of installing Ruby extensions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ svn co http://svn.datanoise.com/fusefs-osx
$ cd fusefs-osx
$ make
$ sudo make install
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's about it. Now you can start playing with examples located in &lt;code&gt;&amp;lt;fusefs-osx&amp;gt;/sample&lt;/code&gt; directory. When you are at it, I'd like you to take a look at one of my personal toys - &lt;strong&gt;the remote DRb-based file system&lt;/strong&gt;. It is located in &lt;code&gt;&amp;lt;fusefs-osx&amp;gt;/sample/drb&lt;/code&gt; directory and that's how you use it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;On the remote side (a Windows box will do just fine) start the drb server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ruby ./sample/drb/drbfs_server.rb ~/shared
druby://myhost:7777
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The script takes the name of a directory you want to share. When the script is started, it'll print the URL you have to use when you mount your DRb filesystem on the client side.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the client side, mount DRb file system:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ruby ./sample/drb/drbfs.rb mount/ druby://myhost:7777
$ ls mount
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The client script takes the name of a directory you want to mount to and the URL of the server from the step one.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Enjoy and &lt;em&gt;don't forget to read &lt;code&gt;&amp;lt;fusefs-osx&amp;gt;/OSX.txt&lt;/code&gt; for the important API changes&lt;/em&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-03-03:129</id>
    <published>2007-03-03T19:42:00Z</published>
    <updated>2007-03-03T19:47:36Z</updated>
    <category term="Ruby"/>
    <link href="http://www.datanoise.com/articles/2007/3/3/conditional-tail" rel="alternate" type="text/html"/>
    <title>Conditional tail</title>
<content type="html">
            &lt;p&gt;So many times while watching log files I wanted to find a command that combines &lt;em&gt;tail&lt;/em&gt; with &lt;em&gt;grep&lt;/em&gt; filtering functionally. The Unix command repository is huge and I'm pretty sure you can do it without resorting to a scripting language. But having spent several minutes googling for this functionality to no avail, I decided to bring Ruby to the rescue.&lt;/p&gt;

&lt;p&gt;At first I thought that I had to port &lt;a href=&quot;http://cpan.uwinnipeg.ca/dist/File-Tail&quot;&gt;File::Tail Perl module&lt;/a&gt; to Ruby, but I found that it has been &lt;a href=&quot;http://rubyforge.org/projects/file-tail/&quot;&gt;done already&lt;/a&gt; by Florian Frank. He has even provided a convenient way of installing it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ sudo gem install file-tail
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;OK, the rest was as obvious as this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ cat tailg
    #!/usr/bin/env ruby

    require 'rubygems'
    gem 'file-tail'
    require 'file/tail'


    if ARGV.size != 2
      $stderr.puts &quot;Usage #$0 &amp;lt;regexp&amp;gt; &amp;lt;log-file&amp;gt;&quot;
    end

    begin
      File.open(ARGV[1]) do |log|
        log.extend(File::Tail)
        log.interval = 2
        log.backward(10)
        log.tail { |line| puts line if line =~ /#{ARGV[0]}/ }
      end 
    rescue Exception
    end

    $./tailg 'products' /var/log/searchd_query.log
    [Sat Mar  3 13:39:40 2007] 0.000 sec [all/0/rel 3 (0,9)] [products] NOA
    [Sat Mar  3 13:39:44 2007] 0.000 sec [all/0/rel 22 (0,9)] [products] lauren
    [Sat Mar  3 13:40:09 2007] 0.000 sec [all/0/rel 22 (9,9)] [products] lauren
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;tailg&lt;/em&gt; command accepts two parameters: a regexp to filter for interesting lines and a log file itself. &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-02-02:94</id>
    <published>2007-02-02T05:46:00Z</published>
    <updated>2007-02-02T05:46:43Z</updated>
    <category term="ruby-debug"/>
    <link href="http://www.datanoise.com/articles/2007/2/2/ruby-debug-0-7-released" rel="alternate" type="text/html"/>
    <title>ruby-debug 0.7 released</title>
<content type="html">
            &lt;p&gt;I'm happy to announce that ruby-debug 0.7 is available now.&lt;/p&gt;

&lt;p&gt;This is mostly a bugfix release. It also has many internal changes that greatly improve the debugger performance. It is so much faster now, that sometime I don't even notice that I'm using it  when I start &lt;em&gt;mongrel&lt;/em&gt; with &lt;em&gt;rdebug&lt;/em&gt; script. The list of changes includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Frame&lt;/code&gt; class has been removed and instead a preallocated block of memory is used to keep frames information. This change has decreased the number of object being created. &lt;/li&gt;
&lt;li&gt;Another major change involves the fact that the debugger by default doesn't create Binding object for each frame. This is a very expensive operation and it's been the major source of performance problems. Instead, ruby-debug keeps references to the live Ruby's data structures that store information about the local context (ruby_scope). It's still possible to restore the old behavior by using &lt;code&gt;--keep-frame-binding&lt;/code&gt; option, or &lt;code&gt;Debugger.keep_frame_binding = true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;New &lt;em&gt;set&lt;/em&gt; command has been introduced. You can use &lt;code&gt;help set&lt;/code&gt; command to see what options are available.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy, and please report any problem you find!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-01-27:77</id>
    <published>2007-01-27T05:08:00Z</published>
    <updated>2007-01-27T05:26:40Z</updated>
    <category term="ruby-debug"/>
    <link href="http://www.datanoise.com/articles/2007/1/27/ruby-debug-0-6-1-released" rel="alternate" type="text/html"/>
    <title>ruby-debug 0.6.1 Released</title>
<content type="html">
            &lt;p&gt;ruby-debug 0.6.1 has been released!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ sudo gem install ruby-debug
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ruby-debug is a C extension that implements the fast Ruby debugger.&lt;/p&gt;

&lt;h3&gt;Changes&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Significant performance improvements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bug fixes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2007-01-27:76</id>
    <published>2007-01-27T04:47:56Z</published>
    <updated>2007-01-27T04:56:34Z</updated>
    <category term="OSX"/>
    <link href="http://www.datanoise.com/articles/2007/1/27/profiling-with-shark" rel="alternate" type="text/html"/>
    <title>Profiling with Shark</title>
<summary type="html">&lt;p&gt;Lately I ran into an &lt;a href=&quot;http://www.sapphiresteel.com/Fast-Ruby-Debugger-Enter-Cylon&quot;&gt;article&lt;/a&gt; talking about a new Ruby debugger called Cylon. Developers of Sapphiresteel IDE have achieved remarkable results. The article stays that their debugger implementation imposes only 20% of an overhead over the standard Ruby interpreter. This is very impressive! I decided to try the same benchmark with &lt;strong&gt;ruby-debug&lt;/strong&gt; and, to tell you the truth, I was kind of disappointed. It's time to profile...&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Lately I ran into an &lt;a href=&quot;http://www.sapphiresteel.com/Fast-Ruby-Debugger-Enter-Cylon&quot;&gt;article&lt;/a&gt; talking about a new Ruby debugger called Cylon. Developers of Sapphiresteel IDE have achieved remarkable results. The article stays that their debugger implementation imposes only 20% of an overhead over the standard Ruby interpreter. This is very impressive! I decided to try the same benchmark with &lt;strong&gt;ruby-debug&lt;/strong&gt; and, to tell you the truth, I was kind of disappointed. It's time to profile...&lt;/p&gt;
&lt;p&gt;I've read several articles describing Shark, the tool with comes with &lt;a href=&quot;http://developer.apple.com/tools/performance/&quot;&gt;CHUD toolkit&lt;/a&gt; from Apple. I've never used it before, but I've heard that it's quite powerful tool. &lt;/p&gt;

&lt;p&gt;First of all, I decided to use Rails application I've been working on lately as a test-bed for measuring the performance. I started it under ruby-debug using rdebug script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ rdebug ./script/server
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When my application was up and running I launched &lt;em&gt;Shark&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://datanoise.com/assets/2007/1/26/shark_main.png&quot; width=&quot;640&quot;&gt;&lt;/p&gt;

&lt;p&gt;Notice that on the main screen I selected my running ruby process from the dropdown menu. There are several profiles available, but the default &lt;em&gt;Time Prifile&lt;/em&gt; is exactly what I needed. It's possible change several options in the config pane, but I decided that defaults would work for me well.&lt;/p&gt;

&lt;p&gt;Then I simply pressed &lt;em&gt;Start&lt;/em&gt; button and started using my application while &lt;em&gt;Shark&lt;/em&gt; was sitting in the background collecting profiling information.&lt;/p&gt;

&lt;p&gt;In thirty seconds &lt;em&gt;Shark&lt;/em&gt; presented me with the following screen:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://datanoise.com/assets/2007/1/26/profile_result_1.png&quot; width=&quot;640&quot;&gt;&lt;/p&gt;

&lt;p&gt;Well, that's nice. It loaded the symbol table successfully, and I can see the call stacks as well. At the bottom of the screen you can select &lt;em&gt;top-down&lt;/em&gt; or &lt;em&gt;bottom-up&lt;/em&gt; view. It just worked and it don't have to recompile my Ruby and ruby-debug with some special compiler directives or do some other magic.&lt;/p&gt;

&lt;p&gt;But wait a minute, I didn't expect to see my &lt;code&gt;debug_event_hook&lt;/code&gt; function somewhere at the bottom of the list. All I could see was memory management functions along with &lt;code&gt;garbage_collect&lt;/code&gt; function. It means that there are a lot of objects being created somewhere, which triggers so much of a garbage collection overhead. Also I saw my lovely &lt;code&gt;debug_event_hook&lt;/code&gt; function right there in the call stack of &lt;code&gt;garbage_collect&lt;/code&gt; method. &lt;/p&gt;

&lt;p&gt;Let's see if I can get more info about it. Right-clicked on &lt;code&gt;debug_event_hook&lt;/code&gt; function and selected &lt;em&gt;Focus Symbol &lt;code&gt;debug_event_hook&lt;/code&gt;&lt;/em&gt;. &lt;em&gt;Shark&lt;/em&gt; made my function the root of the call tree and removed call stacks that do not contain my function.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://datanoise.com/assets/2007/1/27/profile_result_1_1.png&quot; width=&quot;640&quot;&gt;&lt;/p&gt;

&lt;p&gt;OK, that's better. Now I double-clicked on &lt;code&gt;debug_event_hook&lt;/code&gt; function call stack and &lt;em&gt;Shark&lt;/em&gt; displayed this screen:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://datanoise.com/assets/2007/1/26/source_code_view_1.png&quot; width=&quot;640&quot;&gt;&lt;/p&gt;

&lt;p&gt;Wow! Notice these two lines 522 and 523. I didn't expect that they are going to impose so much of a performance overhead. Now it's clear, there are too many String objects being created and most of the time these objects are not referenced after this function returns. &lt;/p&gt;

&lt;p&gt;Ok, I started &lt;a href=&quot;http://macromates.com/&quot;&gt;one of my favorite text editors&lt;/a&gt; and in a couple of hours and several similar iterations I've got this picture:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://datanoise.com/assets/2007/1/27/profile_result_2.png&quot; width=&quot;640&quot;&gt;&lt;/p&gt;

&lt;p&gt;Now, this is much better! There is no &lt;code&gt;garbage_collect&lt;/code&gt; in sight and most of the time &lt;code&gt;debug_event_hook&lt;/code&gt; spends in searching for the current thread info. I could probably change the algorithm and data structure that I use in order to keep this information, but it's already good enough. Now my benchmarks show that instead of 300% of the overhead, ruby-debug imposes only 90%. It's still slower than Cylon though and it would be good to know about the implementation details of Cylon debugger.&lt;/p&gt;

&lt;p&gt;When you are profiling, you need to know when to stop! And I'm going to repeat it: &lt;strong&gt;premature optimization is the root of all evil&lt;/strong&gt;. It makes your code more obscure and should be used with discretion.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And the bottom line is. Shark is very powerful tool. It's free and very easy to use.&lt;/em&gt; &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2006-12-20:27</id>
    <published>2006-12-20T22:38:00Z</published>
    <updated>2007-05-28T23:20:56Z</updated>
    <category term="Ruby"/>
    <category term="ruby-debug"/>
    <link href="http://www.datanoise.com/articles/2006/12/20/post-mortem-debugging" rel="alternate" type="text/html"/>
    <title>Post-mortem debugging</title>
<summary type="html">&lt;p&gt;ruby-debug 0.5.1 has been released! The installation as usual:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ sudo gem install ruby-debug
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Below is the list of changes:&lt;/p&gt;

&lt;h3&gt;Post-mortem debugging&lt;/h3&gt;

&lt;p&gt;First of all, what the heck is post-mortem debugging? Let's say you run a script and instead of the expected result you get an exception trace. Wouldn't it be great if we can roll back to the point where this exception is raised and explore the state of your program (possibly, by moving up and down the frame stack)? &lt;/p&gt;

&lt;p&gt;Note that it is different than setting a &lt;em&gt;catch point&lt;/em&gt;. By setting a catch point you activate the debugger when an exception (of a specific class) is about to be raised and it doesn't matter whether it's going to be handled later in the code or not. In the post-mortem case you know that an exception's been raised and not handled as expected.&lt;/p&gt;

&lt;p&gt;Now I'm going to demonstrate several ways of using this feature, starting from the simplest:&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;ruby-debug 0.5.1 has been released! The installation as usual:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ sudo gem install ruby-debug
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Below is the list of changes:&lt;/p&gt;

&lt;h3&gt;Post-mortem debugging&lt;/h3&gt;

&lt;p&gt;First of all, what the heck is post-mortem debugging? Let's say you run a script and instead of the expected result you get an exception trace. Wouldn't it be great if we can roll back to the point where this exception is raised and explore the state of your program (possibly, by moving up and down the frame stack)? &lt;/p&gt;

&lt;p&gt;Note that it is different than setting a &lt;em&gt;catch point&lt;/em&gt;. By setting a catch point you activate the debugger when an exception (of a specific class) is about to be raised and it doesn't matter whether it's going to be handled later in the code or not. In the post-mortem case you know that an exception's been raised and not handled as expected.&lt;/p&gt;

&lt;p&gt;Now I'm going to demonstrate several ways of using this feature, starting from the simplest:&lt;/p&gt;
&lt;h4&gt;Using rdebug script&lt;/h4&gt;

&lt;p&gt;You run your application with rdebug and use &lt;code&gt;-m&lt;/code&gt; command line option:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    # rdebug -m script_name
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For example,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ cat t.rb 
    def t1
      raise 'test'
    end
    def t2
      t1
    end
    t2

    $ rdebug -m t.rb 
    ./t.rb:1: def t1
    (rdb:1) c
    ./t.rb:2: raise 'test'
    (rdb:post-mortem) l=
    [-3, 6] in ./t.rb
       1  def t1
    =&amp;gt; 2    raise 'test'
       3  end
       4  def t2
       5    t1
       6  end
    (rdb:post-mortem)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice the new &lt;em&gt;post-mortem&lt;/em&gt; prompt. It indicates that at this point you can't use any stepping commands other than &lt;strong&gt;[cont]&lt;/strong&gt;inue. All other commands are still available, so you can &lt;strong&gt;[eval]&lt;/strong&gt;uate an expression in this context, move &lt;strong&gt;up&lt;em&gt;* and *&lt;/em&gt;down&lt;/strong&gt; the stack, etc. &lt;/p&gt;

&lt;h4&gt;Explicit activation of post-mortem debugging&lt;/h4&gt;

&lt;p&gt;You can activate the post-mortem mode with &lt;code&gt;Debugger.post_mortem&lt;/code&gt; method from your script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ cat t.rb 
    require 'rubygems'
    require 'ruby-debug'

    Debugger.start
    Debugger.post_mortem

    def t1
      raise 'test'
    end
    def t2
      t1
    end
    t2

    $ ruby t.rb 
    t.rb:8: raise 'test'
    (rdb:post-mortem) l=
    [3, 12] in t.rb
       3  
       4  Debugger.start
       5  Debugger.post_mortem
       6  
       7  def t1
    =&amp;gt; 8    raise 'test'
       9  end
       10  def t2
       11    t1
       12  end
    (rdb:post-mortem)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Note of caution&lt;/em&gt;: &lt;code&gt;Debugger.post_mortem&lt;/code&gt; method installs a special &lt;code&gt;at_exit&lt;/code&gt; hook. So if your application exits by calling &lt;code&gt;Kernel#exit!&lt;/code&gt; method, the debugger is not activated! Be careful.&lt;/p&gt;

&lt;h4&gt;Local post-mortem debugging&lt;/h4&gt;

&lt;p&gt;All previous examples describe the case when an application exits without handling an exception. What happens if we've got a peculiar block of code that is not supposed to raise any exceptions, yet, contrary to all expectations, it still does. &lt;code&gt;Debugger.post_mortem&lt;/code&gt; method accepts a block of code and activates the post-mortem mode when it executes it. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ cat t.rb 
    require 'rubygems'
    require 'ruby-debug'

    Debugger.start

    def t1
      raise 'test'
    end
    def t2
      t1
    end

    begin
      Debugger.post_mortem do
        t2
      end
    rescue
      debugger
      puts 'handled'
    end

    $ ruby t.rb 
    t.rb:7: raise 'test'
    (rdb:post-mortem) l=
    [2, 11] in t.rb
       2  require 'ruby-debug'
       3  
       4  Debugger.start
       5  
       6  def t1
    =&amp;gt; 7    raise 'test'
       8  end
       9  def t2
       10    t1
       11  end
    (rdb:post-mortem) c
    t.rb:19: puts 'handled'
    (rdb:1) l=
    [14, 23] in t.rb
       14    Debugger.post_mortem do
       15      t2
       16    end
       17  rescue
       18    debugger
    =&amp;gt; 19    puts 'handled'
       20  end
    (rdb:1) c
    handled

    $
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice that the debugger is still activated when we finished with post-mortem breakpoint.&lt;/p&gt;

&lt;h3&gt;Source code reloading&lt;/h3&gt;

&lt;p&gt;Another feature that has been implemented in the latest versions is the source code reloading. This feature is very useful when you debug your Rails application in development mode. You start your application, you make some changes, you hit your browser's &lt;em&gt;Refresh&lt;/em&gt; button and you are done with it. No need to restart your mongrel all the time.&lt;/p&gt;

&lt;p&gt;So wouldn't it be nice if &lt;strong&gt;ruby-debug&lt;/strong&gt; also be able to reflect all these code changes instead of displaying stale source code?&lt;/p&gt;

&lt;p&gt;By entering &lt;strong&gt;reload&lt;/strong&gt; command, you can instruct the debugger to refresh all source code it's aware of. You can also automate this process by using &lt;strong&gt;reload on&lt;/strong&gt; command. In this case, the debugger will be checking the file timestamp and reload the file if it's been updated automatically.&lt;/p&gt;

&lt;h3&gt;New irb command (experimental)&lt;/h3&gt;

&lt;p&gt;Evan Weaver popped &lt;a href=&quot;http://blog.evanweaver.com/articles/2006/12/15/debugging-with-ruby-debug&quot;&gt;the question&lt;/a&gt; in his blog: &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;It would be nice to be able to drop into an IRB instance, too, but I don’t know how to do that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Enter &lt;strong&gt;irb&lt;/strong&gt; command - it activates an irb instance with the current frame's binding. This feature is somewhat experimental and is not available in remote mode. (I wasn't able to install my own input method in order to redirect standard IO).&lt;/p&gt;

&lt;p&gt;That's it for now. Enjoy.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2006-12-17:26</id>
    <published>2006-12-17T00:11:00Z</published>
    <updated>2007-03-04T03:36:10Z</updated>
    <category term="Ruby"/>
    <link href="http://www.datanoise.com/articles/2006/12/17/google-calculator" rel="alternate" type="text/html"/>
    <title>Google Calculator</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.google.com/help/features.html#calculator&quot;&gt;Google calculator&lt;/a&gt; is a very powerful tool. Besides basic arithmetic, you can use it in many other &lt;a href=&quot;http://www.google.com/help/calculator.html&quot;&gt;interesting ways&lt;/a&gt;. But I always wanted to use it from the command line without opening a new Safari window.&lt;/p&gt;

&lt;p&gt;Ruby to the rescue:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ cat gcal 
    #!/usr/bin/env ruby
    %w(rubygems open-uri hpricot erb).each {|lib| require lib }
    doc = Hpricot(open(&quot;http://www.google.com/search?q=#{ERB::Util.u(ARGV*' ')}&quot;))
    puts (doc/'/html/body/p/table/tr/td[3]/font/b').inner_text

    $ ./gcal 2^20
    2^20 = 1 048 576

    $ ./gcal 'sqrt(-1)'
    sqrt(-1) = i

    $ ./gcal 30 rubles in dollars
    30 Russian rubles = 1.1379844 U.S. dollars

    $ ./gcal 2 gallons in liters
    2 US gallons = 7.5708236 liters
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's not too bad for three-liner like this. By the way, did I say that &lt;a href=&quot;http://code.whytheluckystiff.net/hpricot/&quot;&gt;Hpricot&lt;/a&gt; is awesome?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2006-12-13:25</id>
    <published>2006-12-13T22:49:00Z</published>
    <updated>2007-01-22T02:59:03Z</updated>
    <category term="SOAP"/>
    <link href="http://www.datanoise.com/articles/2006/12/13/ws" rel="alternate" type="text/html"/>
    <title>WS-*</title>
<content type="html">
            &lt;p&gt;I've been dealing with SOAP/WSDL a lot lately, and this is beside trying to play a role of ActionWebService maintainer. There are several points to mention. First off, everyone wants to use SOAP no matter whether it makes sense or not. Not a single company I've worked with had a slightest idea of what SOAP/WSDL is. OK, I take it back. &lt;strong&gt;What a &lt;a href=&quot;http://www-128.ibm.com/developerworks/webservices/library/ws-whichwsdl/?ca=dgr-devx-WebServicesMVP03&quot;&gt;f*ing mess&lt;/a&gt; it is...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Anyway, I was quit pleasantly surprised today after reading this &lt;a href=&quot;http://www.infoq.com/articles/pete-lacey-ws-criticism&quot;&gt;article&lt;/a&gt; at InfoQ. It means there are still some sane people left in WS-* crowd. Pete Lacey's &lt;a href=&quot;http://wanderingbarque.com/nonintersecting/2006/11/15/the-s-stands-for-simple/&quot;&gt;The S stands for Simple&lt;/a&gt; only proves my point.&lt;/p&gt;

&lt;p&gt;Also I'd like to thank NAKAMURA Hiroshi, the author of &lt;a href=&quot;http://dev.ctor.org/soap4r&quot;&gt;soap4r library&lt;/a&gt;. It is a tough job to live in the mess like this, and his library is the best one I know in the dynamic language landscape that provides a decent SOAP/WSDL implementation. He also praises &lt;em&gt;ruby-debug&lt;/em&gt; as a quite useful tool for debugging soap4r applications! Very much appreciated.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.datanoise.com/">
    <author>
      <name>kent</name>
    </author>
    <id>tag:www.datanoise.com,2006-09-23:24</id>
    <published>2006-09-23T15:23:00Z</published>
    <updated>2007-01-22T04:38:08Z</updated>
    <category term="Ruby"/>
    <link href="http://www.datanoise.com/articles/2006/9/23/live-ruby-process-inspection" rel="alternate" type="text/html"/>
    <title>Live Ruby process inspection</title>
<content type="html">
            &lt;p&gt;OK, this is totally insane. First &lt;em&gt;Jamis Buck&lt;/em&gt; hit us with &lt;a href=&quot;http://weblog.jamisbuck.org/2006/9/22/inspecting-a-live-ruby-process&quot;&gt;&lt;em&gt;Inspecting a live Ruby process&lt;/em&gt;&lt;/a&gt; article where he demonstrated a number of very interesting technics you can use in order to poke around your live Ruby process. &lt;/p&gt;

&lt;p&gt;But then &lt;em&gt;Mauricio Fernandez&lt;/em&gt; showed us how masters do their katas ( 型 ) in &lt;a href=&quot;http://eigenclass.org/hiki.rb?ruby+live+process+introspection&quot;&gt;&lt;em&gt;&quot;Inspecting a live Ruby process&quot;, easier if you cheat&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I didn't know that &lt;code&gt;gdb&lt;/code&gt; can be that powerful! I need to read more about it.&lt;/p&gt;

&lt;p&gt;On a side note, I've just finished reading &lt;a href=&quot;http://www.samspublishing.com/bookstore/product.asp?isbn=067232699X&amp;amp;rl=1&quot;&gt;Scalable Internet Architectures&lt;/a&gt; by &lt;em&gt;Theo Schlossnagle&lt;/em&gt; and I very enjoyed it. If you followed &lt;a href=&quot;http://www.joelonsoftware.com/items/2006/09/01.html&quot;&gt;this&lt;/a&gt; &lt;a href=&quot;http://www.loudthinking.com/arc/000596.html&quot;&gt;interesting&lt;/a&gt; &lt;a href=&quot;http://www.joelonsoftware.com/items/2006/09/12b.html&quot;&gt;exchange&lt;/a&gt; of &lt;a href=&quot;http://www.loudthinking.com/arc/000598.html&quot;&gt;opinions&lt;/a&gt;, you should definitely read this book. The author make a clear point that the raw speed of your language of choice &lt;strong&gt;does not matter&lt;/strong&gt; in creating scalable solutions. Even if your application is powered by C, you still can reach a point when your single server is not able to serve all incoming requests and you need to scale your application horizontally. This book explains how.&lt;/p&gt;

&lt;p&gt;Next on my &lt;em&gt;&quot;to read&quot;&lt;/em&gt; list is &lt;a href=&quot;http://www.oreilly.com/catalog/web2apps/index.html&quot;&gt;Building Scalable Web Sites&lt;/a&gt; by &lt;em&gt;Cal Henderson&lt;/em&gt;.&lt;/p&gt;
          </content>  </entry>
</feed>
