Difference between . and : when calling a module function / creating function

Hi All,

Hopefully an easy question for someone in the know… im trying to work out how best to create modules to simplify my code.  I know that the module package see all thing seems to be way out dated and the prefered way is to decalare a local table to wrap a module in?

assuming that is now ‘the way’ to do modules, i have a question about the difference between this:

module1 :

local mod1 =  { x = 1 } function mod1:doSomething1() print ("doingSomething") end return mod1

module2

local mod2 = { x = 2 } function mod2.doSomething2() print ("doingSomethingAgain") end return mod2

What is the difference between using the . or using the : ?

in main.lua it doesnt seem to make a difference.  i.e. the below all give the same results.

Just hoping someone can tell me if I am doing this right and if there is a difference or not?

thanks for your help

local m1 = require("module1") local m2 = require("module2") m1.doSomething1() m2.doSomething2() m1:doSomething1() m2:doSomething2() m1:doSomething1() m2.doSomething2() print (m1.x) print (m2.x)

right, module/package/seeall is not recommended.

the difference is whether or not you get a “self” parameter implied for you automatically.  and since your example doesn’t access any members of your table, you haven’t yet noticed - they are all functional equivalent so far.  accessing that “x” within “doSomething()” would expose the difference.

the colon is just syntactic sugar for a “self” parameter, that’ll let you access the other members of the table.  that is…

function t:doSomething() self.x=1 end -- self is implied for you, and automatically defined as the first parameter t:doSomething() -- self is implied for you, and t is automatically passed as the first parameter   -- is equivalent to:   function t.doSomething(self) self.x=1 end -- must specify a self parameter manually (tho free to name as you wish:  "self", "this", etc) t.doSomething(t) -- must pass t manually  -- but not equivalent to: function t.doSomething() t.x=1 end -- oops, no "self" available, must use module scope to resolve, like a "class member" (not unique per instance) t.doSomething() -- no-one (not you, not auto) passes t

there are good reasons for using both forms, and i won’t even attempt to cover it all.  but in general, if you want to treat your tables like “objects”, and particularly if you want to create “class instances” (and refer to instance members rather than class members), then you’ll be wanting the colon form.  otoh, if your table is a singleton, with essentially static utility methods, and you’re ok referring to its members as “mod1.x” instead of “self.x”, then dot form will do.

hth

Ah, i see.  So using the colon is like having a ‘person’ class / object (in oo terms) for example where you might have several instances created but behaving independantly. i.e. they will have a different name / age etc

an added question… so say you had a module (object) that uses the colon. would you get the instances by doing several requires?

i.e. 

-- within the person module:local Person =  {   name= nil,   age = nil, } function Person:init( o )   self.name = o.name   self.age = o.age end return Person

-- in main.lua local employer = require("Person") local employee = require("Person") employer:init ({name="bill", age=31}) employee:init ({name="ben", age=32})

on the other hand - if you had a load of helper type functions i.e. common string manipulation type functions you’d use the dot 

I think im just telling you what you’ve already told me but checking I do actually ‘get it’ haha

thanks for taking the time to reply :slight_smile:

yep, sounds like you got it.

except for using multiple require’s to create instances - require creates the class, class then creates instances (aka “new” or your init).

note there are many OO styles in Lua (some quite esoteric) here’s an intro:  http://lua-users.org/wiki/ObjectOrientationTutorial

Thats great dave - thanks for your help and the link

cheers

right, module/package/seeall is not recommended.

the difference is whether or not you get a “self” parameter implied for you automatically.  and since your example doesn’t access any members of your table, you haven’t yet noticed - they are all functional equivalent so far.  accessing that “x” within “doSomething()” would expose the difference.

the colon is just syntactic sugar for a “self” parameter, that’ll let you access the other members of the table.  that is…

function t:doSomething() self.x=1 end -- self is implied for you, and automatically defined as the first parameter t:doSomething() -- self is implied for you, and t is automatically passed as the first parameter   -- is equivalent to:   function t.doSomething(self) self.x=1 end -- must specify a self parameter manually (tho free to name as you wish:  "self", "this", etc) t.doSomething(t) -- must pass t manually  -- but not equivalent to: function t.doSomething() t.x=1 end -- oops, no "self" available, must use module scope to resolve, like a "class member" (not unique per instance) t.doSomething() -- no-one (not you, not auto) passes t

there are good reasons for using both forms, and i won’t even attempt to cover it all.  but in general, if you want to treat your tables like “objects”, and particularly if you want to create “class instances” (and refer to instance members rather than class members), then you’ll be wanting the colon form.  otoh, if your table is a singleton, with essentially static utility methods, and you’re ok referring to its members as “mod1.x” instead of “self.x”, then dot form will do.

hth

Ah, i see.  So using the colon is like having a ‘person’ class / object (in oo terms) for example where you might have several instances created but behaving independantly. i.e. they will have a different name / age etc

an added question… so say you had a module (object) that uses the colon. would you get the instances by doing several requires?

i.e. 

-- within the person module:local Person =  {   name= nil,   age = nil, } function Person:init( o )   self.name = o.name   self.age = o.age end return Person

-- in main.lua local employer = require("Person") local employee = require("Person") employer:init ({name="bill", age=31}) employee:init ({name="ben", age=32})

on the other hand - if you had a load of helper type functions i.e. common string manipulation type functions you’d use the dot 

I think im just telling you what you’ve already told me but checking I do actually ‘get it’ haha

thanks for taking the time to reply :slight_smile:

yep, sounds like you got it.

except for using multiple require’s to create instances - require creates the class, class then creates instances (aka “new” or your init).

note there are many OO styles in Lua (some quite esoteric) here’s an intro:  http://lua-users.org/wiki/ObjectOrientationTutorial

Thats great dave - thanks for your help and the link

cheers