The simplest of the `eval()`

methods are `Object eval(String script)`

and `Object eval(Reader reader)`

. The former method is invoked to evaluate a script expressed as a `String`

; the latter method is invoked to read a script from some other source (such as a file) and evaluate the script. Each method throws a `NullPointerException`

if its argument is `null`

. Listing 3 demonstrates these methods.

#### Listing 3. FuncEvaluator.java

```
// FuncEvaluator.java
import java.io.*;
import javax.script.*;
public class FuncEvaluator
{
public static void main (String [] args)
{
if (args.length != 2)
{
System.err.println ("usage: java FuncEvaluator scriptfile "+
"script-exp");
return;
}
ScriptEngineManager manager = new ScriptEngineManager ();
ScriptEngine engine = manager.getEngineByName ("rhino");
try
{
System.out.println (engine.eval (new FileReader (args [0])));
System.out.println (engine.eval (args [1]));
}
catch (ScriptException se)
{
System.err.println (se.getMessage ());
}
catch (IOException ioe)
{
System.err.println (ioe.getMessage ());
}
}
}
```

`FuncEvaluator`

is designed to evaluate the functions in a Rhino-based script file via `eval(Reader reader)`

. It also uses `eval(String script)`

to evaluate an expression that invokes one of the functions. Both the script file and script expression are passed to `FuncEvaluator`

as command-line arguments. Listing 4 presents a sample script file.

#### Listing 4. stats.js

```
function combinations (n, r)
{
return fact (n)/(fact (r)*fact (n-r))
}
function fact (n)
{
if (n == 0)
return 1;
else
return n*fact (n-1);
}
```

The `stats.js`

file presents `combinations(n, r)`

and `fact(n)`

functions as part of a statistics package. The `combinations(n, r)`

function works with the factorial function to calculate and return the number of different combinations of `n`

items taken `r`

items at a time. For example, how many different poker hands in five-card draw poker (where five cards are dealt to each player) can be dealt from a full card deck?

Invoke `java FuncEvaluator stats.js combinations(52,5)`

to discover the answer. After outputting `null`

on the first line (to indicate that `stats.js`

does not return a value), `FuncEvaluator`

outputs `2598960.0`

on the line below The `Double`

value returned from `combinations(52,5)`

indicates that there are 2,598,960 possible poker hands.

## Communicating with scripts via script variables

Previously, you learned that `eval()`

can return a script's result as an object. Additionally, the Scripting API lets Java programs pass objects to scripts via *script variables*, and obtain script variable values as objects. `ScriptEngine`

provides `void put(String key, Object value)`

and `Object get(String key)`

methods for these tasks. Both methods throw `NullPointerException`

if `key`

is `null`

, `IllegalArgumentException`

if `key`

is the empty string, and `ClassCastException`

if `key`

is not a `String`

. Listing 5's application demonstrates `put()`

and `get()`

.

#### Listing 5. MonthlyPayment.java

```
// MonthlyPayment.java
import javax.script.*;
public class MonthlyPayment
{
public static void main (String [] args)
{
ScriptEngineManager manager = new ScriptEngineManager ();
ScriptEngine engine = manager.getEngineByExtension ("js");
// Script variables intrate, principal, and months must be defined (via
// the put() method) prior to evaluating this script.
String calcMonthlyPaymentScript =
"intrate = intrate/1200.0;"+
"payment = principal*intrate*(Math.pow (1+intrate, months)/"+
" (Math.pow (1+intrate,months)-1));";
try
{
engine.put ("principal", 20000.0);
System.out.println ("Principal = "+engine.get ("principal"));
engine.put ("intrate", 6.0);
System.out.println ("Interest Rate = "+engine.get ("intrate")+"%");
engine.put ("months", 360);
System.out.println ("Months = "+engine.get ("months"));
engine.eval (calcMonthlyPaymentScript);
System.out.printf ("Monthly Payment = %.2f\n",
engine.get ("payment"));
}
catch (ScriptException se)
{
System.err.println (se.getMessage ());
}
}
}
```

`MonthlyPayment`

calculates the monthly payment on a loan via the formula *MP = P*I*(1+I) ^{N}/(1+I)^{N}-1*, where

*MP*is the monthly payment,

*P*is the principal,

*I*is the interest rate divided by 1200, and

*N*is the number of monthly periods to amortize the loan. Running this application with

*P*set to 20000,

*I*set to 6%, and

*N*set to 360 results in this output:

```
Principal = 20000.0
Interest Rate = 6.0%
Months = 360
Monthly Payment = 119.91
```

The script depends on the existence of script variables `principal`

, `intrate`

, and `months`

. These variables (with their object values) are introduced to the script via the `put()`

method -- `20000.0`

and `6.0`

are boxed into `Doubles`

; `360`

is boxed into an `Integer`

. The calculation result is stored in the `payment`

script variable. `get()`

returns this `Double`

's value to Java.