build 740 and 741- change to json?

has there been a change to the json file included in this latest build as it comes up with an error when calling decode.

getting this error:- attempt to index global ‘json’ (a nil value)

works fine on previous and other builds,

thanks [import]uid: 100222 topic_id: 21532 reply_id: 321532[/import]

+1
experiencing same problem with build 741.
When trying to use the Ice library I’m getting:
“ice.lua:126: attempt to index global ‘json’ (a nil value)”

No problem when compiling using old builds. [import]uid: 33608 topic_id: 21532 reply_id: 85575[/import]

I also can confirm this (just filled a bug report). Spent all day trying to figure out what was wrong with my app. Damn irretaiting because there was nothing about it in the changelog so I was sure it was my own fault…

…Back to the issue

I managed to get my app to run by changing:

require("json")  

to

local json = require("json")  

However it was not a happy result because the json.encoding now returns an empty json string [] and decode seem to encode escpaded unicode to UTF8 (meaning double encoded UTF8 characters).

I sure hope Carlos and the boys (and girls) fix this and compensate us with some Android In App Purchases :slight_smile:
[import]uid: 106083 topic_id: 21532 reply_id: 85584[/import]

Yes, there may have been a change with the JSON module. We have been planning to move to dkjson instead of what we are using now because:

  1. The current module has bugs
  2. dkjson seems to be more compliant to standards
  3. dkjson seems to be more robust
  4. dkjson is faster
  5. dkjson has an optional LPeg backend which is even faster (so if/when we put LPeg into the core, you get an automatic speed boost)

We were trying to make the transition transparent to you guys by renaming the module to ‘json’, but obviously you hit a quirk.

You should use the form:
json = require(“json”)
or
local json = require(“json”)

dkjson is already Lua 5.2 ready and this form seems to be new direction of Lua so rather than fighting the tide, I recommend you start doing this kind of thing with all your modules.

[import]uid: 7563 topic_id: 21532 reply_id: 85618[/import]

Well it is not doing what is expected from it. I filled out a bug explaining my issues. It has problem encoding some tables (it returned an empty json string) and it double encode the UTF8 chars in a json string.

So for now I had to roll back to an older version due to the encoding problem (I temporarily solved UTF8 issue with an extra UTF8-decode). [import]uid: 106083 topic_id: 21532 reply_id: 85621[/import]

You may want to look at your JSON data and make sure it’s correctly formed. We found a number of bugs in the previous JSON library that is fixed by dkjson. The not returning an empty JSON string (in some instances) was one of the bugs.

I’ll update the JSON API page to indicate the change and how to require the library. [import]uid: 7559 topic_id: 21532 reply_id: 85622[/import]

I did look at my data (spent all day trying to figure this out). My JSON data is encoded by the PHP json_encode function and I have never experienced this issue before and was not able to decode it with dkjson. [import]uid: 106083 topic_id: 21532 reply_id: 85623[/import]

Just a quick test.

I downloaded the latest version of dkjson (2.1) and tried it out by loading the lib manually. And the odd thing is, it works?

I will try to upgrade to latest build of Corona again and try this out once more. [import]uid: 106083 topic_id: 21532 reply_id: 85625[/import]

OK this is weird and probably not a issue in the json module. As soon as i upgrade to 2012.741 my UTF8 and json.encodee goes banan, even tough I use my same dkjson library as in 2012.736

local json = require("lib.dkjson")  

Did you change something else besides dkjson? [import]uid: 106083 topic_id: 21532 reply_id: 85629[/import]

I use
local json = require(“json”)

This has worked fine for me for many months, up through build 2012.739. At build 740 and beyond my code crashes with the error message “attempt to index global ‘json’ (a nil value)”.

I prefer the old, buggy json that worked fine without issue over this new-fangled dkjson that breaks my stuff.

Is there anything else I can try to fix this or am I stuck with build 739?

EDIT:
Seems to work fine with the latest build (741) if I remove ‘local’ and just use

json = require(“json”)

Not sure I understand WHY but I’ll take it. [import]uid: 9422 topic_id: 21532 reply_id: 85923[/import]

I’m guessing you used json in another file. Declaring ‘local’ means it is only visible in that file. The old module might have been exporting its symbols globally whether you wanted it to or not.

[import]uid: 7563 topic_id: 21532 reply_id: 85933[/import]

There must be some subtlety to local vs. global in lua that continues to elude me. I do most of my “requires” in main.lua.

json = require(“json”)

local facebook = require(“facebook”)
While both are Ansca “native” libraries, the facebook one works when required locally, but as of build 740 json only works when required globally. In fact, nearly all of the modules I use, including Ansca’s built in ones such as store, crypto, socket, socket.url, and physics work fine as local. But a few libraries I require ONLY work globally, such as text candy, particle candy, ui, and now Ansca’s json. It’s that lack of consistency that has me flummoxed. [import]uid: 9422 topic_id: 21532 reply_id: 86163[/import]

The difference between the new JSON library (dkjson.lua) and the other libraries is the new library is Lua 5.2 compatible. Lua 5.2 has changed the package loading feature of Lua and removed the “module” API. This means that all libraries that are Lua 5.2 compliant, must return a table containing their public functions.

For this reason you must load the library as follows:

value = require( "library name" )  

You can make value “local” but the scope of the library will be limited to the file where it’s loaded. (The “module” API used in the other libraries made the library’s public functions global.) [import]uid: 7559 topic_id: 21532 reply_id: 86168[/import]

Ok, that makes some sense. But doesn’t that mean the json library is now global? I thought we were supposed to steer clear of global anything in Corona/lua for performance reasons. I realize the old “module” API made everything global too, but how does including a library globally solve that?

[import]uid: 9422 topic_id: 21532 reply_id: 86193[/import]

Yes, you’re correct so I need to append my statement and say you should load the library as “local” in every file that needs it. I just did a test and found out that the loader checks to see if the library has already been loaded and doesn’t load it again.

So the bottom line is to “require” the library into a local variable in every file that needs it. You can use that same practice for all libraries, even if they are not Lua 5.2 compliant. [import]uid: 7559 topic_id: 21532 reply_id: 86204[/import]

I don’t think we say anything about steering clear of global variables. Yes, a local variable access is faster than a global variable access. But in most cases, you will not notice the difference. In the json case, the encode/decode process will by far dominate the time you spend.

The cost of a global look up is partly due to the fact that it is a table look up (on the table _G). When you call a function like json.encode, you are still doing a table look up (looking at the table ‘json’ for the ‘encode’ function). So if you really wanted the fastest access you would do:
local json = require(“json”)
local json_encode = json.encode
json_encode(foo)

But this can get ridiculous really fast as you would have to do this for everything in the json table and also for any subtable. Not to mention there is a Lua limit on the number of locals you can have in a scope.

The general rule is: optimize only where performance will make a difference. This would be in places such as tight inner loops where you have to call the same function a lot.
[import]uid: 7563 topic_id: 21532 reply_id: 86213[/import]

Tom and ewing, Thanks for the clarifications. I guess my impression that we were supposed to avoid globals came from various areas of this site, such as this quote from Beebe’s blog post http://blog.anscamobile.com/2011/09/a-better-approach-to-external-modules/

“…Since the general rule of thumb in Lua is to try your best to avoid using globals altogether …”

And this, from your docs http://developer.anscamobile.com/content/performance-and-optimization

“…Avoid global variables. Period. In Lua, you will sacrifice performance if you use global variables. When in doubt, precede your variable declarations with local…”

But, as you say, avoiding globals at all costs can get ridiculous really fast. I fact, I don’t do anything special to avoid them, still use the old module(…, package.seeall) all over the place and haven’t had noticeable performance issues. I guess this is an area open to debate, rather than hard and fast rules, even among the Anscafolk :wink: [import]uid: 9422 topic_id: 21532 reply_id: 86227[/import]

Thanks for finding those links. We should fix/clarify those docs. But the lesson to learn from this case is that ‘Correctness trumps all, including performance’. Improper use of local breaks your program.

[import]uid: 7563 topic_id: 21532 reply_id: 86232[/import]

Is there somewhere I can find some documentation on the new JSON? I have load/save code which used to work (saving a bunch of tables) and now I get the error:

type ‘userdata’ is not supported by JSON.

during my save. I’m not quite sure what it is I’m trying to save which isn’t allowed.

Thanks [import]uid: 93610 topic_id: 21532 reply_id: 87146[/import]

Search for dkjson
http://chiselapp.com/user/dhkolf/repository/dkjson/home

Userdata is a special Lua type that can only be created from C code. Some Corona objects might be of the type userdata. [import]uid: 7563 topic_id: 21532 reply_id: 87198[/import]