{"id":156,"date":"2010-01-11T23:23:49","date_gmt":"2010-01-11T12:23:49","guid":{"rendered":"http:\/\/christopherowen.id.au\/blog\/?p=156"},"modified":"2019-09-12T08:32:59","modified_gmt":"2019-09-11T22:32:59","slug":"the-happy-toggler","status":"publish","type":"post","link":"https:\/\/christopherowen.au\/blog\/2010\/01\/11\/the-happy-toggler\/","title":{"rendered":"The Happy Toggler"},"content":{"rendered":"<p>I&#8217;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?<\/p>\n<p><!--more--><\/p>\n<p>Say I have an object that likes to transition solely between happy states every time a certain event occurs. Here&#8217;s how I might handle it:<\/p>\n<pre lang=\"java\"> theObject.happy = !theObject.happy;\n<\/pre>\n<p>There. Simple huh? Something you probably learn how to do in an introductory programming course. It might be surprising to you, but someone <a href=\"http:\/\/stackoverflow.com\/questions\/224311\/cleanest-way-to-toggle-a-boolean-variable-in-java\">asked a question on how to do this on Stack Overflow<\/a>. The other alternative provided in the answer is the somewhat more cerebral:<\/p>\n<pre lang=\"java\">theObject.happy ^= true;\n<\/pre>\n<p>Thanks Spock. Of course if your language doesn&#8217;t have an assigning XOR operator this option is ruled out. If you value clarity of code, or you simply don&#8217;t want less brainy maintainers pestering you about what your code is doing, you rule this option out as well.<\/p>\n<p>So I&#8217;ve been writing a lot of code recently of the first form, and it&#8217;s been making me sad. There&#8217;s a strong feeling of non object oriented-ness about it. I mean, to toggle the state of an object I have to:<\/p>\n<ol>\n<li>ask it what its current state is;<\/li>\n<li>flip that state locally;<\/li>\n<li>and then tell the object to take on this new state.<\/li>\n<\/ol>\n<p>Bleh! Why the hell should I care what state it currently is in? I just want to toggle it! Shouldn&#8217;t I just be able to ask the object to toggle it&#8217;s own state; perhaps of even multiple properties in a batch sequence?<\/p>\n<p>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.<\/p>\n<p>One such example of a crude toggling abstraction would be a Ruby module defined like the following.<\/p>\n<pre lang=\"ruby\">module Toggler\n\n  class ToggleHelper\n\n    def initialize(target)\n      @target = target\n    end\n\n    def method_missing(sym)\n      @target.toggle(sym)\n    end\n\n    def toggle; end\n\n  end\n\n  def toggle(*sym)\n    return ToggleHelper.new(self) if sym.empty?\n    \n    sym.each { |s| self.send(\"#{s}=\", !self.send(s)) }\n  end\n\nend\n<\/pre>\n<p>Such a module could be mixed-in at the appropriate levels of an inheritance hierarchy, or maybe even at the root level if you&#8217;re game.<\/p>\n<p>With the mix-in mixed-in, toggling code would be more concise and less repetitious:<\/p>\n<pre lang=\"ruby\">the_object.toggle.happy\nthe_object.toggle(:happy)\nthe_object.toggle(:wanted, :happy, :virtuous)\n<\/pre>\n<p>Doesn&#8217;t a declarative syntax such as this feel much more happy?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So I&#8217;ve been writing a lot of boolean toggling code recently, and it&#8217;s been making me sad. Can&#8217;t we make it happier?<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"","activitypub_status":"","footnotes":""},"categories":[15,19],"tags":[],"class_list":["post-156","post","type-post","status-publish","format-standard","hentry","category-nerd","category-programming"],"_links":{"self":[{"href":"https:\/\/christopherowen.au\/blog\/wp-json\/wp\/v2\/posts\/156","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/christopherowen.au\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/christopherowen.au\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/christopherowen.au\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/christopherowen.au\/blog\/wp-json\/wp\/v2\/comments?post=156"}],"version-history":[{"count":1,"href":"https:\/\/christopherowen.au\/blog\/wp-json\/wp\/v2\/posts\/156\/revisions"}],"predecessor-version":[{"id":316,"href":"https:\/\/christopherowen.au\/blog\/wp-json\/wp\/v2\/posts\/156\/revisions\/316"}],"wp:attachment":[{"href":"https:\/\/christopherowen.au\/blog\/wp-json\/wp\/v2\/media?parent=156"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/christopherowen.au\/blog\/wp-json\/wp\/v2\/categories?post=156"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/christopherowen.au\/blog\/wp-json\/wp\/v2\/tags?post=156"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}