[AS3] Class r1.deval.D
Package | r1.deval |
Class | public class D |
This is the only class in the D.eval API for using the eval()
functionality in Adobe® ActionScript™ 3.
Background
The eval()
function in JavaScript is used to execute
textual dynamic code at runtime. ActionScript 3 chooses to break away
from this backward compatibility and deprecated eval()
.
Yet, some programmers and designers still feel strongly about its need.
Hence, this D.eval API, where basically all you need to do is invoke
D.eval()
in AS3 as you would with eval()
in
JavaScript. The interface is simple enough; what is intriguing is the
language actually supported by D.eval.
The D.eval Dynamic Language in a Nutshell
The language supported by D.eval is essentially a full JavaScript with some minor differences. The following summarizes its major features:
- Supports all the operators and flow control statements of JavaScript/AS3.
- Supports all E4X operators and operations.
- Supports user
function
declaration. - Supports the syntax of AS3-style type declarations for
var
and function return values and parameters. Type, however, is simply discarded. - Supports
import
statement to import AS3 classes; they can be used to either create a new instance via thenew
operator or call their static methods. - All Flash top-level functions are available to dynamic code.
- A number of built-in functions, including
printf()
,importFunction()
andimportStaticMethods()
. - Provides interaction with the hosting AS3 environment, with supports
from the built-in language functions and programmatic support of this
D
class. - Does not support JavaScript object-orientation afterthoughts, such as
prototype
and JavaScript-style object constructors. In other words, the language does not support defining classes in any ways. Object usage, i.e., the dot-notation, is supported. - Extended keyword support of
and
,or
,not
,xor
,nand
, andnor
. They are useful for taking end-user input with more English-like logical expressions.
Executing Dynamic Code
The eval(program, context, thisObject)
is the key method; in fact, it is part of the D.eval name itself!
Its program parameter normally is a String of textual program code,
but can also be an executable object returned by the
parseProgram()
method. The return
value is either that of a return
statement, or, if no
return
is present, that of the last expression in the code.
The context and thisObject parameters provides more
sophisticated communication between the dynamic code and the hosting
environment. The thisObject is referenced by the this
.
The context object can hold prepolulated values as named variables accessible
by the dynamic code. Often times, the context is omitted and
thisObject is used to pass a value object. The top-level variables
in the dynamic code are stored in the context object; or you can use
this
to set values to thisObject, so on exit, values
set in either objects can be used by the calling AS3 code.
So why we need these two parameters rather than a single one? The context is needed when a) the thisObject is not a dynamic AS3 class instance, and b) you intend to use the values set by the dynamic code. This is probably not happening very often, but it may.
The following is an example.
Example
import r1.deval.D; // example 1 var code:String = ' switch(fruit) {\n' + ' case "apple": return "sweet";\n' + ' case "lemon": return "sour";\n' + ' default: return "unknown";\n' + ' }'; var taste:String = D.eval(code, { fruit:'apple' }); // example 2 var purchase:Object = { price:3.95, count:12 }; var cost:Number = D.evalToNumber('price count', purchase);
Pre-Import AS3 Resources for Dynamic Code to Use
If you know the AS3 classes to be used by the dynamic code, you can pre-import
them via the importClass()
method
before calling eval()
. This method does exactly what the
import
statement does from within the dynamic code.
If you have AS3 functions to be used by the dynamic code, you can pre-import
them via the importFunction()
method.
This method does exactly the same as the name-sake built-in function from within
the dynamic code.
You can also pre-import a AS3 class's static methods as simple functions with
the importStaticMethods()
method.
This method does exactly the same as the name-sake built-in function from within
the dynamic code.
Dynamically Defined User Functions
Functions declared in the dynamic code are stored like a named variable
within the context object. You can retrieve them by a) explicitly passing a
context object to the eval()
call, and b) on exit, call the helper
method, collectUserFunctions()
,
to cleanse non-function data in the context object. You can pass that object
as a context object to following eval()
calls to reuse those user
functions. This enables a library mechanism of dynamically declared functions.
You can also call the parseFunctions()
to simply retrieve the function declarations, as in this example:
import r1.deval.D; // Compile the user library: var libCode:String = 'function sum(data:Array):Number {\n' + ' var ret:Number = 0;\n' + ' for each(var x in data) ret += x;\n' + ' return ret;\n' + '}\n\n' + 'function avg(data:Array):Number {\n' + ' return (data == null) ? 0 : (sum(data) / data.length);\n' + '}'; var userlib:Object = D.parseFunctions(libCode); // Use the library to execute dynamic code: var prog:String = 'var data = [ 1, 3, 5, 7 ];\n' + 'printf("Sum is: {0}", sum(data));\n' + 'printf("Average is: {0}", avg(data));\n'; D.eval(prog, userlib);
Logging and Output
The D.eval API output, including that of the output of the built-in function,
printf()
, is written to a destination. The default destination is
trace()
. You can set a function or a "receiver", which is an array
containing the host and the property name, via the setOutput()
static method.
<mx:Script><![CDATA[ import r1.util.TextComponentLogger; import r1.deval.D; // creationComplete handler. private function init():void { // stdout is a <mx:TextArea>. var logger:TextComponentLogger = new TextComponentLogger(stdout); logger.includeCategory = logger.includeDate = logger.includeTime = false; D.setOutput(logger); } ]]></mx:Script>
Optimization
Parsing is fairly computationally intensive. This API optimizes by caching
the dynamic code if its length does not exceed a limit. You can control this
behavior via the useCache()
method.
More Information
For more information, please refer to The D.eval API User's Guide, the ultimate reference for the API, the dynamic language and their usages.
Method | Defined by | ||
---|---|---|---|
collectUserFunctions(context:Object):Object
[static]
Collects all the user functions in the context object returned from
the previous
eval() call in order to use them in subsequent
eval() calls. | D | ||
display(msg:String):void
[static]
Prints out a message exactly the same as calling the built-in
printf() function from within the dynamic program. | D | ||
eval(program:*, context:Object = null, thisObj:Object = null):Object
[static]
Evaluates the dynamic program.
| D | ||
evalToBoolean(program:*, context:Object = null, thisObj:Object = null):Boolean
[static]
This is a convenience method for
eval() that casts the return value to Boolean. | D | ||
evalToInt(program:*, context:Object = null, thisObj:Object = null):int
[static]
This is a convenience method for
eval() that casts the return value to int. | D | ||
evalToNumber(program:*, context:Object = null, thisObj:Object = null):Number
[static]
This is a convenience method for
eval() that casts the return value to Number. | D | ||
evalToString(program:*, context:Object = null, thisObj:Object = null):String
[static]
This is a convenience method for
eval() that casts the return value to String. | D | ||
importClass(cls:Class):void
[static]
Imports the AS3 class to be used in the dynamic program.
| D | ||
importFunction(name:String, f:Function):void
[static]
Imports the AS3 function to be used in the dynamic program.
| D | ||
importStaticMethods(cls:Class, criteria:* = null):void
[static]
Imports the AS3 class's static methods as functions to be used in the
dynamic program.
| D | ||
parseFunctions(code:String):Object
[static]
Parses functions in the dynamic code for later uses.
| D | ||
parseProgram(program:String):Object
[static]
Parses the code verbiage into an executable object for the language engine to execute.
| D | ||
setOutput(receiver:Function):void
[static]
Sets the output destination for internal messages and the
printf() built-in function. | D | ||
setOverrideGlobalOption(option:int):void
[static]
To set the flag that controls the language engine's runtime behavior
when a global variable is being overridden.
| D | ||
setTextControlOutput(host:Object, prop:String = "text", limit:int = 2048):void
[static]
Creates a function to be set via
setOutput() ,
which writes multiple lines into a text control. | D | ||
useCache(b:Boolean = true, programSizeLimit:int = -1):void
[static]
Sets the option for caching dynamic programs.
| D |
Constant | Defined by | ||
---|---|---|---|
OVERRIDE_GLOBAL_ERROR : int = 3 [static]
| D | ||
OVERRIDE_GLOBAL_IGNORE : int = 0 [static]
| D | ||
OVERRIDE_GLOBAL_OVERRIDE : int = 1 [static]
| D | ||
OVERRIDE_GLOBAL_WARN : int = 2 [static]
| D |
collectUserFunctions | () | method |
public static function collectUserFunctions(context:Object):Object
Collects all the user functions in the context object returned from
the previous eval()
call in order to use them in subsequent
eval()
calls.
context:Object |
Object — a new object holding all user functions.
|
display | () | method |
public static function display(msg:String):void
Prints out a message exactly the same as calling the built-in
printf()
function from within the dynamic program.
msg:String |
eval | () | method |
public static function eval(program:*, context:Object = null, thisObj:Object = null):Object
Evaluates the dynamic program.
Parametersprogram:* — the program code.
This can either be a String of the code code verbiage, or an
executable object returned by the parseProgram method.
|
|
context:Object (default = null ) — the context object.
If this is null, a default context object is created.
Top-level variables in the dynamic code are set to this context object.
|
|
thisObj:Object (default = null ) — the this object in the dynamic code.
|
Object — the execution result. The result is either the value in a
return or the value of the last expression evaluated.
|
See also
evalToBoolean | () | method |
public static function evalToBoolean(program:*, context:Object = null, thisObj:Object = null):Boolean
This is a convenience method for eval()
that casts the return value to Boolean.
program:* |
|
context:Object (default = null )
|
|
thisObj:Object (default = null )
|
Boolean — the execution result as an Boolean. The result is either the value in
a return or the value of the last expression evaluated.
|
See also
evalToInt | () | method |
public static function evalToInt(program:*, context:Object = null, thisObj:Object = null):int
This is a convenience method for eval()
that casts the return value to int.
program:* |
|
context:Object (default = null )
|
|
thisObj:Object (default = null )
|
int — the execution result as an int. The result is either the value in
a return or the value of the last expression evaluated.
|
See also
evalToNumber | () | method |
public static function evalToNumber(program:*, context:Object = null, thisObj:Object = null):Number
This is a convenience method for eval()
that casts the return value to Number.
program:* |
|
context:Object (default = null )
|
|
thisObj:Object (default = null )
|
Number — the execution result as a Number. The result is either the value in
a return or the value of the last expression evaluated.
|
See also
evalToString | () | method |
public static function evalToString(program:*, context:Object = null, thisObj:Object = null):String
This is a convenience method for eval()
that casts the return value to String.
program:* |
|
context:Object (default = null )
|
|
thisObj:Object (default = null )
|
String — the execution result as a String. The result is either the value in
a return or the value of the last expression evaluated.
|
See also
importClass | () | method |
public static function importClass(cls:Class):void
Imports the AS3 class to be used in the dynamic program.
This is equivalent to the import
statement but can be
called to pre-import classes programmatically.
cls:Class |
importFunction | () | method |
public static function importFunction(name:String, f:Function):void
Imports the AS3 function to be used in the dynamic program. This is equivalent to the name-sake built-in function in the dynamic language but can be called to pre-import functions programmatically.
Parametersname:String |
|
f:Function |
importStaticMethods | () | method |
public static function importStaticMethods(cls:Class, criteria:* = null):void
Imports the AS3 class's static methods as functions to be used in the dynamic program. This is equivalent to the name-sake built-in function in the dynamic language but can be called to pre-import such methods programmatically.
Parameterscls:Class |
|
criteria:* (default = null )
|
parseFunctions | () | method |
public static function parseFunctions(code:String):Object
Parses functions in the dynamic code for later uses.
Parameterscode:String |
Object — an object holding all user functions that can be used by subsequent
eval() calls.
|
See also
parseProgram | () | method |
public static function parseProgram(program:String):Object
Parses the code verbiage into an executable object for the language engine to execute. It always parses the code without consulting the internal cache.
Parametersprogram:String |
Object — an executable object that can be passed as the first parameter of the
eval() (or any of its variations).
|
See also
setOutput | () | method |
public static function setOutput(receiver:Function):void
Sets the output destination for internal messages and the
printf()
built-in function.
receiver:Function — signature is: function(v:String):void {}
|
setOverrideGlobalOption | () | method |
public static function setOverrideGlobalOption(option:int):void
To set the flag that controls the language engine's runtime behavior when a global variable is being overridden.
Parametersoption:int — one of these constants:
OVERRIDE_GLOBAL_IGNORE ,
OVERRIDE_GLOBAL_OVERRIDE ,
OVERRIDE_GLOBAL_WARN , and
OVERRIDE_GLOBAL_ERROR .
|
setTextControlOutput | () | method |
public static function setTextControlOutput(host:Object, prop:String = "text", limit:int = 2048):void
Creates a function to be set via setOutput()
,
which writes multiple lines into a text control.
host:Object |
|
prop:String (default = "text ")
|
|
limit:int (default = 2048 )
|
useCache | () | method |
public static function useCache(b:Boolean = true, programSizeLimit:int = -1):void
Sets the option for caching dynamic programs. By default, the D.eval engine caches dynamic program code that not longer than 512 bytes. You can either disable this caching or change the code length limit.
Parametersb:Boolean (default = true ) — a boolean indicating whether cache should be used or not.
|
|
programSizeLimit:int (default = -1 ) — the new program size limit.
If less than 0, the limit is not changed.
|
OVERRIDE_GLOBAL_ERROR | constant |
OVERRIDE_GLOBAL_IGNORE | constant |
OVERRIDE_GLOBAL_OVERRIDE | constant |
OVERRIDE_GLOBAL_WARN | constant |