Posted on by

Answer

Generally Lua requires “forward references” on variables if the variables are local. This means that the variable needs to be defined before it can be used. Look at the following example.


local function getTax( num )
return num * 0.0825
end

print( getTax( 99.95 ) )

The above works because getTax was defined first.


print( getTax( 99.95 ) )

local function getTax( num )
return num * 0.0825
end

The above doesn’t work because getTax is unknown and returns with a “nil” error. If you always define your variables or functions first (before being called), you won’t have any problems, but sometimes you can’t avoid it. Here is how you can fix


local getTax -- forward reference

local function printTax()
print( getTax( 99.95 ) )
end

function getTax( num )
return num * 0.0825
end

printTax()

This code works because the placeholder for getTax was defined first and then set to the value of the function. The call to getTax is enclosed in a function so it’s called after the function is defined and assigned to the variable.

One common mistake is the following:


local getTax -- forward reference

local function printTax()
print( getTax( 99.95 ) )
end

local function getTax( num )
return num * 0.0825
end

printTax()

This will fail with a “nil” error. The reason is the “local” in front of the getTax function. We already defined getTax as a local variable and when you add “local” in front of “function getTax”, we are effectively defining a new variable, leaving the original getTax variable nil. You can prove this for yourself by adding print statements in your code to display the value of variables at different points to see how they are affected placement in your code.

You can avoid the scoping issue by making all your variables global. You do this by not including local before the variable name. This is fine for a few variables but not recommend if you have a lot of variables or if performance is an issue. It’s also not recommended if you are loading modules with lots of variables.

There is a lot more to variable scoping than what I listed here, so I recommend checking out Lua 5.1 Reference Manual.

Question 2

How can I get the HTTP status code when I access a website with native.webPopup?

Answer

The HTTP Status Code is returned by web servers and used to indicate if a HTTP request was successful or not. Here are some typical status codes:

  • 200 OK
  • 301 Moved Permanenly
  • 404 Not Found
  • 500 Internal Server Error

You can find more information here.

In Corona, native.wevPopup and native.webView don’t provide this HTTP Status Code, but network.request does (in the current Daily Builds). The event.isError field from either webPopup or webView is only set when it fails to connect to the server. If you access a page and get a 404 error (page not found), isError will not be set. You should call network.request the first time you access a web page to verify that it’s available or call it when you are not getting the proper results when you access a page.

Here is how you could use this in your code.


local function loadWebPage()
native.showWebPopup(10, 10, 300, 300, url )
end

local function networkListener( event )
if( event.isError ) then
print( "Network error: ", event.response )
else
print( "Status Code: " .. event.status )
if event.status == 200 then
print( "Loading web page ..." )
loadWebPage()
else
print( "Web page not loaded!" )
end
end
end

network.request( url, "GET", networkListener )

The code calls network.request first to access the web page. If the status code is 200 (meaning OK), loadWebPage is called and the page is loaded using native.webPopup.

Note: native.webView has been implemented on iOS devices to replace native.webPopup and is the recommended API for displaying web pages. We hope to have this API available soon on Android, Mac, and Windows.

Question 3

Does Ansca see my source code when I do a build? How secure is my project when it’s sent to your server?

Answer

During the online build process, our servers never see your raw source code — or for that matter any of your project images, sounds, or other assets. The Lua script is precompiled into bytecodes (stripping out comments, debug information, etc) before it gets sent to our server. The server embeds this data into the Corona engine, but never saves or archives it. By the end of the online build process, you will have an .app bundle or .apk file just as you would get if you had used the iOS or Android SDK yourself.

Question 4

I posted a bug on the API page (comments section) but it doesn’t get fixed. Why?

Answer

The “comments” section on the API pages is not the place to post bugs or ask questions. The intent of this section is to report errors or missing information in the API documentation.

If you think you found a bug with the API, please file a bug report. The link is at the top of Forum and Documentation pages. In the bug report please include as much information as you can about the bug, including the build number, the device, the OS and if this is a new bug, which build number introduced the bug.

It’s also important to include a complete (yet small) project file demonstrating the problem. Just supplying a few lines of code and saying this shows the problem means the bug report will most likely be place at the bottom of our “to do” list. We receive lots of bug reports and it takes time for us to create sample test cases to verify the problem. Sometimes, we don’t see the problem because of a missing config.lua or build.settings file. If the bug is important to you, please help us by sending in a working sample and describe how we can reproduce the problem.

We are working on a new documentation system and it should be available online soon. This new system will not have a “comments” section so you will need to post your API-related questions on the forums or file bug reports.

Question 5

I added print statements to debug my code, but I get a lot of “nil” errors. Is there a secret to avoiding that?

Answer

Most likely you have something like this in your code:


print( "lineNumber = " .. lineNumber )

If lineNumber is nil because of a scoping problem or it has never been set, the print statement will fail saying, “attempt to concatenate ‘lineNumber’ (a nil value)”.

You can avoid the problem by using “,” to separate your variables.


print( "lineNumber = " , lineNumber )

This avoids the concatenation error, but it will add extra spaces before printing the value of lineNumber that you may not want

Another way to avoid the “nil” problem is to use “tostring”.


print( "lineNumber = " .. tostring( lineNumber ) )

This converts the value passed to tostring into a string – no matter what it is (even nil values). This is great for number, strings, tables, display objects, etc. It allows you to control the print formatting without print errors.

That’s it for today’s questions. I hope you enjoyed it and even learned a few things.


Posted by . Thanks for reading...

6 Responses to “FAQ Wednesday #4”

  1. Darren Osadchuk

    Actually, this method of forward-declaring:

    local getTax — forward reference
    print( getTax( 99.95 ) )

    function getTax( num )
    return num * 0,0825
    end

    does not work for functions. getTax may be declared, but at the time when the print statement is called, getTax is still nil, so an error is thrown. This kind of forward-declaration works fine for other data types, but not functions.

    Best approach would be to forward declare every function, and wrap code blocks that reference other functions into a function. So, using the above example, it works fine if you do this:

    local getTax
    local printTax

    function printTax()
    print( getTax( 99.95 ) )
    end

    function getTax( num )
    return num * 0,0825
    end

    printTax()

    (If you comment out ‘local getTax’, it still works, but that’s because the function is now global; if you change’ function getTax(num)’ to ‘local function getTax(num)’ you’ll get the error that is being avoided by forward declaring getTax.)

    Thanks,
    Darren

    Reply
  2. Tom Newman

    Darren,

    You’re right and thanks for catching the errors. I rewrote the examples so it’s correct.

    Thanks,
    Tom

    Reply
  3. J. A. Whye

    When I’m building web sites I pop over to php.net quite often to refresh my memory on available parameters, etc., and in many cases the comments after the “official” docs are actually more helpful.

    While you may have to do some policing when people ask questions in the docs, I think doing away with the comments is a bad move. That’s the *perfect* place for people to post examples that are relevant to the API call.

    The way docs should work is that if I look up transition.to in the API reference, I should get that info, examples of using the call that people have contributed, Q&A from the forum about that call, links to sample code, etc. — all in one place.

    In other words, I shouldn’t have to check 4 different places to get info. Or, if it’s not all on that one page it should automatically be linked at the bottom.

    Not sure how you can make that work with the infrastructure you have, but a good start would be allowing people (anyone, really) to tag everything on the site. API reference pages, forum threads/posts, sample code/templates, etc.

    Over time the tags will grow so finding all the info on any given subject will be quick and painless.

    Just something to think about. :)

    Jay

    Reply
  4. Tom Newman

    @Jay,

    I understand your position but the APi documentation pages as they currently exist have a number of problems.

    1. Anybody can post anything on those pages. So the “transition.to” API page may have a question about “native.webPopups” or “display.newImage” as well as questions or bugs with “transition.to”.

    2. Users will post long code listings and ask for help getting it to work.

    3. If there are lots of comments, the comments will span many pages and become hard to manage.

    4. Users will post bugs on the pages with very little information or the supporting project files to reproduce the problem.

    5. The Corona team is generally not aware of the comments posted to these pages so there is generally very little staff interaction. This leads to comments like “Why hasn’t my bug been addressed? Is anyone monitoring this page?”.

    6. The existing documentation doesn’t work well when changes are made to the APIs and we haven’t officially released a new build. We need a way for users to access the APIs for the build they are using and our existing API documentation doesn’t handle that.

    7. Reported bugs in the comment section that has been fixed, will be misleading to other reading the comments unless someone goes in and removes the comment. (Having the bug reported in the API page and without any response, makes users believe it’s a bug that hasn’t been fixed.)

    We monitor the forums and the bug reports but don’t have the time or staff to monitor, respond, and clean up the documentation page too.

    I have closed the comments on some of the API documentation pages and created Forums for those APIs and that seems to be working well. It may not be as convenient as having the comments under the API pages, but it still provides for feedback with a larger audience.

    Tom

    Reply
  5. Dustin

    I very much agree with J.A., I love having comments right on the API pages. Please reconsider your plan to remove them. Having a strong moderation policy on them is fine, but some comments are very useful!

    Reply

Leave a Reply

  • (Will Not Be Published)