Difference between revisions of "Tutorials:Lua:ObjectOriented"

From Cheat Engine
Jump to navigation Jump to search
(Added first part of LUA OO tutorial)
 
(Calling Notation)
Line 51: Line 51:
 
Using the `.` notation, you can see that the function exists as a property on the  
 
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
 
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
+
function, it's not really tied to operating on the table, it takes a parameter that we called
`self` which should be the table to operate on.  When calling it with a `.`, we
+
`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.
 
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  
 
Although it exists on our table with length and width specified, there is no  
real relation.
+
real relation between it and the table.
  
 
Now look at `calculateArea2()`.  Here we use a `:` when specifying that the function
 
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
 
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
+
function.  By using a `:` in the function declaration, LUA assumes there is an
unspecified argument named `self`.  Functionally the two definitions are equivalent,
+
unspecified argument named `self` before any others.
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
 
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
 
table.  All three of these declarations are functionally the same.  The functions
are simple properties on the `rect` table.
+
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.
 
Now look at the function calls where we use a `:`.  These don't pass any arguments.
Line 73: Line 72:
 
the function resides on is passed as the first argument.  This is the basis for
 
the function resides on is passed as the first argument.  This is the basis for
 
creating methods on objects.
 
creating methods on objects.
 +
 +
== Metatables ==

Revision as of 00:40, 28 May 2018

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