Function Scope - The Answers

The Scope for functions was a popular post and even picked up by AnscaMobile for the Guest Blog (tutorial) section.

However there were a couple of questions that arose from the same.


Question one

If in the example of Cross Calling, the function inside is called wrap, why is it being refereed to as xTemp.wrap and not as resultingObject.wrap

The whole idea of the scope was to explain how lua worked with scopes. I guess that was missed by a few. This is common and easily understandable, if one has not been working with the language for a while. To understand this better, let us *collapse* the code to see what we get.

local function spawnObject()
end

local xTemp = spawnObject()
Runtime:addEventListener("enterFrame", xTemp.wrap)

So if we look at the above few lines, we know that when we invoke the function spawnObject() we are returned an object that we store in a variable called xTemp. This variable has a member function called wrap that we can access via .wrap

Just hold on to that thought there, let us look at the functions inside of spawnObject()

function resultingObject.changeColor ( theColor )
local function onTouch ( event )
function wrap ( event )

Only the onTouch function is prefixed with a local, which means that it will *NOT* be available outside of the spawnObject() scope. Where as the other two wrap and .changeColor are. The idea of using three different type of declarations were used to demonstrate the various styles that one can adopt to declare (perhaps not such a good idea for beginners).

So we can invoke the function changeColor or the function wrap from outside of spawnObject, as long as we have a handle to the block that contains it, which is the object that contains the return object for spawnObject. However there is an error that I thought I had fixed, but as it turns out it got fixed in the second part of the code in the same section. Lines 15 and 16 should be as
if resultingObject.x < 25 then resultingObject.x = 25 end
 if resultingObject.x > 743 then resultingObject.x = 743 end

So the only way that we can access the function is via the handle of xTemp. Outside of the function there is no such thing as a resultingObject, so you have to refer to it via xTemp.wrap and in the second example, since it is inside of the spawnObject function, we can just refer to it directly.

Question Two

What is the difference between the ':' and the '.' ?

This is perhaps the most asked question and many developers just *learn* which functions work with a '.' and which work with a ':', but that should not be the case.
This question was to be answered and therefore I had the code that is there, while it has been fixed on the HowTo blog here .

Right, so the easiest way to remember is that the '.' is a single dot and the ':' are two vertical dots. Seriously, let me explain further...
Let us take the example of the function that all of us use, setFillColor()

local rect = display.newRect(10,10,10,10)
  rect:setFillColor(255,0,0)
this shall create a rectangle and have a reference to it in the variable called rect and then set the fill color to rgb(255,0,0) which is red. The function is called with a ':'

Can we call this function with a '.' ? if we do call it as
local rect = display.newRect(10,10,10,10)
  rect.setFillColor(255,0,0)
, we get errors.

WHY do we get errors?
is it because the API documents say that it should be called with a ':' instead of a '.' ? Not really, going back to when I had said that '.' is a single dot and the ':' a double dot, it was a nice way to remember, The ':' passes an extra variable that we are not aware of. which should be added if we use the '.' notation. This extra parameter that we are talking about is called the 'self', so if we wanted to call the setFillColor with a '.' we would have to call it as
local rect = display.newRect(10,10,10,10)
  rect.setFillColor(rect,255,0,0)

that's about it. From a function defining point of view, we can define the function with a '.' or a ':' as
function object.method1(self, param1, param2)
 end

 function object:method2(param1,param2)
 end

so the full code that you can try and see is as follows
local function spawnObject()
 local resultingObject = display.newRect(10,10,100,100)
 
 function resultingObject.changeColor(theColor)
   resultingObject:setFillColor(theColor[1],theColor[2],theColor[3])
 end
  
 local function onTouch(event)
   if "ended" == event.phase then
    print("touched rectangle")
   end
 end
 
function resultingObject.wrap(event)
 if resultingObject.x < 25 then resultingObject.x = 25 end
 if resultingObject.x > 743 then resultingObject.x = 743 end
end
 
 
 function resultingObject.method1(self, param1, param2)
 	print ("From method1",self.x, self.y)
 end

 function resultingObject:method2(param1,param2)
 	print ("From method2",self.x, self.y)
 end
 
 resultingObject:addEventListener("touch",onTouch)
 
 resultingObject.method1(resultingObject,"a","b")
 resultingObject.method2(resultingObject,"a","b")
 resultingObject:method1("a","b")
 resultingObject:method2("a","b")

 
 return resultingObject
end
 
local xTemp = spawnObject()
Runtime:addEventListener("enterFrame", xTemp.wrap)

Hope that helped explain the difference between the '.' and the ':'

Comments

  1. Hey Jayant,

    Great Article!
    It did help me understand better about the "." and ":".


    Thank You.
    RSCdev.
    Rodrigo.

    ReplyDelete

Post a Comment

Popular Posts