Skip to content

Instantly share code, notes, and snippets.

@gwang
Last active August 29, 2015 14:28
Show Gist options
  • Select an option

  • Save gwang/a97cbf9061d52d84ab39 to your computer and use it in GitHub Desktop.

Select an option

Save gwang/a97cbf9061d52d84ab39 to your computer and use it in GitHub Desktop.
Fantom metaprogramming example
/**
* Created by gwang2 on 8/24/2015.
* The code was based on the book "The ThoughWorks Anthology 2" with a minor bug fix. (see comments below)
*/
class XmlBuilder {
Str content
Int indent
new make() { this.content = ""; this.indent = 0}
/* have to give args a default value with matching type otherwise the compiler complains
* "Parameter 'args' must have default to match overridden method ERROR: cannot compile script"
*/
override Obj? trap(Str name, Obj?[]? args :=[,]) {
this.content += "${doIndent()}<$name>\n"
this.indent += 1
if (args != null && args.size > 0) {
if (args[0] is Func) {
((Func)args[0])(this)
} else {
this.content += doIndent()
this.content += args[0]
this.content += "\n"
}
}
this.indent -= 1
this.content += "${doIndent()}</$name>\n"
return this.content
}
Str doIndent() {
Str.spaces(this.indent*2)
}
}
class Main
{
static Void main() {
x := XmlBuilder()
x->html {
x->title("Done in Fantom")
x->body {
x->h1("Hello, world!")
}
}
echo(x.content)
}
}
require 'builder'
xml = Builder::XmlMarkup.new(:indent=>2)
puts xml.html {
xml.title 'done in ruby'
xml.body {
xml.h1 'Hello World!'
}
}
# 'puts xml' seems to not work, rather use 'puts xml.target!'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment