I’ve been writing a lot of UI code lately, and one of the bread-and-butter operations in UI code is toggling boolean state, usually in response to a button press. Now, what does toggling code look like?
Say I have an object that likes to transition solely between happy states every time a certain event occurs. Here’s how I might handle it:
theObject.happy = !theObject.happy;
There. Simple huh? Something you probably learn how to do in an introductory programming course. It might be surprising to you, but someone asked a question on how to do this on Stack Overflow. The other alternative provided in the answer is the somewhat more cerebral:
theObject.happy ^= true;
Thanks Spock. Of course if your language doesn’t have an assigning XOR operator this option is ruled out. If you value clarity of code, or you simply don’t want less brainy maintainers pestering you about what your code is doing, you rule this option out as well.
So I’ve been writing a lot of code recently of the first form, and it’s been making me sad. There’s a strong feeling of non object oriented-ness about it. I mean, to toggle the state of an object I have to:
- ask it what its current state is;
- flip that state locally;
- and then tell the object to take on this new state.
Bleh! Why the hell should I care what state it currently is in? I just want to toggle it! Shouldn’t I just be able to ask the object to toggle it’s own state; perhaps of even multiple properties in a batch sequence?
Naturally, nobody wants to write a toggling method for every writable boolean property of their objects. So either there needs to be automatic support in the platform or some ability to provide a general toggling abstraction.
One such example of a crude toggling abstraction would be a Ruby module defined like the following.
module Toggler
class ToggleHelper
def initialize(target)
@target = target
end
def method_missing(sym)
@target.toggle(sym)
end
def toggle; end
end
def toggle(*sym)
return ToggleHelper.new(self) if sym.empty?
sym.each { |s| self.send("#{s}=", !self.send(s)) }
end
end
Such a module could be mixed-in at the appropriate levels of an inheritance hierarchy, or maybe even at the root level if you’re game.
With the mix-in mixed-in, toggling code would be more concise and less repetitious:
the_object.toggle.happy
the_object.toggle(:happy)
the_object.toggle(:wanted, :happy, :virtuous)
Doesn’t a declarative syntax such as this feel much more happy?
Leave a Reply