Evil: knowing when a method got passed the default value
Let’s say you’re crazy. Now, as a crazy person, you might have a method like this:
def greet_world(salutation=”Hello“) “#{salutation} World!“ end
You’re not so crazy that you can’t write working Ruby code. Anyway, it’s totally useful:
greet_world # => “Hello World!” greet_world(’Hi‘) # => “Hi World!” greet_world(’Yo‘) # => “Yo World!” greet_world(’Hola‘) # => “Hola World!”
But then you see someone do this:
greet_world(’Hello‘) # => “Hello World!”
And it drives you even crazier. Being totally crazy, you feel a compulsion to make fun of people who pass the default value for an argument of a method. But how in the world can you tell?
Well, it turns out (and you probably know this already) that the argument list of a method is a proper venue for executing code. You know this because you’ve seen this a thousand times: def something(time=Time.now). That Time.now happens when you call the method without that optional argument. It doesn’t happen when Ruby first parses the method and adds it to the method table for the class. That wouldn’t be too helpful.
So… you can execute arbitrary code in the method argument list. But what kind? What’s the scope? Well, anything you can do in a method body is fair game (and anything you can’t is not). You can’t define a class, for instance. And the scope? The method body itself.
You’re crazy, remember? But not so crazy that you don’t remember that every statement has a return value. Like assignment. Assignment returns a value. And you’ve got a place in the argument list that’s scoped with the method body. And you’ve got a deep desire to mock people who pass default values.
BOOM!
def greet_world(salutation=(salutation_not_given=’Hello‘)) if salutation == ‘Hello‘ and not salutation_not_given “YOU HAVE NO IMAGINATION!“ else “#{salutation} World!“ end end greet_world(’Hello‘) # => “YOU HAVE NO IMAGINATION!” greet_world # => “Hello World!” greet_world(’Hi‘) # => “Hi World!”
salutation_not_given is nil if you’ve given a value. It’s one of those things.
ANYWAY. Use that at your own peril.