|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Thu Aug 14, 2008 1:25 am
Unexpected results after using #YESNO |
The following code behaves strangely:
Code: |
#ECHO %cr
;;
$oldname = %getglobal( "Default User")
;;
#IF (%null( $oldname)) {
#MXP <color orange>ResetDefaultUser: </color><color white> Default User is not currently defined</color>
#ABORT 1
}
;;
$legend = %concat( "Do you you want to reset the current Default User value (", $oldname, ")?")
;;
#YESNO $legend { Apply:#CALL %setglobal( "Default User", "");Username = "";#MXP <color orange>ResetDefaultUser: </color><color white> Default User reset</color>}
{Cancel:#MXP <color orange>ResetDefaultUser: </color><color white> operation cancelled</color>}
;;
#ECHO %cr
|
If the user clicks on Apply the global variable gets reset as expected. However, when the user clicks Cancel, the global variable also gets reset.
I have verified that the Apply code is not executed and that the Cancel code is. However somwhere along the line the %setglobal( "Default User", "") is being executed. Clicking on the X bypasses the code, as it should.
I am sure a coding error is involved, I just can't see it. Perhaps someone with fresh eyes can point it out to me. |
|
_________________ Sic itur ad astra. |
|
|
|
Tech GURU
Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Thu Aug 14, 2008 4:11 am |
Definitely something weird going there...
However nothing in the documentation indications you can use multiple commands after the colon in the YESNO, and the examples actually seem to suggest that only one should be used. Having colons ':' in the command line probably isn't helping either. Putting the commands in an alias allows them to execute as expected. |
|
_________________ Asati di tempari! |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Thu Aug 14, 2008 4:22 am |
I see your point. However the command syntax is this:
Syntax: #YE question {commands} {commands}
So I assumed that one could put multiple commands in the stream.
I will do as you suggest and maybe Zugg will explain further.
EDIT: Your suggestion works great, thanks.
Code: |
#ECHO %cr
;;
$oldname = %getglobal( "Default User")
;;
#IF (%null( $oldname)) {
#MXP <color orange>ResetDefaultUser: </color><color white> Default User is not currently defined</color>
#ABORT 1
}
;;
$legend = %concat( "Do you you want to reset the Default User value (", $oldname, ")?")
;;
#YESNO $legend {Apply:apprdu} {Cancel:#MXP <color orange>ResetDefaultUser: </color><color white> operation cancelled</color>}
;;
#ECHO %cr
|
|
|
_________________ Sic itur ad astra. |
|
|
|
Toxic Adept
Joined: 27 May 2008 Posts: 299
|
Posted: Thu Aug 14, 2008 3:41 pm |
I would also like confirmation on using multiple commands in #YESNO. Some of my scripts do this and it 'seems' to work but occasionally I have issues with it.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Aug 14, 2008 4:30 pm |
Well, I did find a problem here. There isn't supposed to be any restriction on multiple commands...that wasn't the problem.
The problem was with the %setglobal function call. Remember that strings and variables are expanded within {}? Well, CMUD has two modes for parsing. In one mode, CMUD expands functions and variables as it parses a string and creates the compiled code for it. In your example above, put the code into an alias and then click on the Compiled Code tab for the alias and you will see it adding the function reference for %setglobal.
But this isn't the behavior that you want for #YESNO. You don't want CMUD to expand the variables and functions in all of the #YESNO arguments when the command is first parsed. You only want it to expand the section that gets executed based upon the button clicked by the user. In the CMUD parser, this is called "delayed" expansion. This is the kind of parsing used for commands like #IF, #CASE, #SWITCH, etc, where you don't know which argument to expand until runtime.
I found two commands that didn't have the "delayed expansion" set for them: #YESNO, #PICK. I have fixed both of these commands so that they don't expand their arguments until they are actually selected for execution. This should fix the problem, and I hope it doesn't have any side-effects. |
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: Thu Aug 14, 2008 6:11 pm |
Anaristos:
Btw, the "color" mxp tag works well with all #SAY, #PRINT, #ECHO, #SUB and like commands, not only with #MXP |
|
_________________ My personal bug|wish list:
-Wrong Priority when copy-paste setting
-1 prompt trigger for Mapper, Session and General Options, not 3 different!
-#SECTION can terminate threads
-Buttons can't start threads |
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: Thu Aug 14, 2008 6:34 pm |
Zugg wrote: |
The problem was with the %setglobal function call. Remember that strings and variables are expanded within {}? Well, CMUD has two modes for parsing. In one mode, CMUD expands functions and variables as it parses a string and creates the compiled code for it. In your example above, put the code into an alias and then click on the Compiled Code tab for the alias and you will see it adding the function reference for %setglobal. |
Could you explain this a bit more as I want completely understand this issue, please? In the given example #CALL %setglobal( "Default User", "") all parameters were static strings, so why immediate expansion has caused #YESNO command to fail? I could understand if there were problems with immediate expansion of _variables_, but why it has caused problems with predefined strings? |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Aug 14, 2008 7:26 pm |
Immediate expansion of functions means that the %setglobal function was being executed when the #YESNO command was parsed, even before the dialog was displayed. Normally this wasn't a problem because most functions just return a value and don't have any side effect. But with %setglobal, just executing the function has the side effect of setting your global variable in your INI file. The same problem would occur with any other function that had a side-effect of setting a value in addition to returning a value.
Just look at the compiled code as I mentioned above and you'll be able to understand the low-level details of this a bit more. When you look at the compiled code you'll see that the "Apply:#CALL" was being treated as a string, but then the %setglobal function was executed with the result concated to the #CALL string. This was causing %setglobal to be executed even before the #YESNO command was called.
Using the delayed expansion fixes all of this because then the argument that contains the %setglobal isn't executed unless the user clicks on that particular button. |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Fri Aug 15, 2008 12:21 am |
Arde wrote: |
Anaristos:
Btw, the "color" mxp tag works well with all #SAY, #PRINT, #ECHO, #SUB and like commands, not only with #MXP |
I am aware of that, Arde, as that is the way I write to the status window. However, most of my message output has the same format, so I copy/paste it from another script, and so forth, and then I modify it so suit, so this is a generational thing all coming from the first time I ever used MXP to output a string. Also, I am in the process of developing elements and I want to make sure that when implemented I don't have to go back and change the #SAYs, #ECHOs, etc, into MXP. Thanks for the suggestion. |
|
_________________ Sic itur ad astra. |
|
|
|
|
|