Type Casing is the act of using case statements
in a program to determine what to do with an object based on what type of object it is. It's an OO fail, often
hoping to implement
Multiple Dispatch. (See also
Case Statements Considered Harmful)
Here are three passive-aggressive ways to feel like you're getting back at typecasers.
The first tactic turns your object into an
everything, so it's whatever the typecaser was looking for. I've called it
OmniObject
.
module OmniObject
def is_a?(*)
true
end
def kind_of?(*)
true
end
def nil?
true
end
end
foo = "hello, world!"
foo.extend OmniObject
puts "Is foo a Fixnum? #{foo.is_a?(Fixnum) ? 'yes' : 'no'}"
puts "Is foo a Kernel? #{foo.is_a?(Kernel) ? 'yes' : 'no'}"
puts "Is foo a NilClass? #{foo.kind_of?(NilClass) ? 'yes' : 'no'}"
puts "foo.nil? => #{foo.nil?}"
The next one makes your object unable to decide what it is, turning it into a
FickleTeenager
. If he has to check more than once,
the typecaser is going to have a tough time with a kid who can't make up his mind.
module FickleTeenager
def is_a?(*)
sorta
end
def kind_of?(*)
sorta
end
def nil?
sorta
end
def sorta
truish
end
def truish
rand < 0.5
end
end
foo = "hello, world!"
foo.extend FickleTeenager
3.times{ puts "Is foo a String? #{foo.kind_of?(String) ? 'yes' : 'no'}"}
Finally, we have the
AntisocialPrivacyAdvocate
. When the typecaser asks him what he is, he tells them like it is: It's none of your damn business!
class WhatBusinessOfItIsYoursError < StandardError; end;
module AntisocialPrivacyAdvocate
def is_a?(*)
raise WhatBusinessOfItIsYoursError
end
def kind_of?(*)
is_a?
end
def nil?
is_a?(NilClass)
end
end
foo = "hello, world!"
foo.extend AntisocialPrivacyAdvocate
result = foo.kind_of?(String) rescue "#{$!} OMG, How Rude!"
puts result
Hey! Why don't you make your life easier and subscribe to the full post
or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate
wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!
Leave a comment
Good stuff -- I literally laughed out loud (as opposed to just LOL). I do believe my favorite is the fickle teenager, but the antisocial module might actually be productive
Posted by
Jesse Wolgamott
on Dec 21, 2011 at 09:02 AM UTC - 6 hrs
Thanks!
I kind of like seeing a program halt and print out a stack trace that looks like this:
whatbusiness.rb:25:in `is_a?': WhatBusinessOfItIsYoursError (WhatBusinessOfItIsYoursError)
from whatbusiness.rb:29:in `kind_of?'
from whatbusiness.rb:39:in `<main>'
Of course I suppose you could rescue WhatBusinessOfItIsYoursError, extend OmniObject and retry. =)
Or if you really wanted to get fancy: rescue, find 3rd method in the stack trace, and rewrite it on the fly.
Posted by
Sammy Larbi
on Dec 21, 2011 at 09:54 AM UTC - 6 hrs
Thanks Rick, great name for it!
Posted by
Sammy Larbi
on Jan 09, 2012 at 12:14 PM UTC - 6 hrs
Leave a comment