Expecco API/en: Unterschied zwischen den Versionen

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen
Zeile 536: Zeile 536:


===== TimeDuration =====
===== TimeDuration =====
Represents an amount of time, to represent time intervals. When reading, a unit-specifier character is allowed to specify milliseconds (ms), seconds (s), minutes (m), hours (h) or days (d). For example, "1h 20s" specifies 1 hour and 20 seconds.
Represents an amount of time, to represent time intervals in millisecond resolution. When reading, a unit-specifier character is allowed to specify milliseconds (ms), seconds (s), minutes (m), hours (h) or days (d). For example, "1h 20s" specifies 1 hour and 20 seconds.
[[http://live.exept.de/doc/online/english/overview/basicClasses/misc.html#TIMEDURATION More Info]]
[[http://live.exept.de/doc/online/english/overview/basicClasses/misc.html#TIMEDURATION More Info]]



Version vom 3. April 2014, 12:21 Uhr

Inhaltsverzeichnis

expecco API[Bearbeiten]

The expecco API provides functions and access to the underlying class library for the use in elementary blocks written in Smalltalk and JavaScript. The API for Groovy elementary blocks is described below. This API is not available for elementary blocks written in other languages which are executed by external script engines (Shell, Batch, Python etc.).


The JavaScript and the Smalltalk API consist of the same functions - both call into the underlying Smalltalk/X system, for which extensive documentation is available as Online Documentation and as Class Reference.

JavaScript and Smalltalk only differ slightly in their syntax; semantically they are very similar:

JavaScript Smalltalk
this self the current activity
this.functionName() self functionName a call without arguments
this.functionName(arg) self functionName:arg a call with one argument
this.namePart1_part2(arg1,arg2) self namePart1:arg1 part2:arg2 two arguments
functionName(...) self functionName... implicit this/self receiver
accessor self accessor slot access - implicit this/self send
stat1 ; stat2 stat1 . stat2 statement terminator / separator
(in ST: required to terminate every statement
in JS: required to separate)
if (cond) {
  ifStats
} else {  
  elseStats
}
cond ifTrue:[
  ifStats
] ifFalse:[
  elseStats
]
conditional execution
while (cond) {
  stats
}
[ cond ] whileTrue:[
  stats
]
while-loop. Notice the extra brackets in Smalltalk
function () { stats } [ stats ] an anonymous (inner) function (called "block" in ST)
function (a1, a2,...) { stats } [:a1 :a2 ...| stats ] in ST: blocks are a reference to an anonymous function
var v1, v2, ... ; | v1 v2 ... | local variables inside a function (or block)
return expr; ^ expr return a value.
In ST: a return from within a block returns the enclosing top-level function
In JS: a return returns from the inner function

All functions are actually implemented in Smalltalk and follow the standard Smalltalk naming conventions. The same function names are used for Javascript. As seen above, this scheme works well for functions without or with a single argument, but requires a name translation for functions with more than one argument. This translation is done by the JavaScript compiler by replacing every colon (:) of the Smalltalk name by an underline (_) character, except for the last colon. Thus for example, the Smalltalk name "at:put:" will be replaced to "at_put" in JavaScript.

In JavaScript, a function-name alone (i.e. without explicit receiver) is translated into a self-send; thus "this.foo()" and "foo()" are equivalent.

Also, for non-argument accessor functions (getters), the empty argument list can be omitted in JavaScript; therefore, "foo" and "this.foo", "foo()" and "this.foo()" are all equivalent.

For example, the JavaScript call:

    this.environmentAt("foo")

is written in Smalltalk as:

    self environmentAt:'foo'

and, to demonstrate the multi-argument translation rule, the Smalltalk code:

    self environmentAt:'foo' put:1234

is written in JavaScript as:

    this.environmentAt_put("foo", 1234)

Syntax[Bearbeiten]

JavaScript Smalltalk Notes
this self the current activity
null nil a null reference (UndefinedObject)
"..." '...' a String constant (JavaScript allows single quotes too)
#'...' a Symbol constant (not available in JavaScript)
[ el1 , el2 , ... ] #( el1 el2 ... ) an Array constant (elements must be constants)
[ expr1 , expr2 , ... ] { expr1 . expr2 . ... } a computed Array (notice the expression terminators in ST)
#[ el1 el2 ... ] a ByteArray constant (not available in JavaScript)
( num / den ) a Fraction constant (not available in JavaScript)
rcvr.f () rcvr f function call
rcvr.f (arg) rcvr f: arg with 1 arg
rcvr.a_b (arg1, arg2) rcvr a: arg1 b: arg2 with 2 args
notice the different names of the function
"a_b" vs."a:b:"
return; ^ self without return value (in ST: from outer function; in JS: from current function)
return expr; ^ expr with return value (in ST: from outer function; in JS: from current function)
return from execute; ^ self return outer from inner function
; . Statement Terminator/Separator

Syntactic Sugar[Bearbeiten]

Some syntactic construct sof the JavaScript language are implemented as library functions in Smalltalk. Among otherse, most noteworthy are conditional execution (if-the-else) and loops.
The JavaScript syntax is mapped to corresponding Smalltalk library functions as follows:

if (expr) { .. } (expr) ifTrue:[ ... ]
if (expr) { .. }
else { ... }
(expr) ifTrue:[ ... ]
ifFalse:[...]
while (expr) { .. } [expr] whileTrue:[ ... ] Notice the square brackets
for (expr1;expr2;expr3) { .. } expr; [expr2] whileTrue:[ ... expr3 ]
for (var i=start; i <= stop; i += incr) { .. } start to: stop by: incr do:[:i | ... ]
try { .. } finally {...} [...] ensure:[...]
try { .. } catch(e) {...} [...] on:Error do:[:e | ...]
try { .. } catch(e) {...} finally {...} [ [...] on:Error do:[:e | ...] ] ensure:[ ... ]
var++ var := var + 1
var-- var := var - 1

Operators[Bearbeiten]

JavaScript Smalltalk Notes
% \ modulu operator
<< bitShift: left-shift; negative shift count is right-shift
>> rightShift: right-shift; negative shift count is left-shift

Inner Functions[Bearbeiten]

Inner Functions in JavaScript[Bearbeiten]

It is possible to create functions within the elementary block's code. This example shows how to do so:

  execute() {
    ...
    function f(arg1, arg2) {
      return(arg1 + arg2);
    }
    ...
}

A inner function f is created with two arguments (arg1, arg2), which returns the sum of both. The function is called like this:

   f(3,5)

Inner functions can be used for example to filter specific elements from collections.

Inner functions are first class objects: they can be stored in variables, collections, passed as argument or returned from functions. They can even be passed to other blocks via input- and output pins or via environment variables. Functions can be anonymous; the above example could also be written as:

  execute() {
    var f;
    ...
    f = function (arg1, arg2) {
      return(arg1 + arg2);
    }
    ...
}

(notice the missing function name after the "function" keyword).


Notice, that there is a difference in the behavior of the return statement between JavaScript inner functions and Smalltalk blocks: a JavaScript "return" statement inside an inner function returns from that inner function only, whereas a return in Smalltalk always returns from the outer-most method. To return from the outermost function in JavaScript, use the "return from <fnName>" statement form.

In expecco, where the outermost function is always named "execute", write:

    execute
       ...
       function myFunction() {
           ...
           return from execute;
       }
    ...

(notice that the execute function is not supposed to return a value)

Inner Functions in Smalltalk (Blocks)[Bearbeiten]

In Smalltalk, inner functions are called "block", and are defined as:

   f := [:arg1 :arg2 | arg1 + arg2 ].

This block can be called by sending at a "value:value:" message (one "value:" for each argument):

   f value:3 value:5

Blocks without argument are defined as:

   f := [ Transcript showCR:'blabla: Euler was great' ].

and invoked with a simple "value" message.

Smalltalk blocks and JavaScript inner functions can be used interchangable - i.e. it is possible to pass a JS inner function to a collection method such as "collect:" or "select:". It is also possible, to pass either via input/output pins to other activities (which is not considered good style, as it could make the program quite hard to understand, if not used with caution).

Notice again, that the behavior of the Smalltalk return ("^") is different from a JavaScript return ("return-Statement") inside inner functions. The JavaScript return returns a value from the inner function, whereas the Smalltalk return forces a return from the containing method (the block's "execute" method). The Smalltalk return always behaves like the "return from execute" JavaScript special form.

Example uses for Inner Functions[Bearbeiten]

In Smalltalk, blocks are very often used when enumerating collections. For example, code corresponding to a C# 3.0 collection select (where(x => ...)) is written in Smalltalk as:

    |names namesStartingWithA|

    names := #( 'Alice' 'Ann' 'Bob' 'Mallory' ).
    namesStartingWithA := names select:[:n | n startsWith:'A'].

or in JavaSript as:

    var names, namesStartingWithA;

    names = [ "Alice" , "Ann" , "Bob" , "Mallory" ];
    namesStartingWithA = names.select( function(n) { n.startsWith("A"); } );

To find the first element in a collection, for which some condition is true, use:

    |names firstNameContainingAnO|

    names := #( 'Alice' 'Ann' 'Bob' 'Mallory' ).
    firstNameContainingAnO:= names detect:[:n | n includesString:'o'].

or in JavaSript as:

    var names, firstNameContainingAnO;

    names = [ "Alice" , "Ann" , "Bob" , "Mallory" ];
    firstNameContainingAnO = names.detect( function(n) { n.includesString("o"); } );

For more information on the Smalltalk syntax, see [Smalltalk Basics] in the [Smalltalk Online Tutorial].

Builtin Data Types[Bearbeiten]

An introductionary overview and links to the detailed documentation of individual classes is found in the Smalltalk Class Documentation of the Smalltalk/X online documentation. The following gives a rough summary of the main concepts.

Numeric Types[Bearbeiten]

The underlying numeric type implementation supports multiple number represenations. These can be used transparently in mixed-operations, and values are automatically converted as required. For example, the division of two integers returns another integer iff the division does not produce a remainder. Otherwise, a fraction object is returned, if there was a remainder. Although very very rarely required in practice, values can be converted explicitly, via one of the "asXXX" messages, if required:

  • asFloat()
  • asInteger()
  • asFraction()
  • asFixedPoint(scale)

Thus, if you want to avoid fractions (why would you?), process the result of an integer division using one of the asFloat(), truncated(), floor(), ceiling() or rounded() functions. But be aware that fractions provide an exact result, whereas float arithmetic is inherently inprecise and rounds on the the last bit.

Integer[Bearbeiten]

This represents arbitrary precision integral numbers. Conversion and memory allocation is completely automatic. Thus, you can write:

x = 100.factorial();

to get the huge number:

933262154439441526816992388562667004907159682643816214685929638952175999932299156089
41463976156518286253697920827223758251185210916864000000000000000000000000

Small integer values (<32 bit) are stored more efficiently than large integers - however, the conversion and representation as used by the system is completely transparent and automatic. The same is true for mixed mode arithmetic between small and large integers.

Occasionally it is required to perform modulo arithmetic in 32 or 64bit, for example to reproduce or check values as generated by C or Java programs. For this, use methods from the "special modulo" category, such as "add_32:", "add_32u", "mul_32" etc. Use a class browser to find those methods.

[More Info]

Float[Bearbeiten]

Float represents double precision IEEE floating point numbers (64bit). Although seldom needed, conversion to single precision (32bit) and high prevision (80bit) is allowed via the asShortFloat() and asLongFloat() conversion functions. [More Info]

Fraction[Bearbeiten]

Fractions are arbitrary-precision rational numbers. You will get them when dividing two integers and the result is not integral. For example:

1 / 3

returns a fraction result with a numerator of 1 and a denominator of 3. Fractions have the advantage of avoiding rounding errors; thus, when the above fraction is divided by 3, you will get (1/9), which we can multiply by 9 to get the exact 1 (an integer) without any rounding error. Be reminded that this is typically not the case with Float or Double precision numbers. Due to rounding errors on the last bit, you will often get 0.9999999 as a result there.

Fractions automatically reduce themself - therefore, when adding (1/3) + (2/6), you will get (2/3). [More Info]

FixedPoint[Bearbeiten]

FixedPoint numbers are decimals, with a configurable number of post-decimal digits. They are typically used when dealing with money. Like fractions, they avoid rounding errors. However, when printed, they round in their last digit (however, the exact information is always kept for further processing). FixedPoint numbers are perfect to represent money and other fractional data, which must be represented with a fixed number of post-decimal digits. [More Info]

String Types[Bearbeiten]

Strings can come in two flavours, depending on how many bits are required to encode the character's codePoint. In general, UNICODE is used internally as the encoding. However, converters are available to translate into other encodings, such as JIS or ISO8859-x.

String[Bearbeiten]

This is used to represent character strings, where each individual character has a one-byte encoding. I.e. the values are 0..255. [More Info]

Unicode16String[Bearbeiten]

This is used to represent character strings, where at least one character needs a two-byte encoding. I.e. any value is in the range 0x0100 .. 0xFFFF. In fact, there is even a Unicode32String class, which supports the full four-byte unicode character set. But in practice, such strings are very rarely ever encountered or needed.

Character[Bearbeiten]

Individual characters (as extracted from a string or possibly read from a file) are represented as instances of the Character class. Queries are available to ask the character for its type (isLetter, isDigit etc.) or its unicode encoding (codePoint). [More Info]

Collection Types[Bearbeiten]

An introductionary overview on the collection classes is found in the [Collections Overview] of the [Smalltalk/X online documentation].

Array[Bearbeiten]

Ordered, fixed size, indexed by an integral index starting with 1. Can store any type of object. As the size is fixed (when created), adding and removing of elements is not possible. Use one of the other collections (OrderedCollection, Set or Dictionary) if the number of elements needs to change later or is not known in advance. When accessing elements by index, access time is constant O(1). Searching for an element in an Array (using the includes: or indexOf: method), time complexity is O(N), because the search is linear through all elements of the array.

[More Info]

ByteArray[Bearbeiten]

Ordered, fixed size, indexed by an integral index starting with 1. Can only store very small byte-valued unsigned integers (0..255). [More Info]

BitArray[Bearbeiten]

Ordered, fixed size, indexed by an integral index starting with 1. Can only store tiny bit-valued unsigned integers (0..1).

BooleanArray[Bearbeiten]

Ordered, fixed size, indexed by an integral index starting with 1. Can only store booleans (false..true).

FloatArray[Bearbeiten]

Ordered, fixed size, indexed by an integral index starting with 1. Can only store short IEEE floats (32bit). [More Info]

DoubleArray[Bearbeiten]

Ordered, fixed size, indexed by an integral index starting with 1. Can only store IEEE doubles (64bit). [More Info]

IntegerArray[Bearbeiten]

Ordered, fixed size, indexed by an integral index starting with 1. Can only store small 32bit unsigned integer values (0..FFFFFFFF)

SignedIntegerArray[Bearbeiten]

Ordered, fixed size, indexed by an integral index starting with 1. Can only store small 32bit signed integer values (-800000000..7FFFFFFF)

LongIntegerArray[Bearbeiten]

Ordered, fixed size, indexed by an integral index starting with 1. Can only store small 64bit unsigned integer values (0..FFFFFFFFFFFFFF)

SignedLongIntegerArray[Bearbeiten]

Ordered, fixed size, indexed by an integral index starting with 1. Can only store small 64bit signed integer values (-80000000000000000..7FFFFFFFFFFFFFFF)

OrderedCollection[Bearbeiten]

Ordered, variable size, indexed by an integral index starting with 1. Can store any type of object. OrderedCollections are specifically tuned for adding/removing elements at either end. Access time to elements via index has a complexity of O(1). When searching for an element in an OrderedCollection (using the includes: or indexOf: method), time complexity is O(n), because a linear search is done. [More Info]

SortedCollection[Bearbeiten]

Sorts itself, variable size, indexed by an integral index starting with 1. Can store any type of object. By default, sorting is by ascending order. However, the sort order can be arbitrarily changed by setting the sortBlock, a two-argument JS-function or a two-argument Smalltalk block which should return true, if its first argument is to be "considered" smaller than the order (i.e. the default sort block is "[:a :b | a < b]"). Access by numeric index is O(1). Insertion and remove is O(1) for the first and last element, O(n) for others, because the elements are moved inside a linear container. When searching for an element in a SortedCollection (using the includes: or indexOf: method), time complexity is O(log n), because a binary search can be done. When a big sorted collection is created, it is faster to first create it as a non-sorted collection (OrderedCollection) and then converting the whole collection via asSortedCollection(), instead of adding individual elements one-by-one.

[More Info]

Set[Bearbeiten]

Unordered, variable size, keeps a single reference only, per equal element. Can store any type of object. When searching for an element in a Set (using the includes: method), time complexity approaches O(1), because the search can be done based on a hashing algorithm in asymptotic constant time.

[More Info]

Bag[Bearbeiten]

Unordered, variable size, keeps a count, per equal element. Adding, removing and insertion check are all asymptotical O(1). Can store any type of object.

Dictionary[Bearbeiten]

Unordered, variable size, implements arbitrary key-value mappings. Can store any type of object. When accessing or searching an element in a Dictionary (using the at: or includesKey: method), time complexity asymptotically approaches O(1), because the key search can be done based on a hashing algorithm. Notice, that the same value may be stored multiple times in a dictionary (i.e. stored under multiple keys); therefore, asking for the presence of a particular value in the dictionary (the reverse query) still has O(N) time complexity.

If you need access both via the key and the value, either use an additional reverse mapping dictionary, or store an additional value -> key mapping in the same dictionary (if the key and value spaces are disjoint).

Java users will know a subset of the dictionary functionality as "Hashtable". [More Info]

OrderedDictionary[Bearbeiten]

Ordered, variable size, implements arbitrary key-value mappings. Can store any type of object. Being similar to dictionaries, these remember the order by which elements were added. It provides both access by hash-key and access by index (which is the order in which elements have been added). Creation of an OrderedDictionary is somewhat slower than for Dictionary or OrderedCollection, but access by either numeric or hashkey is fast O(1).

Queue[Bearbeiten]

Ordered, variable size. Can store any type of object. Queues are especially tuned for adding elements at one end, and removing them at the other. The internal representation uses a buffer in round-robin fashion. Both adding and removal are done on O(1) time. [More Info]

BTree, AATree[Bearbeiten]

Combining the functionality of Dictionaries and SortedCollection, these keep their elements in a sorted order, indexed by a key-object. In contrast to Dictionaries, which use hashing, these use a tree-like representation and guarantee both asymptotic O(log N) worstcase and average runtime. (Dictionaries have a much better average runtime of O(C), but also a worstcase of O(N), if the hash keys are badly distributed). These trees are self balancing to avoid the linear worst case access time of non balanced trees.

Stream Types[Bearbeiten]

Streams are accessors for either internal collections or external files, sockets and other character oriented I/O devices. They are created by either "opening" a file or device or by creation "on" a numerical indexable collection object (String, Array, OrderedCollection etc.). Once created, read streams deliver the next element via a "next()" operation, write streams append elements via the "nextPut(e)" operation. In addition to the above elementary functions, bulk read/write and linewise read/write and various other functionality is provided.

An introductionary overview on the stream classes is found in the [Streams Overview] of the [Smalltalk/X online documentation].

ExternalStream[Bearbeiten]

A common superclass providing bytewise or linewise access to any stream of the underlying operating system. Concrete subclasses are Socket, Filestream, ConsoleStreams, PTYStream etc. [More Info]

FileStream[Bearbeiten]

Provide bytewise or linewise access to the underlying file system. [More Info]

CharacterWriteStream[Bearbeiten]

A special stream usable for mixed single- and multibyte characters (i.e. Unicode).

Socket[Bearbeiten]

Provides low level bytewise or linewise access to a communication socket. Typically, but not limited to TCP/IP connections. [More Info]

Other useful Types[Bearbeiten]

Date[Bearbeiten]

Represents a date. [More Info]

Time[Bearbeiten]

Represents a time-of-day in second resolution. [More Info]

Timestamp (Date and Time)[Bearbeiten]

Represents a timestamp in millisecond resolution. Due to the internal representation (Unix format), only timestamps back to 1.1.1970 can be represented. [More Info]

TimeDuration[Bearbeiten]

Represents an amount of time, to represent time intervals in millisecond resolution. When reading, a unit-specifier character is allowed to specify milliseconds (ms), seconds (s), minutes (m), hours (h) or days (d). For example, "1h 20s" specifies 1 hour and 20 seconds. [More Info]

Standard Objects[Bearbeiten]

In order for a "well known" environment to be provided to those who know JS, but do not know Smalltalk, mimicri classes (Math) and protocol has been added to the underlying Smalltalk system. This is described below. Notice that this represents only a small fraction (less than 1/100) of the real functionality of the base system. In order to find out more about all existing classes, you should open a class browser and navigate through the system yourself. There is also a more detailed introduction to the basic classes found at [1].

Math[Bearbeiten]

Constants[Bearbeiten]
  • E
    Euler's constant, the base of the natural logarithm (approximately 2.718)
  • LN10
    Natural logarithm of 10 (approximately 2.302)
  • LN2
    Natural logarithm of 2 (approximately 0.693)
  • LOG10E
    Base 10 logarithm of E (approximately 0.434)
  • LOG2E
    Base 2 logarithm of E (approximately 1.442)
  • PI
    Pi (approximately 3.14159)
  • SQRT1_2
    Square root of 1/2 (approximately 0.707)
  • SQRT2
    Square root of 2 (approximately 1.414)
Min & Max[Bearbeiten]
  • max(number1 , number2)
    Returns the largest of 0 to 5 arguments
  • min(number1, number2)
    Returns the smallest of 0 to 5 arguments
Miscellaneous[Bearbeiten]
  • abs(aNumber)
    Returns the absolute value of aNumber
  • binco(n, k)
    Returns the binomial coefficient C(n,k) (n over k, choose k from n)
  • ceil(aNumber)
    Returns the smallest integer greater than or equal to aNumber
  • exp(aNumber)
    Returns EaNumber, where aNumber is the argument, and E is Euler's constant, the base of the natural logarithm
  • fac(aNumber)
    Returns the factorial of aNumber
  • floor(aNumber)
    Returns the greatest integer less than or equal to aNumber
  • gcd(a, b)
    Returns the greatest common divisor of a and b
  • log10(aNumber)
    Returns the log base 10 of aNumber
  • log(aNumber)
    Returns the log base E of aNumber
  • pow(base, exp)
    Returns base to the exponent power, that is, baseexp
  • random
    Returns a pseudo random number between 0 and 1
  • round(aNumber)
    Returns the value of aNumber rounded to the nearest integer
  • sqrt(aNumber)
    Returns the square root of aNumber
Trigonometric[Bearbeiten]
  • acos(aNumber)
    Returns the arccosine (in radians) of aNumber
  • asin(aNumber)
    Returns the arcsine (in radians) of aNumber
  • atan2(x, y)
    Returns the arctangent of the quotient of its arguments (in radians)
  • atan(aNumber)
    Returns the arctangent (in radians) of aNumber
  • cos(aNumber)
    Returns the cosine of aNumber (given in radians)
  • sin(aNumber)
    Returns the sine of aNumber (given in radians)
  • tan(aNumber)
    Returns the tangent of aNumber (given in radians)

Number[Bearbeiten]

Properties[Bearbeiten]
  • MAX_VALUE
    The largest representable number
  • MIN_VALUE
    The smallest representable number
  • NEGATIVE_INFINITY
    Returns the special 'negative infinity' value
  • NaN
    Returns the special 'not a number' value
  • POSITIVE_INFINITY
    Returns the special 'positive infinity' value
Methods[Bearbeiten]
  • asFloat()
    Returns a floating-point version of the receiver object. For example: "1.asFloat()" yields the floating point number: "1.0".
  • asInteger()
    Returns an integer version of the receiver object (truncating). For example: "1.0.asInteger()" yields the integer number: "1". Alternatives are ceiling(), floor() and rounded().
  • ceiling()
    For non-integral values, ceiling returns the smallest integer which is larger than the receiver. For integers, the original value is returned. For example: "1.4.ceiling()" yields the integer number: "2", whereas "1.ceiling()" returns "1". See also: floor() and rounded().
  • floor()
    For non-integral values, floor returns the largest integer which is smaller than the receiver. For integers, the original value is returned. For example: "1.4.floor()" yields the integer number: "1", whereas "1.floor()" returns "1". See also: ceiling() and rounded().
  • rounded()
    For non-integral values, rounded returns the nearest integer from rounding. For integers, the original value is returned. For example: "1.4.rounded()" yields the integer number: "1", "1.6.rounded()" yields the integer number: "2" and whereas "1.rounded()" returns "1". See also: ceiling() and floor().
  • roundTo(r)
    Rounds towards the nearest multiple of r. For example, "1.543.roundedTo(0.01)" returns "1.54" and "1.567.roundedTo(0.01)" returns "1.57". See also: ceiling(), floor() and rounded().
  • toExponential(nDigits)
    Returns a string representing the number in exponential notation, where nDigits is the number of digits to appear after the decimal point
  • toExponential(nDigits, nDigitsAfter)
    Returns a string representing the number in exponential notation
  • toFixed(nDigits)
    Returns a string representing the number in fixed notation, where nDigits is the number of digits to appear after the decimal point

Random[Bearbeiten]

  • nextBoolean
    Randomly returns either true or false
  • next
    Returns a random number between 0 and 1 (float)
  • nextIntegerBetween_and_(min, max)
    Returns a random integer between min and max (use 1 and 6, to simulate a dice)


Time / Date[Bearbeiten]

  • getDate
    Returns the day of the month (1..31)
  • getDay
    Returns the day of the week (0..6); Sunday is 0
  • getFullYear
    Returns the year
  • getHours
    Returns the hours (0..24)
  • getMinutes
    Returns the minutes (0..60)
  • getMonth
    Returns the day of the month (1..12)


String[Bearbeiten]

  • charAt0(index)
    Returns the n'th character, using a 0-based indexing scheme
  • charAt1(index)
    Returns the n'th character, using a 1-based indexing scheme
  • charCodeAt0(index)
    Returns the code of the n'th character, using a 0-based indexing scheme
  • charCodeAt1(index)
    Returns the code of the n'th character, using a 1-based indexing scheme
  • indexOf0(aCharacter)
    Returns the index of aCharacter, using a 0-based indexing scheme; -1 if not found
  • indexOf1(aCharacter)
    Returns the index of aCharacter, using a 1-based indexing scheme; 0 if not found
  • lastIndexOf0(aCharacter)
    Returns the last index of aCharacter, using a 0-based indexing scheme; -1 if not found
  • lastIndexOf1(aCharacter)
    Returns the last index of aCharacter, using a 1-based indexing scheme; 0 if not found
  • quote
    Wraps the receiver into quotes ("")
  • split(separator)
    Splits the string into a collection of substrings using the separator
  • substr0(index, count)
    Extracts a substring starting at the index with the given length, using a 0-based indexing scheme
  • substr1(index, count)
    Extracts a substring starting at the index with the given length, using a 1-based indexing scheme
  • substring0(index1)
    Extracts a substring starting at the index, using a 0-based indexing scheme
  • substring0(index1, index2)
    Extracts a substring between the given indices, using a 0-based indexing scheme
  • substring1(index1)
    Extracts a substring starting at the index, using a 1-based indexing scheme
  • substring1(index1, index2)
    Extracts a substring between the given indices, using a 1-based indexing scheme
  • toLowerCase
    Returns a copy of the receiver with all chars in lower case
  • toUpperCase
    Returns a copy of the receiver with all chars in upper case
  • trim
    Returns a copy of the receiver with all leading and trailing white space removed
  • trimLeft
    Returns a copy of the receiver with all leading white space removed
  • trimRight
    Returns a copy of the receiver with all trailing white space removed

 

Collection (Array)[Bearbeiten]

  • concat(aCollection)
    Returns a new collection consisting of the concatenation of the receiver and the argument
  • every(filterFunction)
    Returns true, if "filterFunction" returns true for all elements
  • filter(filterFunction)
    Selects elements for which "filterFunction" returns true
  • forEach(function)
    Applies "function" for each element
  • join(seperator)
    Joins the strings of the receiver into a single string using the separator
  • map(function)
    Returns a new collection collecting the results of applying "function" to each element in sequence
  • pop
    Removes and returns the last element of the collection
  • push(value)
    Adds an element to the end of the collection
  • reduce0(filterFunction)
    Applies "function" against two values, reducing from left to right. Function must be declared as: f(previousValue, currentValue, index, arr). Pass 0-based indices to the filter.
  • reduce0(filterFunction, initialValue)
    Applies "function" against two values, reducing from left to right. Function must be declared as: f(previousValue, currentValue, index, arr). Pass 0-based indices to the filter.
  • reduce1(filterFunction)
    Applies "function" against two values, reducing from left to right. Function must be declared as: f(previousValue, currentValue, index, arr). Pass 1-based indices to the filter.
  • reduce1(filterFunction, initialValue)
    Applies "function" against two values, reducing from left to right. Function must be declared as: f(previousValue, currentValue, index, arr). Pass 1-based indices to the filter.
  • shift
    Removes and returns the first element of the collection
  • slice0(index1, index2)
    Extracts a subcollection, using a 0-based indexing scheme
  • slice1(index1, index2)
    Extracts a subcollection, using a 1-based indexing scheme
  • some(filterFunction)
    Returns true, if "filterFunction" returns true for any element
  • unshift(arg)
    Adds an element to the beginning of the collection

 

Transcript[Bearbeiten]

The global variable "Transcript" refers to either the transcript information window (if it is open) or the standard error stream. As such, it implements most of the stream interface functions. Most noteworthy are:

  • cr()
    Adds a linebreak (i.e. followup text will be shown on the next line)
  • show(arg)
    Adds a textual representation of the argument, which can be a string, number or any other object.
  • showCR(arg)
    A combination of show(), followed by a linebreak.

 

Expecco Objects[Bearbeiten]

Many object are reachable by elementary code (i.e. from within an elementary-coded action's code). A lot of useful and required information can be aquired by consulting these objects. The anchor to all those objects is the "current activity" object.

Current Activity[Bearbeiten]

Within elementary code the activity instance which is executing this piece of code can be accessed via the variable "this" (Smalltalk: "self"). For every executed action, a new activity object is created. It is usually alive during the execution only (i.e. it is destroyed and its memory reused automatically, after the block's action has finished). It supports the following functions:

Reporting[Bearbeiten]

  • error()
    Report a defect (in the test). Stops execution.
  • error(infoString)
    Report a defect (in the test). Stops execution.
  • fail()
    Report a failure (in the SUT). Stops execution.
  • fail(infoString)
    Report a failure (in the SUT). Stops execution.
  • inconclusive()
    Report an inconclusive test. Stops execution.
  • inconclusive(infoString)
    Report an inconclusive test. Stops execution.
  • success() OBSOLETE - see below
    Finishes the current activity with success.
  • success(infoString) OBSOLETE - see below
    Finishes the current activity with success.
  • activitySuccess()
    Finishes the current activity with success.
  • activitySuccess(infoString)
    Finishes the current activity with success.
  • pass()
    Finishes the current testCase with success.
  • pass(infoString)
    Finishes the current testCase with success.

 

Logging[Bearbeiten]

  • logData(data)
    Adds data to the activity log.
  • logDataFile(fileName)
    Adds a file attachment to the activity log.
  • logError(messageString)
    Adds a error message to the activity log.
  • logError(messageString, detail)
    Adds a error message to the activity log.
  • logWarning(messageString)
    Adds a warning to the activity log.
  • logWarning(messageString, detail)
    Adds a warning to the activity log.
  • logInfo(messageString)
    Adds an info message to the activity log.
  • logInfo(messageString, detail)
    Adds an info message to the activity log.
  • logImageInfo(messageString, image)
    Adds an info message with an image (screendump) to the activity log. There is an option in the report generator to include those in the generated pdf-report.
  • alert(messageString) (1.8.1)
    Adds an warning message to the activity log, and also shows a DialogBox, which has to be confirmed by the operator. The dialog box and confirmation can be disabled by a settings flag in the "Execution - Log -Settings" dialog (by default, it is disabled).
  • warn(messageString) (1.8.1)
    Same as alert() (for Smalltalk compatibility).

Notice the similarity and difference between "error()" and "logError()": both actually create a log-data entry, but "error()" stops the execution, whereas "logError()" proceeds (maybe, the naming is a bit confusing here...)  

Reflection, Information, Queries and Accessing[Bearbeiten]

  • activityCreator()
    The triggering activity (i.e. the caller)
  • activityProcess()
    The thread executing the activity
  • blockDescription()
    The definition of the activity (i.e. the tree definition item of the action's step)
  • environment()
    The currently valid environment variables
  • environmentAt(anEnvironmentVarName)
    The value of an environment variable
  • environmentAt_put(anEnvironmentVarName, value)
    Changing the value of an environment variable.
  • executor()
    Returns the current executor.
  • inputValueForPin(pinName)
    The value of a certain pin
  • inventory()
    The inventory of the activity
  • nameOfStep()
    The name of the corresponding step of the activity
  • resources()
    All resources which have been aquired for the activity (as specified in the resource-definition of the action). Retrieves a collection of Resource objects, as described below.
  • resourcesForId(skillId)
    Resources which have been aquired for one particular skill-requirement. The argument skillId corresponds to the name as specified in the first column of the resource definition of the action). Notice, that a collection of Resource objects is returned - even if only one resource has been aquired.
  • step()
    The corresponding step of the activity

 

Executor Functions[Bearbeiten]

  • executorsWorkingDirectory()
    Temporary working directory. This is removed after the execution (i.e. useful only for very temporary files, which are generated in an action and read in another)
  • testplan()
    The currently executed testplan (nil if a block test blocks are executed)
  • project()
    Project (testsuite or library) in which the test is executed

 

Resource Functions[Bearbeiten]

  • name()
    The name of the resource
  • skillNamed(nameOrUUID)
    Fetch a concrete skill-value of that resource. The argument can be either a skills name, or the functional-UUID of the skill element (in the project tree).
  • skillAttributeNamed(name)
    Fetch a concrete skill-attribute-value of the resource

 

Project Functions[Bearbeiten]

  • documentation()
    The documentation or nil
  • functionalId()
    A unique ID which defines this testSuite independent of its name (remains constant after change)
  • projectsWorkingDirectory()
    Project directory - i.a. all attachments. This directory is created when a project file is loaded and is deleted when expecco is closed. Do not use it for permanently needed files.
  • modelLanguageStringFor(aString)
    translates a string according to the model-language translation table
  • versionId()
    A unique ID which defines this testSuite in exactly this version. (changed with any edit operation)

 

Testplan Functions[Bearbeiten]

  • documentation()
    The documentation or nil
  • name()
    The name of the Testplan
  • tags()
    A collection of tags of the testplan
  • functionalId()
    A unique ID which defines this testplan independent of its name (remains constant after change)
  • versionId()
    A unique ID which defines this testplan in exactly this version. (changed with any edit operation)

 

Step Functions[Bearbeiten]

  • name()
    The name of the Step
  • tags()
    A collection of tags of the Step

 

Pin Functions[Bearbeiten]

The input and output pins can be referenced in elementary code by their name. The name refers to the pin - NOT the passed value (this allows for the code to check, if a value is present). For indexed pins (i.e. in steps with a variable number of pins), which is a new feature in v2.1, the collection of pins is referred to by the name, and pins are accessed via an index (1..). See more about how to handle variable pins in the section below.

  • datatype()
    Returns the data type of the pin (Reflection-API)

 

Input Pins:[Bearbeiten]
  • hasValue()
    Returns true if the pin has received a value (important for the trigger conditions ANDConnected and OR)
  • hasEnvironmentFreezeValue()
    Returns true if the pin has a freezeValue from an environment
  • hasFreezeValue()
    Returns true if the pin has a freezeValue
  • isConnected()
    Returns true if the pin is connected (but not frozen)
  • value()
    Returns the value of the pin. Raises an error if the pin did not receive any value.
  • valueIfAbsent(alternativeValue)
    Returns the value of a pin or the alternativeValue if the pin did not receive any value.
  • valueIfPresent()
    Returns the value of a pin or nil if the pin did not receive any value. Similar to "value()", but avoids the exception.
  • waitForValue()
    The pin has to be a mailbox pin. The execution will be interrupted until the pin receives a value.
  • waitForValueWithTimeout(seconds)
    Like above, but the execution will only wait for the specified time limit given in seconds. The parameter is typically an integer, but can also be a fraction (1/3) or a floating-point number (0.3).

 

Output Pins:[Bearbeiten]
  • isBuffered()
    True if the pin is buffered
  • isConnected()
    Returns true if the pin is connected
  • value(data)
    Writes the value.

 

Variable Input Pins[Bearbeiten]

Starting with expecco v2.1, steps can have a variable number of input pins (after placement of the step, pull the pin-handle, to add or remove pins). In elementary code, the following API call entries (to the variable pin) are provided to deal with this situation:

  • numberOfVariablePins()
    returns the number of pins
  • values()
    Retrieves the values passed to the pins as an array.
  • valueAt(i)
    to get the i'th pin's value

 

Functions for Any Tree- or Diagram Element[Bearbeiten]

These include: BlockDescriptions, Types, TestPlans, TestCases, Steps, Connections, Pins, Annotations etc.

  • id
    A globally unique identifier (GUID or UUID).
  • tags
    A collection of tags.
  • isAnnotation
    true, if it is an annotation (in a diagram)
  • isStep
    true, if it is a step (in a diagram)
  • isConnection
    true, if it is a connection (in a diagram)
  • isBlockdescription
    true, if it is a block description (in the tree)
  • taggedValueAt (aKey)
    To retrieve a tagged value. These are usually preserved when objects are transported to/from other systems.
  • taggedValueAt_put (aKey, anObject)
    to change a tagged value. Only a limited set of datatypes are supported: anObject must be a String or a Number.
  • propertyAt (aKey)
    to retrieve an expecco property. These are expecco-internal properties. These are usually not recognized by other systems.
  • propertyAt_put (aKey, anObject)
    to set an expecco property. These are usually not recognized by other systems. Only a limited set of datatypes are supported: anObject must be a String or a Number.

 

Groovy Elementary Blocks[Bearbeiten]

Code written in a Groovy Elementary Block is not executed directly by expecco. Instead, the code is forwarded to a Groovy shell which runs inside a Java Virtual Machine (JVM). This may be a local JVM whose sole purpose is to provide additional utility functions, or the JVM which executes the tested application running on the system under test (SUT). By using Groovy blocks, expecco's basic black box test functionality can be easiliy extended by many powerful white-box tests. You can access the internals of objects inside the SUT, define classes and functions and call them.

The machinery to interact with a JVM (and therefore to execute groovy code blocks) requires the JavaBridge plugin, which is not part of the basic expecco package. Groovy itself is avalable for free as a jar class library, which is loaded with or into the target application. The JavaBridge plugin already includes a prepackaged Groovy interpreter which can be loaded transparently into the SUT application whenever a Groovy block is executed.

Why use Groovy Elementary Blocks ?[Bearbeiten]

The JavaBridge and especially Groovy code is very useful when testing GUI frameworks, communication protocls or machine control soft- and hardware which is written in Java. Especially, if you have to call functions internal to the SUT in order to trigger actions or if you need to be informed about state changes (i.e. to install listeners and callbacks).

Groovy Block Performance Issues[Bearbeiten]

When a groovy action is executed for the very first time, the block's code is transmitted via the bridge to the groovy shell on the target JVM as a string. There, the code is parsed and an anonymus jar is created, containing java byte code. Thus, there is some initial overhead involved in both sending the code and more so in compiling the code in the JVM. However, for every followup call, the JWM will directly call the generated code and run at full java speed (i.e. the execution speed is almost as if native Java code was executed).

Using a Single Local JVM Connection[Bearbeiten]

By default, a groovy action is executed on a JVM which runs on the local machine; i.e. the machine on which expecco itself is running. Whith the execution of the very first groovy action, a JVM is started as defined in the expecco settings dialog then a bridge connection is established to that JVM, and the Groovy interpreter is loaded and instantiated on the JVM. Then a reference to that GroovyShell object is remembered and used for all followup groovy actions which are to execute on that local JVM. This default behavior is convenient if you want to use java support libraries for reporting, statistics or other computations and/or if your SUT is running inside a local JVM.

Using a Particular JVM Connection[Bearbeiten]

If you either need to customize the JVM startup and/or your test scenario has to talk to one or multiple remote systems (or multiple java programs within one scenario), you have to setup multiple java connections, and pass the connection to use to your Groovy actions. This can be done either via an input pin, or via an expecco environment variable. The algorithm to provide this is as follows:

  • if the action has a pin named "groovy", and it is connected, that pin's value is used as Groovy shell handle
  • otherwise, if the environment contains a variable named "GROOVY", that variable's value is used
  • otherwise, a Groovy shell is instantiated and used, on the JVM which is given by:
    • if the action has a pin named "java", and it is connected, that pin's value is used as java-bridge handle
    • otherwise, if the environment contains a variable named "JAVA", that variable's value is used
    • finally, otherwise a local JVM connection is used.

To use input pins, you have to create corresponding pins manually, and the pin names MUST be "java" / "groovy". You cannot use these two reserved names as regular input pin names.

Calling Existing Code in the System Under Test[Bearbeiten]

A Groovy block's code looks very similar to a regular JavaScript block's code. However, it is executed on the SUT, and can therefore instantiate Java objects and call static and member functions.

For example, too call a static function named "foo" in a class named "MyTestClass", use the following groovy block:

def execute() {
    MyTestClass.foo("hello world");
}

if the class is located in another package (or especially: in one of your own), use explicit package prefixes:

def execute() {
    javax.swing.JFrame frame = new javax.swing.JFrame();
    javax.swing.JButton button = new javax.swing.JButton( "Press Me" );

    frame.add(button);
    frame.setSize(300,100);
    frame.setVisible(true);
}

or an import declaration:

import javax.swing.*;

// end of import definitions

def execute() {
    JFrame frame = new JFrame();
    JButton button = new JButton( "Press Me" );

    frame.add(button);
    frame.setSize(300,100);
    frame.setVisible(true);
}

Notice that you may not remove the comment line starting with "// end of....".
This separator pattern has been hardcoded into the Groovy machinery to separate any class and import definitions from the execution method.

Defining a New Class in the System Under Test[Bearbeiten]

You can define your own classes in a Groovy block:

class MyClass extends Object {
    Object someState;

    def set_someState(Object newValue) {
        someState = newValue;
    }
    def get_someState(Object newValue) {
        return someState;
    }
    def toString() {
        return "a very\nlong\nmultiline\na\nb\nstring\n;
    }
}

// end of local definitions

def execute() {
    outputPin.value( new MyClass() );
}

Instances of new classes may be required especially to install listeners and callbacks when testing UI or server applications. A typical scenario is when you want expecco to be informed about mouse or keyboard events (MouseListener).

Datatype Limitations[Bearbeiten]

Integer types[Bearbeiten]

As Groovy executes on top of a regular JVM, the integer range is limited to 32bit (64 bit for "long int" types). No automatic conversion between small and large integers is performed. If required, you will have to use a BigNum package and/or cast int to long int.

No Smallalk Classes[Bearbeiten]

Of course, no Smalltalk classes can be used directly in Groovy code. However, all Java classes are at your hands now! Some limited interaction with expecco and underlying Smalltalk objects is possible via the "eval()" and "perform()" APIs.

Groovy Code API[Bearbeiten]

Groovy code supports a subset of the above activity functions:

Current Activity (Groovy)[Bearbeiten]

The current activity instance is accessed as "this". For every executed action, a new activity object is created. It is usually alive during the execution only (i.e. it is destroyed and its memory reused automatically, after the block's action has finished). In Groovy (as in JavaScript or Java), if no receiver is given for a function call, "this" is the implicit receiver. Thus the statements "this.logInfo("hello")" and "logInfo("hello")" are equivalent.

Reporting (Groovy)[Bearbeiten]

  • error()
    Report a defect (in the test). Stops execution.
  • error(infoString)
    Report a defect (in the test). Stops execution.
  • fail()
    Report a failure (in the SUT). Stops execution.
  • fail(infoString)
    Report a failure (in the SUT). Stops execution.
  • inconclusive()
    Report an inconclusive test. Stops execution.
  • inconclusive(infoString)
    Report an inconclusive test. Stops execution.
  • activitySuccess()
    Finishes the current activity with success.
  • activitySuccess(infoString)
    Finishes the current activity with success.
  • pass()
    Finishes the current testCase with success.
  • pass(infoString)
    Finishes the current testCase with success.

Logging (Groovy)[Bearbeiten]

  • logError(messageString)
    Adds a error message to the activity log.
  • logError(messageString, detail)
    Adds a error message to the activity log.
  • logWarning(messageString)
    Adds a warning to the activity log.
  • logWarning(messageString, detail)
    Adds a warning to the activity log.
  • logInfo(messageString)
    Adds an info message to the activity log.
  • logInfo(messageString, detail)
    Adds an info message to the activity log.
  • alert(messageString)
    Adds an warning message to the activity log, and also shows a DialogBox, which has to be confirmed by the operator. The dialog box and confirmation can be disabled by a settings flag in the "Execution - Log -Settings" dialog (by default it is disabled).
  • warn(messageString)
    Same as alert() (for Smalltalk compatibility).

Reflection, Information, Queries and Accessing (Groovy)[Bearbeiten]

  • environmentAt(anEnvironmentVarName)
    The value of an environment variable
  • environmentAt_put(anEnvironmentVarName, value)
    Changing the value of an environment variable.
  • nameOfActiveTestPlan()
    The name of the currently executing text plan
  • nameOfActiveTestPlanItem()
    The name of the currently executing text case
  • nameOfStep()
    The name of the corresponding step of the activity

Interaction with Expecco (Groovy)[Bearbeiten]

  • eval(smalltalkCodeString)
    Evaluate a piece of Smalltalk code inside expecco.
  • evalJS(javascriptCodeString)
    Evaluate a piece of JavaScript code inside expecco.

Pin Functions (Groovy)[Bearbeiten]

Input Pins (Groovy)[Bearbeiten]
  • hasValue()
    Returns true if the pin has received a value
  • value()
    Returns the value of the pin. Raises an error if the pin did not receive any value.
  • valueIfAbsent(alternativeValue)
    Returns the value of a pin or the alternativeValue if the pin did not receive any value.
Output Pins (Groovy)[Bearbeiten]
  • isBuffered()
    True if the pin is buffered
  • value(data)
    Writes the value.

Attention:
Groovy uses many more reserved keywords for syntax than JavaScript or Smalltalk. These cannot be used as pin names, and you will get a syntax error ("<foo> token not expected"). Be careful to not name your pins as any of: "in", "return", "class", "private", "public", etc. As a proven best practice, add a "Pin" suffix to your pins (i.e. name it "inPin", instead of "in").  

Transcript, Stderr and Stdout[Bearbeiten]

The expecco "Transcript", "Stderr" and "Stdout" are also accessable from Groovy code. However, only a limited subset of messages is supported:

  • cr()
    Adds a linebreak (i.e. followup text will be shown on the next line)
  • show(arg)
    Adds a textual representation of the argument, which can be a string, number or any other object.
  • showCR(arg)
    A combination of show(), followed by a linebreak.
  • writeLine(string)
    For compatibility with Java's PrintStream protocol.

 

Examples[Bearbeiten]

Square Root Block[Bearbeiten]

A function, which computes the square root of its input value, could be implemented like that: (the names of the pins are: in and out, their data type is Number):

JavaScript[Bearbeiten]
execute() {
    var inValue;

    inValue = in.value;          // Reading input pin value
    out.value( inValue.sqrt() ); // Writing to output pin
}

alternative:

execute() {
    var inValue;

    inValue = in.value;              // Reading input pin value
    out.value( Math.sqrt(inValue) ); // Writing to output pin
}
Smalltalk[Bearbeiten]
execute
    |inValue|

    inValue := in value.       "/ Reading input pin value
    out value: inValue sqrt.   "/ Writing to output pin
Groovy[Bearbeiten]
def execute {
    Object inValue;

    inValue = in1.value();           // Reading input pin value
    out.value(Math.sqrt(inValue));   // Writing to output pin
}

(Notice: "in" is a reserved keyword in Groovy and cannot be used as pin name)

Random-Fail Block[Bearbeiten]

A block, which randomly fails (to demonstrate exception handling), could be implemented like:

JavaScript[Bearbeiten]
execute() {
    var dice;

    dice = Random.nextIntegerBetween_and_(1,6);
    if (dice <= 2) {
        fail();
    }
}
Smalltalk[Bearbeiten]
execute
    |dice|

    dice := Random nextIntegerBetween:1 and:6.
    (dice <= 2) ifTrue:[
        self fail.
    ].


Please note, that besides these direct interfaces with the expecco system described here, you can also use the whole class library of the runtime system. Please check the corresponding Smalltalk/X Documentation as well as the Documentation of the Class APIs.

Here are more examples, using that class library:

Bulk-Data Reading from a File[Bearbeiten]

The following code reads a measurement data block of 100000 floating point values from file. The file was created beforehand by a recorder device, which was triggered by a dll-callout. For the demonstration, the code below does not read its values from input pins. In a more reusable real world application, the size of the file and its fileName should be passed in via input pins, of course.

JavaScript[Bearbeiten]
execute() {
    var N;  // should be read from an input-pin
    var fileName; // should be read from an input-pin
    var dataArray;
    var fileStream;

    N = 100000;
    fileName = 'dataFile.dat';
    fileStream = fileName.asFilename().readStream();
    dataArray = Array.new(N);
    for (i=1; i<=N; i++) {
        dataArray[i] = fileStream.nextIEEESingle();
    }
    out.value(dataArray);
}
Smalltalk[Bearbeiten]
execute
    |N fileName dataArray fileStream|

    N := 100000.
    fileName := 'dataFile.dat'.
    fileStream := fileName asFilename readStream.
    dataArray := (1 to:N) collect:[:i | fileStream nextIEEESingle].
    out value:dataArray.


Sending Messages to the Transcript[Bearbeiten]

JavaScript[Bearbeiten]
execute() {
    Transcript.showCR("---------------------");
    for (var y=1; y<=10; y++) {
        for (var x=1; x<=10; x++) {
            Transcript.show( x * y );
            Transcript.show( " " );
        }
        Transcript.cr();
    }
}
Smalltalk[Bearbeiten]
execute
    Transcript showCR:'---------------------'.
    1 to:10 do:[:y |
        1 to:10 do:[:x |
            Transcript show:(x * y); show:' '.
        ].
        Transcript cr.
    ].
Groovy[Bearbeiten]
def execute() {
    Transcript.showCR("---------------------");
    for (int y=1; y<=10; y++) {
        for (int x=1; x<=10; x++) {
            Transcript.show( x * y );
            Transcript.show( " " );
        }
        Transcript.cr();
    }
}

Reading/Writing Pin Values[Bearbeiten]

Assuming that the block has two pins, named "in1" and "in2" and two output pins, named "out1" and "out2", the following blocks write concatenated strings to both outputs:

JavaScript[Bearbeiten]
execute() {
    out1.value( in1.value() + in2.value() );
    out2.value( in2.value() + in1.value() );
}
Smalltalk[Bearbeiten]
execute
    out1 value:(in1 value , in2 value).
    out2 value:(in2 value , in1 value).

Groovy[Bearbeiten]
def execute() {
    out1.value( in1.value() + in2.value() );
    out2.value( in2.value() + in1.value() );
}

Reading/writing Environment Variables[Bearbeiten]

Assuming that a String-typed environment variable named "IncDec" and an Integer-typed variable named "Counter" exist in the project's environment, and are writable, the following blocks read and write to either variable:

JavaScript[Bearbeiten]
execute() {
    if ( environmentAt("IncDec") == "inc" ) {
        environmentAt_put("Counter", environmentAt("Counter") + 1);
    } else {
        environmentAt_put("Counter", environmentAt("Counter") - 1);
    }
}
Smalltalk[Bearbeiten]
execute
    (self environmentAt:'IncDec') = 'inc' ) ifTrue:[
        self environmentAt:'Counter' put:(self environmentAt:'Counter') + 1).
    ] ifFalse:[
        self environmentAt:'Counter' put:(self environmentAt:'Counter') - 1).
    ]
Groovy[Bearbeiten]
def execute() {
    if ( environmentAt("IncDec") == "inc" ) {
        environmentAt_put("Counter", environmentAt("Counter") + 1);
    } else {
        environmentAt_put("Counter", environmentAt("Counter") - 1);
    }
}



Back to Online Documentation



Copyright © 2014-2024 eXept Software AG