<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>8th Light Blog: Tag Ruby</title>
    <link>http://blog.8thlight.com/ruby</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>In the minds of the craftsmen...</description>
    <item>
      <title>Active Record migration dependencies</title>
      <description>&lt;p&gt;We had a new developer join our project recently, and he needed his computer to be setup with the project.  &amp;#8220;Here is the svn repository, when you check it out, run these rake tasks.&amp;#8221;  It unfortunately, is never that easy.  This project setup revealed something about Active Record and migrations that I didn&amp;#8217;t know about.&lt;/p&gt;

&lt;p&gt;When I create a migration, I will often do data manipulation on the database, or pre-populate some fields with data needed for a lookup table.  Lets look at a sample migration from a trivia game.&lt;/p&gt;

&lt;pre&gt;
class CreateQuestions &lt; ActiveRecord::Migration

  def self.up

    create_table :questions do |t|
      t.column :text, :string
      t.column :answer, :string
      t.timestamps
    end

    Question.populate
  end

  def self.down
    drop_table :questions
  end
end

&lt;/pre&gt;

&lt;p&gt;I want to add some sample questions, so that even if you don&amp;#8217;t have your own questions, you will still be able to play the game.  I added the method to the populate model, because I use it elsewhere in the code, and I try to keep it DRY.  The populate method on the question model looks like this:&lt;/p&gt;

&lt;pre&gt;

class Question &lt; ActiveRecord::Base
  belongs_to :game
  has_many :answers

  def self.populate
    Questions.create(:name =&gt; "What is your favorite color?", :answer =&gt; "I don't know")
    Questions.create(:name =&gt; "Who was the first President", :answer =&gt; "George Washington")
    Questions.create(:name =&gt; "Who was born Samuel Clemens?", :answer =&gt; "Mark Twain")
  end

end
&lt;/pre&gt;

&lt;p&gt;So, later on, I decided to add a degree of difficulty to the questions, so the players can get more points for answering harder questions.  Here is what the migration looked like.&lt;/p&gt;

&lt;pre&gt;
class CreateQuestions &lt; ActiveRecord::Migration

  def self.up
    add_column :questions, :rank, :integer
    Question.destroy_all #In case there are any old ones
    Question.populate
  end

  def self.down
    remove_column :questions, :rank
  end
end
&lt;/pre&gt;

&lt;p&gt;Of which I had to change the populate method on the question class to:&lt;/p&gt;

&lt;pre&gt;
class Question &lt; ActiveRecord::Base
  belongs_to :game
  has_many :answers

  def self.populate
    Questions.create(:name =&gt; "What is your favorite color?", :answer =&gt; "I don't know", :rank =&gt; 1)
    Questions.create(:name =&gt; "Who was the first President", :answer =&gt; "George Washington", :rank =&gt; 3)
    Questions.create(:name =&gt; "Who was born Samuel Clemens?", :answer =&gt; "Mark Twain", :rank =&gt; 8)
  end

end
&lt;/pre&gt;

&lt;p&gt;Then I ran my migrations, and continued development.  Then when developer number 2 came across and checked out the project and ran the migrations, he got the error.&lt;/p&gt;

&lt;p&gt;undefined method rank= for class Question (&amp;#8230;or something very similar)&lt;/p&gt;

&lt;p&gt;The problem is the old migration is dependent on the new model.  All models in rails are just a mirror of the database, so the new model has a forward definition of the data.  The code in the model knows about the rank field, but the schema of the database hasn&amp;#8217;t caught up to create that portion of the mirror yet.  This creates a little bit of a catch 22.  The rails wiki (http://wiki.rubyonrails.org/rails/pages/UsingMigrations) about migrations tells you to redefine the class to stop name conflicts.  This would require me to make my migrations model agnostic, inserting straight to the database.  As a spoiled brat when it comes to databases and rails, I refuse to let go of my Active Record sugary syntax.  Another solution I thought of is to just make the last change to question do the populate, and remove it from the previous versions.  This will become a maintenance nightmare.&lt;/p&gt;

&lt;p&gt;I came to the realization that I want to make a distinction between form and content when it comes to migrations.  Form in this case is schema form, the changes to the database which reflect the data which the Active Records can potential hold.  Content is the specific data which is in the database.  This distinction allows for me to use the power of my model classes in my data migrations, which is the place it is useful.  It maintains backwards compatibility, because before I go touching the data, I have to make sure my schema is right.&lt;/p&gt;

&lt;p&gt;What does this look like in Rails?  I am not sure yet.  Possibly db/migrations/schema and db/migrations/data.  Possible saving the data migrations in each migration as a block and executing those at the end, only when you have the schema is correct.  I am going to try it out!&lt;/p&gt;</description>
      <pubDate>Sat, 14 Jun 2008 02:38:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:a2f74c84-789c-4b60-86fb-2ac683c00831</guid>
      <author>Paul Pagel</author>
      <link>http://blog.8thlight.com/articles/2008/06/14/active-record-migration-dependancies</link>
      <category>Coding</category>
      <category>Paul</category>
      <category>Migrations</category>
      <category>Ruby</category>
    </item>
    <item>
      <title>Code Less: A Language Keystroke Expirement </title>
      <description>&lt;p&gt;When I first started writing code in ruby, it was a breath of fresh air after writing C# code for a year.  Ruby had a thesis, a clear purpose, rather than a hodgepodge of features strung together.  It was a language obviously written by someone who cared about what the code looked like.  So I jumped into it and loved writing ruby code (still do!).  Recently I had to write a project in Java using IntelliJ, and the powerful IDE was also a breath of fresh air after using text editors to write ruby code.  The IDE helps me in the same way ruby helped me.  I write less code that does the same thing, without loosing expressiveness or transparency of intent.  Less code in this case meaning less keystrokes.&lt;/p&gt;

&lt;p&gt;So, I am going to do a little experiment using two editors and languages: ruby with textmate and java with IntelliJ.  I want to see how many lines of code I have to write.  The application I am going to start is a simple baseball at bat scorer.  First lets see the ruby version.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;img style="border: 0px;" src="/files/ruby_first.gif"/&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;We have about 27 lines of code written, and other than the describe method, which I have a macro for, I typed them all by hand.  Lets look at the java code.  This is just the JUnit test I wrote, there is no production code yet.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;img style="border: 0px;" src="/files/java_orig_test.gif"/&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;It is about 16 lines of code, which I wrote all of but the import statement.  By doing a few alt-enters on the squiggly lines, I can get a stub of a class looking like this.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;img style="border: 0px;" src="/files/java_class_stub.gif"/&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;That is 13 more lines of code, without really typing, just hitting enter a few times.  Now, lets start to make the method pass.  I am going to write the algorithm without worrying about all the type definition java wants.  Here is what it looks like.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;img style="border: 0px;" src="/files/starting_class.gif"/&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;So the code written is around 4 lines of code.  Lets use the IntelliJ autocomplete features to help us make a passing test, which looks like.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
&lt;img style="border: 0px;" src="/files/java_finished.gif"/&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;So roughly, the ruby version was 23 lines of written code and the java version was about 20 lines of written code.  There is an expense to doing all of the alt-enters to auto-generate the method and variable stubs, but IntelliJ is pretty smart about what it generates.  Also, I understand a single test doesn&amp;#8217;t tell the whole story, but it is a good indication.  I found as I wrote more tests for this application, a smaller amount of keystrokes was needed for the java version, and the same amount was needed for ruby.  This is due to the refactoring tools, and intellisense.  As applications get larger, I find the IntelliJ refactorings become more useful.  Inversely, ruby refactorings become more painful, as they are mostly done by hand.  &lt;/p&gt;

&lt;p&gt;So, in the end the constraints on a static language allows the IDE to make the refactoring tools better.  Specifically, when writing java code, I can lean on the IDE to generate all the uninteresting stubs for me.  All I do is fill in the algorithms: the fun part.  When I start to see places where my code can be cleaned up a bit, I can lean on the IDE again to do those refactorings for me once I recognize the need for them.  Removing and optimizing the code is something which is easily deducible in static languages, as it is mostly pattern matching, with no monkey patches, meta-programming, and evals to worry about.  This is a limitation which frustrates me as a developer who wants to have a large set of tools in my bag, but is helpful when it comes to developing a powerful IDE.  &lt;/p&gt;

&lt;p&gt;The number of lines of code I need to type isn&amp;#8217;t the reason I choose a language over another.  In fact, it would be pretty low on the list of deciding factors.  However, it is interesting to see what each language and its sets of tools do best.  Hopefully the ruby community can take some notes from them.  I would rather solve the other end of the equation, get a powerful ruby IDE.  I know Eclipse and Net Beans have some preliminary refactoring tools, but they are still aways from being as seamless as their java counterparts.&lt;/p&gt;</description>
      <pubDate>Sun, 08 Jun 2008 18:06:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:a89cc279-825b-4aac-aa2c-aff5ec4cfd3d</guid>
      <author>Paul Pagel</author>
      <link>http://blog.8thlight.com/articles/2008/06/08/code-less-a-language-keystroke-expirement</link>
      <category>Coding</category>
      <category>Paul</category>
      <category>Ruby</category>
      <category>Java</category>
    </item>
    <item>
      <title>Sockets Enable Multi-Lingual Applications</title>
      <description>&lt;p&gt;As we work with our clients to delivery new features to them quickly and with high quality code, we are finding that the fastest way forward is often writing code in Ruby.  The problem is that in many cases we are working with an existing application written in a different language.  We may need to add a feature to a C++ application or integrate with a Java Library.  One of our favorite solutions in this situations is to have multiple applications talking to each other over sockets.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ve found that using sockets to communicate between applications is a great way to &amp;#8216;bolt on&amp;#8217; new functionality.  This type of communication has been around for a long time and nearly every language has socket communication in standard libraries or in free open source projects.&lt;/p&gt;

&lt;p&gt;Dean Wampler suggested that &lt;a href="http://blog.objectmentor.com/articles/2007/07/04/applications-should-use-several-languages" target="new"&gt;Applications Should Use Several Languages&lt;/a&gt; and socket communication is another way to enable this.  &lt;/p&gt;

&lt;p&gt;&lt;b&gt;Socket Basics&lt;/b&gt;&lt;br/&gt;
Most internet communication is built on socket communication, so I won&amp;#8217;t try to go into great detail here.  I don&amp;#8217;t pretend to be an expert.  Here is what you need to understand about sockets to use them in your applications.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;UDP vs TCP&lt;/b&gt;&lt;br/&gt;
There are two basic types of IP socket protocols: UDP and TCP.  UPD is what I&amp;#8217;ll call a &amp;#8216;send and pray&amp;#8217; protocol.  In UDP there is really no difference between server and client.  Each node can listen on some port and write on some port.  Messages are sent from point to point or broadcast to all nodes.  Either way, delivery is not guaranteed.  The message will likely make it to the destination, but there are a host of things that could happen that would prevent delivery.  Worse, as the sender you can&amp;#8217;t know whether of not your message made it unless you implement some kind of response protocol on top.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve used UDP communications for monitoring / metering applications where it isn&amp;#8217;t important that every message be delivered, but I&amp;#8217;ve also found that I usually end up implementing some kind of delivery guarantee mechanism anyway.&lt;/p&gt;

&lt;p&gt;TCP sockets build another layer on top of basic IP communication that does guarantee delivery.  Once the connection is established between client and server, both side can communicate knowing that their message will be received.  On the Server side, a socket listens on a particular port for new connections.  Most libraries call this operation &amp;#8216;accept.&amp;#8217;  A client &amp;#8216;opens&amp;#8217; a connection to the server.  This process involves the client and the server agreeing on a new port for communication.  If the server is going to accept multiple connections, then it usually launches a new thread to handle each new connection.&lt;/p&gt;

&lt;p&gt;I use TCP Sockets for most inter-application communication.  It turns out that in most situations, I want that guaranteed delivery and don&amp;#8217;t want to bother with my own acknowledgment protocol.  So it&amp;#8217;s the TCP Socket that I&amp;#8217;ll show you for now.&lt;/p&gt;

&lt;p&gt;Over my next few posts, I&amp;#8217;ll show you how to communicate via sockets in many languages. We&amp;#8217;ll start with Ruby.  Ruby has TCP Sockets built in, though there really isn&amp;#8217;t much documentation on how to use it.  Here is how to do it.&lt;/p&gt;

&lt;p&gt;The TCPSocket class can be found in &amp;#8216;socket&amp;#8217;&lt;/p&gt;

&lt;pre&gt;
require 'socket' 
&lt;/pre&gt;

&lt;p&gt;Create a socket server.  The first parameter is the address to listen on.  If you specify &amp;#8216;0.0.0.0&amp;#8217; then the server will accept connections from any host.  If you specify &amp;#8216;localhost&amp;#8217; or &amp;#8216;127.0.0.1&amp;#8217; this the server will only accept connections from sockets on the same computers.  The port can be anything you want.  Be sure to avoid commonly used ports.&lt;/p&gt;

&lt;pre&gt;
   server = TCPServer.new('localhost', '4138') 
&lt;/pre&gt;

&lt;p&gt;Now, when you call accept on the server it will block until a client opens up a connection.&lt;/p&gt;

&lt;pre&gt;
    server_socket = server.accept
&lt;/pre&gt;

&lt;p&gt;Now that the server is waiting for a new connection, let&amp;#8217;s open that connection from a client.  Note that this needs to be happening in a separate ruby process.  The first parameter is the host address or name of the server.  The second is the port on which the server is listening.&lt;/p&gt;

&lt;pre&gt;
    require 'socket'
    client_socket = TCPSocket.new('localhost', '4138')
&lt;/pre&gt;

&lt;p&gt;Now that there is as new connection open the client and server can talk back and forth at will. In this example, the server just echos the clients message back to it.  So all together, the Server side looks like this:&lt;/p&gt;

&lt;pre&gt;
    require 'socket' 
    server = TCPServer.new('localhost', '4138') 
    server_socket = server.accept
    message = server_socket.recvfrom(256)[0]
    server_socket.write("You Said: #{message}")
&lt;/pre&gt;

&lt;p&gt;And the Client side:&lt;/p&gt;

&lt;pre&gt;
    require 'socket'
    client_socket = TCPSocket.new('localhost', '4138')
    print "Enter Message:  "
    input = gets
    client_socket.write(input)
    response = client_socket.recvfrom(256)[0]
    puts response
&lt;/pre&gt;

&lt;p&gt;So that&amp;#8217;s it, you are communicating between two applications with sockets.  If we want the server to continue processing messages, we can loop reading from the socket:&lt;/p&gt;

&lt;pre&gt;
    require 'socket' 
    server = TCPServer.new('localhost', '4138') 
    server_socket = server.accept

    message = ""
    until message.chomp == "quit" do
        message = server_socket.recvfrom(256)[0]
        server_socket.write("You Said: #{message}")
    end
&lt;/pre&gt;

&lt;p&gt;So far our server can only handle one connection at a time.  Often times, you&amp;#8217;ll want multiple client to be able to open up connections to the server.  To do this, we&amp;#8217;ll need to launch a new thread each time a client connects.  This is a little class that does that.  You can implement your own handler object to handle each socket.  The handler only needs a &amp;#8216;serve&amp;#8217; method that takes a socket.  The ThreadGroup is a nice little class to keep track of the threads.  When a thread finishes, it is automatically removed from the thread group.&lt;/p&gt;

&lt;pre&gt;
require 'socket' 

class MultiTcpServer

  def initialize(handler, port)
    @group = ThreadGroup.new
    @handler = handler
    @server = TCPServer.new('0.0.0.0', port) 
  end

  def connections_open
    return @group.list.size
  end

  def run
    begin
      loop do
        socket = @server.accept
        @group.add(Thread.new {@handler.serve(socket)})
      end
    rescue IOError
    end
  end

  def stop
    @server.close
  end

end
&lt;/pre&gt;

&lt;p&gt;Hopefully this little tutorial was helpful.  Next time I&amp;#8217;ll take a look at sockets in C++ or Java.&lt;/p&gt;</description>
      <pubDate>Sun, 04 Nov 2007 18:51:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:818c5a87-2586-41f6-8882-942a74ba3b28</guid>
      <author>Doug Bradbury</author>
      <link>http://blog.8thlight.com/articles/2007/11/04/sockets-enable-multi-lingual-applications</link>
      <category>Coding</category>
      <category>doug</category>
      <category>sockets</category>
      <category>TCP</category>
      <category>Ruby</category>
      <category>language</category>
      <category>multiple</category>
      <category>Java</category>
      <category>C</category>
    </item>
    <item>
      <title>RubyCocoa Tutorial</title>
      <description>&lt;p&gt;Admit it, you&amp;#8217;re new to Rails.  You just got your new spiffy Rails job, and they gave you a Mac, formerly the computer of long-haired starving-artist types.  It&amp;#8217;s got pretty apps with and even a Remote Control, and it&amp;#8217;s got you thinking about making desktop applications.  Then you remember the Resource Files, C++, Windoze, MFC.  Ugh!  Never mind.  &lt;/p&gt;

&lt;p&gt;If that sounds excactly right, well then you&amp;#8217;re me and I want my body back, but if it sounds close to right then I have great news for you.  RubyCocoa!  Started by Fujimoto Hisa and continued on at http://rubycocoa.sourceforge.net, RubyCocoa allows you to make complete OS X applications in Ruby, using all the features of the Cocoa framework.  There&amp;#8217;s already a few applications out there in it, and a lot of great information, but what I found is that if you&amp;#8217;re a complete newbie to Cocoa/OS X/Interface Builder and Objective-C like I was there&amp;#8217;s no good step-by-step tutorial.  Until now! (Tada!)  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the heck is Cocoa&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cocoa is an application framework for writing applications on OS X.  That really doesn&amp;#8217;t tell me much does it?  How about a diagram:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-08_cocoadiagram.jpg" alt="Cocoadiagram"/&gt;[1]&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s an application layer on the Mac OS, with all the pretty buttons, scrollbars, and other such widgets that you expect from OS X applications.  These are used through the Objective-C classes included in the framework of your application.  Wait, I know what you&amp;#8217;re thinking, &amp;#8220;C?  Did you say C!  Are you out of your mind?  I&amp;#8217;ve never been so lied to in my life!&amp;#8221;  Relax my friend and keep reading.  I promise you there is no C in this tutorial, well except&amp;#8230;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Objective-C&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Objective-C is the preferred development language for applications on the OS X platform.  It was originally developed by Brad Cox as an object-oriented extension to C, and is compiled in the gcc compiler.  It&amp;#8217;s primarily influenced by SmallTalk, much like Ruby.  If you know C or C++, and really if you are over 25 and a programmer you probably do, then you should be able to learn Objective-C quickly.  Fortunately you don&amp;#8217;t, but you will need to understand some bits and pieces of the syntax in order to translate Cocoa documentation to Ruby.  I&amp;#8217;ll point out where this was done in the tutorial.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting RubyCocoa&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You wanna write Cocoa apps in Ruby, you need RubyCocoa.  All those Objective-C classes are available through Ruby calls, removing the need for such Objective-C necessities such as memory allocation and deallocation, keeping your code simple and beautiful.  Guess you&amp;#8217;re going to have to install it.  Here&amp;#8217;s the subversion call:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;svn co https://rubycocoa.svn.sourceforge.net/svnroot/rubycocoa/trunk/src rubycocoa&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next we need to build and install ruby cocoa.  You&amp;#8217;ll need XCode installed for this to work, and for the rest of the tutorial to work.  I&amp;#8217;m assuming that you&amp;#8217;ve been developing in Ruby for more than a few hours, so you&amp;#8217;ve installed some gems.  If so you probably already had to install XCode.  If not then you&amp;#8217;ll need to insert the OS X setup disc that came with your Mac and install it.  I&amp;#8217;ll wait.  Sheesh that took a while.  Next, from the directory where you checked out the source code, do the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ ruby install.rb config
$ ruby install.rb setup
$ sudo ruby install.rb install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The preliminaries are over, let&amp;#8217;s code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your first project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where the fun begins.  We&amp;#8217;re going to make an app together, and as we go I&amp;#8217;ll explain the bits and pieces in baby steps.  Afterwards hopefully you&amp;#8217;ll know the basics of Cocoa as well as the basics of RubyCocoa.  I&amp;#8217;m borrowing liberally from the basic tutorial done in Objective-C on Apple&amp;#8217;s developer website[2], only done entirely in Ruby.  If you&amp;#8217;ve got 20 minutes, you can do this tutorial.  It takes a half-hour in Objective-C.&lt;/p&gt;

&lt;p&gt;Sadly to start we need to use XCode.  Maybe it&amp;#8217;s me, and my bias against overcharged IDE&amp;#8217;s, but I don&amp;#8217;t like XCode.  It&amp;#8217;s awful busy, and it&amp;#8217;s code formatting in Ruby is &amp;#8230;well my mommy told me if you can&amp;#8217;t say something nice don&amp;#8217;t say anything at all.  So start up XCode and choose File-&gt; New Project.  If you installed your RubyCocoa bundle properly you should be able to select Ruby-Cocoa application from the menu.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-08_xcode_screenshot.jpg" alt="Xcode Screenshot"/&gt;&lt;/p&gt;

&lt;p&gt;Create the Ruby-Cocoa application and name it Currency Converter.  You can put it wherever you want.  Once you&amp;#8217;ve created it you should see this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-08_xcode_screenshot_2.jpg" alt="Xcode Screenshot 2"/&gt;&lt;/p&gt;

&lt;p&gt;This is your XCode project, similar to a Visual Studio project for my fellow Windoze converts.  The files you&amp;#8217;ll be dealing with in this example are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CurrencyConverterDemo.app.  You may have named your project differently than I did, but this will be the name of the app file after it&amp;#8217;s built.  This app is distributable to anybody using Mac OS X just like any other application you might have built in Objective-C.  You may be used to writing Ruby scripts that require the user to install various gems or a particular version of Ruby, but thanks to the RubyCocoa.framework also included in the default project this app can be distributed with your users unaware that what language you wrote it in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MainMenu.nib.  You&amp;#8217;ll be making this your friend.  It&amp;#8217;s where you create your interface, your interface objects, and instantiate them as well - assuming they are NSObjects.  You&amp;#8217;ll also setup actions, outlets, and bindings.  I realize none of this makes sense yet, but bear with me.  Double click the Nib file and you&amp;#8217;ll open Interface Builder, where most of the action is.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Interface Builder and .nib files took a little getting used to for me, perhaps because of my time doing Windows development, because it&amp;#8217;s similar to Windows Forms and Resource files while at the same time being completely different.  When a Cocoa application is loaded the first thing it does is load the Nib file, and instantiate all the objects and variables you&amp;#8217;ve setup.  That&amp;#8217;s right, instantiated objects in a GUI.  There&amp;#8217;s a lot more to this than just setting up how the application looks, you&amp;#8217;re setting up objects and how they relate to each other too.  If you&amp;#8217;ve double clicked the Nib file then you should see four windows.  The first we&amp;#8217;ll be dealing with is the Main Menu.  &lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_menu.jpg" alt="Menu"/&gt;&lt;/p&gt;

&lt;p&gt;Okay it&amp;#8217;s not the best screenshot in the world.  You&amp;#8217;re not reading [coding horror] (http://www.codinghorror.com/), you&amp;#8217;ll have to deal with it.  The first thing to do is change the name to Currency Converter.  Just double-click the name and it will open an editor for you, and you can do that.  Single click the Menu title and you&amp;#8217;ll see the drop-down menu.  Edit that so that each name is also Currency Converter.  Next we&amp;#8217;ll setup the window.  That&amp;#8217;s this empty slate:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_window.jpg" alt="Window"/&gt;&lt;/p&gt;

&lt;p&gt;First things first, you don&amp;#8217;t want to let our little app be called Window do you?  You can&amp;#8217;t double-click here, but you can use the Inspector.  The Inspector shows you all the properties for whatever object you have selected in the application.  This comes in real handy when you don&amp;#8217;t know a keyboard shortcut.  Hit Command-Shift-I to bring up the Inspector.  That gives you this screen:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_inspector.jpg" alt="Inspector"/&gt;&lt;/p&gt;

&lt;p&gt;See that field that says Window Title - change it to Currency Converter as well.  Let&amp;#8217;s change the size too.  In the Inspector click the drop-down window that says Attributes and select Size.  In the Content Rectangle section there is a drop down box that says Width/Height and next to it two windows with Width and Height.  Set the size to 400x200.  That&amp;#8217;s a pretty good starting point.  We&amp;#8217;ve got a blank window, think we could use some controls?  See that big window on the right - the one that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_cocawidgets.jpg" alt="Cocawidgets"/&gt;&lt;/p&gt;

&lt;p&gt;Yipee Toys!  The screenshot above shows the Controls view, which isn&amp;#8217;t actually what we want because we won&amp;#8217;t be adding any buttons yet.  We&amp;#8217;re adding some text views.  Along the top of the window are choices for the different types of Cocoa objects we can add to our application.  Select this one:  &lt;img src="http://blog.8thlight.com/files/2007-08-11_textwidgets.jpg" alt="Textwidgets"/&gt; so we can start adding text objects to our window.  First we will add three edit boxes.  Simply take one of the empty edit boxes and drag it to your window.  When you drag your Window over you&amp;#8217;ll see blue lines appear.  If you lock to those you can take a big step in meeting Apples User Interface guidelines.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_text_box.jpg" alt="Text box"/&gt;&lt;/p&gt;

&lt;p&gt;You&amp;#8217;ve added the first, but to make life easier on yourself hit Apple-D to make the other two.  Make sure you align then on the right blue line, and you should also see a blue line on the top of each box, which marks equal spacing between each edit box.  Next add the System Font Text to the left of each box.  Add the first one to align with the top box, then again use Apple-D to duplicate them.  Align them with each of the boxes, using the blue lines.  It should look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_edit_boxes_and_text.jpg" alt="Edit Boxes and Text"/&gt;&lt;/p&gt;

&lt;p&gt;We aren&amp;#8217;t exactly finished with our application yet are we?  For starters we need to change that to useful text.  Double click each text box and change the text to read Amount of Money:, Conversion Rate:, New Amount: respectively.  Um - uh oh.  This doesn&amp;#8217;t look right does it?&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_bad_text.jpg" alt="Bad Text"/&gt;&lt;/p&gt;

&lt;p&gt;We&amp;#8217;re gonna have to fix that.  Holding down the shift button click each box.  This should select them all.  Next choose Layout from the top menu, and choose Size To Fit.  This will make all the boxes size to fit the text, and extend the top box to include the text you entered earlier.  If any of your boxes are two lines long it&amp;#8217;s because you added a return to the text when you edited it the first time.  Go ahead and re-edit the text, deleting the return then size to fit the box again.  Now select each text element individually, and head to the Inspector.  It should already be open from previous uses but if not use Apple-Shift-I to open it up.  Select the attributes for the text object in the drop-down and set the alignment to the right.   &lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_alignright.jpg" alt="Alignright"/&gt;&lt;/p&gt;

&lt;p&gt;Once again select all the text boxes again making sure you start from Amount of Money:.  Choose Layout-&gt; Same Size.  Then choose Layout-&gt;Alignment-&gt;Right edges.  Drag all those boxes to the left side of the window, aligning with the blue line when it appears.  I use the keyboard for this so that I don&amp;#8217;t accidentally move the text up or down.  Finally drag the edit boxes over to the text, again aligning with the blue line.  You do this by selecting all of them, then moving them to the left.  At this point the box should look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_window_with_text.jpg" alt="Window With Text"/&gt;&lt;/p&gt;

&lt;p&gt;Looks like it&amp;#8217;s a little big, but we don&amp;#8217;t want to resize it until we add our button.  In the Cocoa window go back to the controls view. with this button: &lt;img src="http://blog.8thlight.com/files/2007-08-11_control_button.jpg" alt="Control Button"/&gt;.  Not surprisingly we&amp;#8217;re going to add a button to the window, in order to actually convert the currency.  Take the button and drag it over to the Window, putting it underneath the boxes and once again aligning with a blue line that will appear above it.  Double click the button and rename it to Convert.  Now let&amp;#8217;s take a peek at one of the cool parts of Interface Builder.  With the button selected, hold the option key and move your mouse over the box.  You should see this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_option_bars.jpg" alt="Option Bars"/&gt;&lt;/p&gt;

&lt;p&gt;Now by moving the keyboard left and right we can actually put the button directly in the middle of the three boxes.  Now it&amp;#8217;s time to shrink the screen to fit, just like you would shrink any window until the ever-so-ubiquitous blues appear.  Do that now.  Finally just for a flourish let&amp;#8217;s add a little line between the button and the boxes.  Drag the horizontal line from the controls on to the window right underneath the boxes, aligning with yet another blue line.  Extend it to the blue lines on the left and right to make it full sized. You should have a dialog box that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_final_dialog.jpg" alt="Final Dialog"/&gt;&lt;/p&gt;

&lt;p&gt;I swear we&amp;#8217;re almost to Ruby code, so quit complaining and save your interface.  We now need a way to interact with this pretty little picture.  The way that&amp;#8217;s done in the land of Cocoa is through Actions and Outlets.  Actions are methods that can be triggered by other objects, whereas outlets are pointers to other objects.  Essentially if you want to &lt;em&gt;do_ something you need an action if you want to _set or get&lt;/em&gt; something you need an outlet.  The first thing to setup is an action - the Convert button needs to _do_ something does it not?  In order to connect the action from the button we need to have a class.  That&amp;#8217;s right - we&amp;#8217;re going to make some Ruby code.  There&amp;#8217;s one more window we haven&amp;#8217;t yet used in Interface Builder:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_instances_view.jpg" alt="Instances View"/&gt;&lt;/p&gt;

&lt;p&gt;Click the Classes tab so we can crate two Ruby classes, both of which will inherit from NSObject.  That&amp;#8217;s right, Ruby classes inheriting from Objective-C classes.  Like a Picasso it&amp;#8217;s disturbing and beautiful at the same time.  The Classes view lists all the available Cocoa classes, so scroll to the left side and select NSObject.  Then hit enter and it will automatically create a class named ConverterController.  &lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_class_view.jpg" alt="Class View"/&gt;&lt;/p&gt;

&lt;p&gt;Now this creates a class in the Nib file so that the interface knows about it, but because we&amp;#8217;re using Ruby we don&amp;#8217;t actually generate our class from it.  Let&amp;#8217;s also create a class called Converter.  Even though it&amp;#8217;s overkill we&amp;#8217;re going to create a MVC framework here, simply for demonstration purposes.  After you&amp;#8217;ve done that select ConverterController and use Apple-Shift-I to again bring up the inspector.   You should see this view:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_currency_converter_inspector.jpg" alt="Currency Converter Inspector"/&gt;&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s think for a moment.  What is the controller going to need to do.  When the button is clicked it needs to get the values for the original amount and conversion rate, calculate the new amount, then set the new amount.  This means we will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Action - for the convert button&lt;/li&gt;
&lt;li&gt;Outlet - for getting the original amount&lt;/li&gt;
&lt;li&gt;Outlet - for getting the conversion rate&lt;/li&gt;
&lt;li&gt;Outlet - for setting the new amount&lt;/li&gt;
&lt;li&gt;Outlet - for sending the data to the model to calculate the new amount.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Admit it, you were going to just do the calculation right then and there in the Controller class.  Say 10 Hail Matz&amp;#8217;s for punishment.  Good job.  Adding these outlets and actions is pretty self explanatory.  Just click add.  There&amp;#8217;s one gotcha.  The action is a method.  Methods in Objective-C will have a colon at the end and you must have the colon at the end in your description of the outlet, even though the method you actually declare will not have one.  Otherwise things won&amp;#8217;t be found.  When adding outlets there is a drop down for the type.  This has a use in Objective-C, but we&amp;#8217;re doing Ruby.  Leave it at id.&lt;/p&gt;

&lt;p&gt;What we&amp;#8217;ve created here is a class definition, so that Objective-C can call the classes you haven&amp;#8217;t implemented yet.  However we also need to instantiate the class, otherwise there&amp;#8217;s nothing to connect.  Everything you&amp;#8217;ve just defined is a variable, it needs to be set to something.  To do that select ConverterController and select from the top-level menu Instantiate ConverterController.  Then do the same for Converter.  This lets the Cocoa Framework know that when it starts up it needs to create each of these objects.  You won&amp;#8217;t be calling new here, in fact you never define initialize or call new on a Ruby Cocoa object.  That&amp;#8217;s a topic for another day however.  In the Instances view you should now see this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_instances_classes_instantiated.jpg" alt="Instances Classes Instantiated"/&gt;&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m going to re-iterate something.  These aren&amp;#8217;t a resource file, or an XML definition.  What you&amp;#8217;ve done here is create real live objects.  If you attempt to build and run now it will fail because you haven&amp;#8217;t written an underlying implementation, but the objects are there.  They will be allocated.  They&amp;#8217;re the real thing.  Now look at that tiny exclamation point next to ConverterController.  What it says is you have unconnected outlets.  When the Cocoa application starts up it&amp;#8217;s going to attempt to link those outlets and if you haven&amp;#8217;t connected them they will be set to nil.  Let&amp;#8217;s connect them.  To connect a control to an action you hold the Ctrl key and drag from the button to the class.  Think of the connections as following the path of the event, so for example you&amp;#8217;ll drag from the Convert button to the class that will implement the action: ConverterController.  When you do that the Inspector will display automatically with the convert: action highlighted.  On the bottom of that dialog click connect.  It should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_connection.jpg" alt="Connection"/&gt;&lt;/p&gt;

&lt;p&gt;You&amp;#8217;ve connected your first action to its target.  Now when you click Convert the action convert in the ConverterController class will be called.  It&amp;#8217;s time to go the other way.  Ctrl-drag another line from the ConverterController to the first edit box and connect it to the appropriate outlet.  Do the same with the other two edit boxes.  You should see this in the Inspector window:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_outlets_without_converter.jpg" alt="Outlets Without Converter"/&gt;&lt;/p&gt;

&lt;p&gt;One more to go.  You don&amp;#8217;t have to go from an instantiated class to an object in the window, you can go from object to object right in the Instances view.  Let&amp;#8217;s do that now to connect the ConverterController to the Converter object, and you&amp;#8217;ve got your final outlet.  Save your Nib file, and go to the XCode window.  On the top window go ahead and click the Build and Go button.  The application should start up just fine displaying your new shiny dialog.  If you click Convert it does absolutely nothing, say it again.  Yea!   We get to write Ruby code to implement those classes now.  About time isn&amp;#8217;t it?  In the action drop down select New File.  In the New file dialog make sure you select Ruby NSObject class like so:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://blog.8thlight.com/files/2007-08-11_new_file.jpg" alt="New File"/&gt; &lt;/p&gt;

&lt;p&gt;Create converter_controller.rb and converter.rb.  Both these will be opened for you in XCode, but I prefer to open the project at this point in Textmate.  Either way your will begin editing your Ruby code.  Let&amp;#8217;s start with the Converter Controller class.  First things first we&amp;#8217;ll delete the boilerplate comments and the require, which is unnecessary.  Next we better rename that class to CurrencyConverter and converter to Converter.  Don&amp;#8217;t blame me, XCode doesn&amp;#8217;t know much about Ruby and has no idea about naming rules.  Now we need to implement those outlets and actions and it couldn&amp;#8217;t be easier.  First the outlets.  Where you would normally type attr declarations and the like add this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ib_outlets :amount_of_money, :conversion_rate, :converter, :new_amount&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;I know I know, it&amp;#8217;s not DRY.  I&amp;#8217;m sorry but Interface Builder does not support generating this code from the GUI with Ruby, at least not yet.  Next the action.  Create an empty method named convert.  Done!  For some perspective in Objective-C you would have had to define this in the interface, with the proper macro, then implement it in the implementation file.  Sure it&amp;#8217;s a few more lines, but you&amp;#8217;re a Ruby programmer so you know just how much nicer four lines can be, especially when you keep adding them up over the course of an entire project.  Build and run your project again.  It will still do a whole lotta nuthin&amp;#8217;, but the console won&amp;#8217;t show any errors about being unable to find CurrencyConverter or Converter.   If you get errors that classnames must be constant it&amp;#8217;s because you forgot to rename the classnames.  You&amp;#8217;ve got an implementation ready to be written, and you can add the code.   Let&amp;#8217;s go into your convert action and get the  values from the outlets that will have the user type in.  Add this to your class:&lt;/p&gt;

&lt;pre&gt;
def convert
  amount_of_money = @amount_of_money.floatValue
  conversion_rate = @conversion_rate.floatValue
end
&lt;/pre&gt;

&lt;p&gt;I know I&amp;#8217;m an idiot right?  There&amp;#8217;s no initialize method so the outlets are both nil.  Okay you got me, so how come when you build and run this the app doesn&amp;#8217;t crash?  Try it now.  Build your new app and add values to those two boxes, then hit convert.  Did it crash?  It didn&amp;#8217;t?  Then I expect an e-mail apology for those nasty thoughts you had about me.  The reason it didn&amp;#8217;t crash is because of the way Cocoa works.  On the start of your application it instantiated the classes necessary and setup all the outlets with the values you specified in the Nib file.  In fact if you &lt;em&gt;were&lt;/em&gt; to add an initialize this code wouldn&amp;#8217;t work, because RubyCocoa does not even allow initialize in classes that inherit from Cocoa classes.  The reason for this is that Cocoa doesn&amp;#8217;t have initialize, it has alloc and init.  You can instantiate your own class, and you should for testing, but don&amp;#8217;t use initialize.  &lt;/p&gt;

&lt;p&gt;There&amp;#8217;s one other thing funny about the code, and that is the name floatValue.  Unfortunately Objective-C methods use camelcase.  I wish RubyCocoa rubified the names, however on the bright side every time you see that naming convention you should be able to instantaneously identify it.  Cocoa object here!  Our object still doesn&amp;#8217;t convert anything, so let&amp;#8217;s finish off the controller&amp;#8217;s implementation.  Add the calculation and the setting here:&lt;/p&gt;

&lt;pre&gt;
def convert
  amount_of_money = @amount_of_money.floatValue
  conversion_rate = @conversion_rate.floatValue

  new_amount = @converter.convert amount_of_money, conversion_rate

  @new_amount.setFloatValue new_amount
  @amount_of_money.selectText @amount_of_money
end
&lt;/pre&gt;

&lt;p&gt;Reads pretty darn well doesn&amp;#8217;t it?  Get a float value out of the amount of money and conversion rate boxes, use the converter object to then convert that to a new amount, then set the float value for the new amount.  Finally we select the text to the amount of money dialog box, so that we can calculate again.  I realize I&amp;#8217;m explaining method calls very quickly, but I&amp;#8217;m not sure there&amp;#8217;s that much to say.  Compare this to the Objective-C version:&lt;/p&gt;

&lt;pre&gt;
#import "ConverterController.h"

@implementation ConverterController

- (IBAction)convert:(id)sender
{
    float rate, currency, amount;

    currency = [dollarField floatValue];
    rate =     [rateField floatValue];
    amount =   [converter convertCurrency:currency atRate:rate];

    [amountField setFloatValue:amount];
    [rateField selectText:self];
}

@end
&lt;/pre&gt;

&lt;p&gt;Honestly that&amp;#8217;s not even fair to the Ruby version, since I could easily shrink down the calls to get that method into two lines and I didn&amp;#8217;t display the header file for ConverterController.  Finally let&amp;#8217;s write the one-line implementation of the converter model:&lt;/p&gt;

&lt;pre&gt;
def convert(amount, rate)
  return amount * rate
end
&lt;/pre&gt;

&lt;p&gt;We&amp;#8217;re done!  Look at that, 90% of the work was getting used to interface builder.  Build and run your app.  Yipee!  You can convert currency now.  You&amp;#8217;re a God.  Well at least a demi-god, like Heracles.  Here&amp;#8217;s hoping this can be a series of articles, and that you keep coming back for more.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;* Footnotes *&lt;/em&gt;
[1] http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/WhatIsCocoa/chapter&lt;em&gt;2&lt;/em&gt;section&lt;em&gt;2.html#//apple&lt;/em&gt;ref/doc/uid/TP40002974-CH3-DontLinkElementID_20
[2] http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCTutorial/&lt;/p&gt;

&lt;p&gt;This article is largely a conglomeration of other sources and could not have been completed without the following:  Aaron Hillegass&amp;#8217;s excellent Cocoa Programming for Mac OS X, RubyCocoa.com, the Apple developer website, and of course http://rubycocoa.sourceforge.net.  I wholeheartedly recommend going through Aaron&amp;#8217;s book, using Ruby as your chosen language.  You&amp;#8217;ll be amazed at how fast you can translate the code.&lt;/p&gt;</description>
      <pubDate>Mon, 13 Aug 2007 10:44:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:24b4d8ec-c9f6-4d6b-8edc-e0ece99efe5f</guid>
      <author>Eric</author>
      <link>http://blog.8thlight.com/articles/2007/08/13/rubycocoa-tutorial</link>
      <category>Coding</category>
      <category>Ruby</category>
      <category>Eric</category>
      <category>cocoa</category>
    </item>
  </channel>
</rss>
