Tutorials:Lua:ObjectOriented

From Cheat Engine
Revision as of 00:40, 28 May 2018 by Jgoemat (talk | contribs) (Calling Notation)
Jump to navigation Jump to search

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 operating on the table, it takes a parameter that we called `tbl` 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 between it and the table.

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 an unspecified argument named `self` before any others.

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, they each take one argument, and they return the value of multiplying the `length` and `width` properties on that argument.

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.

Metatables