Thursday, June 29, 2006

Eureka, "Small Town, Big Secrets"

My brother Andrew's new TV series EUReKA premieres July 18 @ 9/8C on the SCIFI channel.

Think 'Twin Peaks' meets 'Mayberry RFD'.

Don't miss it! Tell your friends. If you're a SCIFI geek, tell your enemies too.

Dreadful Ed


Dreadful Ed is a new children’s book written by my talented kid brother Andrew. I read it to my daughter last night. Published by DarkHorse comics, it’s a sweet story about a little boy who thinks he doesn't quite meet with his father’s or schoolmates’ approval and expectations.

(Oh, btw: Ed’s family and school chums are spooky monsters! Perhaps my brother is working out some childhood issues here...)

My daughter really enjoyed the story and the creepy artwork. It’s not a scary story by any means, but afterwards she didn’t want to go to sleep with the book in the same room. ;)

From the back cover:

"It's a little known fact among those in the know
that on one night each year when the howling winds blow
if you stay up past bedtime 'til thirteen past three
there's a place not like this place you're likely to see."

"Welcome to Nocturnia, home to nightmares, monsters, and one little misfit named Edgar Grimm. Like most kids, Ed would love to make his parents proud. For Ed that means following in the big, frightful footprints of his dad, who just happens to be the Bogeyman! Unfortunately, unlike his famous father, Ed's not very scary. You see, Ed isn't like the other monsters his age. In fact, he isn't a monster at all... but that won't stop him from trying to prove that even a good little boy can find a place among the biggest, baddest monsters there are."

Saturday, June 24, 2006

Ruby, the Consummate Delegator

Maybe one of the reasons inheritance is so overused in certain static languages like Java and C# is that it can be a pain in the ass to write those tiny methods that hand off operations to the delegate class.

Ruby, on the other hand, makes it a no-brainer with the method_missing callback.

Here a ShuffleArray extends Array to add some shuffling behavior. Since a ShuffleArray's relationship to Array is an "is a" relationship, that seems a valid use of inheritance.

But a CardDeck is much more than a ShuffleArray - or will be anyway as it will provide more behavior in the future - and its relationship to ShuffleArray is more of a "uses a" association. Still I'd like CardDeck to be able to make use of all the nifty methods and properties of a ShuffleArray, and I'd like to do that without having to write all those methods to pass through from CardDeck to ShuffleArray.

To do that CardDeck uses Ruby's method_missing callback to delegate any messages other than its own to the ShuffleArray that it composes. This way CardDeck gets the same behaviors and properties of a ShuffleArray (and Array by extension) without having to subclass ShuffleArray and without having to explicitly define those pass-through delegate methods.

Each class is very small, cohesive, and extensible.

class ShuffleArray < Array
def shuffle
sort_by { rand }
end
end

class CardDeck
alias :method_missing_orig :method_missing
def initialize(cards)
@cards = ShuffleArray.new(cards)
end
def method_missing(m, *args, &block)
if @cards.respond_to?(m)
@cards.send(m, *args, &block)
else
method_missing_orig(m, *args, &block)
# or you could just raise the exception or return nil
# raise NoMethodError
end
end
end

class Card
attr_reader :face, :suit
def initialize(face, suit)
@face, @suit = face, suit
end
def to_s
puts "#{face} of #{suit}"
end
end

aos = Card.new("Ace", "Spades")
kod = Card.new("King", "Diamonds")
qoh = Card.new("Queen", "Hearts")
joc = Card.new("Jack", "Clubs")

cards = [aos, kod, qoh, joc]
card_deck = CardDeck.new(cards)

irb(main):041:0> puts card_deck.size
4
=> nil
irb(main):042:0> card_deck.each {|card| puts card }
Ace of Spades
#<Card:0x2c1d510>
King of Diamonds
#<Card:0x2c19820>
Queen of Hearts
#<Card:0x2c15c08>
Jack of Clubs
#<Card:0x2c12170>
=> [#<Card:0x2c1d510 @suit="Spades", @face="Ace">,
#<Card:0x2c19820 @suit="Diamonds", @face="King">,
#<Card:0x2c15c08 @suit="Hearts", @face="Queen">,
#<Card:0x2c12170 @suit="Clubs", @face="Jack">]

irb(main):043:0> puts card_deck[3]
Jack of Clubs
#<Card:0x2c12170>
=> nil

irb(main):044:0> cards_shuffled = card_deck.shuffle
=> [#<Card:0x2c15c08 @suit="Hearts", @face="Queen">,
#<Card:0x2c1d510 @suit="Spades", @face="Ace">,
#<Card:0x2c19820 @suit="Diamonds", @face="King">,
#<Card:0x2c12170 @suit="Clubs", @face="Jack">]

irb(main):046:0> cards_shuffled = card_deck.shuffle
=> [#<Card:0x2c12170 @suit="Clubs", @face="Jack">,
#<Card:0x2c15c08 @suit="Hearts", @face="Queen">,
#<Card:0x2c1d510 @suit="Spades", @face="Ace">,
#<Card:0x2c19820 @suit="Diamonds", @face="King">]

irb(main):050:0> cards_shuffled = card_deck.shuffle
=> [#<Card:0x2c1d510 @suit="Spades", @face="Ace">,
#<Card:0x2c12170 @suit="Clubs", @face="Jack">,
#<Card:0x2c19820 @suit="Diamonds", @face="King">,
#<Card:0x2c5c08 @suit="Hearts", @face="Queen">]

irb(main):051:0> card_deck.find {|c| c.face == "Ace" }
=> #<Card:0x2c1d510 @suit="Spades", @face="Ace">

irb(main):052:0> card_deck.reverse
=> [#<Card:0x2c12170 @suit="Clubs", @face="Jack">,
#<Card:0x2c15c08 @suit="Hearts", @face="Queen">,
#<Card:0x2c19820 @suit="Diamonds", @face="King">,
#<Card:0x2c1d510 @suit="Spades", @face="Ace">]

irb(main):053:0> card_deck.sort_by { |c| c.suit }
=> [#<Card:0x2c12170 @suit="Clubs", @face="Jack">,
#<Card:0x2c19820 @suit="Diamonds", @face="King">,
#<Card:0x2c15c08 @suit="Hearts", @face="Queen">,
#<Card:0x2c1d510 @suit="Spades", @face="Ace">]

Other approaches might include adding the shuffle behavior to the core Array class itself, but changing core class behavior might get you in trouble with other core or imported classes.

UPDATE: Thanks to Roy and Rick for getting me to think about this a bit more. Earlier I was needlessly delegating shuffle behavior from ShuffleArray to Array with the overhead of an extra call to method_missing.