<section>
<name filename="scope">Scope Modifiers</name>

Now that we've seen how methods can be nested and treated as objects, we
can revisit the topic of variable scope and scope modifiers.
<p/>

<h2>'this', 'super', and 'global'</h2>

In the "Scripted Methods" section we described the use of 'super' to refer to a 
method's parent scope (the scope in which the method is defined).  
And in the previous section we talked 
about super's brother 'this', which refers to the current method's scope,
allowing us to think of a method scope as an object.  Now we can see how 
these concepts are related.  Any method scope, and indeed the 'global' scope,
can be thought as an object context. A scripted object can be thought of as
encapsulated in a parent scope that determines its "environment" - its inherited
variables and methods.  
<p/>

The references 'this', 'super', and 'global' are really the same
kind of reference - references to BeanShell method contexts, which can 
be used as scripted objects.  From here on We'll refer to 'this', 
'super', 'global', and any other reference to a scripted object context in
general as a <em>'this' type reference</em>.
<p/>

<note>
If you print a 'this' type reference you'll see what it refers to:

<pre>
    BeanShell 1.3 - by Pat Niemeyer (pat@pat.net)
    bsh % print( this );
    'this' reference (XThis) to Bsh object: global
    bsh % foo() { print(this); print(super); }
    bsh % foo();
    'this' reference (XThis) to Bsh object: foo
    'this' reference (XThis) to Bsh object: global
</pre>
</note>
<p/>

The above note shows that the foo() method's 'this' reference is local
(named 'foo') and that it's parent is the global scope; the same scope in
which foo is defined.

<h3>'global'</h3>

The scope modifier 'global' allows you to always refer to the top-most
scope.  In the previous note you can see that the top level script context
is called "global" and that it appears again as the 'super' of our foo() 
method.  The global context is always the top scope of the script.  
It is the global namespace of the current interpreter.  Referring
to 'super' from the top scope simply returns the same 'global' again.  

<example>
  global.foo = 42; 
</example>

Global variables are not special in any way.  Their visibility derives simply
from the fact that they are in the topmost scope.  However, for those who do
not like the idea of qualifying anything with "global".  You can always use a
more object oriented approach like the following.

<example>
// Create a top level object to hold some state
dataholder = object();

foo() {
    ...
    bar() {
        dataholder.value = 42;
    }

    bar();
    print( dataholder.value );
}
    
</example>

In the above example we used a global object to hold some state, rather than
putting the 'value' variable directly in the global scope. 

<tip>
In the above example we used the BeanShell object() command to create an
"empty" BeanShell scripted object context in which to hold some data.  The
object() command is just a standard empty method named object() that 
returns 'this'.  The variable 'dataholder' above is a 'this' type reference and
has all of the properties of any other BeanShell object scope.
</tip>

<h2>Synchronized Methods Revisited</h2>

Now that we have covered the meaning of 'this' and 'super' with respect to
BeanShell methods we can define the meaning of the 'synchronized' modifier
for BeanShell methods.  Synchronized BeanShell methods behave as if they were
in a common class by synchronizing on their common 'super' reference object.
For example, in the four cases in the following example, synchronization occurs
on the same Java object.  That object is the 'this' type reference of the 
global scope (a Beanshell object of type bsh.This):

<example>
print( this ); // 'this' reference (XThis) to Bsh object: global

// The following cases all synchronize on the same lock
synchronized ( this ) { }     // synchronized block
synchronized int foo () { }   // synchronized method foo()
synchronized int bar () { }   // synchronized method bar()
int gee() {
	synchronized( super ) { }  // synchronized blockinside gee() 
}
</example>

</section>

