Tutorials:Lua:ObjectOriented
Calling Notation
The first thing to understand is that you can create functions on your tables. Think of a simple table for a rectangle with a length and width and a function that calculates the area. You can go ahead and run this script in CE (go to Memory Viewer and hit `CTRL+L` to open the Lua Engine)
local rect = { length = 7, width = 9 } function calculateArea(tbl) return tbl.length * tbl.width end print('Width: '..tostring(calculateArea(rect)))
Let's look at creating the function *on the table*. This helps avoid naming
collisions and keeps the global namespace clean. Here's an example up front
showing how that works:
local rect = { length = 7, width = 9 } function rect.calculateArea(tbl) -- `.` specifies object as argument return tbl.length * tbl.width end function rect:calculateArea2() -- `:` creates assumed 'self' first argument return self.length * self.width end rect.calculateArea3 = function(tbl) return tbl.length * tbl.width end -- need to pass table with `.` print('Area: '..tostring(rect.calculateArea(rect))) print('Area2: '..tostring(rect.calculateArea2(rect))) print('Area3: '..tostring(rect.calculateArea3(rect))) -- `:` passes rect as first arg print(':Area: '..tostring(rect:calculateArea())) print(':Area2: '..tostring(rect:calculateArea2())) print(':Area3: '..tostring(rect:calculateArea3())) -- you can pass other tables as arguments even though the function is -- on the `rect` table print('Other Area:'..tostring(rect.calculateArea({ length = 4, width = 3 }))) -- p print('Other Area2:'..tostring(rect.calculateArea2({ length = 4, width = 3 }))) print('Other Area3:'..tostring(rect.calculateArea3({ length = 4, width = 3 }
Using the `.` notation, you can see that the function exists as a property on the table like any other table value like `length` and `width`. Since it is a simple function, it's not really tied to the object, it takes a parameter that we called `self` which should be the table to operate on. When calling it with a `.`, we also need to pass the object to operate on because it is just a simple function. Although it exists on our table with length and width specified, there is no real relation.
Now look at `calculateArea2()`. Here we use a `:` when specifying that the function exists on our `rect` table. There are no arguments, but we use `self` inside of the function. By using a `:` in the function declaration, LUA assumes there is a first unspecified argument named `self`. Functionally the two definitions are equivalent, they both take one argument and it's named `self` in both. As you can see by the last two lines, you can pass different tables to each function, even the one defined with a `:`.
And with `calculateArea3` we directly assign the function as a property on the table. All three of these declarations are functionally the same. The functions are simple properties on the `rect` table.
Now look at the function calls where we use a `:`. These don't pass any arguments. That is because when using a `:` when *calling* a function property, the table the function resides on is passed as the first argument. This is the basis for creating methods on objects.