 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Wed Jun 23, 2010 10:22 pm
[3.20]BUG: (expression) doesn't evaluate in following conditions |
Since you asked for cases where (expression) doesn't produce the results like %eval does, here goes... (and mainly, this is the reason why I continue to use %eval to this day, despite being told otherwise... :P Yes, I should have reported it as bugs earlier on, but meh...)
1.
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<alias name="test" copy="yes">
<value>#LOOP %1 {#SAY {%i+%2 is (%i+%2)}}</value>
</alias>
</cmud>
|
Usage: test 10 10
Correct output: 10+10 is 20*
What it outputs: 10+10 is (10+10)*
2.
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<func name="convert" copy="yes">
<value>#RETURN %if((%1+%1>200),(%1+(%1/2)),%if((%1+%1<201),(%1+(%1*3))))</value>
</func>
</cmud>
|
Usage: #SAY {@convert(100)}
Correct output: 400
What it outputs: (100+(100*3))
*: This is just one line out of the loop. All lines output in this format.
These are just two examples that I can come up with right now, but will continue to find other examples where %eval needs to be used or you won't get proper output.
Charneus |
|
Last edited by charneus on Wed Jun 23, 2010 10:34 pm; edited 1 time in total |
|
|
 |
GeneralStonewall Magician
Joined: 02 Feb 2004 Posts: 364 Location: USA
|
Posted: Wed Jun 23, 2010 10:24 pm |
I can't import that 2nd one. That and it's a rather convoluted example. Simplify it a bit?
Edit: Simplified a bit: #return %if( %1 < 100, (%1 + 100), (%1 - 100))
But, the first one is because it's inside of a string. Using #SAY %concat({%i+%2 is }, (%i+%2)) works. No comment on whether or not it should work like that, though. |
|
|
 |
charneus Wizard

Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Wed Jun 23, 2010 10:42 pm |
Not sure why the second one is giving problems to importing, but you're right - I just recopied and pasted what I have, deleted it, and tried to copy this one and paste it, and it failed. However, just copying in the session, deleting, and repasting worked. In any case, the second one's code (simplified... somewhat) is this:
Code: |
#FUNCTION convert {#RETURN %if((%1+%1)>200,(%1+%1),(%1*%1))} |
While testing, I came up with a third one:
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<alias name="testthree" copy="yes">
<value>#LOOP 10 {#ADDITEM TestList %i}
#SEND {echo (%numitems(@TestList)+(%numitems(@TestList)-1))}</value>
</alias>
</cmud>
|
Usage: testthree
Correct output: 19
What it outputs: echo (10+(10-1))
Yes, you could be right about it being strings, however, it's still a large reason why many of my scripts contain %eval to this day. *sigh* No sense in doing %concat({blah blah}, (expression)) when %eval is quicker anyway. Hadn't occurred to me that it's using strings, though. :\
Charneus |
|
|
 |
Tech GURU

Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Wed Jun 23, 2010 11:13 pm |
Confirmed that 2 is bug. It looks like %if is treating the true and false expressions as strings.
The third is example doesn't evaluate because the outer curly braces {} says to treat things literally. |
|
_________________ Asati di tempari! |
|
|
 |
GeneralStonewall Magician
Joined: 02 Feb 2004 Posts: 364 Location: USA
|
Posted: Wed Jun 23, 2010 11:26 pm |
I don't believe that's true, Tech. Doesn't {} signify an expanded string, not a literal one? Maybe I'm mixing up the distinction command parameters and strings. I've always been a bit fuzzy on that.
|
|
|
 |
Tech GURU

Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Thu Jun 24, 2010 3:29 am |
I'm pretty sure it's literal string but Zugg will set my right. My rule of thumb was that the {} could be used instead of quotes "". Plus the fact that if you remove the curly braces, it works as expected.
|
|
_________________ Asati di tempari! |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Jun 24, 2010 5:15 pm |
Confirmed #2 and added it to bug list. And yes, the < and > characters get screwed up within the Forum CODE tag so you have to manually edit it to get it to paste into CMUD.
Tech is correct about the other cases. You cannot use () to evaluate an expression within {} quotes.
I think we need to have a serious talk here about all of the people relying upon "implicit concat" all the time. I swear, I should have never added that as a feature to the original zMUD. No other programming language has anything like this. It really promotes some lazy scripting and causes huge headaches in the CMUD design.
Let's look at example #1 in detail. Specifically the line:
Code: |
#SAY {%i+%2 is (%i+%2)} |
OK, what are you really trying to do here? You are trying to output a line that looks like "1+2 is 3". The STRICT way to code this using EXPLICIT CONCAT is this:
Code: |
#SAY %concat(%i,"+",%2," is ",(%i+%2)) |
Most any other programming language (C, PHP, Lua, Java, etc) is going to require some syntax like this. Languages that have a concat operator (like + or &) can do this:
Code: |
#SAY (%i+"+"+%2+" is "+(%i+%2)) |
But again, you can see that you need to be very specific and exact about putting " quotes around string values, and () around values that you want to evaluate.
The problem you run into is when using {}. In *most* cases, {} acts as " quotes with variable expansion allowed. However, {} has also traditionally been used in CMUD/zMUD to just group arguments. Because of this backwards compatibility confusion, {} sometimes don't work the way you'd expect and you cannot always just replace " with {}. For example, you would normally expect this to work:
Code: |
#SAY ({%i+%2 is }+(%i+%2)) |
but it doesn't (at least not in 3.20, but I think I fixed a bug in the parser for this for 3.21). However, going back to the EXPLICIT %concat function, you CAN do this:
Code: |
#SAY %concat({%i+%2 is },(%i+%2)) |
So, the bottom line is:
1) {} mostly work as quotes. While you can expand variables and functions within quotes, you cannot use () within quotes to evaluate an expression because the ( and ) characters are treated as verbatim characters just like any others.
2) Be careful when using "implicit concat". When in doubt, put in the proper %concat call. That's what %concat is for. %concat is fast. It makes your scripts more readable. It will ensure improved compatibility with future versions of CMUD. Use it.
3) Use %eval if you don't mind a big performance drop.
I know some people like to try to cram as much on one line as possible. That's what ends up making a lot of C code unreadable and hard to support. Just because a language allows you to cram a bunch of stuff into a single line with obscure syntax doesn't mean it's always a good idea. |
|
|
 |
|
|
|
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
|
|