 |
GeneralStonewall Magician
Joined: 02 Feb 2004 Posts: 364 Location: USA
|
Posted: Mon Jun 14, 2010 11:32 pm
[3.19d] BUG: #var db.key screwing up nested lists. |
Using the #var db.key syntax is collapsing the list in the json table into a simple string; Which makes it unusable as a list.
Code:
| Code: |
#addkey testvar list {one|two|three|four|five|six|seven}
#print ""
#print {Database: %expanddb( @testvar)}
#print {Item 3: %item( %delitem( seven, @{testvar.list}), 3)}
#print {Json: %json( @testvar)}
#addkey testvar list %delitem( seven, @{testvar.list})
#print {Item 3 %item( %db( @testvar, list), 3)}
#print {Json: %json( @testvar)}
#var {testvar.list} %delitem( six, @{testvar.list})
#print {Item 3: %item( %db( @testvar, list), 3)}
#print {Json: %json( @testvar)} |
Output:
| Quote: |
Database: list=one|two|three|four|five|six|seven
Item 3: three
Json: {"list":["one","two","three","four","five","six","seven"]}
Item 3 three
Json: {"list":["one","two","three","four","five","six"]}
Item 3: one|two|three|four|five
Json: {"list":"one|two|three|four|five"} |
|
|
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Mon Jun 14, 2010 11:50 pm |
It's actually not the #VAR db.key syntax itself, but it's the combination of that with %delitem along with the @{testvar.list} as the argument for %delitem.
All of the %functions are a bit tricky. Normally they take string values for their arguments and return string values. Each function needs to have special code to detect if you are supplying an existing list variable to prevent it from converting to and from a plain string value.
If you look at the line:
#var {testvar.list} %delitem( six, @{testvar.list})
you can see that it's very tricky and complicated. Not only does %delitem need to detect that @{testvar.list} is already a json table, but then %delitem needs to return that table with key "six" removed, then #VAR needs to assign that new list to testvar.list. All without any string conversion.
In any case, it's a good find. It's not going to prompt a quick update because it's a pretty obscure issue. But it's on the bug list.
I must say that you are very good at coming up with some good test cases. Even as detailed as some of my existing tests are, your examples are even trickier. I'm pretty annoyed at how "kludgy" the code has become to handle all of these cases, all because of backwards compatibility with existing string lists and for performance reasons. I shouldn't need to be testing so many special cases like this. |
|
|
|
 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Tue Jun 15, 2010 12:51 am |
Perhaps it would have been easier just to create a new type of variable, then have the code convert between the new and the old if one chose.
|
|
_________________ Sic itur ad astra. |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Jun 15, 2010 4:47 pm |
No, because it's *not* a new "type" of variable. It's a new low-level implementation of the existing string list and database variable types.
The issues are the performance optimization. Most of the previous string list and database variable code always converted to and from normal string formats, which was very slow. The purpose of this new low-level table code is to improve performance and allow proper nested tables and lists. |
|
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Jun 16, 2010 12:27 am |
Actually, the issue here was just with the indirect variable reference: @{testvar.list}
Just goes to show that while this uncovered a bug, you shouldn't add extra {} unless they are really needed. The correct (optimized) command in this case is:
| Code: |
| #var testvar.list %delitem( six, @testvar.list) |
Using @{testvar.list} causes the compiler to process the variable reference at runtime instead of at compile time, which was always returning a string value and never a table. I've fixed this so it can handle returning tables now. But for speed purposes it is faster if you just use @testvar.list directly.
I think putting {} around the #VAR name is left over from old versions (maybe zMUD) which required the {} to evaluate a nested variable name. But these {} are not needed in CMUD anymore either. |
|
|
|
 |
GeneralStonewall Magician
Joined: 02 Feb 2004 Posts: 364 Location: USA
|
Posted: Wed Jun 16, 2010 12:38 am |
Alright, so the @{} syntax would be for something like @{db.@var} and @{%concat( @var, "blah")} ?
|
|
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Jun 16, 2010 12:40 am |
Yep, exactly. What you were really kind of doing was saying: take the value of db.list and use that as the name of the variable to fetch. So it was using the entire string list as the name of the variable ;)
|
|
|
|
 |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|