"Recovering from Enterprise" video available

It appears that Confreaks has posted the video of my ‘Recovering from Enterprise’ talk from RubyConf 2008. As usual, Confreaks did a great job recording the talks at RubyConf.

For those who missed it, I also posted an article version of my presentation, titled Legos, Play-doh, and Programming.

The HTTParty has just begun

After releasing the new RubyURL API, I decided that it was time to look around at libraries to interact with it. I came across a new Ruby gem from John Nunemaker named, HTTParty, which aims to make it easy to talk to XML and JSON-based web services. Be sure to read John’s announcement of HTTParty.

So, I decided it might be fun to introduce more people to the gem by showing you all how to use it to talk to the new RubyURL API.

Install HTTParty

Before we get started, you’ll need to install the HTTParty gem with the following command:


   ~ : sudo gem install httparty
  Password:
  When you HTTParty, you must party hard!
  Successfully installed httparty-0.1.6
  1 gem installed
  Installing ri documentation for httparty-0.1.6...
  Installing RDoc documentation for httparty-0.1.6...

Great! Now that we’re ready to party hard, let’s build something.

Talking to the RubyURL API

The RubyURL API currently supports both XML and JSON, which are each supported by HTTParty. The great thing about HTTParty is that all you need to do is include it in a class and you’re able to quickly talk to remote services.

In this following example, we’re going to create a new class called Rubyurl.

class Rubyurl
end

What we’ll want to do now is include the HTTParty library. (note: you’ll need to require both rubygems and httparty gems and I’ll skip those lines in following code samples)

class Rubyurl
  include HTTParty
end

The HTTParty provides a few class methods, which we can use to configure our library. We’ll go ahead and specify the base_uri, which we’ll set to rubyurl.com.

class Rubyurl
  include HTTParty
  base_uri 'rubyurl.com'
end

Now that our class is setup to talk to the Rubyurl.com site, we’ll want to add a new method which we can use to communicate with the RubyURL API. We’ll call this shorten as we’re using RubyURL to shorten long URLs… right?

class Rubyurl
  include HTTParty
  base_uri 'localhost:3000'

  def self.shorten( website_url )
  end
end

Our new shorten method will expect us to provide it with a website url, which we’ll want RubyURL to return a shortened URL for. The PATH for the API that we’ll want to talk to is: /api/links, which we’re expected to pass XML or JSON to.

Here are two examples of using the RubyURL API with HTTParty.

RubyURL via JSON w/HTTParty

We’re going to use the post method that is provided with HTTParty to send a request to /api/links.json. As you can see, we’re providing the original website url to the web service.

class Rubyurl
  include HTTParty
  base_uri 'rubyurl.com'

  def self.shorten( website_url )
    post( '/api/links.json', :query => { :link => { :website_url => website_url } } )
  end
end

When ran, it’ll produce the following:

  >> Rubyurl.shorten( 'http://github.com/jnunemaker/httparty/tree/master/lib/httparty.rb' ).inspect
  => {"link"=>{"permalink"=>"http://rubyurl.com/uJVu", "website_url"=>"http://github.com/jnunemaker/httparty/tree/master/lib/httparty.rb"}}

Pretty simple, eh?

RubyURL via XML w/HTTParty

The great thing about HTTParty is that you can use XML without changing much.

class Rubyurl
  include HTTParty
  base_uri 'rubyurl.com'

  def self.shorten( website_url )
    post( '/api/links.xml', :query => { :link => { :website_url => website_url } } )
  end
end

Produces the following

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<link>
  <website_url>http://github.com/jnunemaker/httparty/tree/master/lib/httparty.rb</website_url>
  <permalink>http://rubyurl.com/uJVu</permalink>
</link>

Closing thoughts

So… there you have it. HTTParty makes it extremely easy to interact with various web services that work over HTTP. I’d encourage you all to take a few minutes to experiment with it and see what crazy ideas that come to mind during the process. 🙂

What’s New in Edge Rails: No More Formatted Routes


This feature is scheduled for: Rails v2.3/3.0


Parallel to the addition of :except and :only options to Rails’ routing comes the removal of all those formatted_xxx named routes. Turns out these routes ate up a lot of memory and served minimal purpose.

So with this routes.rb definition:

1
2
3
ActionController::Routing::Routes.draw do |map|
  map.resources :articles
end

you’ll no longer have any of the formatted_xxx url helpers available. However, you will be able to get the same functionality by passing in a :format option to the base view helper methods:

1
2
3
4
# Old => New
formatted_article_path(article, :xml) => article_path(article, :format => :xml)
formatted_new_article_path(:json) => new_article_path(:format => :json)
# etc...

A minimal change that will have a big impact on the memory consumption of each of your Rails processes – especially if you’ve got a complex app with lots of routes.

If you’re on Edge Rails you’re going to start seeing deprecation warnings where you reference these formatted url helpers, so you’ve got some warning before you have to make the switch.

tags: ruby,
rubyonrails


#137 Memoization

Rails 2.2 is out! In this episode I show how to upgrade Rails and then demonstrate one of the new additions: Memoization.

#137 Memoization

Rails 2.2 is out! In this episode I show how to upgrade Rails and then demonstrate one of the new additions: Memoization.

Monty Williams on MagLev – Ruby on Rails Podcast

Monty Williams of Gemstone recounts the history of the MagLev Ruby interpreter project.
From RubyConf 2008 in Orlando.

Sponsor

Monty Williams on MagLev – Ruby on Rails Podcast

Monty Williams of Gemstone recounts the history of the MagLev Ruby interpreter project.
From RubyConf 2008 in Orlando.

Sponsor

Can Software Updates Be Made Simpler?

Generally speaking, I like Apple’s Software Update mechanism more than I liked Microsoft’s Windows Update. It generally seems less intrusive, runs faster, and has a simpler UI (disclaimer: I’m more familiar with WinXP than Vista; if the Vista experience has made it a lot better, be sure to comment to this post).

However, it still takes a lot more clicks than it should, especially for iTunes updates. iTunes seems to update itself more often than any other piece of software I own, and every time there’s an update I have to click once or twice to get past the License Agreement nonsense in addition to the clicks needed to just get the update installed. For minor “point” releases, I wish it wouldn’t ask me about the license agreement every single time:

Agreeing to the terms and conditions of, say, version 8.0.0, should imply that I agree for 8.1 through 8.9. Or heck, through 125.2. Does anybody read these things anymore anyway? Just give me a way to view the license agreement from the Help menu or something if I’m really worried about it.

Software updates should be, ideally, invisible; and when they can’t be, they should be simple to apply. I think Apple has done a good job with making them simple to apply. But many of them could be invisible. Windows Update had an option to automatically download and install (and even reboot if necessary) updates at 2AM. The next morning, updates are applied, and you’re none the wiser. Unfortunately this was a little scary, because there wasn’t a way to select which updates are authorized for automatic installation. It was all or nothing.

I want an option in iTunes where I can say, “Yes, yes, install whatever you want, whenever you want – just don’t bother me, kthx.”

I guess I want something more akin to the experience I have with software like Adium and Skitch. You’re told that there’s an update available, and you have to agree to install the update. After watching the progress bar (can’t anybody think of anything a little more entertaining than a solid bar filling up with the standard color? How about a clown juggling 3 balls, then 4, then 5? Or something?), I get a button that just stays “Install and Relaunch.” Which, unfortunately, is followed by a dialog asking if I want to allow it to touch all my keychain stuff (which I always say yes to). So there’s room for improvement there, too, but overall the experience seems cleaner and faster.

I don’t have all the answers, and I know that client software is supposed to be a dying breed, but I do think it’s time that someone – either Apple, Microsoft, or Linux – figure out a nicer way to install updates.

Speaking of Linux, I’ve never used a Linux Desktop OS. Those of you who have, I’d be interested in hearing about your experiences with operating-system updates as well as client software updates.

Vim Follow-up

So, it’s been over a month and a half since I switched back to Vim, and I figured I’d post a bit about how things are going.

I love it. Though the future is notoriously difficult to foretell, I think it’s safe to say that I won’t be switching editors again anytime soon. Vim is where it’s at, for me.

Here’s the combination of plugins and such that I’ve found work best for me.

MacVim FTW

Any Vim will do, really, but if you’re on a Mac, you really ought to consider MacVim. Like any self-respecting Vim port, it does the command-line really well, but it also has a great OS X GUI interface.

Settings

I’ve got my <Leader> character (:h mapleader) mapped to the comma (since it’s easier to reach than the backspace character).


let mapleader = ","

I’ve installed ack and have configured Vim to use ack for grep.

1
2
set grepprg=ack
set grepformat=%f:%l:%m

I’m a believer in spaces instead of tabs (let’s just agree not to go there), and I prefer a tab size of 2. I also like editors to try and guess the indentation level.

1
2
3
4
5
6
set tabstop=2
set smarttab
set shiftwidth=2
set autoindent
set expandtab
set backspace=start,indent

But, some file types really do require explicit tabs, and not spaces:

1
2
autocmd FileType make     set noexpandtab
autocmd FileType python   set noexpandtab

(Update: apparently, python can do tabs or spaces. All my python vimming for the last 8 years has been read-only, so it never actually came up.)

I like my lines numbered, syntax highlighting on, and highlighted searches:

1
2
3
set number
set hlsearch
syntax on

I’ve got quite a few other things tweaked in my .vimrc, but those are the major biggest ones.

Plugins

FuzzyFinder

The FuzzyFinder and FuzzyFinder TextMate plugins have become essential for me. For now, installation of the TextMate-like behavior is kind of painful, but I plan to get something up on the Vim scripts index in the nearish future.

My settings for FuzzyFinder TextMate:

1
2
3
4
5
let g:fuzzy_ignore = "*.log"
let g:fuzzy_matching_limit = 70

map <leader>t :FuzzyFinderTextMate<CR>
map <leader>b :FuzzyFinderBuffer<CR>

NERD_tree

Thanks to all who recommended the NERD tree plugin by Marty Grenfell. It really is fantastic, definitely the best-of-breed of VIM project/directory explorers. I especially like that it is easily toggled away. I usually keep it hidden, and toggle it open only when I need to browse to something. (Thanks to the fuzzyfinder stuff, my need for a project browser is pretty small, but when I need one, NERD_tree works great.)

1
map <leader>d :execute 'NERDTreeToggle ' . getcwd()<CR>

rails.vim

The rails.vim plugin is pretty extensive, and I’m currently only scratching the surface. I don’t use snippets at all (never did in TextMate, either), but the Rake integration is pretty handy, and I’ve used the migration generator pretty often lately.

I need to spend some more time reading the docs for this one, and practicing some of the commands, since I’m sure it could turn into a real time-saver for programmers (like myself) who spend a good part of their day in Rails code.

scratch.vim

I’ve really come to love scratch.vim. Sometimes I just need to jot down some numbers, or paste the result of some query, or even take notes on a phone call. Writing any of that on a scrap of paper is a sure way to lose the info. The scratch plugin lets me take notes right where I am all day: in Vim. It doesn’t come with a way to toggle the scratch buffer (which is odd), so I wrote a quick one:

1
2
3
4
5
6
7
8
9
function! ToggleScratch()
  if expand('%') == g:ScratchBufferName
    quit
  else
    Sscratch
  endif
endfunction

map <leader>s :call ToggleScratch()<CR>

tComment

Maybe it’s just my own coding style, but I find myself commenting and uncommenting large blocks of code on a daily basis. The tComment plugin from Tom Link is perfect for this. You can toggle comments by using the Vim motion operators, or just do a quick visual block followed by “gc”. Good stuff!

Others

There are a few other plugins I’m experimenting with (surround.vim, vcscommand.vim), but which I use infrequently enough that they haven’t become muscle memory yet.

Workflow

Because I prefer the GUI version of MacVim, I typically have only one or two terminal windows open. I then type “mvim” to open vim from the root of whichever project(s) I’m working on, and then use ”,t” (my FuzzyFinder TextMate trigger) to search for and open files. I also use ”,b” (my FuzzyFinderBuffer trigger) to search my buffer list if I know the file is already open.

Switching between buffers with the carat character ”^” is a huge time saver. I used to use :ls (to list open buffers) and :buffer (to jump to a buffer), but the FuzzyFinderBuffer has really taken the place of both of those.

Ironically, split windows (which I missed most of all when I switched to TextMate) have taken me the longest to fit back into my workflow. TextMate trained them out of me. 🙂 That said, I’m still trying to fit them back in, and when I remember to use them, I love them.

You?

So, that’s me. How does Vim fit in your own workflow? What settings do you prefer, and why? And what customizations are you using in your own setup?

Moving "private" and non-Rails related entries to

I received a couple of comments and emails about my non-Rails related entries, more specifically about the iPhone related entries. So from now on I will move these type of entries to my new “private” blog http://blog.wanja.com. As I am starting the development of a new iPhone app and will report about it over there. I am still doing quite some Rails related work and will keep posting about it here (http://onrails.org). I am also experimenting with MacRuby, which is so cool, and will report about it here unless it’s specific to iPhone development. I short if you are only interested in Rails or Ruby keep ready this blog, if you are interested in the other “stuff” I play with, such a iPhone, games, Wii, PS3, programming the Wii Remote, and any other geek stuff, check out http://blog.wanja.com

#136 jQuery

How do you use jQuery with Rails? In this episode I redo episode #43 using jQuery instead of Prototype/RJS.

#136 jQuery

How do you use jQuery with Rails? In this episode I redo episode #43 using jQuery instead of Prototype/RJS.

RubyConf 2008 – Ruby on Rails Podcast

Conversations from RubyConf 2008. With Matt Aimonetti of Merb, Blake Mizerany of Sinatra, and Josh Peek of Rails.

Sponsor

RubyConf 2008 – Ruby on Rails Podcast

Conversations from RubyConf 2008. With Matt Aimonetti of Merb, Blake Mizerany of Sinatra, and Josh Peek of Rails.

Sponsor

Speaking at ChicagoRuby this Saturday

Sorry for the late notice – I was having too much fun at RubyConf last week – but I’ll be speaking at the upcoming ChicagoRuby meeting this Saturday. If you’re in the neighborhood, come join us!

ChicagoRuby is headed up by Ray Hightower, the same guy who made Windy City Rails a reality. You can let us know you’re coming by using this Meetup.com link.

See you there!

#135 Making a Gem

Want to create a Ruby Gem instead of a Rails plugin? In this episode I will walk you through creating a gem to extend Rails.

#135 Making a Gem

Want to create a Ruby Gem instead of a Rails plugin? In this episode I will walk you through creating a gem to extend Rails.

LEGOs, Play-Doh, and Programming

This article is based on a talk I gave at the 2008 RubyConf in Orlando, Florida, entitled “Recovering from Enterprise: how to embrace Ruby’s idioms and say goodbye to bad habits”.

The other day I went to Target with my son. Like most kids, I think, he’s convinced that Target is a toy store, which just happens to sell towels and shoes and cleaning supplies, too, so in his eyes it’d be criminal to not walk through the bare handful of toy aisles.

Besides, the toy section is across from the electronics section, which all geeks know is where the real toys are.

So, we went to the toy section and started browsing. I’ve always loved LEGO sets, and it’s a good thing they’re so expensive or I’d come home with a new box of bricks every time. At the Target near our home, they have half of an entire aisle devoted to boxes and boxes of LEGO sets. Need a battle-axe-wielding LEGO dwarf figure? A LEGO shark? How about a giant LEGO skull, a la Indiana Jones? And who could pass a LEGO Star Wars’ Star Destroyer model without a wistful thought or two?

It struck me at that time, though, how incredibly specific so many of these pieces are. With all of those sets in your possession, you could build a secret agent headquarters with a boulder trap that crushes angry battle-axe-wielding dwarves as they drive by in Martian exploration buggies. Which themelves are adorned with flower beds and creeper vines. And you could do all that in under 10 LEGO bricks! (Or, maybe a few more than that.)

Did you know that LEGO currently produces over 900 distinct LEGO pieces, or “elements” as they call them? Over the course of their history, there have been almost 13,000 distinct elements created. Now, that number includes variations in color and material, but even if you exclude those permutations, you’re still left with a staggering 2,800 different elements in the LEGO line.

It’s interesting that LEGO tends to encourage the use of specific pieces, rather than letting you build those pieces from more fundamental parts. It means that in order to master LEGO brick building, you have to know all of the pieces available to you, and have a good intuitive feel for how and when they should be used. That’s…a lot of information to keep tabs on. Myself, I just keep to the standard rectangular blocks and plug an exotic or two on as an afterthought when I see one that looks cool.

Also, if you’ve built up a model, and decide later that you want to change or extend some part of the model, you’ll often have to dismantle part (or all!) of it in order to do so. Kind of a pain.

Regardless, I still love building with LEGO bricks, and I suspect I always will.

Play-Doh

Now, my son being all of 6 years old, his attention span requires us to spend no more than a few minutes in any one toy aisle. So, long before I was ready to tear my eyes away from the LEGO sets, we found ourselves in the next aisle over. This was a much more colorful aisle, with bright pastels coloring various pre-school toys. My son, though, has nothing against pre-school toys, and was more than willing to drag me through them.

My eyes caught on the Play-Doh section.

The Play-Doh section at this Target is small, maybe 8 different hangers and a few square feet of shelf-space. You can get Play-Doh in as many as 50 different colors, but regardless of color, it’s all still the same thing: a bucket of malleable dough that you can pound, press, pinch, roll, and sculpt. (And rub into the carpet. And hair. And clothes. But we won’t get into that.)

Honestly, Play-Doh has a bad rap as a pre-schooler toy. It’s remarkably fun to play with. You can do all kinds of things with Play-Doh that you just can’t do with LEGO bricks. For example, the other day I built an arch out of cubes of Play-Doh that were held together only by friction. (You may not be impressed, but my 6-year-old was.)

The best part is that it doesn’t require so much memorization to become proficient in Play-Doh, though it might require more of an artistic streak than LEGO bricks do. Since I’m more engineer than artist, my Play-Doh creations tend to come out blocky and functional, rather than elegant and designed, but then, so do my LEGO creations.

Also, where LEGO models require significant work to alter or extend, Play-Doh models are dead-simple. If you want to add something to the base of your model, just graft more Play-Doh onto it. Want to change the shape of the keystone of your arch? Just pinch and mold in place. Simple!

Interestingly, I’ve found that while you can’t build with LEGO bricks using Play-Doh construction techniques, you can build with Play-Doh using LEGO construction techniques. Just build bricks out of Play-Doh. It’s unwiedly and impractical, but it can be done. The real question is: why would you want to? It’s pretty obvious that to build with Play-Doh, you should just embrace Play-Doh’s own strengths and run with it.

As obvious as that may seem, the lesson didn’t click for me for a long time. It’s not that I went about building Indiana Jones sets out of Play-Doh, one brick at a time. Rather, I didn’t realize that the same lesson applied to programming languages.

Java and LEGOs

Consider Java. Most would consider it the poster child of “enterprise” environments (though .NET is giving it a run for its money). And would you believe, Java and LEGO bricks have several things in common?

As of Java 1.6, there are well over 11,000 different classes and interfaces available to programmers in the standard library. (That’s not even counting the inner and anonymous classes that are usually not publicly documented.) Eleven. Thousand. Classes.

This is readily apparent when you consider the set of collection implementations that Java ships with.

Collection Interfaces:

  • Collection
  • Set
  • List
  • Queue
  • Deque
  • Map
  • SortedSet
  • SortedMap
  • NavigableSet
  • NavigableMap
  • BlockingQueue
  • BlockingDeque
  • ConcurrentMap
  • ConcurrentNavigableMap

General-Purpose Collection Implementations:

  • HashSet
  • TreeSet
  • LinkedHashSet
  • ArrayList
  • ArrayDeque
  • LinkedList
  • PriorityQueue
  • HashMap
  • TreeMap
  • LinkedHashMap

Special-Purpose Collection Implementations:

  • WeakHashMap
  • IdentityHashMap
  • CopyOnWriteArrayList
  • CopyOnWriteArraySet
  • EnumSet
  • EnumMap

Concurrent Collection Implementations:

  • ConcurrentLinkedQueue
  • LinkedBlockingQueue
  • ArrayBlockingQueue
  • PriorityBlockingQueue
  • DelayQueue
  • SynchronousQueue
  • LinkedBlockingDeque
  • ConcurrentHashMap
  • ConcurrentSkipListSet
  • ConcurrentSkipListMap

Abstract Collection Implementations:

  • AbstractCollection
  • AbstractSet
  • AbstractList
  • AbstractSequentialList
  • AbstractQueue
  • AbstractMap

Yes, that is FORTY-SIX different interfaces and implementations related to collections. Now, just like LEGO construction, having this volume of distinct elements on hand affects how you architect things. Writing software becomes more of a smorgasbord, where you pick and choose the specialized bricks you need, fitting them together just so. It also means that, in order to master Java, you need to have that intuitive grasp of how and when to use those thousands of classes. When do you use a HashSet versus a TreeSet? When would you use an ArrayDeque, and when would you want to subclass an AbstractQueue? It’s all part of the job.

Also, IDE’s are popular with Java in part because of the pain of refactoring. If you want to extend or modify a Java application, it can involve (like LEGO models) a lot of dismantling and reassembling.

Ruby as Play-Doh

But if Java is the LEGO of programming languages, then it could be argued that Ruby is the Play-Doh. Just as Play-Doh has been typically considered a pre-school toy, so Ruby has had a bad rap as a “toy” language, not fit for the “real world”. Also, compared to Java’s library of 11,000 classes, Ruby’s meager 1,400 classes (which number does include internal and anonymous ones, but not modules) seems paltry. And collections! Look what Ruby has to offer:

Modules:
  * Enumerable
  * Comparable (for elements within a collection)
Classes:
  * Hash
  * Array
  * Set
  * SortedSet

Just 6 options, to Java’s 46. What if you need a queue? Well, Ruby’s Array class has a queue-like interface; you could just use that. What about a sorted map? In that case, you might need to make do with a sorted set, or you could write your own, but it’s not hard. Most data structures are not rocket science, and for those that are, you can bet someone else has implemented it already.

But when you need to extend or modify your application, Ruby is a dream. Like Play-Doh, you can often just “pinch and mold” in place, grafting new code on or pulling old code out.

Ruby’s philosophy is like that of Play-Doh’s: provide a basic set of tools and make it relatively simple to build something complex with them. The very Ruby language itself is designed for this: closures, super-simple introspection of objects, runtime modification of existing objects, and the use of modules for extending classes and objects all tend to result in an environment that is simple, malleable, and extensible.

And just as you cannot use Play-Doh construction techniques with LEGO bricks, you also really cannot use Ruby programming techniques with Java. Using closures for delayed execution, or iteration, is tricky (at best) in Java, when it’s possible at all. Extending objects at runtime typically requires bytecode modification. And Ruby’s use of modules to extend classes and objects, while similar to both inheritance and interfaces, is slightly different (and arguably more powerful) than either.

You can write Ruby programs using Java programming techniques, but just as using LEGO techniques with Play-Doh is unwieldy and overcomplicated, so is mimicking Java in Ruby.

This is the lesson that I was slow to learn.

Copland

Consider exhibit A, from my Copland library.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# copland/configuration/loader.rb (collapsed)
module Copland
  module Configuration
    class Loader
      attr_reader :search_paths
      attr_reader :loaders

      def initialize( search_paths=[] )
      def add_search_path( *paths )
      def add_loader( loader )
      def load( options={} )
      def load_path( path, options )
      def use_library( name )
    end
  end
end

Copland was my first stab at a dependency injection (DI) framework, and is more-or-less a feature-for-feature port of the HiveMind project in Java. (Ironically, it was the subject of my first presentation at a Ruby conference, in 2004!)

It was designed to automatically scan directories in the load path for YAML configuration files (I’ll mention those shortly), and load them up and parse them. The thing is, I imagined a case where someone might want to use XML instead of YAML. I couldn’t just leave these folks behind! So I made the whole configuration loading framework extendible. Want XML config files? Fine! Just implement an XML parser system and register it with the configuration loader framework, and you’re good to go!

That’s just wrong on so many levels. Always, always, always build just what you need, and only when you need it. You’re in Ruby, the Play-Doh of programming languages, and the cost of adding features later is really, really low. Remember YAGNI! Obviously, this principle holds in Java, too, but it really seems like the opposite philosophy has become the standard among many Java projects. It’s too bad, because it has contributed to a bad reputation that Java probably doesn’t entirely deserve.

Here’s a classic Java pattern that just really doesn’t translate to Ruby:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# copland/class-factory.rb
module Copland
  class ClassFactory
    include Singleton

    def initialize
      @pools, @constructors = Hash.new, Hash.new
    end

    def create_pool( name, &block )
      block ||= proc { |k,*args| k.new( *args ) }
      @pools[ name ] = Hash.new
      @constructors[ name ] = block
    end

    def get_pool( name )
      pool = @pools[ name ] or raise NoSuchPoolException, name
      return pool
    end

    def register( pool_name, name, klass )
      pool = get_pool( pool_name )
      pool[ name ] = klass
    end

    def get( pool_name, name, *args )
      pool = get_pool( pool_name )
      klass = pool[ name ]
      raise NoSuchRegisteredClassException, "#{pool_name}:#{name}" unless klass
      constructor = @constructors[ pool_name ]
      return constructor.call( klass, *args )
    end
  end
end

This is an implementation of a class factory. In Ruby. The HiveMind project had a class factory, so the Copland project needed one, too!

But you know, class factories are absolutely pointless in Ruby. There are plenty of reasons for these in Java, but they just aren’t necessary in Ruby. Want a namespace? Declare the class in a module. Want the class to exist in multiple namespaces? Use constant assignment within whatever modules you desire. Need a dynamic lookup? Try #const_get. In the very worst case, just use a Hash if you need to map arbitrary strings to classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
module A
  class B
  end 
end

# method #1, use const_get to dynamically look up classes
name = "B" 
klass = A.const_get(name)
object = klass.new

# method #2, use a hash to map arbitrary strings to classes
map = { "bimpl" => A::B }
map["bimpl"].new

Seriously. You don’t need explicit class factories in Ruby, because anything can be a class factory, implicitly.

I’ll mention one more painful Javaism that I ported to Copland. It’s so painful that I won’t even bother pasting it here—if you’re following along, look at examples/solitaire-cipher/lib/package.yml in the copland distribution.

If you do, what you’ll see are 106 lines of YAML describing how different Ruby objects in a simple, 250-line program should be initialized and connected. Yes. 106 lines of YAML. For 250 lines of Ruby.

Now, don’t get me wrong. YAML can be great for configuration. Rails, for instance, uses it for database connection information. The problem here, in Copland, was that I was using a static configuration for what would be better served with a block of code. Ruby reads elegantly; a YAML configuration file does not.

Fortunately, those wiser than myself showed me the way.

RubyConf 2004

I still remember Rich Kilmer, sitting in the front row in the October 2004 RubyConf. As I wrapped up my presentation on Copland and dependency injection, I asked if there were any questions.

Rich raised his hand. “Why didn’t you just use Ruby?”

I was confused by his question, and he had to explain. Why did I use YAML instead of just doing the configuration in Ruby code?

I think I mumbled something like “that would be a neat idea”. To me, it was a novel concept. I’d never heard of it before. You’d never see a Java program that was configured by writing Java code. That screams “hard coding”! But Ruby, you see, is different.

Ruby lets you write these beautiful little mini-languages. You’ll hear them called “Domain Specific Languages”, or DSL’s. They are subsets of the Ruby language, and you’ll find them in Rake, Capistrano, rspec, shoulda, and more. They’re really everywhere in Ruby, to varying degrees.

Although Rich tried to open my eyes, I think I would have continued to try and push Copland if it weren’t for Jim Weirich. Jim took the idea of a Ruby-ish DSL for dependency injection and made something concrete of it. A few days after the conference he forwarded me a draft of an article he was writing, in which he described dependency injection and gave a very simple (and very elegant) implementation of a DI framework in Ruby. Instead of static configuration, he’d written a basic DSL for declaring how the dependencies related to each other.

It was a moment of epiphany for me. Suddenly, I got it. I understood what DSL’s were about. I asked Jim for permission to take his simple implemention and build upon it.

The result was Needle.

Needle

Now, I’m much prouder of Needle than of Copland, because it is much closer to Ruby’s philosophy than Java. There are some pretty cool designs in there, too, though I use the term “cool” here to mean “neat without having any real practical application.”

Needle, though better, was still far from the mark.

As an example of why it misses the mark, consider Needle’s “pipeline” concept. Conceptually, it allowed you to specify a sequence of post-processors that operated on an object, allowing you to wrap code around it and mimicking (among other things) AOP-like operations. It also let me (as the author of the library) easily implement things like deferred instantiation, singleton services, and the like.

For example, suppose you wanted to declare a “deferred singleton” service, that logged all accesses to one of the methods. Underneath, Needle will create a pipeline of processors that operate on the service, returning a proxy object. The first time the proxy is accessed, it will check to see if the object has been instantiated yet. If it hasn’t, it’ll instantiate it (and cache it). The instantiation, though, actually just hands control to the next element in the pipeline, which in this case checks to see that the “singleton” constraint is enforced (e.g., all requests for this service return the same object, rather than instantiating a new object). The next pipeline element in the chain will wrap the interceptor code around the method in question, and yet another pipeline element would perform the actual object instantiation.

Pipelines really were pretty slick in Needle.

The problem, though, is that instead of leaving them as an implementation detail, I advertised them as one of Needle’s features. “Implement your own service models!” I cried. But, how often, really, is that likely to happen? Instead of exposing only the bare minimum of Needle’s API, I exposed as much of it as I could, because I could.

That’s a bad idea. Expose only what you need. The rest can be there, available, but not formally exposed. Only when (and if) you discover a need to expose more, should you expose more. This helps for several reasons.

  • A smaller API is easier to describe, document, and support.
  • A smaller API is easier for people to learn.
  • A smaller API is easier for you to test.
  • Extending a small API is much less onerous on your users than changing or restricting a larger API.

Net::SSH 1.x

Now, I’ve since come to my senses, but at one time I was completely head-over-heels in love with dependency injection. Like any schoolboy crush, it embarrasses me now to think about it, but there’s no denying it. The proof is everywhere in my project history.

Net::SSH, in particular.

At the time, I was looking for a good demonstration of the flexibility and power of dependency injection, and since Net::SSH was another of my pet projects at the time, it seemed like the perfect candidate.

I was still stuck in the “just in case” mindset, though, and Net::SSH 1.x reflected that. Badly. For instance, I isolated all the OpenSSL crypto interfaces into their own module, because “what if someone wanted to plug in a different crypto lib?” Nevermind that there was no other crypto lib for Ruby (and still isn’t, 4 years later). But WHAT IF?!?

Now, separation of concerns and modularity are good things, when used in moderation. But like any design pattern, it becomes evil when taken to extremes. Too much modularity and you wind up with component soup (and I hope you’re hungry, because you’re going to have a lot of it). With lots of tiny components, the interactions between those components can become difficult to test.

It also fuzzes the line between the public, documented API and the internal, private API. When you have two large components, it is very easy to say “A is public, and B is private”, but when you have two hundred components, where do you draw the line? It’s far too easy to let the “public” boundary meander a bit further into “private” territory than it should.

Even worse, when I added dependency injection to the mix, it became very, very difficult to follow the the flow of the program, and to understand the dependencies. Pull up Net::SSH 1.1.4, for instance, and find net/ssh.rb. Just try and figure out how a connection session is instantiated. It’s a mess. Unless you’re familiar with Needle, it’ll probably take you a long time to discover that the actual services are configured in the various services.rb files, but even after you figure that out, you still have to figure out how the different services interrelate. It’s a mess.

But, isn’t that the opposite of what DI is supposed to do? Isn’t DI supposed to improve the maintainability and testability of your code? Yeah. The problem, though, was three-fold.

First, Net::SSH, though complex in its way, was not really complex enough to need a dependency injection framework. DI itself adds complexity, and a framework for doing dependency injection adds even more, so before you go that route you need to be very sure that the trade-off in complexity is worth it. If your project is too small, you’ll actually increase the complexity of your project by adding a framework for doing DI.

Secondly, I was using a DI framework at a level that was really too granular. I was using the framework to wire together everything. No component was too small! No object too insignificant! I was on the dependency injection horse, and riding it for all it was worth. If I’d taken the time to really understand the pattern, though, I would have learned that though the pattern itself may be applied at the micro level, using a framework to do so is like nuking a mosquito—it works, but it leaves a mess behind.

Which leads to the last problem with Net::SSH’s use of Needle: it is really only appropriate for wiring together components of an application. Very, very few (Ruby) libraries will ever be complex enough, in themselves, to justify adding a dependency injection framework to them. Rather, let the application wire the libraries together as (and when) it needs to. Any more granular than that, and you’ll run into the same quagmire I did, I promise you.

Dependency Injection in Ruby

So, is there no room for DI in Ruby? There definitely is. I use DI nearly every day in Ruby, but I do not use a DI framework. Ruby itself has sufficient power to represent any day-to-day DI idioms you need. Consider this one:

1
2
3
4
5
6
7
8
class A
end

class B
  def new_client(with=A)
    with.new
  end
end

Here, B declares a factory method for generating new client objects. Because Ruby lets you declare default values for method arguments, you can let the default client implementation be A, which is the common case. But for testing, you can easily inject a mock into that method by passing an explicit parameter.

For cases where that doesn’t work, you can use a second factory method:

1
2
3
4
5
6
7
8
9
10
11
12
class A
end

class B
  def new_client
    client.new
  end

  def client
    A
  end
end

Then, in your tests, you can subclass B, overriding the client method to return your mock client implementation. It’s dependency injection, Jim, but probably not as you’ve known it.

Hashes, too, are your friend. You can allow optional arguments via hashes to specify implementation classes, defaulting to the standard implementation classes but allowing clients to inject their own implementations where needed:

1
2
3
4
5
6
7
8
9
10
11
12
class A
end

class B
  def initialize(options={})
    @client_impl = options[:client] || A
  end

  def new_client
    @client_impl.new
  end
end

“Loose coupling” and “high cohesion” are terms you’ll hear bandied about in defense of dependency injection, and those traits are certainly desirable. But strike a balance with pragmatism. There will be some who call me heretic for saying this, but don’t be afraid to introduce tighter coupling when it makes sense. Loose coupling everywhere is what I had with Net::SSH 1.x, and the result was nearly unmaintainable.

Be wise. You’re competent. Trust your instincts.

Lessons learned

If you read nothing else from this article, take to heart these bite-sized bullet-points:

  • Direct translations are rarely accurate. Try using the Google translator to translate a paragraph from English, to Italian, to Japanese, and back to English, and you’ll see what I mean. The same is true of programming languages. Each language has it’s own idioms, and trying to take what works well in one language and force it directly into another language is doomed to fail, more often than not.
  • Use your environment efficiently. Try as you might, you’ll never make a ball out of a LEGO brick by rolling it between your hands. You’ll just bloody your palms. Learn what your environment is capable of. Reading other people’s code is a great way to do this.
  • DSL’s, not static configuration. Ruby excels at representing DSL’s. Whenever you can, consider using a DSL instead of static configuration for your applications. You’ll find it will simplify a lot more than it complicates.
  • DI frameworks are unnecessary. In more rigid environments, they have value. In agile environments like Ruby, not so much. The patterns themselves may still be applicable, but beware of falling into the trap of thinking you need a special tool for everything. Ruby is Play-Doh, remember! Let’s keep it that way.
  • Just in time. Not just in case. Don’t play “what if” games when you’re coding. Practice discipline, and implement only what you need, when you need it. You’ll wind up with tighter, more testable code that is easier to maintain in the long run.

Learning to program is a journey, and I’m still learning, myself. I’m not perfect at applying the rules above, but I’ve found that when I do, I’m much happier. I think you will be, too.

Rails Deployment On Heroku Using Git

I was checking out different sites to deploy the Rails apps we presented with Tony at RailsConf for our Powering AIR with Rails tutorial and the easiest and fastest way is still heroku.com. So for the 3rd app, TwitterFriends, I make this little video showing how I deployed the Rails to heroku using the heroku gem and git:


Rails Deployment On Heroku Using Git from daniel wanja on Vimeo.

Note flexonrails.com is still “under constructions” and I am adding stuff for the launch of the book…which is now set to shortly after December 19th. Yea!

#134 Paperclip

Need to add image attachments to a model? See how with paperclip in this episode.