ScriptUO

Official ScriptUO EasyUO Scripts => Scripting Chat => Topic started by: 12TimesOver on February 13, 2010, 05:01:07 AM

Title: Namespace var interaction
Post by: 12TimesOver on February 13, 2010, 05:01:07 AM
A quick question just to make sure I understand namespace var interaction.

Consider the following:
Code: [Select]
gosub 1
gosub 2
Display %_var
Halt

sub 1
   namespace push
   namespace local 1
   set %_var Hello
   namespace pop
return

sub 2
   namespace push
   namespace local 2
   set %_var World
   namespace pop
return
I was assuming that proper Namespace execution would mean that this snippet wouldn't display anything (NULL) however it does indeed display "World".

Now consider the following:
Code: [Select]
gosub 1
gosub 2
halt

sub 1
   namespace push
   namespace local 1
   set %_var 1
   set %_var2 %_var + 9
   Display %_var2
   namespace pop
return

sub 2
   namespace push
   namespace local 2
   set %_var2 %_var + 9
   Display %_var2
   namespace pop
return

Again, proper Namespace execution would have me assume that this code would show "10" as the first Display value (from sub 1) and "9" as the second Display value (from sub 2) but it does indeed display "10" for both.

I would have thought that the reason to use Namespace would be to isolate variables and even their values to the namespaces in which they were defined. Not only are the values not stored but the variables aren't even isolated. I don't understand the point of using Namespace if this is the case. Maybe I need to go re-read the Namespace tutorials TM and Cerv have so kindly put together but I was a little annoyed this morning when I discovered my use of Namespaces in a script assumed they were implemented correctly and this idiotic assumption has caused me a ton of needless troubleshooting on the next version of my miner LOL.

Anyhow, I'm running off little sleep so hopefully this discussion makes sense.

Any constructive input is welcome!

X
Title: Re: Namespace var interaction
Post by: Paulonius on February 13, 2010, 05:26:02 AM
Also interested in getting the answer and posting to get a notice. I wonder if we could put a toggle on threads to add yourself without putting in a post that doesn't add value...
Title: Re: Namespace var interaction
Post by: 12TimesOver on February 13, 2010, 05:44:32 AM
Ok so I thought to try values between and outside of subs/namespaces to see if that makes a difference and the following results in all displays being the value of "2" which is the last value set:

Code: [Select]
set %_var 0
gosub 1
display %_var
halt

sub 1
   wait 10
   namespace push
   namespace local 1
   set %_var 1
   gosub 2
   Display %_var
   namespace pop
return

sub 2
   wait 10
   namespace push
   namespace local 2
   set %_var 2
   Display %_var
   namespace pop
return

So obviously I'm missing something as to why I would bother or I'm simply executing namespaces wrong.

X
Title: Re: Namespace var interaction
Post by: TrailMyx on February 13, 2010, 09:05:55 AM
Remember you have to reference namespace variables with the "!" and not the "%" qualifier:

set !_var 0
namespace copy _var to local 0
gosub 1
display !_var
halt

Code: [Select]

sub 1
   wait 10
   namespace push
   namespace local 1
   set !_var 1
   gosub 2
   Display !_var
   namespace pop
return

sub 2
   wait 10
   namespace push
   namespace local 2
   set !_var 2
   Display !_var
   namespace pop
return

"%" variables are available in ALL namespaces.
Title: Re: Namespace var interaction
Post by: 12TimesOver on February 13, 2010, 10:08:35 AM
Ahh... like I said, my execution is probably wrong. Awesome, thanks for clearing that up TM.

Everything is executing as expected now, thanks. It's funny how after all this time I still have so much to learn and can miss such "minor" details hehe.

X
Title: Re: Namespace var interaction
Post by: TrailMyx on February 13, 2010, 10:33:29 AM
If you look at the picture I did for the namespace interaction, you'll see what I mean.

http://www.scriptuo.com/index.php?topic=108.15
Title: Re: Namespace var interaction
Post by: 12TimesOver on February 14, 2010, 05:36:16 AM
Funny that I've always viewed the difference between "!" and "%" entirely incorrectly.

With that said, why is it that so many people use Namespace variables in the main body of their scripts? Would this make these variables available ONLY in the "default" namespace?

Consider the following:

Code: [Select]
set !Var1 Hello
gosub sub1
Display !var1 , #spc , !var2
halt

sub sub1
   namespace push
   namespace local Test
   set !var2 World
   Display !var1 , #spc , !var2
   namespace pop
return
I'm assuming the results of the first Display that runs (in the sub) will be "N/A World" and the result of the second Display (in the main body before Halt) would be "Hello N/A". Am I on the right track?

I suppose I could go test this and get my own answer.

X
Title: Re: Namespace var interaction
Post by: TrailMyx on February 14, 2010, 09:41:01 AM
Yup, exactly.

When you try and reference the "!" variables (either local or global), all you are doing is looking into the place that described with the #NSNAME and #NSTYPE. system variables.  You can think of this sort of like a big array.  When you change the #NSNAME and #NSTYPE variables, you basically point to a whole new memory pool.  That pool is addressable to only on script running (#NSTYPE = LOCAL) or all scripts running in an EUO instance (#NSTYPE = GLOBAL).

Also notice that #NSNAME and #NSTYPE have default values of std:local.  That means you can use "!" referenced variables immediately.
 
Title: Re: Namespace var interaction
Post by: 12TimesOver on February 14, 2010, 11:45:38 AM
Awesome help here, thanks!

So, if you don't mind TM (or anybody else) if you could entertain a couple more questions.

First, a question regarding var types being passed to a sub declaring a new #NSNAME:

Code: [Select]
set !var1 Hello
gosub sub1 !var1
halt

sub sub1
   namespace push
   namespace local Test
   set !NSVar1 %1
   Display !NSVar1
   namespace pop
return

So, as #NSNAME Test knows nothing about !var1 in the default space why does passing the variable actually work? Wait, maybe I've just answered my own question. Is it becaue the value of !var1 gets assigned to the %1 global variable thus making it available to all namespaces as the currently declared %1? That just makes too much sense.

On a similar note, I'm assuming that any variable being set in a declared namespace that will be used in another namespace (default or otherwise) will need to be a global thus the following won't work:

Code: [Select]
gosub sub1
Display !NSVar1
halt

sub sub1
   namespace push
   namespace local Test
   set !NSVar1 Hello , #spc , World
   namespace pop
return !NSVar1

Now what would be cool is if namespace vars were indeed like an array in that they could be called throught a script such as #NSNAME:!NSVarName (e.g. #TEST:!NSVar1) - now this would be cool!! ;)

Last question - do the variable values in a namespace get saved in memory until overwritten? In other words, can I repeatedly go back to a namespace and further modify a NS variable?

Code: [Select]
for %i 1 10
   gosub sub1
halt

sub sub1
   namespace push
   namespace local Test
   set !NSVar1 !NSVar1 +1
   Display !NSVar1
   namespace pop
return

Would the result of the above be 1,2,3,4,5,6,7,8,9,10 in 10 Display iterations?

X
Title: Re: Namespace var interaction
Post by: TrailMyx on February 14, 2010, 02:37:29 PM
Yup, you answered your own question.  Subroutine arguments are "%" vars, so they are available in ALL namespaces.  However, they will be unique for each script you run.  So Tab1 EUO will have their own set of "%" vars and Tab2 EUO will also be separate.  Local namespace variables function very similarly to "%" vars.  Remember that namespace variables were added well after the first implementation of EUO.  You can consider "%" variables as being legacy.

Here's an example that might answer one of your questions:

Code: [Select]
set !NSVar1 FIRST
gosub sub1
Display !NSVar1 ; hey! it's still FIRST.
namespace copy NSVar1 from local Test
Display !NSVar1 ; There now it's SECOND.
halt

sub sub1
   namespace push
   namespace local Test
   set !NSVar1 SECOND
   namespace pop ; Whoops!  You just flopped back to the original namespace!
return !NSVar1

Finally, once you start writing variables in a namespace, they will persist until you clear the namespace.  That's what the "namespace clear" command does for you.

If you have any questions, check out the Vardump feature of EUO.  You can see all the variables as they have been declared.
Title: Re: Namespace var interaction
Post by: 12TimesOver on February 14, 2010, 03:03:45 PM
You know I was totally looking for a good example for Namespace Copy too, this is great stuff. I'm not sure why it finally started making sense all of a sudden but I'm on a roll this week!! ;P

Thanks much, I'm off to implement now!

X
Title: Re: Namespace var interaction
Post by: 12TimesOver on February 26, 2010, 02:43:44 AM
Man, I'm obviously still missing something. So I understand that the "default" NS is STD. So I would assume, and looking at your examples above I should be correct, that if you set !NSVar1 in the main body of the script that 1)it will not be available in a different namespace and 2)it will still be set when I return to the STD namespace.

Example:

Code: [Select]
set !NSVar1 Hello
gosub 1
Display !NSVar1 , #spc , !NSVar2  ;<-----result here should be "Hello N/A"
Halt

sub 1
   namespace push
   namespace local 1
   set !NSVar2 World
   Display !NSVar1 , #spc , !NSVar2  ;<-----result here should be "N/A World"
   namespace pop
return

Rather than getting the above results in a script I'm working on, when I do a Namespace Pop in the sub and return to the STD NS the variables I set in the main body script stay N/A rather than returning to their original values. In other words, the "Display !NSVar1, #spc , !NSVar2" is resulting in "N/A N/A". Shouldn't the originally set value of !NSVar1 be restored?

Hopefully this reads correctly.

X
Title: Re: Namespace var interaction
Post by: TrailMyx on February 26, 2010, 05:29:06 AM
Hmm, works for me.
Title: Re: Namespace var interaction
Post by: Scrripty on February 26, 2010, 10:46:05 AM
Hmm, works for me.

That was fun to read... I've been looking at namespace use also.  Keep going please... hehe
Title: Re: Namespace var interaction
Post by: 12TimesOver on February 26, 2010, 11:23:26 AM
Hmm, works for me.
Well I can't actually run my example at the moment so it must be something I'm doing wrong in my application yet again. I'll bet I'm jumping from STD to a new NSName then to another NSName but not Pop'ng somewhere before dropping back to STD.

As always, thank you Mr. Miyagi!

X
Title: Re: Namespace var interaction
Post by: 12TimesOver on February 26, 2010, 11:54:46 AM
K, I'm still digging in my code but I'm at work so no runnie for me :(

So the following should be true:

Code: [Select]
set !NSVar Hello  ;<----- Set the value of !NSVar to Hello
gosub 1
Halt

sub 1
   namespace push  ;<----- stores !NSVar from #NSNAME=STD
   namespace local 1  ;<----- Value of !NSVar becomes N/A because the value set in the STD Namespace has been stored by the "Push" and a new NS created
   set !NSVar World1  ;<----- Set the value of !NSVar to World1
   gosub 2
   namespace pop  ;<----- Value of !NSVar Becomes Hello because we've "popped" thus the value from STD is restored
return

sub 2
   namespace push  ;<----- stores !NSVar from #NSNAME=1
   namespace local 2  ;<----- Value of !NSVar becomes N/A because the value set in Sub 1 has been stored by the "push" and a new NS created
   set !NSVar World2  ;<----- Set the value of !NSVar = World2
   namespace pop  ;<----- Value of !NSVar becomes World1 because we've "popped" thus the value from Sub 1 is restored
return

If so, I think I've finally got somewhere but I still don't know what in hades is going on with my script yet because everything seems ok.

Lastly, I'm assuming it is a best practice to clear a namespace before pop'ng if those vars aren't necessary for the next iteration just to save memory; would that seam reasonable?

Thanks again.

X
Title: Re: Namespace var interaction
Post by: Scrripty on February 26, 2010, 12:30:44 PM
How do you debug your namespaces TM?  There's gotta be an easy way... you said you had something that does it for you once I think...?
Title: Re: Namespace var interaction
Post by: TrailMyx on February 26, 2010, 12:33:51 PM
Clearing the name space is really up to you.  Just like in "C", you might have a "volatile" region of memory that you may want data to persist.  So it's really up to you and whether you want to keep the data.  For me, I end up using namespaces quite a bit like one might use arrays for, so I want that data to persist.  A good example of that is my Advanced Journal Handler.  Each journal scanner you include in your script resides in its own namespace.  That way it keeps its own copy of the #Jindex value and remains separate from the rest of the journal scanners.  But because of that, I never want to "clear" the namespace.

For your example, if you do a display of the data once you call gosub 1, try this:

Code: [Select]
namespace copy NSVar from local 1
set %NSVar1 !NSVar
namespace copy NSVar from local 2
set %NSVar2 !NSVar
display ok %NSvar1 , #SPC , %NSVar2
stop
Title: Re: Namespace var interaction
Post by: TrailMyx on February 26, 2010, 12:34:51 PM
How do you debug your namespaces TM?  There's gotta be an easy way... you said you had something that does it for you once I think...?

I have an unreleased namespace debugger I use.  However, you can get a good indication about how badly you are borking up your namespace code by looking at the VARDUMP.  Very useful, even though it's very clunky.
Title: Re: Namespace var interaction
Post by: Cerveza on February 26, 2010, 12:41:25 PM
Your confusion confuses me.
Title: Re: Namespace var interaction
Post by: 12TimesOver on February 26, 2010, 04:45:59 PM
Hehe, I manage to confuse myself pretty quickly so I'm sure it's not to hard to confuse others ;)

I do get the Namespace Copy portion and can see why in some cases you wouldn't want to clear namspace vars. The thing I'm troubleshooting is in the miner script. I've made a bunch of logic changes and tried to streamline some funcitons in 2.6 in order to prep for the feature updates in 3.0. Part of this has been to implement my own standardized subs for gumps, clicks, etc. Somewhere in the logic I'm leaving variables set in STD as N/A so I'm thinking, based on all of our discussion, that I must be jumping out of a sub without pop'ng. Unfortunately I can see nothing glaringly obvious.

My logic is somehting like:

Code: [Select]
Set !totinker yes

Find shovel
If #findkind = -1 && !totinker = yes
   gosub Tinker shovel

sub tinker
   do stuff to use tool
   gosub gumpwait gumpname gumpname gumpsize
   gosub click x y
return

sub click
   namespace push
   namespace local Click
   set !clickx %1
   set !clicky %2
   click !clickx !clicky
   gosub gumpwait generic_gump generic_gump 507_123
   namespace pop
return

sub gumpwait
   namespace push
   namespace local GW
   set !GName1 %1
   set !GName2 %2
   set !GSize %3
   wait for stuff
   namespace pop
return

So this is obviously an oversimplified version but it makes the point. I go from the script body with the value of !ToTinker set to Yes. I Push STD and make a new namespace for clicking and gosub to the gumpwait and another push and new namespace GW. I pop/return, then pop/return thus I should be back to the STD namespace with !Totinker being back to a value of Yes but, instead, it stays N/A. This would seem as though I'm not pop'ng correctly out of one of the click or gump subs but I see nothing wrong.

Point is, this is why I'm asking so many questions lol! I'm really learning a lot, just not enough to figure out WTH I'm doing wrong hehe.

At some point I may post the code for debug if I end up giving up.

Any low-level dirt on how a namespace variable gets stored in memory during a namespace push operation?

X
Title: Re: Namespace var interaction
Post by: Scrripty on February 26, 2010, 06:37:24 PM
Don't blank namespaces default to STD?  I thought I read that...
Title: Re: Namespace var interaction
Post by: TrailMyx on February 26, 2010, 06:38:55 PM
Don't blank namespaces default to STD?  I thought I read that...

Well, the default to what you left them at last.  Look at #NSNAME to see.  Upon power up, it is STD.