<?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>Ruby Fleebie &#187; In depth</title>
	<atom:link href="http://www.rubyfleebie.com/category/in-depth/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rubyfleebie.com</link>
	<description>Because programming should be fun</description>
	<lastBuildDate>Tue, 29 Jun 2010 16:12:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>XMPP4r: A real world example</title>
		<link>http://www.rubyfleebie.com/xmpp4r-a-real-world-example/</link>
		<comments>http://www.rubyfleebie.com/xmpp4r-a-real-world-example/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 17:48:53 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[In depth]]></category>

		<guid isPermaLink="false">http://www.rubyfleebie.com/?p=102</guid>
		<description><![CDATA[It&#8217;s been a while since I wrote about XMPP and XMPP4r. I&#8217;m glad because my introductory posts on this topic were very well received. Today I want to push further and share with you a tutorial-like post explaining step by step how to build a simple application with a XMPP interface. The complete listing is [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I wrote about <a href="http://www.rubyfleebie.com/im-integration-with-xmpp4r/">XMPP</a> and <a href="http://www.rubyfleebie.com/im-integration-with-xmpp4r-part-2/">XMPP4r</a>. I&#8217;m glad because my introductory posts on this topic were very well received. Today I want to push further and share with you a tutorial-like post explaining step by step how to build a simple application with a XMPP interface. The complete listing is also available on <a href="http://bitbucket.org/flamontagne/fleebie_weather">bitbucket</a></p>
<h3>The application</h3>
<p>I couldn&#8217;t find something better than writing a xmpp weather bot. You type the name of a city and the bot answers with the current temperature and forecast information using the Google Weather API. Simple enough for this tutorial.</p>
<h3>The gems you&#8217;ll need to install</h3>
<ul>
<li><a href="http://home.gna.org/xmpp4r/">XMPP4r</a> : <strong>sudo gem install xmpp4r</strong></li>
<li><a href="http://flori.github.com/json/">json_pure</a>, to convert ruby hashes into json: <strong>sudo gem install json_pure</strong></li>
<li><a href="http://github.com/jnunemaker/crack">Crack</a>, a xml and json parser: <strong>sudo gem install crack</strong></li>
<li><a href="http://github.com/starling/starling">starling</a>, a ruby message queue: <strong>sudo gem sources -a http://gems.github.com/ &#038;&#038; sudo gem install starling-starling</strong> Then, start the starling daemon by typing : <strong>sudo starling -d</strong></li>
</ul>
<h3>Why using a message queue like starling?</h3>
<p>starling is a message queue library that speaks the memcache protocol. It is my opinion that a message queue is often a very clever and powerful way to establish a direct communication between the various parts of an application or even between different applications. For the sake of this tutorial, I wanted to separate our application into two distinct components and I didn&#8217;t want these components to talk to each other via the http protocol.</p>
<h3>We won&#8217;t install a XMPP server</h3>
<p>We won&#8217;t go to the pain of installing a XMPP server like <a href="http://www.ejabberd.im/">ejabberd</a> or <a href="http://www.igniterealtime.org/projects/openfire/">openfire</a> because it would be beyond the scope of this article. Instead, we&#8217;ll simply use a Google account for our bot</p>
<h3>Application architecture</h3>
<p>Like I said, I wanted to separate the application into 2 components : The xmpp listener and the backend logic. You probably already guessed that the xmpp listener component job will be to send and receive xmpp stanzas to the user at the other end. To get the weather data, our listener will send the request to the backend component via a starling message queue that we&#8217;ll name <em>backend</em>. The backend component will do what is needed to compute the weather data and it will send the result back to the listener component via another starling message queue that we&#8217;ll name <em>listener</em></p>
<p>This setup might be overkill for our simple app but one of my objective was to show you how easy and interesting it can be to work with message queues. Let&#8217;s get the ball rolling.</p>
<h3>The listener component</h3>
<p>create a new file in your code editor and give it the name listener.rb. Here is the complete source code for this file. I will add comments at the bottom of the listing. To copy this code in your clipboard, don&#8217;t forget to click on the small &#8220;view plain&#8221; link at the top or else you will copy the line numbers as well.</p>
<pre name="code" class="ruby">
require 'starling'
require 'json/pure'
require 'xmpp4r'
require 'xmpp4r/roster'
require 'cgi'
class Fleebie
  include Jabber
  attr_accessor :jid, :password
  attr_reader :client, :roster

  def initialize
    self.jid = ARGV[0]
    self.password = ARGV[1]
    @client = Client.new(self.jid)
    Jabber::debug = true
    connect
  end

  def connect
    @client.connect
    @client.auth(@password)
    @client.send(Presence.new.set_type(:available))

    #the "roster" is our bot contact list
    @roster = Roster::Helper.new(@client)

    #...to accept new subscriptions
    start_subscription_callback

    #...to do something with the messages we receive
    start_message_callback

    #When the backend application has done its job, it tells the listener
    #via the "listener" message queue.
    process_queue
  end

  private

  #Whatever we receive, we send it to our "backend" message queue. It's
  #not our job to parse and decode the actual message
  def start_message_callback
    @client.add_message_callback do |m|
      @starling.set('backend',{:from => m.from, :body => m.body}.to_json)
        unless m.composing? || m.body.to_s.strip == ""
    end
  end

  #whenever someone adds the bot to his contact list, it gets here
  def start_subscription_callback
    @roster.add_subscription_request_callback do |item,pres|
      #we accept everyone
      @roster.accept_subscription(pres.from)

      #Now it's our turn to send a subscription request
      x = Presence.new.set_type(:subscribe).set_to(pres.from)
      @client.send(x)

      #let's greet our new user
      m=Message::new
      m.to = pres.from
      m.body = "Welcome! Type a location to get the weather forecast"
      @client.send(m)
    end
  end

  #The backend application talks to this XMPP interface via starling.
  #in process_queue we process our job list.
  def process_queue
    @starling = Starling.new('127.0.0.1:22122')
    th = Thread.new do
      Thread.current.abort_on_exception = true
      loop do
        item = @starling.get('listener')
        unless item.nil?
          jitem = JSON.parse(item) rescue nil
          msg = Message::new(jitem["from"])
          msg.type=:chat
          if jitem["success"] == true
            msg.body = "\n"
            msg.body += jitem["message"] + "\n"
            msg.body += "Current temp: #{jitem["details"]["current_temperature"]}\n"
            msg.body += "Winds: #{jitem["details"]["winds"]}\n\n"
            msg.body += "<b>TODAY</b>\n"
            msg.body += jitem["details"]["today"]["condition"] + "\n"
            msg.body += "Min/Max : #{jitem["details"]["today"]["low_f"]} / "
            msg.body += jitem["details"]["today"]["high_f"] + " ("
            msg.body += jitem["details"]["today"]["low_c"] + " / "
            msg.body += jitem["details"]["today"]["high_c"] + ") \n\n"

            msg.body += "<b>TOMORROW</b>\n"
            msg.body += jitem["details"]["tomorrow"]["condition"] + "\n"
            msg.body += "Min/Max : #{jitem["details"]["tomorrow"]["low_f"]} /"
            msg.body += jitem["details"]["tomorrow"]["high_f"] + " ("
            msg.body += jitem["details"]["tomorrow"]["low_c"] + " / "
            msg.body += jitem["details"]["tomorrow"]["high_c"] + ") \n"

            msg.add_element(prepare_html(msg.body))
            msg.body = msg.body.gsub(/<.*?>/, '')
          else
            msg.body = jitem["message"]
          end
          @client.send(msg)

        end
      end
    end
  end

  def prepare_html(text)
    h = REXML::Element::new("html")
    h.add_namespace('http://jabber.org/protocol/xhtml-im')

    # The body part with the correct namespace
    b = REXML::Element::new("body")
    b.add_namespace('http://www.w3.org/1999/xhtml')

    # The html itself
    t = REXML::Text.new(text.gsub("\n",""), false, nil, true, nil, %r/.^/ )

    # Add the html text to the body, and the body to the html element
    b.add(t)
    h.add(b)
    h
  end
end

Fleebie.new
Thread.stop
</pre>
<h3>Important parts of this listing</h3>
<p>I hope that you will find the code above self explaining. However, here are a few important things about the listing. At line 98-99, we set 2 versions of the same message that will be sent to the XMPP user : one in plain text, the other in XHTML. If the client at the other end has support for XHTML messages, the XHTML version will be displayed, otherwise the plain text version will be used. This is a <a href="http://xmpp.org/extensions/xep-0071.html">pretty interesting feature of the XMPP protocol</a>.</p>
<h3>The process_queue method</h3>
<p>We start a new thread, we subscribe to the &#8216;listener&#8217; message queue and we process our job list until the program ends or gets interrupted (by typing Ctrl-C for example). You can see that by using a message queue, we move away from the traditional &#8220;Request / Response&#8221; paradigm. In our case the request (line #44) is &#8220;disconnected&#8221; from the response (line #103). </p>
<p>Finally, at line #129 we stop the main thread (not the same thread that we started in process_queue). We do this for an obvious reason : we don&#8217;t want our script to terminate once it will reach the end of the file. We just ask him to wait until the other threads are done executing.</p>
<h3>The backend component</h3>
<p>It is here that we will fetch, compute and prepare the actual weather data. For the sake of this tutorial I use the google weather API but it could have been anything else. Create a new file in your code editor and call it backend.rb</p>
<pre name='code' class='ruby'>
require 'starling'
require 'crack'
require 'net/http'
require 'cgi'
require 'iconv'
require 'json'
class Backend
  def run
    process_queue
  end

  private
  def process_queue
    @starling = Starling.new('127.0.0.1:22122')
    th = Thread.new do
      Thread.current.abort_on_exception = true
      loop do
        item = @starling.get('backend')
        unless item.nil?
          jitem = Crack::JSON.parse(item) rescue nil

          google_api_url = "http://www.google.com/ig/api?weather=#{CGI::escape(jitem["body"])}"

          ig_weather = Crack::XML.parse(Iconv.conv('UTF-8',
          'ISO-8859-1',
          Net::HTTP.get(URI.parse(google_api_url))
          )
          ) rescue nil

          if jitem &#038;&#038; ig_weather
            process_job(jitem,ig_weather)
          else
            puts jitem["from"]
            @starling.set('listener',
            {
              :from => jitem["from"],
              :success => false,
              :message => "An error occured while accessing Google Weather API. You may try again later"
            }.to_json) unless jitem.nil?
          end

        end
      end
    end

  end

  def process_job(jitem,ig_weather)
    if ig_weather["xml_api_reply"]["weather"]["problem_cause"]
      @starling.set('listener',{
        :from => jitem["from"],
        :success => false,
        :message => "Data not available. Try being more precise when typing your location (ex. trois-rivières, québec)"
      }.to_json)
    else
      weather = ig_weather["xml_api_reply"]["weather"]
      data = {
        :forecast_obj => weather["forecast_conditions"],
        :city => weather["forecast_information"]["city"]["data"],
        :winds => weather["current_conditions"]["wind_condition"]["data"],
        :unit_system => weather["forecast_information"]["unit_system"]["data"],
        :temp_f => weather["current_conditions"]["temp_f"]["data"],
        :temp_c => weather["current_conditions"]["temp_c"]["data"],
      }      

      @starling.set('listener',
      {
        :from => jitem["from"],
        :success => true,
        :message => "Weather data for <b>#{data[:city]}:</b>",
        :details => {
          :current_temperature => "#{data[:temp_f]} ° F / #{data[:temp_c]} ° C",
          :unit => data[:unit_system],
          :winds => data[:winds],
          :today => temperatures(
                      data[:unit_system],
                      data[:forecast_obj][0]
                    ).merge(:condition => data[:forecast_obj][0]["condition"]["data"]),

          :tomorrow => temperatures(
                        data[:unit_system],
                        data[:forecast_obj][1]
                      ).merge(:condition => data[:forecast_obj][1]["condition"]["data"])
        }
      }.to_json)
    end
  end

  def temperatures(source_unit,obj)
    x = {}

    if(source_unit == "US")
      #we convert to Celcius
      x["low_c"] = obj["low"]["data"].to_i.to_celcius
      x["high_c"] = obj["high"]["data"].to_i.to_celcius
      x["low_f"] = "#{obj["low"]["data"]} ° F"
      x["high_f"] = "#{obj["high"]["data"]} ° F"

    else
      #we convert to farenheit
      x["low_f"] = obj["low"]["data"].to_i.to_farenheit
      x["high_f"] = obj["high"]["data"].to_i.to_farenheit
      x["low_c"] = "#{obj["low"]["data"]} ° C"
      x["high_c"] = "#{obj["high"]["data"]} ° C"
    end
    x
  end
end

class Fixnum
  def to_celcius
    ((self - 32) / 1.8).round.to_s + " °C"
  end

  def to_farenheit
    (self * 1.8 + 32).round.to_s + " °F"
  end
end

Backend.new.run

#Always remember to pause the main thread at the end since it does not contain any
#blocking call.
Thread.stop
</pre>
<p>This code is not very sexy&#8230; It just queries the google api, parse the result, convert temperatures from Farenheit to Celcius or the other way around (because the Google API doesn&#8217;t do that by itself) and send back the response to the listener component via the corresponding message queue.</p>
<h3>Launch the script</h3>
<p>Create a shell script and call it launcher.sh (don&#8217;t forget to chmod +x). put the following in it :</p>
<pre name='code'>
#!/bin/bash
export RUBYOPT=rubygems
d=`dirname $0`
ruby $d/backend.rb &#038;
ruby $d/listener.rb yourbot@gmail.com somepassword
</pre>
<p>Now you can type ./launcher.sh and you should be ready to go. If you encounter a problem while following the tutorial, don&#8217;t hesitate to post a comment and I&#8217;ll do my best to help you resolve it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rubyfleebie.com/xmpp4r-a-real-world-example/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to setup a password-less &#8220;cap deploy&#8221; with Capistrano</title>
		<link>http://www.rubyfleebie.com/how-to-setup-a-password-less-cap-deploy-with-capistrano/</link>
		<comments>http://www.rubyfleebie.com/how-to-setup-a-password-less-cap-deploy-with-capistrano/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 14:26:29 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[In depth]]></category>

		<guid isPermaLink="false">http://www.rubyfleebie.com/how-to-setup-a-password-less-cap-deploy-with-capistrano/</guid>
		<description><![CDATA[The situation
You want to type &#8220;cap deploy&#8221; without having to enter your ssh password every time
The background
You have configured your server to allow public key authentications over ssh and have given the proper permissions to the resulting files &#038; folders (how to do this). Oh and the repository as well as your application is located [...]]]></description>
			<content:encoded><![CDATA[<p><strong>The situation</strong><br />
You want to type &#8220;cap deploy&#8221; without having to enter your ssh password every time</p>
<p><strong>The background</strong><br />
You have configured your server to allow public key authentications over ssh and have given the proper permissions to the resulting files &#038; folders (<a href="http://sial.org/howto/openssh/publickey-auth/#s2">how to do this</a>). Oh and the repository as well as your application is located in the same server.</p>
<p><strong>The problem</strong><br />
Capistrano still asks for your password at one time in the deployment procedure!</p>
<p><strong>Why Does this happens?</strong><br />
Once you typed cap deploy and the ssh session is established, the remote server will do a checkout (or clone, or whatever) at some point to fetch the latest revision from your repository. It will do this by using your capistrano :repository variable that probably looks like &#8220;ssh://me@blablabla.com/home/user/repositories/myapp&#8221;. The &#8220;problem&#8221; (which is not really a problem) is on your remote server only&#8230; it has nothing to do with your public key authentication setup or your local machine. If you want to reproduce the problem, log into your ssh server and do the same checkout/clone operation that capistrano is trying to do. It should asks for a password. Why? Because you do the checkout with an &#8220;external url scheme&#8221;. So even if the repository url is pointing to the very same server that does the request, it still needs a password.</p>
<p><strong>Solution</strong><br />
Checkout/Clone your repository with a physical path.</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">set :repository,&nbsp; <span style="color:#996600;">&quot;/home/#{user}/repositories/#{application}&quot;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">set :local_repository, <span style="color:#996600;">&quot;ssh://#{user}@#{domain}/home/#{user}/repositories/#{application}&quot;</span></div>
</li>
</ol>
</div>
<p>And that&#8217;s it!</p>
<p>At first you might think that it should be the other way around. Wouldn&#8217;t it make more sense if the :repository variable was set to a &#8220;ssh://&#8221; path and local_repository to a &#8220;local&#8221; path?</p>
<p>Well, yes. But for capistrano it means : &#8220;When I&#8217;m on your local workstation, I will use :local_repository to access your repository. And when I&#8217;m connected on the remote server, I will use :repository&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rubyfleebie.com/how-to-setup-a-password-less-cap-deploy-with-capistrano/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ruby and C : Part 1</title>
		<link>http://www.rubyfleebie.com/ruby-and-c-part-1/</link>
		<comments>http://www.rubyfleebie.com/ruby-and-c-part-1/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 04:07:33 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[In depth]]></category>

		<guid isPermaLink="false">http://www.rubyfleebie.com/ruby-and-c-part-1/</guid>
		<description><![CDATA[This first part aims at explaining how Ruby in the background is not Ruby anymore. In the next part I&#8217;m going to talk about HOW to bridge some existing C library with your ruby application.
As you might know already, the official ruby interpreter is written in pure C. This means that whenever you type a [...]]]></description>
			<content:encoded><![CDATA[<p>This first part aims at explaining how Ruby in the background is not Ruby anymore. In the next part I&#8217;m going to talk about HOW to bridge some existing C library with your ruby application.</p>
<p>As you might know already, the <a href="http://www.ruby-lang.org">official ruby interpreter</a> is written in pure C. This means that whenever you type a ruby instruction, the interpreter will call the corresponding C function for you. For example, if you do :</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">arr = <span style="color:#7b0303; font-weight:bold;">Array</span>.<span style="color:#3a27c9;">new</span></div>
</li>
</ol>
</div>
<p>Ruby will call a C function (probably rb_ary_new) and a C structure will be created to hold the content of <i>arr</i>. When you will try to access <i>arr</i> later in your code, the interpreter will use that same C structure.</p>
<h3>On the ruby side of things we say that everything is an object. On the C side of things we say that everything is a VALUE</h3>
<p>
You also already know that everything in ruby is an object. To represent this reality on the C side of things, a custom type (typedef) has been created and has been given the name of VALUE. This type is a pointer (well, in fact it is not really a pointer but we won&#8217;t go into this right now) that can reference any kind of data type. When C defines something as a VALUE, you know that it is dealing with something that either A) comes from the ruby side of things, B) will be returned to the ruby side of things or C) is usable on the ruby side of things in one way or another. In all other situations, C is just C and doesn&#8217;t need the VALUE data type. When you see C using VALUE, what you are really seeing is ruby from the inside, and ruby from the inside is an ugly beast. It is not pretty, not elegant, not easy, not cool and honestly not that interesting. The thing is, it can save you a lot of work if you want to bridge an existing C library into your ruby application instead of having to rewrite the whole thing in plain ruby. That, in part, is why it can be very useful to know a little bit of ruby&#8217;s ugly side.</p>
<p>Let&#8217;s move on. We said that VALUE was the C way to represent a ruby object. If you open one of the source file of the ruby interpreter (array.c, string.c, etc.), you will find that the word VALUE is used everywhere :</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">VALUE rb_do_stuff<span style="color: #66cc66;">&#40;</span>VALUE param1, VALUE param2<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; VALUE some_variable;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color: #993333;">int</span> x;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color: #808080; font-style: italic;">//bla bla bla bla</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color: #b1b100;">return</span> some_variable; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div>
</li>
</ol>
</div>
<p>Since everything in ruby is an object (or a VALUE), the C functions that are responsible of returning something ready to use on the ruby side of things <b>always have to return a VALUE</b>. If they would return something else (int, char, char *, long), ruby would complain because it can understand objects and only objects. </p>
<p>A Fixnum is not a <i>int</i>, it is a VALUE. A Bignum is not a <i>long</i>, it is a VALUE. A String is not a <i>char *</i>, it is a VALUE, and so on.</p>
<h3>VALUE is not really a pointer, you say?</h3>
<p>Ok the following is not really important for the sake of this post but if you&#8217;re curious it will interest you. I said earlier that VALUE wasn&#8217;t really a pointer. Time has come to explain what it is and why. <a href="http://www.ruby-doc.org/doxygen/1.8.4/ruby_8h-source.html#l00066">VALUE is in fact an <strong>unsigned long</strong></a>.</p>
<p>There is only one reason why VALUE is an unsigned long and not a pointer : efficiency.</p>
<p>Remember what a pointer is? It is a variable that contains an address to some structure in memory. It is perfect for complex objects like arrays, hashes and custom objects&#8230; but it is a bit overkill for more primitive objects like Fixnums, booleans (TrueClass and FalseClass instances) and nil (NilClass instance). Ruby inventor thought that <strong>it would be great if in some cases the VALUE object could BE the data instead of POINTING TO the data</strong>. I mean, why having a VALUE that points to a structure that contains an integer that contains the number 1 when you could simply have a VALUE that contains the number 1?</p>
<p>So instead of being a pointer, VALUE is an unsigned long that can contain either A) an address to some structure that contains the data or B) the data itself (immediate value).</p>
<p>The data in a VALUE is stored in such a way that it is possible to know if it contains an address to some structure in memory or an immediate value. Ingenious, ain&#8217;t it?</p>
<p>In my next post, I will try to explain how you can use the ugly side of ruby to bridge an existing C library into your ruby (or rubyonrails) application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rubyfleebie.com/ruby-and-c-part-1/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>How to display a collection grouped by an attribute value in Rails</title>
		<link>http://www.rubyfleebie.com/how-to-display-a-collection-grouped-by-an-attribute-value-in-rails/</link>
		<comments>http://www.rubyfleebie.com/how-to-display-a-collection-grouped-by-an-attribute-value-in-rails/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 19:44:32 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[In depth]]></category>

		<guid isPermaLink="false">http://www.rubyfleebie.com/how-to-display-a-collection-grouped-by-an-attribute-value-in-rails/</guid>
		<description><![CDATA[Flashback time. We are in 1999 and you are coding in ASP... yet people are not laughing at you.]]></description>
			<content:encoded><![CDATA[<p>Flashback time. We are in 1999 and you are coding in ASP thinking that this language is the future. You use ADODB recordsets to iterate over collections. You have a recordset containing some records from a &#8220;quotes&#8221; table. The &#8220;quotes&#8221; table contains a author column (varchar) and a body column (varchar). Now you want to display the results grouped by author name so it looks like this : </p>
<p><strong>Georges Brassens</strong><br />
- Les filles quand ça dit &#8220;je t&#8217;aime&#8221;, c&#8217;est comme un second baptême<br />
- Aucune idée sur terre n&#8217;est digne d&#8217;un trépas</p>
<p><strong>Billie Holiday</strong><br />
- Don&#8217;t threaten me with love, baby. Let&#8217;s just go walking in the rain.<br />
- I never hurt nobody but myself and that&#8217;s nobody&#8217;s business but my own.</p>
<p>Assuming your recordset is ordered by author, you do something like this (remember, we&#8217;re in 1999) : </p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;TABLE style=<span style="color: #ff0000;">&quot;color:fushia;font-style:MSONormal generated=frontpage&quot;</span>&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;%<span style="color: #b1b100;">while</span> <span style="color: #b1b100;">not</span> objRS.<span style="color: #b1b100;">eof</span> %&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;%<span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span>current_author &lt;&gt; objRS<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;author&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>%&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;h1&gt;&lt;%=objRS<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;author&quot;</span><span style="color: #66cc66;">&#41;</span>%&gt;&lt;/h1&gt;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;%<span style="color: #b1b100;">end</span> if%&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;Tr&gt;&lt;td&gt;&lt;%=objRS<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;body&quot;</span><span style="color: #66cc66;">&#41;</span>&lt;/td&gt;&lt;/TR&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;%current_author = objRS<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;author&quot;</span><span style="color: #66cc66;">&#41;</span>%&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;%objRS.<span style="color: #66cc66;">MoveNext</span>%&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;%loop%&gt;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;%objRS.<span style="color: #66cc66;">close</span>%&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;/TABLE&gt;</div>
</li>
</ol>
</div>
<p>Ok welcome back in 2008. ASP is dead. You are coding in rails and you want to do the same thing. How will you do it? Storing the author name in a buffer variable like in 1999? Not too sure about it.</p>
<p>This is a job for Enumerable#group_by (Enumerable is a <a href="http://www.rubyfleebie.com/an-introduction-to-modules-part-2">module</a> that is mixed in the Array class)</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">all_quotes = Quote.<span style="color:#3a27c9;">find</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>:all<span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@authors = all_quotes.<span style="color:#3a27c9;">group_by</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>&amp;:author<span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
</ol>
</div>
<p>Enumerable#group_by will create different sets of quotes based on the &#8220;author&#8221; values. Why the &#8220;&#038;&#8221; sign? It&#8217;s because group_by expects a block. I could have done it this way  : @authors = all_quotes.group_by{|quote| quote.author}</p>
<p>So @authors is now a hash that will look like this:</p>
<p>{&#8220;George Brassens&#8221; => [#&lt;Quote id:131 ...&gt;, #&lt;Quote id:331 ...&gt;], &#8220;Billie Holiday&#8221; => [#&lt;Quote id:111 ...&gt;, #&lt;Quote id:911 ...&gt;] }</p>
<p>Now you can iterate over it like this :</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@authors.<span style="color:#3a27c9;">each_pair</span> <span style="color:#3a27c9; font-weight:normal;">do</span> |author_name, quotes|</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &lt;h1&gt;&lt;%=author_name%&gt;&lt;/h1&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &lt;%quotes.<span style="color:#3a27c9;">each</span> <span style="color:#3a27c9; font-weight:normal;">do</span> |quote| %&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp; &#8211; &lt;%=quote.<span style="color:#3a27c9;">body</span>%&gt;&lt;br /&gt;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &lt;%end%&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;%end%&gt;</div>
</li>
</ol>
</div>
<p>One more thing to note : @authors is a hash, and hashes cannot be ordered. If you want to display quotes by sorted author name, you could do this :</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@authors.<span style="color:#3a27c9;">keys</span>.<span style="color:#3a27c9;">sort</span>.<span style="color:#3a27c9;">each</span> <span style="color:#3a27c9; font-weight:normal;">do</span> |author_name|</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &lt;h1&gt;&lt;%=author_name%&gt;&lt;/h1&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &lt;%@authors<span style="color:#3a27c9; font-weight:bold;">&#91;</span>author_name<span style="color:#3a27c9; font-weight:bold;">&#93;</span>.<span style="color:#3a27c9;">each</span> <span style="color:#3a27c9; font-weight:normal;">do</span> |quote|%&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp; &#8211; &lt;%=quote.<span style="color:#3a27c9;">body</span>%&gt;&lt;br /&gt;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &lt;%end%&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&lt;%end%&gt;</div>
</li>
</ol>
</div>
<p>Note : Enumerable#group_by does not exist in ruby 1.8, it only exists in Rails. The method will be in ruby 1.9 however.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rubyfleebie.com/how-to-display-a-collection-grouped-by-an-attribute-value-in-rails/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Life beyond the each iterator</title>
		<link>http://www.rubyfleebie.com/life-beyond-the-each-iterator/</link>
		<comments>http://www.rubyfleebie.com/life-beyond-the-each-iterator/#comments</comments>
		<pubDate>Mon, 25 Feb 2008 03:37:38 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[In depth]]></category>

		<guid isPermaLink="false">http://www.rubyfleebie.com/life-beyond-the-each-iterator/</guid>
		<description><![CDATA[Today I will take a break from the IM integration with XMPP4r series and write about something completely different. Writing about XMPP4r just for the heck of it would become boring for everyone quite fast.
Let me dim the light, start some sentimental music, light some candles, make an exaggerated smile so I can become intimate [...]]]></description>
			<content:encoded><![CDATA[<p>Today I will take a break from the <a href="http://www.rubyfleebie.com/im-integration-with-xmpp4r/">IM integration with XMPP4r</a> series and write about something completely different. Writing about XMPP4r just for the heck of it would become boring for everyone quite fast.</p>
<p>Let me dim the light, start some sentimental music, light some candles, make an exaggerated smile so I can become intimate with you and talk about the past.</p>
<p><img src='http://www.rubyfleebie.com/wp-content/uploads/2008/02/sdc_candles1_md1.jpg' alt='sdc_candles1_md1.jpg' /></p>
<p>More than 1 year ago&#8230; I was so excited. I was learning Ruby and, most precisely, I was learning <a href="http://www.rubyfleebie.com/an-introduction-to-code-blocks/">blocks</a> and <em>block-based</em> iterators. Once I grasped the concept, I made the mistake of using almost exclusively the <em>each</em> iterator in every situations.</p>
<p><strong><em>each</em> is like your oldest pair of slippers</strong></p>
<p>Old slippers are comfortable and comforting. You put them on without shame, ignoring the laughs as well as the cruel remarks coming from your &#8220;friends&#8221;. The <em>each</em> iterator is also a comfortable pair of slippers. If you came to ruby from another language, it probably turned you on right away. Chances are that you said to yourself : &#8220;Damn, I will put my feet into that!&#8221;</p>
<p><img src='http://www.rubyfleebie.com/wp-content/uploads/2008/02/0410653194313_275x275.jpg' alt='0410653194313_275×275.jpg' /></p>
<p>There is no problem with the <em>each</em> iterator, it is simple, easy to use and easy to read. The problem is when you use it in every situations. When you do something like in the following example, you suffer from the syndrome of the comforting slippers.</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs = Dog.<span style="color:#3a27c9;">find</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>:all<span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs_to_keep = <span style="color:#3a27c9; font-weight:bold;">&#91;</span><span style="color:#3a27c9; font-weight:bold;">&#93;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs.<span style="color:#3a27c9;">each</span> <span style="color:#3a27c9; font-weight:bold;">&#123;</span> |dog| @dogs_to_keep.<span style="color:#3a27c9;">push</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>dog<span style="color:#3a27c9; font-weight:bold;">&#41;</span> <span style="color:#3a27c9; font-weight:normal;">if</span> calculate_emotional_intelligence<span style="color:#3a27c9; font-weight:bold;">&#40;</span>dog<span style="color:#3a27c9; font-weight:bold;">&#41;</span> &gt;= <span style="color:#3a27c9;">50</span> <span style="color:#3a27c9; font-weight:bold;">&#125;</span></div>
</li>
</ol>
</div>
<p>Here the programmer refused to remove his old slippers because he refused to see the life beyond the <em>each</em> iterator. A class like Array proposes other iterators that would have simplify the above code greatly.</p>
<p><strong>select</strong></p>
<p>This method is exactly what our programmer needed. Like <em>each</em>, it iterates over all elements in the array&#8230; but it does more. At each passage in the block, and if the value returned by the block is true, the corresponding element will be pushed into a new array.</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs = Dog.<span style="color:#3a27c9;">find</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>:all<span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs_to_keep = @dogs.<span style="color:#7b0303; font-weight:bold;">select</span> <span style="color:#3a27c9; font-weight:bold;">&#123;</span>|dog| calculate_emotional_intelligence<span style="color:#3a27c9; font-weight:bold;">&#40;</span>dog<span style="color:#3a27c9; font-weight:bold;">&#41;</span> &gt;= <span style="color:#3a27c9;">50</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span></div>
</li>
</ol>
</div>
<p><strong>reject</strong></p>
<p>You could also do it the other way around, rejecting dogs with little emotional intelligence.</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs = Dog.<span style="color:#3a27c9;">find</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>:all<span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs_to_keep = @dogs.<span style="color:#3a27c9;">reject</span> <span style="color:#3a27c9; font-weight:bold;">&#123;</span>|dog| calculate_emotional_intelligence<span style="color:#3a27c9; font-weight:bold;">&#40;</span>dog<span style="color:#3a27c9; font-weight:bold;">&#41;</span> &lt; <span style="color:#3a27c9;">50</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span></div>
</li>
</ol>
</div>
<p>Or you could modify the original array directly with <strong>reject!</strong></p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs = Dog.<span style="color:#3a27c9;">find</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>:all<span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs.<span style="color:#3a27c9;">reject</span>! <span style="color:#3a27c9; font-weight:bold;">&#123;</span>|dog| calculate_emotional_intelligence<span style="color:#3a27c9; font-weight:bold;">&#40;</span>dog<span style="color:#3a27c9; font-weight:bold;">&#41;</span> &lt; <span style="color:#3a27c9;">50</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span></div>
</li>
</ol>
</div>
<p><strong>collect and map (same thing)</strong></p>
<p>Finally, collect and map can be used when you want to create a new array based on the values returned at every passage in the block.</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs = <span style="color:#3a27c9; font-weight:bold;">&#91;</span><span style="color:#3a27c9; font-weight:bold;">&#123;</span>:name =&gt; <span style="color:#996600;">&quot;Benji&quot;</span>, :fear_factor =&gt; <span style="color:#3a27c9;">3</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span>,<span style="color:#3a27c9; font-weight:bold;">&#123;</span>:name =&gt; <span style="color:#996600;">&quot;Rex&quot;</span>, :fear_factor =&gt; <span style="color:#3a27c9;">7</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span><span style="color:#3a27c9; font-weight:bold;">&#93;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">if</span> outside_atmosphere == :dark_and_scary</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; @fear_factors = @dogs.<span style="color:#3a27c9;">collect</span> <span style="color:#3a27c9; font-weight:bold;">&#123;</span>|dog| dog<span style="color:#3a27c9; font-weight:bold;">&#91;</span>:fear_factor<span style="color:#3a27c9; font-weight:bold;">&#93;</span> + <span style="color:#3a27c9;">5</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#7b0303; font-style:normal;">#Output : @fear_factors contains [8,12]</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
</ol>
</div>
<p>You can also modify the original array with <strong>collect! </strong>or <strong>map!</strong></p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs = <span style="color:#3a27c9; font-weight:bold;">&#91;</span><span style="color:#3a27c9; font-weight:bold;">&#123;</span>:name =&gt; <span style="color:#996600;">&quot;Benji&quot;</span>, :fear_factor =&gt; <span style="color:#3a27c9;">3</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span>,<span style="color:#3a27c9; font-weight:bold;">&#123;</span>:name =&gt; <span style="color:#996600;">&quot;Rex&quot;</span>, :fear_factor =&gt; <span style="color:#3a27c9;">7</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span><span style="color:#3a27c9; font-weight:bold;">&#93;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">if</span> outside_atmosphere == :dark_and_scary</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; @dogs.<span style="color:#3a27c9;">map</span>! <span style="color:#3a27c9; font-weight:bold;">&#123;</span>|dog| dog<span style="color:#3a27c9; font-weight:bold;">&#91;</span>:fear_factor<span style="color:#3a27c9; font-weight:bold;">&#93;</span> + <span style="color:#3a27c9;">5</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#7b0303; font-style:normal;">#Output : @dogs contains [8,12]</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
</ol>
</div>
<p>Note how the resulting array contains 2 Fixnum items AND NOT 2 hashes. As you can see, the value returned by the block BECOMES an element in the new array. If you want to operate on the array directly, use the <em>each</em> slippers, that way :</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">@dogs = <span style="color:#3a27c9; font-weight:bold;">&#91;</span><span style="color:#3a27c9; font-weight:bold;">&#123;</span>:name =&gt; <span style="color:#996600;">&quot;Benji&quot;</span>, :fear_factor =&gt; <span style="color:#3a27c9;">3</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span>,<span style="color:#3a27c9; font-weight:bold;">&#123;</span>:name =&gt; <span style="color:#996600;">&quot;Rex&quot;</span>, :fear_factor =&gt; <span style="color:#3a27c9;">7</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span><span style="color:#3a27c9; font-weight:bold;">&#93;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">if</span> outside_atmosphere == :dark_and_scary</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; @dogs.<span style="color:#3a27c9;">each</span> <span style="color:#3a27c9; font-weight:bold;">&#123;</span>|dog| dog<span style="color:#3a27c9; font-weight:bold;">&#91;</span>:fear_factor<span style="color:#3a27c9; font-weight:bold;">&#93;</span> += <span style="color:#3a27c9;">5</span><span style="color:#3a27c9; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#7b0303; font-style:normal;">#Output : @dogs contains [{:name =&gt; &quot;Benji&quot;, :fear_factor =&gt; 8},{:name =&gt; &quot;Rex&quot;, :fear_factor =&gt; 12}]</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
</ol>
</div>
<p>Do you think of using select, reject and collect/map, or does the <em>each</em> slippers have too much influence on your life?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rubyfleebie.com/life-beyond-the-each-iterator/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>IM Integration with XMPP4r &#8211; 2 mistakes to avoid</title>
		<link>http://www.rubyfleebie.com/im-integration-with-xmpp4r-2-mistakes-to-avoid/</link>
		<comments>http://www.rubyfleebie.com/im-integration-with-xmpp4r-2-mistakes-to-avoid/#comments</comments>
		<pubDate>Tue, 12 Feb 2008 12:26:47 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[In depth]]></category>

		<guid isPermaLink="false">http://www.rubyfleebie.com/im-integration-with-xmpp4r-2-mistakes-to-avoid/</guid>
		<description><![CDATA[In this 3rd part we&#8217;re going to be concrete but a little bit less technical. Here are 2 big mistakes you have to avoid when trying to setup an IM based application (Sorry for those who wanted more technical info about xmpp4r&#8230; maybe in the next one).
The #1 mistake : Trying to run XMPP4r under [...]]]></description>
			<content:encoded><![CDATA[<p>In this 3rd part we&#8217;re going to be concrete but a little bit less technical. Here are 2 big mistakes you have to avoid when trying to setup an IM based application (Sorry for those who wanted more technical info about xmpp4r&#8230; maybe in the next one).</p>
<p><strong>The #1 mistake : Trying to run XMPP4r under Rails</strong></p>
<p>I&#8217;m not proud to say I did this mistake at first. Perhaps it&#8217;s because I was so excited to see xmpp4r in action that my head started making some strange electricity noises, thus short-circuiting my capacity to think rationally. Anyway, please, don&#8217;t try to put XMPP4r under your &#8220;vendor&#8221; directory believing it makes some sense&#8230; because it does not. <strong>You cannot make a XMPP robot in a Web context</strong>. The Web is stateless in nature. User ask for a resource, Apache kicks in and &#8220;tunnels&#8221; your request to some web framework, a response is returned to the user <strong>and then it&#8217;s over</strong>. (this was over-simplificated&#8230; but the main idea is there)</p>
<p>What we need here instead is <strong>something that runs on its own</strong>, something persistent, something completely independant of user requests on port 80.</p>
<p>So in order to build something out of XMPP4r, you need to create a separate program (in our case it makes sense to call it a <strong>listener</strong>) that will be running in permanence. But be careful because this could lead to mistake #2.</p>
<p><strong>The #2 mistake : Putting business logic in the listener </strong></p>
<p>I almost thought of doing this mistake but fortunately I didn&#8217;t. It would have been awful. Rails (or merb, or whatever) is your friend, you cannot ignore it and code your whole app in plain ruby! <strong>You want to get out of your XMPP4r listener as quickly as possible because it is not the &#8220;brain&#8221; of your application</strong>.</p>
<p>Try to make your listener as stupid as possible :</p>
<ol>
<li>Receives input (from a callback)</li>
<li>Sends the data to a standard Rails application (data will be &#8220;understood&#8221; and &#8220;managed&#8221; there)</li>
<li>Sends back to the IM user the response received from the Rails application</li>
</ol>
<p>So basically the idea is to use the listener for IM interaction only and a Rails application for everything else. Said that way, some self-sufficient cool guys who like to show their attitude could be tempted to take a relax voice and say &#8220;Well, duh&#8230;&#8221;, but it might not be that evident for the rest of us.</p>
<p>So now you know 2 traps to not fall into&#8230; how you decide to design your application after that is completely up to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rubyfleebie.com/im-integration-with-xmpp4r-2-mistakes-to-avoid/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>IM Integration With XMPP4r : Part 2</title>
		<link>http://www.rubyfleebie.com/im-integration-with-xmpp4r-part-2/</link>
		<comments>http://www.rubyfleebie.com/im-integration-with-xmpp4r-part-2/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 14:04:55 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[In depth]]></category>

		<guid isPermaLink="false">http://www.rubyfleebie.com/im-integration-with-xmpp4r-part-2/</guid>
		<description><![CDATA[In the first part, we talked less about XMPP4r and more about XMPP, this time it will be the other way around.
Now that we know that XMPP messages are XML bits of information exchanged between a client and a server via a TCP connection, we are more able to understand the purpose of XMPP4r.
What is [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://www.rubyfleebie.com/im-integration-with-xmpp4r">first part</a>, we talked less about XMPP4r and more about XMPP, this time it will be the other way around.</p>
<p>Now that we know that XMPP messages are XML bits of information exchanged between a client and a server via a TCP connection, we are more able to understand the purpose of XMPP4r.</p>
<p><strong>What is XMPP4r?</strong></p>
<p>Here is the most simple definition I came out with : XMPP4r is a ruby library that acts as a XMPP Client. Understand it that way and you won&#8217;t be confuse about what XMPP4r is supposed to do. Like any other jabber client (google talk, pidgin, etc), Xmpp4r sends, receives and manages XML messages called stanzas.</p>
<p>In a sense, XMPP4r is like GoogleTalk without the GUI. (And, of course, XMPP4r is not already implemented&#8230; you have to code the behavior of the client yourself). With GoogleTalk, you connect on a Jabber Server by pressing the connect button. With XMPP4r, you connect on a Jabber server that way :</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">client = Client.<span style="color:#3a27c9;">new</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>JID::new<span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;somejabberaccount@somewhere.com&quot;</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">client.<span style="color:#3a27c9;">connect</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">client.<span style="color:#3a27c9;">auth</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;my_extremely_secret_password&quot;</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">client.<span style="color:#3a27c9;">send</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>Presence.<span style="color:#3a27c9;">new</span>.<span style="color:#3a27c9;">set_type</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>:available<span style="color:#3a27c9; font-weight:bold;">&#41;</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
</ol>
</div>
<p>The first line simply creates a new instance of the <em>Client</em> class. This instance represents the user itself. The 2nd line tries to establish a connection between the user and the Jabber server (somewhere.com). The 3rd line tries to authenticate the user using the following mechanisms.</p>
<ul>
<li>SASL DIGEST-MD5</li>
<li>SASL PLAIN</li>
<li>Non-SASL digest</li>
</ul>
<p>Now about the 4th line. Remember when I talked about stanzas in the first part? Well, at the 4th line, we sent our first stanza to our Jabber Server&#8230; a <em>presence</em> stanza. We did this because <strong>we want our server to know we are there</strong>. That way, everyone in our buddy list will know we are online and ready to chat! </p>
<p><strong>Sending messages</strong><br />
So, what now? You are online, fine&#8230; but how can you exchange messages with people? That&#8217;s pretty simple&#8230;</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">msg = Message::new<span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;john@somejabberserver.com&quot;</span>, <span style="color:#996600;">&quot;Hello&#8230; John?&quot;</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">msg.<span style="color:#3a27c9;">type</span>=:chat</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">client.<span style="color:#3a27c9;">send</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>msg<span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
</ol>
</div>
<p><strong>Important note</strong> : You have to set the message type to &#8220;chat&#8221; because some clients will react differently depending of the message type. A <a href="http://www.gajim.org/">Gajim</a> user will hate you if you send him messages with a message type of &#8220;normal&#8221;, because Gajim popups a new window for every single &#8220;normal&#8221; messages it receives. On the other hand, it uses the same window for &#8220;chat&#8221; messages coming from the same user.</p>
<p>Ok so we know how to send a message to someone, but what if that someone is not in our buddy list? Well, simply put, it will not work. XMPP just doesn&#8217;t allow this and we all agree that it&#8217;s a good thing. Who like to be spammed?</p>
<p>Say we want to add john@someserver.com to our buddy list, we do :</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">pres = Presence.<span style="color:#3a27c9;">new</span>.<span style="color:#3a27c9;">set_type</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>:subscribe<span style="color:#3a27c9; font-weight:bold;">&#41;</span>.<span style="color:#3a27c9;">set_to</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;john@someserver.com&quot;</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">client.<span style="color:#3a27c9;">send</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>pres<span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
</ol>
</div>
<p>Ok so we sent our request&#8230; what about the response? Fortunately, the line above won&#8217;t wait for a result. As you can imagine, it could get pretty long&#8230; we don&#8217;t control the answer of the person at the other end after all. This leads me to talk to you about a key feature of xmpp4r : <strong>callbacks</strong>. </p>
<p><strong>Registering Callbacks</strong></p>
<p>Let&#8217;s get back to our subscription request we sent to John earlier. Since we said that our line of code would NOT wait for a response, we need some other way to get that response when it will come.  (that&#8217;s pretty much what callbacks are for, right?)</p>
<p>Because we sent a <em>subscription request</em>, <strong>the callback &#8220;add_update_callback&#8221; will be called as soon as the user at the other end will reply</strong>. If you want to be notified when this happens, you have to register to this callback :</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">client.<span style="color:#3a27c9;">add_update_callback</span> <span style="color:#3a27c9; font-weight:normal;">do</span> |presence|</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">if</span> presence.<span style="color:#3a27c9;">from</span> == <span style="color:#996600;">&quot;john@someserver.com&quot;</span> &amp;&amp; presence.<span style="color:#3a27c9;">ask</span> == :subscribe</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp; client.<span style="color:#3a27c9;">send</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>presence.<span style="color:#3a27c9;">from</span>, <span style="color:#996600;">&quot;I am so very happy you have accept my request John, you rock! I will spam you for the rest of my life, but I know you will understand because I feel we do &#8216;connect&#8217;&quot;</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
</ol>
</div>
<p>Xmpp4r provides callbacks for a lot of purposes. Now if I want to be notified of the messages sent to us by others, what do I have to use? The answer is <em>add_message_callback</em>!</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">client.<span style="color:#3a27c9;">add_message_callback</span> <span style="color:#3a27c9; font-weight:normal;">do</span> |m|</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">if</span> m.<span style="color:#3a27c9;">from</span> == <span style="color:#996600;">&quot;john@someserver.com&quot;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#7b0303; font-style:normal;">#oh great! I have received a response from my new friend Johh! Better see what he says.</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp;m.<span style="color:#3a27c9;">body</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#7b0303; font-style:normal;"># output : Listen, you moron. I don&#8217;t know who you are nor why you are so enthusiast about speaking with someone you don&#8217;t know, but I strongly suggest you to get a life. Stop or I remove you from my buddy list, FOREVER!</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
</ol>
</div>
<p>There is also a very useful callback that lets you know when the availability of someone in your buddy list change.</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">client.<span style="color:#3a27c9;">add_presence_callback</span> <span style="color:#3a27c9; font-weight:normal;">do</span> |old_presence, new_presence|</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">if</span> new_presence.<span style="color:#3a27c9;">from</span> == <span style="color:#996600;">&quot;john@someserver.com&quot;</span> &amp;&amp; new_presence.<span style="color:#3a27c9;">show</span> == :dnd</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg = Message::new<span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;john@someserver.com&quot;</span>, <span style="color:#996600;">&quot;John&#8230; I know you don&#8217;t want to be bothered (dnd = do not disturb) but I just wanted to say HI anyway! I read your previous message and I sill think we do &#8216;connect&#8217;. I just think you have trouble assuming your sensibility&quot;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg.<span style="color:#3a27c9;">type</span>=:chat</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; client.<span style="color:#3a27c9;">send</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>msg<span style="color:#3a27c9; font-weight:bold;">&#41;</span> </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
</ol>
</div>
<p>Note that the various callbacks in xmpp4r run <strong>within their own thread</strong>.</p>
<p>Well, this is the end of the 2nd part. Next part should be about the Roster helper and I also want to criticize Xmpp4r about his stability (lack of) and somewhat incomplete documentation.</p>
<p><strong> Woooh! Silly me&#8230; here is an important update</strong></p>
<p>Don Park and Nilu had problems with this tutorial&#8230; and it&#8217;s probably because I forgot to talk about an essential part : The subscription. To receive messages from others, you have to accept their subscription requests first! Here is how</p>
<ol>
<li>require &#8216;xmpp4r/roster&#8217; (a roster is an object representing your buddy list)</li>
<li>roster = Roster::Helper.new(client)</li>
<li>Implement the add_subscription_request_callback that way (if you want to accept everyone) :
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">roster.<span style="color:#3a27c9;">add_subscription_request_callback</span> <span style="color:#3a27c9; font-weight:normal;">do</span> |item,pres|&nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; roster.<span style="color:#3a27c9;">accept_subscription</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span>pres.<span style="color:#3a27c9;">from</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
</ol>
</div>
</li>
</ol>
<p>You should be fine now.. sorry about that</p>
<p><strong>UPDATE October 21st 2008</strong><br />
Some interesting remarks in the comments deserved a proper update :</p>
<p>Nilu, </p>
<p>I&#8217;m sure you have your answer already, but let me explain the &#8220;running in their own thread&#8221; thing :</p>
<p>The callbacks are invoked in the context of the &#8220;parser thread&#8221; which is the one doing the actual &#8220;listening&#8221; of the the XML stream. When something happens in the parser thread (e.g. message stanza received), callbacks are invoked from there. So the code you have in your various callbacks are effectively executed in the parser thread context.</p>
<p>Like Leonardo wrote, you have to write Thread.stop in your main thread when you have set all your callbacks and other initialization stuff.</p>
<p>It might sound confusing, but you have to write Thread.stop to keep the current thread alive. Thread.stop will simply put the current thread into sleep mode and leave all the scheduling time to the other threads (the parser thread in our case). If you don&#8217;t write Thread.stop, everything ends when the main thread has nothing left to do.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rubyfleebie.com/im-integration-with-xmpp4r-part-2/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>IM Integration With XMPP4r</title>
		<link>http://www.rubyfleebie.com/im-integration-with-xmpp4r/</link>
		<comments>http://www.rubyfleebie.com/im-integration-with-xmpp4r/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 04:49:53 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[In depth]]></category>

		<guid isPermaLink="false">http://www.rubyfleebie.com/im-integration-with-xmpp4r/</guid>
		<description><![CDATA[Some of you might be aware that I worked on a project called TimmyOnTime. It is a product that allow you to track your time using your Instant Messaging application only. How we did it exactly? Where&#8217;s the code? Nice try! But I won&#8217;t tell you&#8230; however I will help you getting start with XMPP4r [...]]]></description>
			<content:encoded><![CDATA[<p>Some of you might be aware that I worked on a project called <a href="http://www.timmyontime.com">TimmyOnTime</a>. It is a product that allow you to track your time using your Instant Messaging application only. How we did it exactly? Where&#8217;s the code? Nice try! But I won&#8217;t tell you&#8230; however I will help you getting start with <a href="http://home.gna.org/xmpp4r/">XMPP4r</a> (XMPP For Ruby).</p>
<p>This will be a multipart article. You know, it wouldn&#8217;t be my style to talk about XMPP4R without talking about <a href="http://www.xmpp.org/">XMPP</a> first. One thing at a time! So, this article is just about XMPP&#8230; no XMPP4r.</p>
<h3>What is XMPP?</h3>
<p>The e<strong>X</strong>tensible <strong>M</strong>essaging and <strong>P</strong>resence <strong>P</strong>rotocol (aka as Jabber) is a protocol to exchange messages between 2 entities. Those messages are transmitted over the wire in the XML format.</p>
<h3>Decentralized</h3>
<p>Unlike <a href="http://get.live.com/messenger/overview">MSN</a> and <a href="http://www.aim.com">AIM</a> which are proprietary protocols/technologies, no one owns Jabber. You don&#8217;t log on THE Jabber Network like you log on MSN. When you use a Jabber client like <a href="http://www.pidgin.im/">Pidgin</a>, <a href="http://www.google.com/talk/">Google Talk</a> (Technically, GTalk is not a jabber client&#8230; but we won&#8217;t go into this) or <a href="http://www.gajim.org/">Gajim</a>, you log on SOME Jabber server.  You could even setup <a href="http://www.ejabberd.im/">your own Jabber server</a>. It doesn&#8217;t matter because these servers can talk to each other (but are not forced to&#8230; private jabber servers are pretty common). Server-to-server communication is in fact one of the primary asset of the Jabber architecture. </p>
<p>Say I&#8217;m using Pidgin and that my Jabber Account is located on <a href="http://www.jabjab.de">www.jabjab.de</a> (it&#8217;s just one of the many <a href="http://www.jabber.org/user/publicservers.shtml">public jabber servers</a>), this will probably give me a JID (Jabber identifier) like frank@jabjab.de/home.</p>
<h3>JID?</h3>
<p>So suppose my JID is indeed frank@jabjab.de/home. The first part of the JID is &#8220;frank&#8221;, which identifies the NODE or, in other words, identifies <em>a person</em>. The second part of the JID is &#8220;jabjab.de&#8221; and it identifies the SERVER to call in order to send messages to &#8220;frank&#8221;. The last part of the JID is &#8220;/home&#8221; and it identifies the RESOURCE. Think of resources as &#8220;multiple identities&#8221;. Frank could in fact load 2 instances of Pidgin at the same time (one  IM at home and the other at work) so it would result in two different JID, respectively &#8220;frank@jabjab.de/home&#8221; and &#8220;frank@jabjab.de/work&#8221;.</p>
<h3>The XML messages : Streams and Stanzas</h3>
<p>Like I said, Jabber messages are encoded in the XML format. A stream is a container to exchange information between a client and a server (e.g. between pidgin and jabjab.de). It simply is a XML element called &#8220;stream&#8221; that starts with &lt;stream&gt; and ends with &lt;/stream&gt;. Within the stream element, both the client and the server can exchange other kind of XML messages (called stanzas). The communication is terminated when one of the 2 sides sends the closing &lt;/stream&gt; element to the other. For example, if i close Pidgin, Pidgin will send the &lt;/stream&gt; to jabjab.de and the <em>session</em> will be over.</p>
<p>One important thing to understand is that the stream DOES NOT exist between USER A and USER B&#8230; it exists between YOUR CLIENT (e.g. Pidgin) and the SERVER where YOUR Jabber account is located (e.g. jabjab.de).</p>
<p>Stanzas are special kind of XML messages that are sent within a stream element. The 3 most common stanzas are :</p>
<ol>
<li>Message</li>
<li>Presence</li>
<li>IQ</li>
</ol>
<p>A message stanza is used when USER A (john@someserver.com/home)  sends a message to USER B (frank@someotherserver.com/home)&#8230; you know, like &#8220;Frank&#8230; are you there?&#8221;. it may looks like :</p>
<p>&lt;stream&gt;<br />
&lt;message to=&#8217;frank@someotherserver.com/home&#8217;&gt;<br />
    &lt;body&gt;Frank&#8230; are you there?&lt;/body&gt;<br />
&lt;/message&gt;<br />
&#8230;<br />
&#8230;<br />
&lt;/stream&gt; &lt;!- &#8211; Well&#8230; the closing stream element is not there if the session is still active! Everything happens at real time after all &#8211; -&gt;</p>
<p>Let&#8217;s take a second to think about what happens exactly when a message is sent between 2 entities from 2 different servers. USER A sends the message through his IM client. The message stanza will be sent to USER A server, which is <em>someserver.com</em>. someserver.com will see that the message is intended to USER B from <em>someotherserver.com</em> so it will send the message there. someotherserver.com will finally send the message stanza to USER B (considering that USER B and someotherserver.com have established a session together thru a stream element). Yay!</p>
<p>A presence stanza is sent when the status of a user changes (Idle, Offline, Available, Do not disturb, etc).</p>
<p>IQ (Info / Query) stanzas are more general purpose messages. It can be used when USER A wants to know something about USER B but that it cannot be achieved by sending a message or a presence stanza. For example, if USER A choose the &#8220;get info&#8221; option for USER B, an IQ stanza will be sent to USER B, and USER B will answer to USER A with another IQ stanza containing the information that USER A asked for.</p>
<p>That&#8217;s it for part 1&#8230; in the next part I think we&#8217;ll be ready to dive into XMPP4r. There is also one point that I didn&#8217;t address about XMPP&#8230; and this is the Authentication process (SASL or TLS). So, next part should talk about this as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rubyfleebie.com/im-integration-with-xmpp4r/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>An introduction to RDoc</title>
		<link>http://www.rubyfleebie.com/an-introduction-to-rdoc/</link>
		<comments>http://www.rubyfleebie.com/an-introduction-to-rdoc/#comments</comments>
		<pubDate>Mon, 12 Nov 2007 12:18:50 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[In depth]]></category>

		<guid isPermaLink="false">http://www.rubyfleebie.com/an-introduction-to-rdoc/</guid>
		<description><![CDATA[Documenting used to be a pain
This will stay between you and me I promise : How many of you take the time to write complete and meaningful documentation for your applications? It seems to always be the last thing we want to work on or think about. There are many reasons for that, but the [...]]]></description>
			<content:encoded><![CDATA[<h3>Documenting used to be a pain</h3>
<p>This will stay between you and me I promise : How many of you take the time to write complete and meaningful documentation for your applications? It seems to always be the last thing we want to work on or think about. There are many reasons for that, but the most obvious is because documentation is not mandatory for your application to work&#8230; so it&#8217;s easy to &#8220;forget&#8221;. It&#8217;s way more exciting to code new features, improve the design, refactor some old code, drink Buckley’s syrup, roll discretely on the floor pretending you are Rambo and so on than it is to document your application. But the fact doesn&#8217;t change : Having good documentation for your application is important. Without a good tool to help you create documentation that is dynamic, structured, easily editable, consistent and visually pleasing, it will take you forever because you will have to do it by hand. And even if you&#8217;re crazy enough to do that, it will have taken so much of your time that just thinking about doing it again for your next project will make your nose bleed&#8230; and ultimately you will start to regret the day you choose to become a developer.</p>
<h3>RDoc to the rescue</h3>
<p>RDoc is a ruby library that generates documentation for you. What is great with RDoc is that it gives you some basic documentation &#8220;out of the box&#8221; for your application without you having to do anything. Like with many other existing tools, RDoc parses your code and try to understand its structure. Then, it produces a nice HTML formatted documentation that allows you to navigate between the various classes, methods, attributes of your code.</p>
<h3>Generating documentation with RDoc could not be easier</h3>
<p>We&#8217;ll suppose that your application is a Rails application. </p>
<ol>
<li>Go to the root of your application</li>
<li>Type <em>rake doc:app</em></li>
</ol>
<p>This rake task (that uses RDoc) will start generating the documentation for your application. It will detect every controllers, every models, every helpers, every methods, every attributes, every constants, every whatever and will structure all of this in a logical manner. Then, it will output a bunch of HTML files that you will find in <em>doc/app</em>. Moreover, it will detect every comments you wrote and try to include them at the right place in the doc. For example, if you wrote a comment just above a method, RDoc will presume that this comment describes what this method is doing. Clever RDoc, clever&#8230;</p>
<p>While it generates the files, sit back and think about how competent and professional you will look with this great documentation. After that, open <em>yourapp/doc/app/index.html</em> in your favorite browser and laugh in a sinister way (if you are alone). Finally, send an email to your boss/employee/friend/camel with the compressed files attached to the message and tell him that &#8220;you have just finished working on a complex and interactive knowledge base system that will help the other human resources of your department to become more efficient while using, modifying and adding new functionalities to the core application&#8221;. That should impress him for years to come. Please note that this paragraph was completely useless.</p>
<h3>Using RDoc to your advantage</h3>
<p>RDoc recognizes a certain <em>commenting syntax</em> that you can use in your ruby source files to increase the quality of your documentation. You can ignore this syntax and write your comments like you always did&#8230; but you can also choose to benefit from a richer and cleaner documentation without much more effort on your part. In fact, it will take 5 minutes of your life to learn the basic syntax. It&#8217;s that simple really. Here is a small demo I made that shows how RDoc is great to produce clean and well organized HTML documentation. I&#8217;m sure you&#8217;ve seen a lot of RDoc generated doc already, but what I want to show you here is how to write ruby comments that are <em>RDoc-friendly</em>. In other words, I used RDoc to show you how RDoc works.</p>
<p>Here is the <a href="http://www.rubyfleebie.com/wp-content/uploads/rdocdemo/doc/app/index.html"><strong>demo</strong></a></p>
<p>One final note : <strong>RDoc is not specific to Rails</strong>. Like I said earlier, it is a ruby library and thus you can use it in other contexts. I took Rails because I knew that the % of people using Ruby without Rails was rather small.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rubyfleebie.com/an-introduction-to-rdoc/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>An introduction to modules : Part 2</title>
		<link>http://www.rubyfleebie.com/an-introduction-to-modules-part-2/</link>
		<comments>http://www.rubyfleebie.com/an-introduction-to-modules-part-2/#comments</comments>
		<pubDate>Mon, 10 Sep 2007 03:27:57 +0000</pubDate>
		<dc:creator>Frank</dc:creator>
				<category><![CDATA[In depth]]></category>

		<guid isPermaLink="false">http://www.rubyfleebie.com/an-introduction-to-modules-part-2/</guid>
		<description><![CDATA[It’s modules like Comparable and Enumerable that makes the concept of modules so attracting. Yes, modules can be used as namespaces only, but they really shine when you use them to enhance your classes.]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://www.rubyfleebie.com/an-introduction-to-modules-part-1/">first part</a>, we learned that a module was a namespace, a way to regroup similar things to help us organize our application better and to avoid name clashes. It was rather easy to understand because we didn&#8217;t speak about the true power that resides in modules.</p>
<p><strong>Other than a namespace, what is a module?</strong></p>
<p>A module is like a class with 3 key differences :</p>
<ol>
<li>It is not a class (this one is the killer)</li>
<li>It cannot be instantiated (i.e. you cannot do x = MyModule.new)</li>
<li>It can be <em>mixed in</em> a class to enhance its possibilities</li>
</ol>
<p>And here is the tricky part : Although a module cannot have instances, it can still have instance methods. How is it possible? Well, you guessed it : those instance methods will become the instance methods of the client (the class). </p>
<p><strong>That is what we call a <em>mixin</em>!</strong></p>
<p><em>Mixins</em>, quite a funny word don&#8217;t you think? No, you&#8217;re absolutely right, it is not funny at all.  Mixin just means <em>Mixed in</em>, as in : This module has been mixed in my class, let&#8217;s play Twister!</p>
<p>When you decide to mix a module in one of your class, the latter automatically gains some new functionalities&#8230; for free! In a sense, it&#8217;s a little bit like class inheritance, at the exception of these 2 points :</p>
<ol>
<li>There is no hierarchy : the class isn&#8217;t the child of the module, it just includes it. You just have to see the mixed-in module as a set of additional methods for your class. </li>
<li>You can include more than one module in a class, thus creating the effect of multiple inheritance&#8230; which is something most languages simply don&#8217;t allow</li>
</ol>
<p>A little example to illustrate my first point :</p>
<p>Class inheritance : An aloes (class) <strong>IS A</strong> plant (class)<br />
Mixins : An aloes (class) <strong>HAS</strong> some healing properties (module)</p>
<p>If we take for granted that our module &#8220;HealingProperties&#8221; is general enough in its implementation to fit many purposes, we could very well mix it in any other class that needs healing properties. (a drug, Wolverine, Kenny in South Park, etc). This is how we would do it :</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">module</span> HealingProperties</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">def</span> heal_wounds</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp; <span style="color:#7b0303; font-style:normal;">#do something that heal wounds</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">class</span> Wolverine</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">include</span> HealingProperties</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">def</span> kill_something_with_my_claws!</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp; <span style="color:#7b0303; font-style:normal;">#Arrr!</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">logan = Wolverine.<span style="color:#3a27c9;">new</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">logan.<span style="color:#3a27c9;">kill_something_with_my_claws</span>!</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">logan.<span style="color:#3a27c9;">heal_wounds</span></div>
</li>
</ol>
</div>
<p><strong>The Comparable module</strong></p>
<p>The built-in module called <em>Comparable</em> is possibly one of the best example to use to understand the usefulness of modules because it contains general purpose methods that can interest different kind of classes.</p>
<p>Comparable contains the following methods (yes, <a href="http://www.rubyfleebie.com/oh-ruby-who-are-you-trying-to-fool/">these are all methods, not operators</a>) : </p>
<p><strong><, <=, ==, >, >=, between?</strong></p>
<p>What are those methods doing exactly? Well, they compare sortable things together. However, those &#8220;things&#8221; to compare have to be in the class that includes the module, not in the module itself. How can the module knows what the &#8220;client&#8221; class is all about? The answer lies in the secret treaty that exists between <em>Comparable</em> and any class that wants to use it. The class has to specify, by implementing the <=> method, the attribute on which the comparison must operate. Note that <=> is a comparison method that is always expected to return +1 if the receiver is higher than the method argument, -1 if the method argument is higher then the receiver and 0 if both the receiver and the method argument are equal. In case you&#8217;re confused, if I write x <=> y, x is the receiver and y is the method argument.</p>
<div class="ch_code_container" style="font-family: monospace;">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">class</span> Dog</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">include</span> Comparable</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; attr_accessor :iq</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">def</span> initialize<span style="color:#3a27c9; font-weight:bold;">&#40;</span>iq<span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp; <span style="color:#3a27c9; font-weight:bold;">self</span>.<span style="color:#3a27c9;">iq</span> = iq</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#7b0303; font-style:normal;">#Honoring the contract with Comparable&#8230;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">def</span> &lt;=&gt;<span style="color:#3a27c9; font-weight:bold;">&#40;</span>other<span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; &nbsp; <span style="color:#3a27c9; font-weight:bold;">self</span>.<span style="color:#3a27c9;">iq</span> &lt;=&gt; other.<span style="color:#3a27c9;">iq</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp; <span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#3a27c9; font-weight:normal;">end</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">spike = Dog.<span style="color:#3a27c9;">new</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#3a27c9;">60</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">rex = Dog.<span style="color:#3a27c9;">new</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#3a27c9;">40</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">retard = Dog.<span style="color:#3a27c9;">new</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#3a27c9;">30</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">dumbass = Dog.<span style="color:#3a27c9;">new</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#3a27c9;">20</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">dumber = Dog.<span style="color:#3a27c9;">new</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#3a27c9;">15</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">bozo = Dog.<span style="color:#3a27c9;">new</span><span style="color:#3a27c9; font-weight:bold;">&#40;</span><span style="color:#3a27c9;">10</span><span style="color:#3a27c9; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#7b0303; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Make fun of dumbass&quot;</span> <span style="color:#3a27c9; font-weight:normal;">if</span> spike &gt; dumbass</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#7b0303; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Make fun of dumbass even more&quot;</span> <span style="color:#3a27c9; font-weight:normal;">if</span> dumbass &lt;= rex</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;">
<div style="font-family: 'Trebuchet MS', Arial, Verdana; font-weight: normal;"><span style="color:#7b0303; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Realize in shame that dumbass is not a dog but an African violet&quot;</span> <span style="color:#3a27c9; font-weight:normal;">if</span> dumbass &lt; bozo</div>
</li>
</ol>
</div>
<p>In this example, I told Comparable that the comparison had to operate on the iq attribute. Doing so, my Dog class gained access to 6 comparison methods without me having to write a single line of code.</p>
<p><strong>A little clarification about <=></strong></p>
<p>This hasn&#8217;t much to do with mixins, but it may be confusing at first : Why do we used <=> once more in the implementation of our <=> method? Wouldn&#8217;t it create some kind of infinite loop? No&#8230; because when we do <em>self.iq <=> other.iq</em>, we call the <=> method that resides in the Fixnum class (since iq is a fixnum). The <=> implementation in the Fixnum class already returns -1, 0 or +1 based on which one of the 2 fixnums is the highest. If iq would have been something else that DOESN&#8217;T implement the <=> method, we would have been forced to implement the <=> ourselves (e.g. return 0 if this_condition; return -1 if this_other_condition; return 1 if yet_another_condition)</p>
<p>It&#8217;s modules like Comparable and Enumerable that makes the concept of modules so attracting. Yes, modules can be used as namespaces only, but they really shine when you use them to enhance your classes. They become especially powerful when they are consisted of <strong>general purpose methods</strong> and when they only <strong>require a small piece of information from the class</strong> to work properly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rubyfleebie.com/an-introduction-to-modules-part-2/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
