Skip to content

Instantly share code, notes, and snippets.

@agladysh
Created December 6, 2009 01:39
Show Gist options
  • Save agladysh/249973 to your computer and use it in GitHub Desktop.
Save agladysh/249973 to your computer and use it in GitHub Desktop.
Example to Article on Lua Declarative Programming
local function build_message_box_imperative(gui_builder)
local my_dialog = gui_builder:dialog()
my_dialog:set_title("Message Box")
local my_label = gui_builder:label()
my_label:set_font_size(20)
my_label:set_text("Hello, world!")
my_dialog:add(my_label)
local my_button = gui_builder:button()
my_button:set_title("OK")
my_dialog:add(my_button)
return my_dialog
end
--------------------------------------------------------------------------------
local function declarative_method(method)
return function(self, name)
return function(data)
return method(self, name, data)
end
end
end
--------------------------------------------------------------------------------
local gui = { }
gui.dialog = declarative_method(function(self, title, element_list)
return function(gui_builder)
local my_dialog = gui_builder:dialog()
my_dialog:set_title(title)
for i = 1, #element_list do
my_dialog:add(
element_list[i](gui_builder)
)
end
return my_dialog
end
end)
gui.label = declarative_method(function(self, text, parameters)
return function(gui_builder)
local my_label = gui_builder:label()
my_label:set_text(text)
if parameters.font_size then
my_label:set_font_size(parameters.font_size)
end
return my_label
end
end)
gui.button = declarative_method(function(self, title, parameters)
return function(gui_builder)
local my_button = gui_builder:button()
my_button:set_title(title)
-- Our button doesn't have any parameters somehow. :-)
return my_button
end
end)
--------------------------------------------------------------------------------
local build_message_box_declarative = gui:dialog "Message Box"
{
gui:label "Hello, world!" { font_size = 20 };
gui:button "OK" { };
}
--------------------------------------------------------------------------------
local gui_builder = { }
function gui_builder:dialog()
local dialog = { }
function dialog:set_title(title)
self.title_ = title
end
function dialog:add(gui_element)
self[#self + 1] = gui_element
end
function dialog:dump()
local dump =
"dialog { "
.. "title = " .. ("%q"):format(self.title_ or "(no_title)") .. "; "
for i = 1, #self do
dump = dump .. self[i]:dump()
end
dump = dump
.. "}; "
return dump
end
return dialog
end
function gui_builder:label()
local label = { }
function label:set_text(text)
self.text_ = text
end
function label:set_font_size(font_size)
self.font_size_ = font_size
end
function label:dump()
return "label { "
.. "font_size = " .. (self.font_size_ or 10) .. "; "
.. "text = " .. ("%q"):format(self.text_ or "(no_text)") .. "; "
.. "}; "
end
return label
end
function gui_builder:button()
local button = { }
function button:set_title(title)
self.title_ = title
end
function button:dump()
return "button { "
.. "title = " .. ("%q"):format(self.title_ or "(no_title)") .. "; "
.. "}; "
end
return button
end
--------------------------------------------------------------------------------
local EXPECTED =
'dialog { '
.. 'title = "Message Box"; '
.. 'label { font_size = 20; text = "Hello, world!"; }; '
.. 'button { title = "OK"; }; '
.. '}; '
print("EXPECTED")
print(EXPECTED)
print("IMPERATIVE")
print(build_message_box_imperative(gui_builder):dump())
print("DECLARATIVE")
print(build_message_box_declarative(gui_builder):dump())
assert(build_message_box_imperative(gui_builder):dump() == EXPECTED)
assert(build_message_box_declarative(gui_builder):dump() == EXPECTED)
print("OK")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment