With Statement
A common pattern involving the creation of an object is calling a series of functions and setting a series of properties immediately after creating it.
This results in repeating the name of the object multiple times in code, adding unnecessary noise. A common solution to this is to pass a table in as an argument which contains a collection of keys and values to overwrite. The downside to this is that the constructor of this object must support this form.
The with block helps to alleviate this. Within a with block we can use a special statements that begin with either . or \ which represent those operations applied to the object we are using with on.
For example, we work with a newly created object:
MoonScript:
with Person!
.name = "Oswald"
\add_relative my_dad
\save!
print .name
Lua:
do
local _with_0 = Person()
_with_0.name = "Oswald"
_with_0:add_relative(my_dad)
_with_0:save()
print(_with_0.name)
end
The with statement can also be used as an expression which returns the value it has been giving access to.
MoonScript:
file = with File "favorite_foods.txt"
\set_encoding "utf8"
Lua:
local file
do
local _with_0 = File("favorite_foods.txt")
_with_0:set_encoding("utf8")
file = _with_0
end
Or…
MoonScript:
create_person = (name, relatives) ->
with Person!
.name = name
\add_relative relative for relative in *relatives
me = create_person "Leaf", {dad, mother, sister}
Lua:
local create_person
create_person = function(name, relatives)
do
local _with_0 = Person()
_with_0.name = name
for _index_0 = 1, #relatives do
local relative = relatives[_index_0]
_with_0:add_relative(relative)
end
return _with_0
end
end
local me = create_person("Leaf", {
dad,
mother,
sister
})
In this usage, with can be seen as a special form of the K combinator.
The expression in the with statement can also be an assignment, if you want to give a name to the expression.
MoonScript:
with str = "Hello"
print "original:", str
print "upper:", \upper!
Lua:
do
local str = "Hello"
print("original:", str)
print("upper:", str:upper())
end