So here is the new Buzz plan... for each Buzz I will revisit a language introduced in a previous Fizz entry, and re-work a number entry not in that language using some of the unique features of the language. For this first entry the selection is limited, but actually relevant to the current numeric theme, especially since Groovy has so many ways to do repitition.
100 times { int i = it+1 if ((i % 3 == 0) && (i % 5 == 0)) { println "FizzBuzz" } else if (i % 3 == 0) { println "Fizz" } else if (i % 5 == 0) { println "Buzz" } else { println i } }
Lines one and two are the focus for this post, because the rest of it is a simple transliteration to standard Groovy.
On first reading, it does what it says. Repeat the enclosed block 100 times. But in the syntax sugar and details of the API are some common assumptions. First, what the current count is matters, but there is no explicit variable for that. Each closure without an argument block gets a single variable
it
that you don't need to declare and just exists. Kind of like this
in methods. (And when is some programming language going to introduce that
?)The next assumption is what number to count from. You would think that counting from 1 would be sensible. But Groovy uses zero based arrays, like nearly all popular languages, so instead it starts all couting from zero. Line 2 is an optimization so we don't have to extend our math into the rest of the method.
The rest is pure syntactic sugar. When a symbol that could be a method trails an object with no punctuation it is presumed to be a method call in Groovy. And when a single closure follows a method call, whether or not it is in the argument list, it is added to the argument list of the method. The integer 100 is boxed up to a
java.lang.Integer
class. And via the Meta-Object-Protocol we can graft in a random times
method onto the Ingeger
class even though it doesn't exist in the plain JDK. The end result is something that looks a little bit more like a spoken sentence, but not too close.
No comments:
Post a Comment