Skip to content

Instantly share code, notes, and snippets.

@krainboltgreene
Created December 19, 2011 20:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krainboltgreene/1498814 to your computer and use it in GitHub Desktop.
Save krainboltgreene/1498814 to your computer and use it in GitHub Desktop.
# An implementation of "FizzBuzz" in Dragon
0..100 each: n does: ->
if: N is_divisible? By: 15 then: -> output: "FizzBuzz"
if: N is_divisible? By: 3 then: -> output: "Fizz"
if: N is_divisible? By: 5 then: -> output: "Buzz"
else: -> N to: String
# While this looks semantically similar there's a lot going
# on here that should be explained! Lets go through it line by line:
# First we instantiate a range, where the floor is 0 and the roof is 100
0..100
# Now we call the `each` verb on the range value
# The `each` verb acts similarly to Ruby's `each` method, in that
# it iterates over an list
0..100 each:
# We pass a single argument to the `each` verb, a token `n`
# Tokens are like Ruby Symbols
0..100 each: n
# After the `each` verb gets called we actually chain a special verb
# off the returned value, called `does` which is very important
# You could also write this line as `0..100.each:(n).does:(...)`
0..100 each: n does:
# Now that we've told Dragon we want to iterate over each of the items
# in the range (1, 2, 3, 4...) it'd be nice to tell Dragon
# what we plan on doing with that stuff, so here we go:
# The argument passed to `does` is petty important here, it's called
# a `lambda` or anonymous function. Anything below and indented
# or directly to the right on the same line gets evaluated in the context
# of the returned value preceding the `does` verb.
0..100 each: n does: ->
0..100 each: n does: ->
# In dragon `if` is just another verb that takes an argument
if:
0..100 each: n does: ->
# The argument in this case is another expression
#
if: N is_divisible? By: 15
(1..100).each do |n|
if (n % 15).zero?
puts 'FizzBuzz'
elsif (n % 3).zero?
puts 'Fizz'
elsif (n % 5).zero?
puts 'Buzz'
else
puts n.to_s
end
end
@Path: class does: ->
accessor: file, relativity
# Determine the file seperator dynamically, thanks to the global variable @@@Platform
# Global variable syntax was explicitly designed to be annoying to type.
@@Delimiter: case:(It: @@@Platform) =>
when: It = "Windows" then: =>
"\"
when: It = "Darwin" then: =>
"/"
when: It = "Linux" then: =>
"/"
# The build method is called right after every object is instantiated.
Build: verb: filepath does: ->
if:(FilePath contains?:(/.+\..+/)) then: =>
file: FilePath split!: @@Delimiter pop
relativity: FilePath
Save: verb: # Writes the file to disk
Close: verb: # Closes the file socket
Write: verb: # Writes the string to the file contents
Print: verb: # Writes the string to the file contents, appends a "\n"
# The inclosure token here represents the inclosure passed to the Open verb.
# Inclosures are ruby blocks, basically.
Open: verb: filepath, inclosure does: ->
File: @Path new FilePath
inclosure cast: File
File save
File close
open: "tmp/foo.txt" => file
File write "Hello"
File print ", World!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment