# BeanShell User's Guide

## Introduction

This guide explains how to use the BeanShell Java interpreter with the Java Development Environment for Emacs. This guide contains the following sections:

About the BeanShell | Brief overview of the BeanShell
Using the BeanShell | Explains how to start and shut down the BeanShell, enter statements, and show results.
The BeanShell Language | Describes the Java constructs and scripting extensions supported by the BeanShell
BeanShell Commands | Describes the commands supported by the BeanShell

## About the BeanShell

The BeanShell is a Java interpreter that evaluates Java statements directly (without first compiling them). The BeanShell has been included in the JDE with the permission of its author, Pat Niemeyer.

The BeanShell can operate as a stand-alone application or as a part of another application. When running as a stand-alone application, the interpreter accepts input from the command line of the shell in which it runs. The BeanShell distribution includes a shell for running the interpreter. It can, however, be run from other shells, such as bash or the DOS command window. The JDE includes a command for running the BeanShell in an Emacs shell (comint) buffer. This enables you to interact with the interpreter directly while developing Java programs.

The JDE also uses the interpreter to implement some JDE commands. The JDE invokes the interpreter via Lisp functions that pass Java statements to the interpreter via the standard input of the interpreter process and retrieve results via the standard output. This guide documents BeanShell functionality that seems relevant to JDE users. See the BeanShell home page home page for additional information and to download the latest version of the BeanShell.

## Using the BeanShell

### Starting the BeanShell

To start the BeanShell, select Interpret from the JDE menu or enter the command `M-x bsh`. Emacs starts the BeanShell, if not already started, and displays its prompt in an Emacs shell buffer window.

The JDE allows you to run only one instance of the BeanShell at a time. If an instance is already running, the `bsh` command simply displays the buffer containing the instance, without starting another instance. Note that you can indirectly start a BeanShell instance when you invoke commands implemented as hybrid Lisp/Java scripts, such as `jde-wiz-override-method`. Such commands start a BeanShell instance if one is not already running.

### Evaluating Statements

To evaluate a Java statement, type it at the BeanShell prompt and press the Enter key. The BeanShell evaluates the statement. When it is done, it redisplays the the BeanShell command prompt. You can then enter another statement.

Statements must conform to Java syntax. For example, simple statements must end in a semicolon. Compound statements, such as if-then constructs, must end in a right brace. Statements may span multiple lines. To continue a statement on a new line, press the Enter key. The BeanShell does not evaluate the statement until you have entered the last line of the statement.

### Displaying Results

You can display the results of evaluating Java statements via the BeanShell `print` and `show` commands. The print command accepts any Java expression as an argument and displays the result of evaluating that expression in the BeanShell window. For example,

> `print(2+2);`

displays

> `4`

in the BeanShell window. Note that `print(expr)` is equivalent to `System.out.println(expr)` and you can use either method to print a Java expression.

The `show();` command toggles automatic display of the results of evaluating statements as they are entered.

### Exiting the Shell

To exit the BeanShell, enter

> `exit();`

at the command prompt.

## The BeanShell Language

### Java Language Support

The BeanShell language includes most of the constructs of the Java language. Standard Java constructs supported by the BeanShell include variable assignments, method calls, math expressions, for-loops, etc.. Here are some examples:

        // Use a hashtable
        Hashtable h = new Hashtable();
        Date d = new Date();
        h.put("today", d);

        // Print the current clock value
        print( System.currentTimeMillis() );

        // Loop
        for (int i=0; i<5; i++)
            print(i);

        // Pop up an AWT frame with a button in it
        Button b = new Button("My Button");
        Frame f = new Frame("My Frame");
        f.add(b, "Center");
        f.pack();
        f.show();

By default, the BeanShell imports the Java core classes at startup. You can import additional classes, using standard Java import syntax, for example,

> `import mypackage.*;`

or

        import mypackage.MyClass;

### Scripting Extensions

The BeanShell defines a number of extensions to the Java language designed to facilitate creation of scripts. The scripting extensions include

- Script Variables
- Script Methods
- Implicit Objects
- Syntax for accessing Bean properties and Hashtable entries

### Script Variables

The BeanShell allows you to create a special type of variable named a script variable. Unlike a standard Java variable, which can reference objects only of a specified type, a script variable can be defined to reference any type of object, including primitive types, such as `int` and `boolean`. You create a script variable by declaring it with or without a type specifier. If you include a type specifier, the variable can reference only values of the specified type. If you do not specify a type, the variable can reference values of any type. For example, the following statement

        foo = new Button("Another Button");

creates an untyped script variable named `foo` and assigns it a Button object. You are free to subsequently assign `foo` to any other type of object.

#### Predefined Variables

- $_ - the value of the last expression evaluated.
- bsh.Console bsh.console - The primary console, if one exists.
- java.awt.AppletContext bsh.appletcontext - the applet context, if one exists.
- String bsh.cwd - used by the cd() and dir() commands.
- boolean bsh.show - used by the show() command.
- boolean bsh.interactive - is this interpreter running in an interactive mode or sourcing a file?
- boolean bsh.evalOnly - Does this interpreter have an input stream or is it only serving as a bag for eval() operations.

#### Undefined variables

You can test to see if a variable is "undefined" with the value `void`, e.g.:

        if ( foobar == void )
            // undefined

You can return a defined variable to the undefined state using the unset() command:

> `a == void; // true`
> `a=5;`
> `unset("a"); // note the quotes`
> `a == void; // true`

### Script Methods

BeanShell lets you define and use a special type of method called a script method. Script methods differ from standard Java methods in the following ways:

- Script methods are methods of an implicit, typeless object
- Script methods can be defined to accept and return values of any type
- Script methods can define other script methods

You use standard Java syntax to declare a script method that accepts and returns specific types. For example, the following code

        int addTwoNumbers( int a, int b ) {
            return a + b;
        }

defines a BeanShell method called `addTwoNumbers` that accepts and returns values of type `int`. The next example

        int a = addTwoNumbers( 5, 7 );

uses the newly defined method to add two values of type `int`.

You define an untyped script method by omitting type specifications. For example, the following statement

        add( a, b ) {
            return a + b;
        }

defines a script method that accepts arguments of any type. When you invoke an untyped script method, BeanShell interprets the method based on the types of the arguments that you pass to the method. Consider, for example, the following invocations of the untyped add method defined in the preceding example:

        foo = add(1, 2);
        print( foo ); // 3

        foo = add("Oh", " baby");
        print( foo ); // Oh baby

The first invocation returns the result of adding, the second, of concatenating the arguments.

Methods with unspecified return types may return any type of object or no object. A return statement is optional. If omitted, the method returns the value of the last statement or expression in the method body.

#### Method Namespace

The namespaces of script methods and variables are separate. Thus, you can define a method and a variable having the same name.

#### Nested Methods

Script methods may define methods, for example,

        foo() {
            bar() {
                ...
            }
        }

Method may be nested in this way to an arbitrary depth. Within a nested method, locally declared variables and methods shadow identically named variables and methods declared in outer methods. Otherwise, variables and methods are visible to an arbitrary depth of scope. Outer methods can invoke methods defined by inner methods that return a `this` object, for example,

### Implicit Objects

The methods and variables defined by a script method are considered to be methods and fields of an implicit object. The reserved identifiers, `this`, `super`, and `global`, refer, respectively, to the current object, the calling object, and the global object. A method can access any variable or method in these scopes by qualifying the variable's name with the name of the appropriate implicit object.

        a = 42;
        foo() {
            a = 97;
            print( a );
            print( this.a );
            print( super.a );
        }

        foo();  // prints 97, 97, 42

A script method can return its implicit object, thereby allowing the invoking script to access variables and methods defined by the method, using standard Java "." notation. For example,

        foo() {
            int a = 42;
            bar() {
                print("The bar is open!");
            }

            bar();
            return this;
        }

        obj = foo();     // prints "the bar is open!"
        print ( obj.a )  // 42
        obj.bar();       // prints "the bar is open!"

#### Using Implicit Objects as AWT Event Handlers

Implicit method objects can serve as AWT event handlers. To handle an AWT event, a script method defines the appropriate event-handling method and then registering its implicit (`this`) object with the object in which the event originates. For example, the following script

        button = new java.awt.Button("foo!");

        actionPerformed( event ) {
            print( event );
        }

        button.addActionListener( this );
        frame( button );  // show it

defines an Action event handler and registers it with a button.

Remember that you don't have to define all of your event handlers globally. You can handle events in any bsh object scope. For example, the following method creates a button that displays a message when pushed:

        messageButton( message ) {
            b = new Button("Press Me");
            b.addActionListener( this );
            frame(b);

            actionPerformed( e ) {
                print( message );
            }
        }

        messageButton("Hey you!");
        messageButton("Another message...");

The above will create two buttons and each will display its own message when pushed. Each has a separate instance of the event handler object. Note too that we could return a 'this' reference from the handler method and use it in other contexts to register listeners...

#### Using Implicit Objects as Threads

'This' type references also implement the standard Runnable interface, so you can declare a "run()" method in your objects:

> `foo() {`
> `run() {`
> `// do work...`
> `}`
> `return this;`

> `}`
> ``
> `foo = foo();`
> `new Thread( foo ).start();`

#### Implicit Object Members

Implicit objects have four "magic" members:

> - `this.interpreter` refers to the currently executing BeanShell Interpreter object.
> - `this.namespace` refers to the BeanShell NameSpace object of the current context.
> - `this.variables` refers to an array of strings listing the variables defined in this namespace.
> - `this.methods` refers to an array of strings listing the methods defined in this namespace.

These are mainly for internal use by BeanShell commands. Note that there are certain special situations in which the `this.interpreter` reference may not be available, such as in AWT event handlers.

### Extended Syntax for Accessing Bean Properties and Hashtables Entries

You may use the following syntax

> `x{name}`

to access properties of Java beans and Hashtable entries, where `x` is a bean or Hashtable and `name` is a String that identifies a bean property or hashtable entry, for example:

        b = new java.awt.Button();
        b{"label"} = "my button";
        // Equivalent to: b.setLabel("my button");

        h = new Hashtable();
        h{"foo"} = "bar";
        // Equivalent to: h.put("foo", "bar");

## BeanShell Commands

The BeanShell provides a set of commands for displaying data, invoking system utilities, and performing various other tasks. See the BeanShell Command Reference for a description of the syntax and usage of each command. The current crop of bsh commands follow. These are, for the most part, just very short bsh scripts, supplied in the bsh.jar file. See making bsh commands below for more details on adding to the "built-in" bsh command set.

### bg

`bg( String script )`

This is like `run()` except that it runs the command in its own thread. Returns the thread object (for `stop()`ing, `join()`ing, etc.)

### browseClass

`void browseClass(String classname);`

Displays a class browser. The browser enables you to browse the contents of any packages packaged as `jar` files on the classpath defined by `jde-global-classpath`.

### cat

`void cat( String filename )`

Print the contents of filename (like Unix cat)

### cd

`void cd(String dirname);`

Change working directory for the `dir()` command (like Unix `cd`).

### console

`bsh.Console console()`

Create a console window attached to the current interpreter. Returns the console Frame.

### dir

`void dir(String dirname)`

Display the contets of directory dirname. The format is similar to the Unix ls -l command.

### debug

`void debug()`

Toggle on and off debug mode... Note: debug output is verbose and gross.

### editor

`Frame Frame editor();`

Create an editor window with an "eval" button. This is primarily useful for typing multi-line commands and experimenting with methods when running the BeanShell outside of the Emacs environment. Returns the editor Frame.

### eval

`void eval( String expression )`

Evaluate the string in the current interpreter (see `source`).

### exec

`exec(String process);`

Get the Java Runtime and start the external process, display any output.

### exit

`void exit()`

Call System.exit(0);

### frame

`Frame frame(Component component);`

Display the component, centered and packed, in a top level Frame. Returns the frame. Frame takes additional steps to handle the WindowClosing AWT event and dispose of the frame, so that you an close the window normally.

### getResource

`URL getResource( String path )`

The equivalent of calling getResource() on the interpreter class in the bsh package. Use absolute paths to get stuff in the classpath.

### load

`Object load( String filename )`

Load a serialized Java object from filename. Returns the object.

### pathToFile

`File pathToFile( String filename )`

Create a File object corresponding to the specified file path name, taking into account the bsh current working directory (bsh.cwd)

### print

`void print(item);`

Print the string value of the item. item may be of any type.

### pwd

`void pwd();`

Print the bsh working directory. This is the cwd obeyed by all the unix like bsh comands.

### rm

`void rm( String pathname );`

Remove the file (like Unix rm)

### run

`run( String script )`

run() is like source() except that it runs the command in a new, subordinate and prune()'d namespace. So it's like "running" a command instead of "sourcing" it ;)

### save

`void save(Component component, String filename);`

Save a serializable Java object to filename.

Since the AWT Button class happens to be serializable, we could test drive the save() command.

        save(foo, "myButton.ser");

If we did save our button, we could revive it later with the load() command.
`bar = load("myButton.ser");`
`frame(bar);`

### server

`void server( int port )`

Create a Server Mode server attached to the current interpreter, listening on the specified port.

### setFont

`Font setFont( Component comp, int ptsize )`

Change the point size of the font on the specified component, to ptsize.

### show

`void show();`

Toggle on or off the display of the value of expressions evalauted on the command line. Show mode may be useful if you find yourself typing print() a lot.

### source

`void source( String filename )`

Read filename into the interpreter and evaluate it in the current namespace. Like Bourne Shell "." command.

### unset

`void unset(String name);`

"undefine" the variable specified by 'name' (So that it tests == void).

## Making BeanShell Commands

Adding to the set of "prefab" commands supplied with bsh can be about as easy as writing any other bsh methods. You simply have to place your bsh scripts in a bsh/commands/ directory in the classpath (or inside the JAR file).