F3/swiby style declaration blocks
swiby is a proof of concept framework inspired by F3. Both use a hierarchical block format for defining Java/Swing visual elements. eg:
Frame {
title "Hello World F3"
width 200
content {
Label {
text bind(model, :saying)
}
}
visible true
}
I was looking through the documentation, and got curious as to how the class level block declaration is actually implemented in swiby. After a bit of digging around, it is relatively straight forward.
There is some code in swiby that looks kinda like this:
def component_factory(class_name)
eval %{
def #{class_name}(&block)
x = #{class_name}.new
x.instance_eval(&block)
x
end
}
end
I’ve removed the error handling and some extra functionality, but the basic idea is the same. component_factory is called for each class that is required to be instantiated as a declared block. Here’s an example:
class Foo
end
class Bar
end
component_factory :Foo
component_factory :Bar
my_foo = Foo {
@my_bar = Bar {
@baz = 'baz'
}
}
puts my_foo.inspect
Which outputs:
#<Foo:0x60544 @my_bar=#<Bar:0x604e0 @baz="baz">>
A Foo instance has been created containing a Bar instance, with a variable of baz. This sort of syntax could be useful for DSL implemented in Ruby.
One limitation I ran into, is that calling attr_accessor methods don’t get recognized (they just get defined as local variables that go out of scope at the end of the block) - but that may just be a limitation of useing instance_eval to set the newly created object as the object in scope as self.