Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD Beta Forum
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Tue Nov 06, 2007 12:10 pm   

[2.10] Function context issues
 
This is a somewhat bad test. In one attempt while trying to set it all up with the PE I got an untrapped loop, but it is pretty neat and the display of 7 yes's actually makes sense after thinking about it a few times. Very Happy

1. Launch CMud
2. Close Sessions window (ESC)
3. Enter at the command line
Code:
#module pub;b="";#function a {#SHOW yes @{%char(64+%1)};b=2;#return ""};#CLASS 0;#window test;:test:#VAR c {c is 3};:test:#VAR d 4;:test:#status {@a(3)@b};:test:#button 1 "@a(4)@b" {};b=1;:test:#CALL @a(3);:test:#SHOW end @{%char(64+3)}


You will see that the function could never find the variables no matter how it was used from the test window.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Tech
GURU


Joined: 18 Oct 2000
Posts: 2733
Location: Atlanta, USA

PostPosted: Tue Nov 06, 2007 2:43 pm   
 
Confirmed I think... not sure I follow the context stuff though. I'm heading to work so I'll review it later. Here's the out put in my test window.

And the button displays '2'.

Code:
yes
yes
yes
yes
yes
end c is 3
yes
yes
_________________
Asati di tempari!
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Nov 06, 2007 5:38 pm   
 
I get the same result as Tech, but I'm going to need to think more about what the result *should* be. This is a pretty complicated test. I *think* what you are saying is that neither @b nor the @a function should be available because it is in the *local only* module "pub"? Is that correct?

Also, keep in mind that when you do:

#WINDOW test

the "test" window is set to the current window/module context (and it gets the focus), so your :test: shouldn't be needed on the following lines of your script.
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Tue Nov 06, 2007 5:54 pm   
 
The function and variable should be available to the 'test' window from the local only module 'pub' because it is all in the same package. Notice how the 'yes' from the functions command '#SHOW yes @{%char(64+%1)' appears in the correct window, but give null returns for the variables C and D. The last command there ":test:#SHOW end @{%char(64+3)}" demonstrates that variables exist, have a value, and are accessible through the same indirection as the function.

Also as I say the order and number of yes's displayed makes sense, I had to think about it quite a few times to decide if it was right and I believe it is.
Quote:
Also, keep in mind that when you do:

#WINDOW test

the "test" window is set to the current window/module context (and it gets the focus), so your :test: shouldn't be needed on the following lines of your script.
#WINDOW doesn't function like #MODULE in terms of becoming the default location, and I think it is a very gray area as to whether we would want it to. It would be ambiguous to have it do so, because it is already somewhat overloaded.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Nov 06, 2007 6:16 pm   
 
Quote:
The function and variable should be available to the 'test' window from the local only module 'pub' because it is all in the same package.

Right...doh ;) Wasn't thinking straight.
Quote:
#WINDOW doesn't function like #MODULE in terms of becoming the default location

When just given a single argument (the name of the window), I think it is *supposed* to act like #MODULE, but I'll take a look at the code. It certainly makes the specified window get the keyboard focus though.

OK, so you are saying that the results make sense? Was there any bug report here? Or was it just a good mind-bender? ;)

Definitely calling a function from the status bar and button caption that contains a #SHOW side-effect is a pretty nasty thing to do Twisted Evil
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Tue Nov 06, 2007 7:27 pm   
 
The bug is the null returns for the variables C and D in the #SHOW from the function a. Bold is bug.
yes where is the variable
yes where is the variable
yes where is the variable
yes where is the variable
yes where is the variable
end c is 3
yes where is the variable
yes where is the variable

I am sorry about just how confusing this test is. It was late for me and I had to dodge the bug about buttons not being notified when a variable is changed in a module, hence the funciton changes the value from the status which in turn notifies the button. I also wanted to cover every way the function could be called with methods that have unquestionable contexts. The where is the variable is the bug. Even when using the function from #CALL which is explicitly contexted in the test window the value of the variable doesn't show up. So the bug is entirely a matter of the context in which the function runs.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Nov 06, 2007 8:50 pm   
 
Functions run within the context of the module that they are defined in (just like aliases). From within the "pub" module where the @a function is defined, it cannot see the variables within the Window (because Windows are private).

Sounds like maybe functions should maybe execute in the "current" context rather than executing within their own module like aliases do?

Anyway, I think it is executing the current scoping rules correctly, and maybe they need to be changed. Functions are new enough that this might not cause any compatibility issues, but it makes me want to re-think the alias context since it seems like aliases and functions should really operate the same (like methods and functions in other languages).
Reply with quote
JQuilici
Adept


Joined: 21 Sep 2005
Posts: 250
Location: Austin, TX

PostPosted: Tue Nov 06, 2007 9:28 pm   
 
Functions and aliases should definitely behave the same.

And, while you don't want to expose the settings in all windows all the time, there's no good reason to prevent them from accessing items in the currently active window. (Every script, whether trigger, alias, function, etc., is associated with a window at runtime, right?) Similarly, triggers shouldn't be barred from accessing things in their own module/package. So, what if ALL the setting types behave the same, and can all access their own module (first) and the active window (second)?

Specifically, have the following scopes be visible and searched in the following order:
  1. The class in which the setting is defined
  2. The current class in the module/window in which the setting is defined
  3. Other classes in the module/window in which the setting is defined, in an undefined order
  4. Other global or local modules in the package in which the setting is defined, in an undefined order
  5. The current class in the active window (if different from #2 above)
  6. Other classes in the active window (if different from #3 above), in an undefined order
  7. Other global or external modules in any package, in an undefined order

This basically reflects the order in which I would (naively) expect names to resolve. E.g. if I've defined a variable 'foo' in the same class or module as my trigger, I'd expect the trigger to find it before the one in the active window.

This scope nesting allows aliases and functions (plus anything that acts like them) to operate on settings in the active window, if needed. It allows triggers to fiddle with settings in the module/package in which they are defined (which is probably a good thing). And best of all, it eliminates the difference in scoping between triggers and aliases - everything resolves names in the same way.

Of course, it runs the risk of breaking scripts that relied on the previous scoping of triggers, but only in the case that there is a name conflict with a setting in the same module or package where the trigger is defined. If so, you can just add the above behavior (access to the active window) to aliases/functions/etc. and leave triggers alone. And I don't know how difficult this would be for Zugg to implement. So feel free to tell me I'm all wet.
_________________
Come visit Mozart Mud...and tell an imm that Aerith sent you!
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Nov 06, 2007 10:16 pm   
 
Unfortunately, this would break most existing zMUD scripts. In zMUD, unless the "Set as Default" option is used for a class, it always looks within the "current" class (defined by the #CLASS command), then the parent class until it gets to the top class. Then it looks in all enabled classes for a match.

As I've said, we have had a *lot* of scoping discussions over the past year to arrive at the point we are at now. So I'm not going to start from scratch on this. I can *tweak* the scoping, but I can't make these kind of massive changes. We'd then be spending the next three months debugging it all over again, and I'm not willing to do that right now.

The reason Windows are all private is because that is how they were in zMUD. If you had a "tells" window, it wouldn't access variables in your main window by default (there was a special syntax for accessing variables in other windows similar to the //window/varname syntax that we have in CMUD).

Here is a simple example: let's say I have several child windows, like "tells", "clanchat", "groupchat", etc all tabbed at the top of my main MUD window. Now imagine that the main MUD window is running triggers, gagging spam, and doing all of the stuff that a normal MUD window is typically scripted to do. You do *not* want this behavior to change when you click on another window to give it focus. So you should really *never* access the currently active window. Otherwise if you clicked on the "tells" window, then suddenly some scripts might start accessing variables in the tells window instead of the main MUD window.

Triggers can already access variables within their own module. It just looks in the module that fired the trigger *first*. If you have a trigger in a separate module and have @a defined in the module, and also have @a defined in the window that fires the trigger, then the trigger will use the @a from the window. But if @b is only defined within the module containing the trigger, then the trigger can still access @b. And you can *always* override the default scoping with the //module/class/var syntax.

The reason triggers look in the window that causes the trigger first is that typically you want to write general purpose triggers and put them into a package/module and have the single trigger operate on any window that causes it to fire. For example, if you make a generic Prompt trigger to capture your hp/mana/etc, and you do this:

#TRIGGER {(%d)hp (%d)mana} {#VAR hp %1;#VAR mana %2}

then obviously you want these variables to be created in the *window* and NOT in the module. Otherwise you couldn't use this same trigger with multiple session windows. This means that triggers *must* look in the window that fires the trigger first.

This isn't the same as the "active" window. The "active" window is the window that has keyboard focus. That can be different than the window which receives the text that causes the trigger to fire. This is why triggers are different...they are fired from text received from the MUD and not from anything related to the "active" window.

Macros use the active window as the context because a macro is a keyboard event, and so it is associated with the window that has the keyboard focus (which is the active window). Same thing for buttons since they are fired from a mouse event from clicking on the window, and the mouse event comes from the window with the focus.

Aliases are different because they don't have a defined "master" context. They are called from the command line of a window, but they are also called from within scripts (like from a trigger). Same with functions.

Now, CMUD *used* to keep the context unchanged when an alias was executed. So if you execute from the command line, the context was the window with the focus, and if the alias was called from a trigger, the context was the current context of the trigger. This was changed several versions ago so that aliases are executed within the context of the module they are defined within. I'm pretty sure we all had a good reason for making this change, but I'd need to search the forums to find the threads were we talked about this.

Anyway, my point is that the default context (where CMUD searches first) *is* different for different types of settings on purpose.
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Tue Nov 06, 2007 11:07 pm   
 
Pretty much put my reply about this in the current 'Make a Scoping FAQ' topic, but I will add an item here before I dig up the old scoping threads and reread them. Where the output for the #SHOW goes is the evidence of the context.
Quote:
Functions run within the context of the module that they are defined in (just like aliases). From within the "pub" module where the @a function is defined, it cannot see the variables within the Window (because Windows are private).
A module should not have or be a context it can not receive keyboard focus or display anything.

With that said I am going to go find the old topics and have another look. I may bump and lock all the relevant ones to make it easier for everyone to look at the why something was done. I think the reasons it was done was focus which is a seperate issue, and even though something may get broken by all this it needs to be right otherwise there will end up being further problems with thread handling. I am not saying change it all now just before a public release, but I am saying it isn't quite right yet and needs to be right before too many people build settings based on something that is wrong.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
JQuilici
Adept


Joined: 21 Sep 2005
Posts: 250
Location: Austin, TX

PostPosted: Tue Nov 06, 2007 11:27 pm   
 
I may have been imprecise in my terminology. When I said 'active window', I didn't mean 'the window with focus'. I meant 'the window with which this script is associated'. So for a trigger, that would be the window that caused the trigger to fire (whether or not it has focus). For an alias, whichever window the command was sent to, etc.

However, it's clear that I should do some more reading (and code up some tests) before stirring this pot any further.
_________________
Come visit Mozart Mud...and tell an imm that Aerith sent you!
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Wed Nov 07, 2007 12:34 am   
 
I can't find the old topic that led to aliases behaving as they do, although I did read through a bunch of the other old topics regarding scoping. I will revisit this tommorrow when I am totally rested and can really think completely through all the concepts and reasons involved past, present and future. Right now I just haven't had enough sleep to really be clear on this.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD Beta Forum All times are GMT
Page 1 of 1

 
Jump to:  
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

© 2009 Zugg Software. Hosted by Wolfpaw.net