Tutorial: Scopes for Functions

Share on Facebook0Share on Google+2Tweet about this on TwitterShare on LinkedIn0

This tutorial is written by Jayant Varma of OZ Apps and is cross-posted from OZ’s Teach Me How To… blog. If you have a tutorial you’d like us to cross-post, let me know and we’ll get that ball rolling. 🙂

It is the most frequently asked question, this is due to the fact that a lot of developers still mix up with the scope of a variable, what about a function? Did you think that functions also have scopes? Yes they have and let us look at the scope of a function in this tutorial.

Let’s work the sample code as we learn about function scopes…

Simple function

This shall work perfectly fine and print Hello from CoronaSDK when we run it.

Forward Declarations

There are cases when we need to pre-declare a function, so here’s how we do it

In this example, we call init, which in turn calls main and for forward declaration, we declare that main is a local variable by declaring it then we just define main as a function, note that we did not add the local in front of it, if we did, it would become a new declaration and would not work for us.

Encapsulated Function

What if we wanted to have a function that is only available from within a function?

This example is not very illustrative of where this can be used, so let us look at a practical example

You can see that the function that handled touch is well within the function spawnObject, this is one cool way of having all related function to the object inside, more like a class without creating a class. These function shall be available to the object to be invoked internally.

Member functions

Member functions are a bit different than normal functions as they become part of the object than being just local to the object. so, in the previous example, let us say we want to change the color of the resultingObject, we do not have a function as yet, let us add a function that will help change the color of the object.

We cannot access this function from outside of the spawnObject function even though it is not local as there is no way to have a handle to it. So we just make a small modification to the same and we get

As you can see after running this code, a pink/magenta rectangle is seen on the screen.
If we were to call the changeColor from within the function spawnObject, we would have a bit of a dilemma, how would we access it? we would not have a handle on the function. So, in cases like these, since it is inside of the function and we are referring to another function that is part of the function, we use the keyword self and we call it as

Cross calling

This is based off a question on the forum, where the user wanted to know how to call a particular function that was inside of another function. Now by the sound of that sentence it is such a complicated and complex thing to achieve, but in reality, let us see.

We want to be able to call a function that checks for the bounds of the object and make it wrap on the screen like the asteroids game. Now in any thing that we want to do, it is better to actually put what we want to achieve on paper before we attempt to actually achieve that. So, we want that the player object wraps around the screen. We shall call this via a runtime event listener. Since it is not inside of the function, we cannot use the self, though both could be part of the main.lua, self would not work, and the only way is to use the function names. Also since we have determined initially that one function is inside of a function and the other is outside, we need to be able to cross call. We would in the way that we have just seen in the previous example.

The same code can be made even more structured and cleaner as

Now every time a new object is spawned, it is fully encapsulated, having its own functions for enterFrame and for touch.

Advanced Function

Functions in Lua are an amazing thing, they are nothing bu pointers to a memory address that holds the code and therefore can be modified on the fly, this is lots of flexibility and also dangerous, useful for obfuscation too.

Now at first glance that is a bit strange looking code, but you know why, coz we have assigned hide to the function print and the local variable print to the function math.random.

More Advanced Function

Functions can also be stored as part of tables, but for this tutorial we shall stop here, the functions as part of tables shall be *perhaps* part #3 of the tables in lua series. So you can read up on those at Part #1 or at Part #2

Share on Facebook0Share on Google+2Tweet about this on TwitterShare on LinkedIn0

This entry has 5 replies

  1. Eiswuxe says:

    Great tutorial, hental! I bet Corona devs will all be LUA pros soon 🙂

    Just to things to mention:
    In the first code-sample of the “Cross Calling” example is a function called
    “function wrap(event)”.
    This function is then used OUTSIDE of the object (xTemp.wrap). My understanding (and also your info in the turorial) is that the function then must be named “function resultingObject.wrap()”, like with the “changeColor” function. Or am I wrong?

    Second, could you please point out the difference between “function resultingObject.changeColor” and “function resultingObject:changeColor”? So basically “.” vs “:”? I know it makes no difference to the result when you execute the code, but its a difference from a syntax kind of view 🙂

  2. Ingemar says:

    Regarding ‘:’ vs ‘.’
    The only difference I know of is that the ‘:’ call has an implicit object reference as the first parameter.

    Example 1:
    function resObject:someFunction(value);

    Example 2:
    function resObject.someFunction(self, value);

    Example 3:
    function resObject.someFunction(value);

    Examples 1 and 2 above are the same.
    It’s important to know how a function has been declared (with ‘:’ or ‘.’), otherwise you can get parameter mis-matches if you call a ‘:’-declared function with a ‘.’ or vice versa.
    A ‘:’-declared function will expect the first parameter to be a reference to the calling object.

    The function for Examples 1 and 2 can be called as:
    myObject.someFunction(myObject, myValue);

    However Example 3 can only be called with

    If you try to call Example 3 with

    you’ll get unexpected results as the parameter ‘value’ will get an object reference and not the value of ‘myValue’.

  3. OZApps says:

    firstly, that is Hetal, not Hental or Hentai and he is the great guy at Ansca Mobile that is the author of the blog posts on this site, not the Author of the content.

    secondly, you had a valid question and a bit of a misunderstanding, so here’s a follow up article to clarify what you asked here


    The Author of the article

  4. Pablo says:

    Hi, the example above “Encapsulated Function” is not correct, the function “insideMain” will be accessible outside of “main”as long as “main” ran already, so the function is not really encapsulated.

    I don’t understand why lua works that way, it makes 0 sense to me and it’s very frustrating since it leads to scope leaking all over the place.

    The alternative would be defining “insideMain” as local inside of “main”, but this forces you to define the function before using it even if that usage is inside another function, which is a really annoying contraint.

    Does anybody know of another way of encapsulating functions (without relying on defining them as properties in tables)?

    • Pablo says:

      I found a workaround, defining the inner as local at the beginning of the function that encapsulates the others, a real encapsulating example then would be:

      local function main()
      local insideMain
      print (“Hello from CoronaSDK”)

      function insideMain()
      print(“This is a function inside of main, not available to be called from any other”)

      insideMain() — Now this would throw an error since it won’t be accessible from outside main