Tuesday, July 25, 2006

Ruby, the Consummate Delegator - Part 2

Back in June, I posted about using Ruby's method_missing for simplified delegation.

Well, I might have known Ruby would have even more options for handling delegation.

The following achieves the same result without having to implement method_missing. DelegateClass implements method_missing for you, along with some other conveniences.
require 'delegate'

class CardDeck < DelegateClass(ShuffleArray)
def initialize(cards)
I suppose the downside here is that we are back to using inheritance, even though we're delegating to ShuffleArray, and we wanted to avoid that since we thought CardDeck was going to evolve a bit more.

Now if we wanted to selectively delegate certain methods to certain objects, we could instead extend our class with Forwardable. Here we avoid inheritance at the expense of some repetition as we'd have to call def_delegators for each method that we want to expose from ShuffleArray.
require 'forwardable'

class CardDeck
extend Forwardable

def initialize(cards)
@cards = ShuffleArray.new(cards)

def_delegators :@cards, :shuffle, :size,
:[], :find,
:reverse, :each,
This might be a better approach as we've left CardDeck open for later inheritance and we can now delegate to other composed objects in the future. Though we could still do that with method_missing with just an extra if block, so I'm not sure how much we've gained here.

For one thing we're somewhat back to writing those pesky delegation methods that we hoped to avoid in the first place. def_delegators certainly makes it a bit easier than doing the same thing in say C# or Java, and I suppose we shouldn't be too lazy. But we also could forget to pass in some methods and if Array or ShuffleArray gets redefined at runtime, then we won't delegate to them like we would with method_missing.

I'll grant you this whole CardDeck example is a bit contrived and if I thought about it a bit more I could probably come up some better examples of when to use these different approaches "in the real world."

For example, Forwardable could be useful for writing an adapter for a class that needs to conform to the same interface as another, or for building a façade to expose a subset of a delegate's interface.

I'd certainly be interested in hearing about how others have used these nifty features in Ruby.

Saturday, July 22, 2006

Please ditch your gas guzzler

I love it. I saw this great Greenpeace ad referenced from grist.org (a great site by the way).

This is what makes me see Seattle as a whole so hypocritical. Everyone thinks they are so environmentally conscious, but there are bloody SUVs EVERYWHERE!

The thing that really makes we want to scream is when I see a sticker on the back of one these things that says "Support our troops." If you really support our troops, then why don't you put your wallet where your mouth is and drive a responsible vehicle that doesn't require an expansionist foreign policy that kills for oil? Why don't you elect a government that would work toward alternative energy solutions and invest in companies that are researching those technologies?

Wake up, America.

Thursday, July 20, 2006

There's A Preferred Way To Do It - But Go Ahead If You Need To

I finally got around to watching DHH's keynote address at RailsConf 2006. It's good to listen to it while flipping
the slide deck.

David made a good point about Ruby's and Rail's opinionated nature. While they are opinionated, they aren't draconian; they allow for flexibility outside of convention if that's what you need.

The example he gives is Ruby's ability to call private methods externally. By convention you can't break that encapsulation and Ruby's nature is to discourage it and push you to do the right thing. BUT if you feel for some reason you absolutely must - perhaps you are doing some meta-programming or reflection - Ruby makes it possible and easy to do. The responsibility is ultimately left to the developer.

He also talks about how he's working on leveraging the HTTP protocol's built-in strengths by using POST, GET, PUT, and DELETE to map to CRUD operations and using models to simplify and encapsulate relationships while keeping controllers simpler with fewer actions. Rails also will be extending support for HTTP's accept header to return the desired formats from the same controller methods without having to repeat yourself for different content types like XML, JavaScript and RJS templates, icl, atom, rss, etc. And he's bringing in the recognition of file extensions to define content types if you aren't sending in the accept header.

The new ActiveResource will be provide way of building APIs and mapping models, represented as Structs, to RESTful services much like ActiveRecord does with models and CRUD operations. A slick approach, providing a proxy to the REST service - simpler than a .NET generated proxy from a WSDL on top of SOAP and it's all done at runtime. Even nicer, both ActiveRecord and ActiveModel will descend from ActiveModel, enabling you to create subclasses for things like ActiveLDAP, ActiveSOAP and ActiveFileSystem, etc. and reuse the shared concerns such as model validations. He hasn't quite thought through associations between resources and database models. ActiveResource will be available as a separate gem.

DHH is truly a master of abstraction.

My favorite quote:
"Doing things by hand is another one of those constraints. If you have the initial assumption that things should be able to be done by hand without leaving you crying, it leads to better designs. And I think that is Ruby in general. At lot of Java people are crying "We need our IDEs!" Yeah, you do need your IDE in Java. You'd be insane to write Java without an IDE."

irb(main):003:0> class Foo
irb(main):004:1> private
irb(main):005:1> def bar
irb(main):006:2> puts "baz"
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):09:0> foo = Foo.new
=> #<Foo:0x2c4acc0>
irb(main):010:0> foo.bar
NoMethodError: private method `bar' called for #<Foo:0x2c4acc0>
from (irb):12
irb(main):011:0> foo.send(:bar)

EUReKA sets new SCIFI ratings record

To all those who watched my brother Andrew's new series EUReKA on the SCIFI channel, thanks for helping the show set a new record with over 4 million viewers.
"(Broadcasting & Cable) _ Sci Fi Channel's premiere of Eureka ranked as the network's highest-rated series telecast ever with a 3.2 household rating and more than 4 million total viewers, according to Nielsen Media Research. The two-hour premiere of the series, about an unknown U.S. town of geniuses, ran at 9 p.m. Tuesday night (July 18)."
-- Anne Becker

If you didn't get a chance to see it, Sci Fi is broadcasting the pilot episode in its entirety on their site.

If you have any feedback about the show, post it here and I'll see that it gets back to my brother. Hopefully I can convince him to start blogging about the show.

UPDATE: Check out the season promo below. And Sci Fi is running a "Made in Eureka" promo sweepstakes where you can win a
Sony HDTV and BluRay player.

Wednesday, July 19, 2006

Saving the planet, one gallon at a time

The green machine has gone green. Finally got around to converting my Jetta TDI to biodiesel the other day.

Filled the tank with some golden natural goodness, courtesy of our local supplier, Quality Auto Service. They apparently don't have a web site, but if you drive a diesel and live on the island or commute via the ferry, they are conveniently located. If you have any questions, give 'em a call @ 206-780-8088.

If you live somewhere else, check out this nifty biodiesel mashup with Google maps to find a location near you.

So what was involved with conversion? Well, I pulled up to the station, the friendly attendant opened the fuel cap, and stuck in the nozzle. Voila! And full service, no less.

The cost was $3.40/gal which is a bit more than the going price of regular diesel on the island, but seems like a small price to pay for decoupling my car from the war for oil, investing in our country's own economy, and helping to keep the air and water cleaner because biodiesel has lower emissions. And since the Jetta gets about 40 city and 45 freeway, and I drive very little, the hit to the wallet should be marginal.

I haven't driven much since the 'conversion,' but so far I haven't noticed any decrease in power and I swear the engine runs more quietly.

I spoke to my own mechanic and several owners who have made the switch before making the conversion, which I would definitely recommend. Also check with your auto manufacturer, especially if your car is still under warranty. For example, Volkswagen officially approves a B5 grade (5% biodiesel) for TDI engines and it might void your warranty if you use anything with a higher percentage. My car is past its warranty, so that wasn't a concern.

It's likely that I will have to change the fuel filter (and prefilter if there is one) after a couple of tanks; since biodiesel runs much cleaner than regular diesel, there will be lots of dislodged crud. A buddy of mine who has also made the switch with his Mercedes told me that in a couple of years, I might need to replace the fuel lines.

For more info, check out GreaseWorks and NBB.

Friday, July 14, 2006

EUReKA, my bro's new TV show, premieres next week

My brother’s new TV series starts on the SCIFI channel next week, Tues, July 18 @ 9/8C. Tell your family and friends!


And yes, that is the Brother from Another Planet and Max Headroom in the cast. The 80’s are making a comeback!

Sunday, July 02, 2006

TextMate Withdrawal; jEdit to the Rescue

Since my powerbook crapped out on me (long story to be continued), I've been going through TextMate/MacOS withdrawal. But thanks to some nifty plug-ins for jEdit, and some very helpful tutorials, I'm finding a workable interim 'fix' on Windows and Ubuntu.

In fact, there are some nice features like pop-up code-completion with context sensitive rdoc (including Rails docs) that I'd like to see in TextMate.

If you're on Windows or *nix - or you don't have the moolah for TM - then it might be worth a look.
Drop me a comment if you know of any other useful tips or plug-ins for jEdit. I'm not too happy with the default syntax color scheme.

Full screenshot of jEdit and context sensitive rdoc (click for full view)

link to jedit screenshot

I'm having a few problems getting some things to work. Please let me know if you know how to:
  • run script/console or irb inside the Console. It just sits and spins when I run anything that takes input.
  • hook up to Subversion.
  • get tabbed views for file buffers instead of the buffer dropdown.
    [I got this working with the BufferTabs plug-in]
  • get class and method folding to work.
    [This just required setting Utilities > Global Options > Editing > Folding Mode to Sidekick]