When a class function is called, say mytile:doSomething(args)
, then the actual function called is tiles.doSomething(mytile,args)
. Within the function, the mytile
becomes the self
variable. This is local to the function, but because it is a table then any assignments to it “just work”.
That is to say, if your code is:
a = class()
function a:init()
end
function a:doSomething(x)
self.x = x
end
b = a()
b:doSomething(3)
print(b.x)
then at the call b:doSomething(3)
what actually is called is a.doSomething(b,3)
. Inside doSomething
, self
points to the same table that b
points to and thus self.x = 3
updates the x
entry of b
s table. Thus b.x
is now 3
and so the print
statement outputs 3
.
Now what if we change the code of a:doSomething
to:
function a:doSomething(x)
self = {}
self.x = x
end
When this is called, self
points to the same table as b
. But the first line self = {}
now reassigned self
to point to a new table. This new table gets its x
value set to 3
but because the link between self
and b
is broken, nothing happens to b
.
Okay, so that’s why the self = {}
line shouldn’t be there.
Incidentally, the return value of an init
function is discarded so return self
doesn’t do anything.
Next, self.draw = tile:draw()
. This actually invokes tile:draw
! What you probably wanted here was self.draw = tile.draw
, except that you didn’t need this at all because without the self = {}
then self.draw
is already set to tile.draw
.
Then as Briarfox says, calling tile(x,y)
invokes tile:init(x,y)
automatically and also does some extra stuff which isn’t done if you call the init function itself.