Home

Back

Contents

Next

Visibility and Scope Modifiers

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. BeanShell's first rule is to maintain Java compatability. Where new features are added that go beyond standard Java syntax however, we sometimes have to add new rules. The ability to use loose, undeclared variables as they are implemented in BeanShell can make for some situations that look ambiguous with respect to Java.

'this', 'super', and 'global'

As we discussed in the "Syntax" section early on, variables references in BeanShell default to the local scope, unless otherwise qualified. This is a little different from some other scripting languages, but we feel is more consistent with Java, with object oriented design in general, and a more natural extension of Java syntax into the scripting domain. Now let's look at what this means.

In the "Syntax" 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 this 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 can be thought of or used as an object context. A scripted object can be thought of as encapsulated in a parent scope that determines its "environment" - inherited variables and methods. The references 'this', 'super', and 'global' are really the same kind of reference - references to BeanShell method contexts, which can be thought of as scripted objects. From here on We'll refer to 'this', 'super', and any other reference to a scripted object context in general as a 'this' type reference.

Note:
If you print a 'this' type reference you'll see what it refers to:
    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

The above example 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.

'global'

A third 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. Referring to 'super' from the top scope simply returns the same 'global' again. It is legal to say things like the following:

  super.super.super...foo = 42;  // Chain super. to reach the top

However if we are really trying to reach the top context it would probably better to use 'global' in this situation:

  global.foo = 42; 

More generally, in the spirit of object oriented programming we could simply refer to some other object, defined in a parent context, without specifying where it is:

// Create a global object to hold some state
dataholder = object();

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

    bar();
    print( dataholder.value );
}
    

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'.)


Home

Back

Contents

Next