Example: Your own 'if'

Brat comes with three built-in conditionals: true?, false?, and null?. Of course, only true? or false? are necessary (anything else could be derived from one or the other). They correspond to if and unless in Ruby. I am afraid there is no real justification for not using if and unless other than simple rebellion.

In any case, let’s say one did wanted a more traditional if...then...else structure. How might that be achieved in Brat? Maybe like this:

if = { condition, options = [:] |
  then = true? options.key?(:then)
    { options[:then] }
    { false }

  else = true? options.key?(:else)
    { options[:else] }
    { true }

  true? condition
    { then }
    { else }
}

What’s going on here? First, we are defining a method named if which has one required parameter (the condition) and a second parameter which defaults to an empty hash table.

Inside the method, we first check if the options hash has values for :then and :else. If they do, we save that value. Otherwise, we use true and false for defaults.

Next we use the built-in true? method to actually test the condition. If it is true, we want to return the value of then. Otherwise, we return the value of else. If either of those values is a function, then it is the return value of the function that is returned.

You can use it like this:

if "cats" > "dogs" then: { p "Cats rule, dogs drool" } else: { p "Woof, woof!" }

But Brat’s syntax, especially for method arguments, is pretty flexible. So you could use it this way, too:

p if 1 < 2
  then:
    "Yes, one is less than two"
  else:
    "This makes no sense"

Both of these examples are taking advantage of Brat’s syntax to make our new if seem natural. The “naked” hash syntax will gather all key : value pairs into a single hash table and pass it in as the final arguments. The key: value syntax (note the missing space) makes key into a string automatically. Because we are careful about our condition and hash values, we can omit any commas (passing in functions also helps this). Because the “naked” hash syntax can only be used for method arguments, we can throw in some line breaks.

We can also use it in a completely awkward way:

p if({ random > 0.5 }, ["then" : "heads", "else" : "tails"])

Of course, we do not have to specify a then and else value. We can do one, the other, or neither.

comments by Disqus
Fork me on GitHub