<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><description>A collection of thoughts by Thiago Jackiw about Ruby and Software in general.</description><title>Practical Ruby</title><generator>Tumblr (3.0; @tjackiw)</generator><link>http://tjackiw.tumblr.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PracticalRuby" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="practicalruby" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><item><title>A Look at Ruby 2.0</title><description>&lt;p&gt;With Ruby 2.0 set to be released on February 24th, exactly on the 20th anniversary of Ruby’s first debut, I decided to write this article to give you a quick rundown of some of the most interesting changes. And if you would like to experiment with this version before the official release, you can do so by following the instructions in this article.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rubysource.com/a-look-at-ruby-2-0/" title="A look at Ruby 2.0" target="_blank"&gt;Read more&amp;#8230;&lt;/a&gt;&lt;/p&gt;</description><link>http://tjackiw.tumblr.com/post/40533720638</link><guid>http://tjackiw.tumblr.com/post/40533720638</guid><pubDate>Mon, 14 Jan 2013 11:19:50 -0800</pubDate><category>ruby 2.0</category><category>ruby</category></item><item><title>Using a Graph Database with Ruby. Part II: Integration</title><description>&lt;p&gt;Yes, it is real, it is finally here! The long waited follow-up to the &lt;a href="http://rubysource.com/using-a-graph-database-with-ruby-part-i-introduction/" target="_blank"&gt;introductory article&lt;/a&gt; is here, just in time for the new year!&lt;/p&gt;
&lt;p&gt;In the &lt;a href="http://rubysource.com/using-a-graph-database-with-ruby-part-i-introduction/" target="_blank"&gt;first article&lt;/a&gt;, we learned about graph databases, their differences and advantages over traditional databases, and about Neo4j. In this article, we are going to install Neo4j, integrate and evaluate the gems listed in the &lt;a href="http://rubysource.com/using-a-graph-database-with-ruby-part-i-introduction/" target="_blank"&gt;first part&lt;/a&gt; of this series.&lt;/p&gt;
&lt;p&gt;The scenario that we are going to be working with is the continuation of the simple idea in the &lt;a href="http://rubysource.com/using-a-graph-database-with-ruby-part-i-introduction/" target="_blank"&gt;first article&lt;/a&gt;, a social networking example that is capable of producing traversal queries such as “given the fact that Bob is my friend, give me all friends that are friend’s of friend’s of friend’s of Bob”.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rubysource.com/using-a-graph-database-with-ruby-part-ii-integration/" target="_blank"&gt;Read more&amp;#8230;&lt;/a&gt;&lt;/p&gt;</description><link>http://tjackiw.tumblr.com/post/40053789444</link><guid>http://tjackiw.tumblr.com/post/40053789444</guid><pubDate>Tue, 08 Jan 2013 17:01:46 -0800</pubDate><category>ruby</category><category>graph database</category><category>neo4j</category></item><item><title>Using a Graph Database with Ruby. Part I: Introduction</title><description>&lt;a href="http://rubysource.com/using-a-graph-database-with-ruby-part-i-introduction/"&gt;Using a Graph Database with Ruby. Part I: Introduction&lt;/a&gt;: &lt;p&gt;Check out the interesting article “&lt;a href="http://rubysource.com/using-a-graph-database-with-ruby-part-i-introduction/" target="_blank"&gt;Using a Graph Database with Ruby. Part I: Introduction&lt;/a&gt;” I wrote for the blog &lt;a href="http://www.rubysource.com" title="RubySource.com" target="_blank"&gt;RubySource.com&lt;/a&gt;. It covers the basics of Graph databases, how it differs from traditional databases, and how it can be used with Ruby.&lt;/p&gt;</description><link>http://tjackiw.tumblr.com/post/25258991894</link><guid>http://tjackiw.tumblr.com/post/25258991894</guid><pubDate>Sat, 16 Jun 2012 17:43:17 -0700</pubDate><category>ruby</category><category>graph database</category><category>neo4j</category></item><item><title>Obscenity, a profanity filter for Ruby, ActiveModel, and Rack.</title><description>&lt;p&gt;Obscenity is a profanity filter gem for Ruby/Rubinius, Rails (through ActiveModel), and Rack middleware.&lt;/p&gt;
&lt;p&gt;What that means is that you can use Obscenity in plain Ruby or Rubinius, use it to validate and sanitize attributes in your models through ActiveModel (ActiveRecord, MongoMapper, Mongoid, etc), and use the Rack middleware to automatically reject requests that include profane parameters or sanitize those values before they reach your Application.&lt;/p&gt;
&lt;p&gt;Enough said, let&amp;#8217;s see some action!&lt;/p&gt;
&lt;p&gt;&lt;strong class="heading"&gt;&lt;!-- more --&gt;Installation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re using Bundler, add this line to your application&amp;#8217;s Gemfile:&lt;/p&gt;
&lt;pre class="ruby"&gt;gem 'obscenity'&lt;/pre&gt;
&lt;p&gt;And then execute:&lt;/p&gt;
&lt;pre class="ruby"&gt;bundle install&lt;/pre&gt;
&lt;p&gt;Or install it yourself as:&lt;/p&gt;
&lt;pre class="ruby"&gt;gem install obscenity&lt;/pre&gt;
&lt;p&gt;&lt;strong class="heading"&gt;Configuration&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Obscenity allows you to set custom configuration options, including a blacklist, a whitelist, and the replacement method used when sanitizing profane text. Here&amp;#8217;s how you configure Obscenity:&lt;/p&gt;
&lt;pre class="ruby"&gt;Obscenity.configure do |config|
  config.blacklist   = "path/to/blacklist/file.yml"
  config.whitelist   = ["safe", "word"]
  config.replacement = :stars
end
&lt;/pre&gt;
&lt;p&gt;You can find more details about Obscenity&amp;#8217;s configuration in the project&amp;#8217;s &lt;a href="https://github.com/tjackiw/obscenity" target="_blank"&gt;github page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong class="heading"&gt;Basic Usage&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To check if a text contains profanity:&lt;/p&gt;
&lt;pre class="ruby"&gt;Obscenity.profane?("simple text")
=&amp;gt; false

Obscenity.profane?("text with shit")
=&amp;gt; true
&lt;/pre&gt;
&lt;p&gt;To sanitize a text that may or may not include profanity:&lt;/p&gt;
&lt;pre class="ruby"&gt;Obscenity.sanitize("simple text")
=&amp;gt; "simple text"

Obscenity.sanitize("text with shit")
=&amp;gt; "text with $@!#%"
&lt;/pre&gt;
&lt;p&gt;To use a custom replacement method when sanitizing a text:&lt;/p&gt;
&lt;pre class="ruby"&gt;Obscenity.replacement(:default).sanitize("text with shit")
=&amp;gt; "text with $@!#%"

Obscenity.replacement(:garbled).sanitize("text with shit")
=&amp;gt; "text with $@!#%"

Obscenity.replacement(:stars).sanitize("text with shit")
=&amp;gt; "text with ****"

Obscenity.replacement(:vowels).sanitize("text with shit")
=&amp;gt; "text with sh*t"

Obscenity.replacement("[censored]").sanitize("text with shit")
=&amp;gt; "text with [censored]"
&lt;/pre&gt;
&lt;p&gt;To return the list of offensive words:&lt;/p&gt;
&lt;pre class="ruby"&gt;Obscenity.offensive("simple text")
=&amp;gt; []

Obscenity.offensive("text with shit and another biatch")
=&amp;gt; ["shit", "biatch"]
&lt;/pre&gt;
&lt;p&gt;You can find more details about Obscenity&amp;#8217;s basic usage in the project&amp;#8217;s &lt;a href="https://github.com/tjackiw/obscenity" target="_blank"&gt;github page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong class="heading"&gt;Using with ActiveModel&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The ActiveModel component provides easy profanity validation for your models, and you can use it with any ORM that supports ActiveModel, e.g: ActiveRecord, MongoMapper, Mongoid, etc&lt;/p&gt;
&lt;p&gt;First, you need to explicitly require the ActiveModel component:&lt;/p&gt;
&lt;pre class="ruby"&gt;require 'obscenity/active_model'&lt;/pre&gt;
&lt;p&gt;Then you can use it in your models as such:&lt;/p&gt;
&lt;pre class="ruby"&gt;# ActiveRecord example
class Post &amp;lt; ActiveRecord::Base
  validates :title, obscenity: true
  validates :body,  obscenity: { sanitize: true, replacement: "[censored]" }
end
&lt;/pre&gt;
&lt;p&gt;Now that we have the model setup, let&amp;#8217;s see what happens when we try creating a record that contains profanity:&lt;/p&gt;
&lt;pre class="ruby"&gt;  post = Post.new(title: "The story of an assclown", body: "Profane, like shit or assclown.")
  post.valid?
  =&amp;gt; false
  post.errors.messages
  =&amp;gt; {:title=&amp;gt;["cannot be profane"]}
  post.body
  =&amp;gt; "Something profane, like [censored] or [censored]."
&lt;/pre&gt;
&lt;p&gt;You can find more details about Obscenity&amp;#8217;s ActiveModel usage in the project&amp;#8217;s &lt;a href="https://github.com/tjackiw/obscenity" target="_blank"&gt;github page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong class="heading"&gt;Using as a Rack middleware&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can use Obscenity as a Rack middleware to automatically reject requests that include profane parameter values or sanitize those values before they reach your Application.&lt;/p&gt;
&lt;p&gt;First you need to explicitly require the Rack middleware:&lt;/p&gt;
&lt;pre class="ruby"&gt;require 'obscenity/rack'&lt;/pre&gt;
&lt;p&gt;Now, to reject requests, we simply do:&lt;/p&gt;
&lt;pre class="ruby"&gt;  use Rack::Obscenity, reject: true
&lt;/pre&gt;
&lt;p&gt;And any parameters that contain profanity will cause the request to be rejected.&lt;/p&gt;
&lt;p&gt;Alternatively, you can silently sanitize parameters that contain profanity:&lt;/p&gt;
&lt;pre class="ruby"&gt;  use Rack::Obscenity, sanitize: true
&lt;/pre&gt;
&lt;p&gt;You can find more details about Obscenity&amp;#8217;s Rack usage in the project&amp;#8217;s &lt;a href="https://github.com/tjackiw/obscenity" target="_blank"&gt;github page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong class="heading"&gt;What&amp;#8217;s next?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I encourage you reading the full documentation in the project&amp;#8217;s &lt;a href="https://github.com/tjackiw/obscenity" target="_blank"&gt;github page&lt;/a&gt; to better understand the ins-and-outs of this gem. As always, feedback, bug report and contribution are always welcome.&lt;/p&gt;</description><link>http://tjackiw.tumblr.com/post/23998177553</link><guid>http://tjackiw.tumblr.com/post/23998177553</guid><pubDate>Tue, 29 May 2012 07:46:00 -0700</pubDate><category>ruby</category><category>rubinius</category><category>gems</category><category>rails</category><category>rack</category></item><item><title>Adding extra sauce to the profanity_filter Ruby gem</title><description>&lt;p&gt;I&amp;#8217;ve been using the &lt;a href="https://github.com/intridea/profanity_filter" target="_blank"&gt;profanity_filter&lt;/a&gt; gem off and on for quite a while now and yes, I know it&amp;#8217;s a bit old now but it gets the job done. In this post I&amp;#8217;ll share a couple of simple yet &amp;#8220;extra sauce&amp;#8221; that I added to the gem to make it a bit more useful for both pre and post Rails 3.0.&lt;/p&gt;
&lt;p&gt;&lt;strong class="heading"&gt;Adding model validation with &lt;em&gt;validates_profanity_of&lt;/em&gt; for Rails &amp;lt; 3.0&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One thing that I needed that the gem didn&amp;#8217;t &amp;#8220;natively&amp;#8221; provide was a simple way to do profanity validation on an attribute. I could use a custom &lt;em&gt;validate&lt;/em&gt; method every time I needed to check wether or not an attribute was profane but that would require me to duplicate the code on different models, not a clean way.&lt;/p&gt;
&lt;p&gt;What I did instead was actually extend the gem&amp;#8217;s functionality to add a simple &lt;em&gt;validates_profanity_of&lt;/em&gt; method that behaved similar to other ActiveRecord&amp;#8217;s validation methods:&lt;!-- more --&gt;&lt;/p&gt;
&lt;pre class="ruby"&gt;  # config/initializers/profanity_filter.rb
  require 'profanity_filter'
  
  module ProfanityFilter
    module ClassMethods
      def validates_profanity_of(*attr_names)
        options = attr_names.extract_options!.symbolize_keys
        validates_each(attr_names, options) do |record, attribute, value| 
          record.errors.add(attribute, options[:message] || "cannot be profane") if ProfanityFilter::Base.profane?(value)
        end
      end
    end
  end
&lt;/pre&gt;
&lt;p&gt;With that in place I can then do things like:&lt;/p&gt;
&lt;pre class="ruby"&gt;  # app/models/post.rb
  class Post &amp;lt; ActiveRecord::Base

    attr_accessible :title, :body
    validates_profanity_of :title, :body

  end
&lt;/pre&gt;
&lt;p&gt;This method also allows you to pass the extra options that you find in ActiveRecord&amp;#8217;s validation methods, such as &lt;em&gt;:on&lt;/em&gt;, &lt;em&gt;:allow_nil&lt;/em&gt;, &lt;em&gt;:allow_blank&lt;/em&gt;, &lt;em&gt;:if&lt;/em&gt;, &lt;em&gt;:unless&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong class="heading"&gt;Adding model validation with &lt;em&gt;validates :profanity =&amp;gt; true&lt;/em&gt; for Rails 3.0+&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Rails 3.0 introduced a shortcut &lt;a href="http://apidock.com/rails/v3.0.0/ActiveModel/Validations/ClassMethods/validates" target="_blank"&gt;&lt;em&gt;validates()&lt;/em&gt;&lt;/a&gt; method to all default validators, which allows you to do things like:&lt;/p&gt;
&lt;pre class="ruby"&gt;  validates :title, :presence =&amp;gt; true, :uniqueness =&amp;gt; true
&lt;/pre&gt;
&lt;p&gt;Instead of:&lt;/p&gt;
&lt;pre class="ruby"&gt;  validates_presence_of   :title
  validates_uniqueness_of :title
&lt;/pre&gt;
&lt;p&gt;Taking advantage of this shortcut, let&amp;#8217;s write our new profanity validator:&lt;/p&gt;
&lt;pre class="ruby"&gt;  # config/initializers/profanity_filter.rb
  require 'profanity_filter'
  
  class ProfanityValidator &amp;lt; ActiveModel::EachValidator
    def validate_each(record, attribute, value)
      record.errors.add(attribute, options[:message] || "cannot be profane") if ProfanityFilter::Base.profane?(value)
    end
  end
&lt;/pre&gt;
&lt;p&gt;With that in place we can now do:&lt;/p&gt;
&lt;pre class="ruby"&gt;  # app/models/post.rb
  class Post &amp;lt; ActiveRecord::Base

    attr_accessible :title, :body
    validates :title, :body, :presence =&amp;gt; true, :profanity =&amp;gt; true

  end  
&lt;/pre&gt;
&lt;p&gt;&lt;strong class="heading"&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve seen how easy it is to extend the functionality of the &lt;em&gt;profanity_filter&lt;/em&gt; gem to make it a bit more useful.&lt;/p&gt;</description><link>http://tjackiw.tumblr.com/post/23552386914</link><guid>http://tjackiw.tumblr.com/post/23552386914</guid><pubDate>Tue, 22 May 2012 10:57:34 -0700</pubDate><category>ruby</category><category>gems</category><category>rails</category></item><item><title>Interview challenge: Ruby method chaining</title><description>&lt;p&gt;I&amp;#8217;m going to start my first post with an interview challenge that I presented to candidates while working at one of my past employers. This tested the understanding of method chaining, blocks and metaprogramming in Ruby.&lt;/p&gt;
&lt;p&gt;The challenge was:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Develop the class structure for the following code:&lt;/p&gt;
&lt;pre class="ruby"&gt;Interpreter.new { at("7pm").when("tomorrow night").we("John", "Bob").going("drinking") }.output
=&amp;gt; "John and Bob are going drinking tomorrow night at 7pm."&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;For some, this seems fairly straight-forward, but for others it may seem too advanced or somewhat impossible to do. I&amp;#8217;m going to show you step-by-step how to write the class structure for that code and if you don&amp;#8217;t already know, you&amp;#8217;ll see how simple it is to do method chaining in Ruby. &lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;To better understand the code, let&amp;#8217;s analyze what it is doing:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;It instantiates a class&lt;/li&gt;
&lt;li&gt;The initializer method works with a block&lt;/li&gt;
&lt;li&gt;Each method inside the block receives an argument and each method can be chained&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;output&lt;/em&gt; method returns a string based on the values passed to the methods inside the block&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;With this information in hand we can start to model our class.&lt;/p&gt;
&lt;p&gt;&lt;strong class="heading"&gt;The basic structure&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The basic structure is as straight-forward as it can be, we&amp;#8217;re just setting up the initial &amp;#8216;shell&amp;#8217; with the class name and its methods:&lt;/p&gt;
&lt;pre class="ruby"&gt;class Interpreter
  
  def initialize()    
  end
  
  def at(time)
    @time = time
  end
  
  def when(date)
    @date = date
  end
  
  def we(people)
    @people = people
  end
  
  def going(where)
    @where = where
  end
  
  def output
  end
  
end
&lt;/pre&gt;
&lt;p&gt;That by itself doesn&amp;#8217;t seem to be doing much yet but let&amp;#8217;s see what happens when we try some method chaining in IRB:&lt;/p&gt;
&lt;pre class="ruby"&gt;1.9.3-p125 :001 &amp;gt; require File.expand_path 'interpreter'
 =&amp;gt; true 
1.9.3-p125 :002 &amp;gt; interpreter = Interpreter.new
 =&amp;gt; #&amp;lt;Interpreter:0x007faa2c133f20&amp;gt;
1.9.3-p125 :003 &amp;gt; interpreter.at('7pm')
 =&amp;gt; "7pm"
1.9.3-p125 :004 &amp;gt; interpreter.at('7pm').when('tomorrow night')
NoMethodError: undefined method `when' for "7pm":String
	from (irb):4
	from /Users/thiago/.rvm/rubies/ruby-1.9.3-p125/bin/irb:16:in `'
&lt;/pre&gt;
&lt;p&gt;As expected, an exception is raised because we&amp;#8217;re trying to access a method that doesn&amp;#8217;t exist in the String class.&lt;/p&gt;
&lt;p&gt;&lt;strong class="heading"&gt;The magic sauce&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The trick to having method chaining work is quite simple actually, all we need to do is return an instance of &lt;em&gt;self&lt;/em&gt; in each of the methods. Let&amp;#8217;s improve our Interpreter class:&lt;/p&gt;
&lt;pre class="ruby"&gt;class Interpreter
  
  def initialize()    
  end
  
  def at(time)
    @time = time
    self
  end
  
  def when(date)
    @date = date
    self
  end
  
  def we(people)
    @people = people
    self
  end
  
  def going(where)
    @where = where
    self
  end
  
  def output
  end
  
end
&lt;/pre&gt;
&lt;p&gt;Now, let&amp;#8217;s try in IRB and see what happens:&lt;/p&gt;
&lt;pre class="ruby"&gt;1.9.3-p125 :001 &amp;gt; require File.expand_path 'interpreter'
 =&amp;gt; true 
1.9.3-p125 :002 &amp;gt; interpreter = Interpreter.new
 =&amp;gt; #&amp;lt;Interpreter:0x007ff07b970b80&amp;gt; 
1.9.3-p125 :003 &amp;gt; interpreter.at('7pm')
 =&amp;gt; #&amp;lt;Interpreter:0x007ff07b970b80 @time="7pm"&amp;gt; 
1.9.3-p125 :004 &amp;gt; interpreter.at('7pm').when('tomorrow night')
 =&amp;gt; #&amp;lt;Interpreter:0x007ff07b970b80 @time="7pm", @date="tomorrow night"&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Great, method chaining is now working as expected. And since all methods return an instance of &lt;em&gt;self&lt;/em&gt;, the order in which we call the methods in the chain doesn&amp;#8217;t really matter:&lt;/p&gt;
&lt;pre class="ruby"&gt;1.9.3-p125 :001 &amp;gt; require File.expand_path 'interpreter'
 =&amp;gt; true 
1.9.3-p125 :002 &amp;gt; interpreter = Interpreter.new
 =&amp;gt; #&amp;lt;Interpreter:0x007ff8b31665d0&amp;gt; 
1.9.3-p125 :003 &amp;gt; interpreter.when('tomorrow night').at('7pm')
 =&amp;gt; #&amp;lt;Interpreter:0x007ff8b31665d0 @date="tomorrow night", @time="7pm", @where="drinking"&amp;gt; 
&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt;&lt;strong class="heading"&gt;Improving the &lt;em&gt;initialize()&lt;/em&gt; method&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now that we&amp;#8217;ve got the method chaining working, the next step is to enable our &lt;em&gt;initialize&lt;/em&gt; method to receive a block. Let&amp;#8217;s see what happens when we use &lt;em&gt;yield&lt;/em&gt;:&lt;/p&gt;
&lt;pre class="ruby"&gt;class Interpreter

  def initialize()
    yield
  end
  ...
end
&lt;/pre&gt;
&lt;p&gt;In IRB, let&amp;#8217;s try passing a block to the Interpreter class&amp;#8217; &lt;em&gt;initialize&lt;/em&gt; method:&lt;/p&gt;
&lt;pre class="ruby"&gt;1.9.3-p125 :005 &amp;gt; require File.expand_path 'interpreter'
 =&amp;gt; true 
1.9.3-p125 :006 &amp;gt; Interpreter.new { puts 'hello' }
hello
 =&amp;gt; #&amp;lt;Interpreter:0x007f98bb0ab328&amp;gt;

&lt;/pre&gt;
&lt;p&gt;As we can see, so far so good. Now, what happens if we try accessing the instance methods?&lt;/p&gt;
&lt;pre class="ruby"&gt;1.9.3-p125 :007 &amp;gt; require File.expand_path 'interpreter'
 =&amp;gt; true 
1.9.3-p125 :008 &amp;gt; Interpreter.new { at('7pm') }
NoMethodError: undefined method `at' for main:Object
	from (irb):8:in `block in irb_binding'
	from /Users/thiago/Projects/rubytech/0.rb:4:in `initialize'
	from (irb):8:in `new'
	from (irb):8
	from /Users/thiago/.rvm/rubies/ruby-1.9.3-p125/bin/irb:16:in `&amp;lt;main&amp;gt;'
&lt;/pre&gt;
&lt;p&gt;You may be asking &amp;#8220;how come that doesn&amp;#8217;t work if the &lt;em&gt;at&lt;/em&gt; method is defined?&amp;#8221;. The method is indeed defined but it&amp;#8217;s defined as an instance of the Interpreter class.&lt;/p&gt;
&lt;p&gt;Next we&amp;#8217;re going to pass an argument to &lt;em&gt;yield&lt;/em&gt; that returns an instance of &lt;em&gt;self&lt;/em&gt;&amp;#160;:&lt;/p&gt;
&lt;pre class="ruby"&gt;class Interpreter
  
  def initialize()
    yield(self)
  end
  ...
end
&lt;/pre&gt;
&lt;p&gt;And when we run this in IRB:&lt;/p&gt;
&lt;pre class="ruby"&gt;1.9.3-p125 :001 &amp;gt; require File.expand_path 'interpreter'
 =&amp;gt; true 
1.9.3-p125 :002 &amp;gt; Interpreter.new {|i| i.at('7pm') }
 =&amp;gt; #&amp;lt;Interpreter:0x007fbaad1626b8 @time="7pm"&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Bingo! Works like a charm. Yes, it does work but it isn&amp;#8217;t the final solution based on the original challenge.&lt;/p&gt;
&lt;p&gt;The missing link for us is to use &lt;em&gt;instance_eval &lt;/em&gt;instead of &lt;em&gt;yield&lt;/em&gt;&lt;em&gt;. &lt;/em&gt;Without going into a deep explanation of how &lt;em&gt;instance_eval&lt;/em&gt; works, here&amp;#8217;s the fundamental idea: &lt;em&gt;instance_eval&lt;/em&gt; is a method of the Object class, meaning that the receiver will be an object and the block that you pass in is evaluated in the context of that object. &lt;/p&gt;
&lt;p&gt;I recommend you read the book &lt;a href="http://pragprog.com/book/ppmetr/metaprogramming-ruby" title="Metaprogramming Ruby" target="_blank"&gt;Metaprogramming Ruby&lt;/a&gt; or research online if you&amp;#8217;re interested in learning more about Metaprogramming in Ruby. I will also be covering the subject on future posts.&lt;/p&gt;
&lt;p&gt;Now, let&amp;#8217;s change our &lt;em&gt;initialize&lt;/em&gt; method to use &lt;em&gt;instance_eval&lt;/em&gt;:&lt;/p&gt;
&lt;pre class="ruby"&gt;class Interpreter
  
  def initialize(&amp;amp;block)
    instance_eval(&amp;amp;block)
  end
  ...
end
&lt;/pre&gt;
&lt;p&gt;And let&amp;#8217;s try in IRB now:&lt;/p&gt;
&lt;pre class="ruby"&gt;1.9.3-p125 :001 &amp;gt; require File.expand_path 'interpreter'
 =&amp;gt; true 
1.9.3-p125 :002 &amp;gt; Interpreter.new { at('7pm') }
 =&amp;gt; #&amp;lt;Interpreter:0x007f8041170d90 @time="7pm"&amp;gt;
&lt;/pre&gt;
&lt;p&gt;As you can see, it works as expected. The reason why it works is because &lt;em&gt;instance_eval&lt;/em&gt; is evaluated to the context of the Interpreter object, thus making all methods in the class accessible from within the block.&lt;/p&gt;
&lt;p&gt;&lt;strong class="heading"&gt;The final touches&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are two final changes that we need to make: 1) the &lt;em&gt;output&lt;/em&gt; method needs to returns the string set by the challenge; 2) the &lt;em&gt;we&lt;/em&gt; method needs to be able to receive an array of names:&lt;/p&gt;
&lt;pre class="ruby"&gt;class Interpreter
  ...
  def we(*people)
    @people = people
    self
  end

  def output
    [@people.join(' and '), "are going", @where, @date, "at", @time].join(' ')
  end
  
end
&lt;/pre&gt;
&lt;p&gt;We should now have the Interpreter class work as expected by the challenge:&lt;/p&gt;
&lt;pre class="ruby"&gt;1.9.3-p125 :001 &amp;gt; require File.expand_path 'interpreter'
 =&amp;gt; true 
1.9.3-p125 :002 &amp;gt; Interpreter.new { at("7pm").when("tomorrow night").we("John", "Bob").going("drinking") }.output
 =&amp;gt; "John and Bob are going drinking tomorrow night at 7pm" 
&lt;/pre&gt;
&lt;p&gt;Here&amp;#8217;s the final class:&lt;/p&gt;
&lt;pre class="ruby"&gt;class Interpreter
  
  def initialize(&amp;amp;block)
    instance_eval(&amp;amp;block)
  end
  
  def at(time)
    @time = time
    self
  end
  
  def when(date)
    @date = date
    self
  end
  
  def we(*people)
    @people = people
    self
  end
  
  def going(where)
    @where = where
    self
  end
  
  def output
    [@people.join(' and '), "are going", @where, @date, "at", @time].join(' ')
  end
  
end

&lt;/pre&gt;
&lt;p&gt;&lt;strong class="heading"&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This example has demonstrated how simple it is to add method chaining to any Ruby class. It also discussed the use of blocks and briefly covered Metaprogramming in Ruby. The final class could be simplified by utilizing metaprogramming but that was purposely left out in order to maintain the focus of the article.&lt;/p&gt;</description><link>http://tjackiw.tumblr.com/post/23155838377</link><guid>http://tjackiw.tumblr.com/post/23155838377</guid><pubDate>Wed, 16 May 2012 00:28:00 -0700</pubDate><category>ruby</category></item></channel></rss>
