Deprecated: Function set_magic_quotes_runtime() is deprecated in /home/mwexler/public_html/tp/textpattern/lib/txplib_db.php on line 14
The Net Takeaway: Judoscript 0.9 comments and notes:


Danny Flamberg's Blog
Danny has been marketing for a while, and his articles and work reflect great understanding of data driven marketing.

Eric Peterson the Demystifier
Eric gets metrics, analytics, interactive, and the real world. His advice is worth taking...

Geeking with Greg
Greg Linden created Amazon's recommendation system, so imagine what can write about...

Ned Batchelder's Blog
Ned just finds and writes interesting things. I don't know how he does it.

R at LoyaltyMatrix
Jim Porzak tells of his real-life use of R for marketing analysis.







Judoscript 0.9 comments and notes: · 03/18/2005 03:02 PM,

What is Judoscript?

(First off, if you found this page via a web search or bookmark, you may be much happier in the JudoScript Section of this site to see the multiple articles about Judoscript, including this one, but also about Databases, Graphics, Files, etc. Secondly, the Yahoo Groups is also a great source of help, don’t forget about it!

Judoscript is an open-source Java scripting language written primarily by James Huang (most recently an IT Developer with BEA Systems. Previously, he was a lecturer in the Department of Electric and Computer Engineering at East China Normal University. He’s also a really, really nice guy.)

The language is very similar to Javascript with lots of syntactic sugar to ease Java programming.

Many of the notes below come from his site but I’ve added my own spin to point out some of the really useful stuff. I’ve also glossed over things that he presents really well in the Articles section of his site

Oh, one more thing: James is a frequent updater… when he or the group finds a bug, its often fixed within days with a new jar release. So, always check the date version of your judoscript jar and make sure you have the latest; chances are, your bug is already fixed!

For example, as of this writing, the current version is v0.9, 2005-02-25 (Feb 25, 2005). You can always check the live up-to-date version at the Download page.

More info may wind up at the Judoscript Wiki at some point…

Latest Features
Always check the release notes at; you’ll be amazed at what’s new!

For example, Judoscript now relies heavily on namespaces. This means, for example, using “db::” namespace for all SQL scripting statements. Check the release notes now for the rest of the myriad changes…

Getting Judoscript is the home of Judoscript, including articles, code samples, docs, source, and (of course) the binaries.

Running Judoscript
The easiest way is like this:

 java -jar judo.jar some_program.judo

However, when run with java -jar, the environment classpath is not in effect, i.e., you are only using the classes in the jar file. So, if you have any other classes involved (such as external jars), you shouldn’t use -jar option. Instead, try this (for Windows): java -cp classpath;judo.jar judo test.judo

So, in my case:

 java -cp %classpath%;../judoscript.v0.9/judo.jar judo sw1.judo

or (just including the current dir, ignoring previous classpath)

 java -classpath .;../judoscript.v0.9/judo.jar judo showcp.judo

Note that you still need to either add each jar manually to the classpath this way, or add the to general environment variable. This can be long and annoying if you are using, say, Hsql, or you need additional functionality from existing java code distributed in a jar.

But, if you want to use a java class from within Judoscript, one option is to use “dynamic classpath”:

j = new java::pippo;

java judo [option] filename_or_code
where option is one of these:
-h or —help: this help screeen
-c or —compile: compile
-d or —dump: dump
-q or —quiet: quiet
-x or —exec: commandline arguments as program
-l=level or —logger=level:
start the program with a given logging level.
Valid levels are: ‘trace’, ‘debug’, ‘info’, ‘warn’, ‘error’, ‘fatal’,
from most verbose to least.

When running judoscript, most of the time it prints a copyright banner. Here are some options to control that:
* -c: to compile the script only to check for the syntax.
* -q: quiet mode, run the script without displaying the copyright notice.
* -x: to execute the code specified on the command line. Everything on the command line is concatenated, and an extra ; is appended. For instance, the following are some sample command lines:
java judo -x “println #versionInfo”
java judo -x “println (1234).fmtRoman(‘M’)”
java judo -x “println (1234).fmtHex()”
java judo -x “println 0x4D2”
java judo -x “println 49.95 * 1.0825”


Judoscript is now integrated with Apache commons-logging. This means that lots of additional “INFO” lines get printed by default. If you want, you can set up your logging options by copying judoscript-0.9.jar/ or into your classpath. is in effect if the log4j.jar file is in the classpath; otherwise, if you are runing jdk1.4, then is used (meaning the built in logging from the more recent JVMs). In either of these, you can set the logging level to higher severity (to view less messages).

You can start judo with -l=warn (or -l=error, -l=fatal, or even -l=off) to supress the INFO messages like this:

 java judo -l=error my_script.judo a b c

I’ve also been including these lines in the top of my files, and they seem to help reduce that annoying logging output as well.

 !pragma logger.judo = 'fatal'
 !pragma logger.judo.user = 'fatal'
 !pragma logger.judo.jdbc = 'fatal'
 !pragma logger.judo.hibernate = 'fatal'

Techie Alert: James mentioned this on the groups: To completely turn off the logging messages, you can do this when running judo: java -Drg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog judo .. Also, it is also recommended to have log4j.jar in your classpath to override the JDK1.4 logging, whose default logging message format is funny. Finally, feel free to edit the properties files, but note that they can affect all logging, so be careful.

Basic Syntax Tips
Comments: //, /* … */, /? … ?/, #! (for unix autorun)
// is for single line, and by convention, /* */ is more for regular comments, and /? ?/ is for disabling code. BTW, in SQL statements, the “traditional” — comment is also allowed.

Variables in JudoScript are dynamically typed which means that even though a variable doesn’t have a specific type, the value in it does.

#varname (variable beginning with a pound sign) means constant, immutable variable. However, you do need the “const” decorator:

  const #PI = 3.1415926536;

You can use defined to detect whether a constant has been defined or not. Alternatively, you can compare a constant against the undefined value.

There are actually 4 “null” type values:
null, undefined, eof, and nl

$$varname are internal Judoscript variables (similar to how perl handles things) $_ is another special variable; include “last line read”, etc. just like perl. Its used for when a result is expected but no explicit variable reference is given. Such $_ variables are always in the local scope

Older JudoScript versions required a single $ for variables; that is no longer necessary (but doesn’t hurt). You could also use the var keyword (as in const above), but not really needed.

Scoping works as you’d expect; Variables in the global scope can be accessed explicitly via the :: decorator for the variable name. See “” : for lots of details.

Other special variables
JudoScript has defined a few special variables, like the global variable $$con that holds the default database connection and $$args in a function that is an array that holds all the passed-in parameters. These variables are generally read-only by the application code.

Handy Constants:
#script = Script path
#prog = script name
#cmd_args = an array that contains all the command line arguments; #args is same but without options, #options has the options
#sysprops = the system properties of the currenv JVM
#classpath = the classpath object

Btw, can add to the classpath in script: #classpath.add(‘c:/temp’);

${:} = the platform-dependent path separator. On Unix it is :; on Windows it is ;. This character is frequently used in constructing classpaths.
${/} = the platform-dependent file name separator, that is, the character that separates the file name and directory names in a path. On Unix it is /; on Windows it is \.
${.} = the current directory. This can be changed by the cd command, so it is not strictly a constant value; it starts with the current directory when the script is being run
${~} = the home directory of the user running the script.

If you are a “reflective” programmer, you can create variables programmatically via setVariable() and convertToVariables()

Println formatting codes
Aligned left, right or centered with >, < or * and a width
ex. :>3 means the value printed right-aligned to 3 letters. If the text is longer than 3, it is printed as-is (i.e., no truncation). To truncate any long text to 3 letters, use :>3!

nl means newline.

Format functions include formatBool(), etc.

Can use REPEAT 16 to repeat sequences (or just {16})

Note that print does not put newlines, and flush can clear buffers.

print, println and flush can write text to any of Java’s objects. The built-in print targets include out, err, log and pipe; variables of open text files can be used, too. You can also print into a string.

You can set print flags like debug flags:

 verbose = true;
 println {verbose} 'If you see this, verbose is on.';

The operator @ is string concatenation. (It is not + because that is used for numeric addition. Since JudoScript is a
weakly-typed language, this is necessary.) (And, actually, from v0.9 on, + can be used for strings…)

(Trying to be ECMAScript 4/javascript compliant, as time goes on)

Data Structures
In JudoScript, a variable is a container for any value. A value is either of a simple type (number or string) or an object of some kind. For objects, the value is weakly typed, so the uses determine what type is intended (i.e., lots of implicit coercion, very handy). Constants start with #.

JudoScript supports these primitive data types: integer, floating-point number, string and date/time

Numerically, true is 1 and false is 0 = Boolean.
Otherwise, follows all the standard Java definitions of integer and floating point.

There is no “character” type; characters are strings of 1 character. Otherwise, follows all the usual Java string issues (always creating new ones, etc.)

Can use either double or single quotes to assign strings; if double quotes are used, single quotes are legitimate characters, and vice versa. If both double quotes and single quotes appear in the text, one of them has to be escaped. The escape sequences are the same as in Java. JudoScript supports unicode escape sequence as well.

JudoScript supports two forms of multi-line text literals,==[[* *]]== and [[[* *]]. Both formats quote a chunk of text, which may include new-lines. The [[* *]] is used more often; it allows the chunk of text to be indented, resulting in code that is nicely aligned. In other words, the leading number of whitespace characters at the beginning of each line are stripped. For this reason, it is better not to use tabs to avoid potential confusions. The [[* *]] also trims the leading and trailing whitespace characters. The [[[* *]] format simply quotes the chunk of text as-is. Similar to a “here-doc” from PERL. BTW, in mutli-line text literals, expressions can be embedded with the (* *) syntax. The embedded expressions will be evaluated to string values and concatenated to the rest of the text. Strictly speaking, the text is not a literal any more, but rather, a template.

Embedding works elsewhere as well. Variables (including environment variables) can be embedded all forms of string literals via the ${varname} syntax.

The csv() method turns a character-separated value into an array. It takes a string as its parameter, all “character”s are separators; if missing, uses comma. This method returns null for two consecutive separators; this is different than java.util.StringTokenizer which discards such values. Note that \t can be used for tab (single backslash t)!

  s = '2001/10/01||XYZ|12.00|10000';

  a = s.csv('|');
  println 'Date:   ',a[0];

(Also, \r (carriage return) and \n (linefeed) have their usual meanings, and can be used in searches and such to simulate PERL’s chomp:

DOS: CarriageReturn/LineFeed (“\r\n”)
Unix: LineFeed (“\n”)
Mac: CarriageReturn (“\r”)

Useful methods include isEmpty() and others, Replace() and replaceIgnoreCase(), endsWith(). count() counts the occurrences of a character within the string. Regionmatches allow full regexes.

IgnoreCase() does the same as in java.lang.String. getReader() returns a reader that uses the string as its input. Programs can, for instance, read lines from a string.

Regular expressions
JudoScript uses the regex built into Java 1.4 and above, specifically the java.util.regex classes. The patterns are documented here.

The string data type has these regex methods: matches(), matchesStart(), replaceAll(), replaceFirst(), split() and match(). All these methods take a pattern as their first parameter. The pattern can be a single string, or an array of two strings: the first one is the pattern and the second is the modes.

A nice short PDF explaining how to use Jave regex is here: Java Regex Primer

Here is an example of extracting a pattern and printing it, direct from James and the Judoscript Yahoo group:

  text = '<head><title>Judo</title></head>';
  m = text.matcher('(<title>)(.*)(</title>)');
  while m.find() {
    . m.groupCount();
    . ' : ',;
    . '0: ',;
    . '1: ',;
    . '2: ',;
    . '3: ',;

The result is:

  : <title>Judo</title>
  0: <title>Judo</title>
  1: <title>
  2: Judo
  3: </title>

For those not up with Regex, the parens tell regex to match in groups; the overall found pattern is an implicit group. The first with no index prints the entire overall found pattern; the 0-based indexes print each of the groups in turn.

Note that when we use the matcher() function, the returned object is an instance of java.util.regex.Matcher and can use any of its associated functions. For example, .start() and .end() can print the first and last character position of a group, so strings can be truncated and such…

Date(year, month, day, hour, minute, second, milli-second) where month is an integer between 1 and 12. Date() with no parameters is current date/time.

time() creates a date object with year, month and day fields all initialized to 0. timeToday() is a convenience method that creates a time in today’s date. Also has formatDate() or fmtDate() convenience functions.

System functions

Built In DataTypes:

Arrayone- or multi-dimensional linear container
LinkedListSame as array but is implemented as a linked list.
StructA map (aka Hash); is the root of all user-defined classes. User-defined classes can extend this.
OrderedMapSame as struct except the order in which keys are added is retained. User-defined classes can extend this, too.
SortedMapsimilar to OrderedMap except the keys added are sorted. User-defined classes can NOT extend this.
Stacka first-in-last-out container.
Queuea first-in-first-out container.
Set and Sorted Seta one-dimensional container with no duplicate elements, optimized for testing of the existance of an element.
TableDataa two-dimensional array with column captions and methods for retrieving rows or columns.
TreeNodea convenience for building a tree. User-defined classes can extend this.

Can also use java data:

  hash = new java::Hashtable;
  ba = new java::byte[]{ 0, 1, 2 };

And the “for…in” and “keys=hash.keys; while keys.hasMoreElements()” type loops work on these as well

In fact, can link lots to java:
Nice mention of array usage and access.

Can also Extend Java Classes..

Like perl: The built-in variable $_ representes the current event. In the case of HTML or XML, it represents the tag itself. In GUI programs, it is the event object in various listener methods.


 arr = [ [ 1, 2 ], [ 3, 4 ] ]; // multi-dimension
 arr = new Array( 1, 'abc', date(2001,10,1) );

or linked list…

 lst = linkedList[ 1, 'abc', 
                       new java::Hashtable() ];
 lst = [ linkedList[ 1, 2 ], linkedList[ 3, 4 ] ];

Ways to access arrays:

  zodiacs = [ 'mouse',  'ox',  'tiger', 
                  'rabbit', 'dragon', 'snake', 
                  'horse',  'sheep', 'monkey',
                   'rooster', 'dog',   'pig'];
  for i=0; i<zodiacs.size()-1; ++i { . zodiacs[i]; }
  for i from 0 to zodiacs.lastIndex() { . zodiacs[i]; }
  for x in arr { . x; }

Arrays are 0-base indexed.
.length() or .size() gives number of elements
.append() or .add() adds elements; .prepend() adds to front; .insert() at a specific position

.appendArray() or prependArray() to merge arrays
.subarray() to pull out a chunk
.clear() clears array; .remove() removes a specific element.
.indexof() gives index of an element; .reverse() can reverse the elements

Three ways to enumerate an array:

1. You can iterate “manually” with an index:

 for idx=0; idx < arr.length; ++idx {
   local x = arr[idx];
   println idx, '  ', x;


2. You can let the loop handle the iteration for you:

 for idx from 0 to arr.lastIndex() {
    local x = arr[idx];

    println idx, '  ', x;

3. Or, you can ignore the index entirely and let the loop be both iterator and accessor:

 for x in arr {
    println x;

Can use aggregate functions on array: sum(), max(), min(), average() or avg(), and range()

Can use .sort() (with customized comparator using & as a lambda function), but JudoScript has already included sortAsNumber(), sortAtDate() and sortAsString() methods.

Array has .filter() that takes a user-defined filter function. It can return a new array for the qualified elements, or change the array locally. See

Array .convert() also uses a & (lambda) function to convert.

Multi-dimensional arrays, stacking, and accessing: From the mailing list…

  a = { 'a', 'b', 'c' };
  b = { 'A', 'B', 'C' };
  arr = { a, b, 'hello' };
  println arr[0][1]; // => 'b'

Structs (maps) and Ordered Maps (aka Hashtables)
A struct is nothing but a map.

 names = new struct( Gustavo = 'Kuerton',
                        Paradorn = 'Srichaphan',
                        Conchita = 'Martinez' );
 names.Venus = 'Williams';
 names.('Marat') = 'Safin';

Accessing maps:

 for firstName in names.keys() 
    { . names.(firstName), ', ', firstName; }
 // Remember, . is shortcut for println
 // Result:
 //  Martinez, Conchita, etc.

Can also sort by Values!

 for firstName in names.keysByValue() 
   { . names.(firstName), ', ', firstName; }
 // Result:
 //  Kuerton, Gustavo, etc.

An orderedMap is exactly the same as a struct except the order of the added elements is retained as the order of the keys. Ordered map also has an indexOf() method that works the same way as for arrays. An ordered map essentially serves the use of an array (for the names) along with a name-value mapping, which can be very handy in some situations.

To access an attribute, use the dot operator; if the attribute name has non-identifier characters, have it quoted. If an attribute is not defined, a null is returned.

 println a.'first name';      // access by name
 field = 'first name';        // access by expression
 println a.(field);

To remove an attribute, use .remove() or .delete(). Method .size() returns the number of attributes, and clear() removes them all.

Method .keys() returns all the keys in an array. It is used to enumerate all attributes. Method values() returns an array
of all values.

 a = new Struct( alfa = 'A', beta = 'B', 
                         gamma = 'C', delta = 'D' );
 for x in a.keys() {
       println x, ' => ', a.(x);

Keys and values can be sorted. keysSorted(), keysFiltered(), keysSortedByValue(), keysFilteredByValue() and
keysSortedAndFilteredByValue(). All of them may take a comparator function and/or filter function.
Nice example on using Lambda

BTW, this all works pretty similarly with Java native Hashtables:

 a = new java::java.util.Hashtable;
 a.put('date',      Date(2001,1,1));
 a.put('integer',   1);

 a.put('double',    10.01);
 a.put('string',    'Hello, World!');
 a.put('Dimension', new java::java.awt.Dimension(10,20));
 for k in a.keys() { // for-in statement handles  Enumeration/Iterator
   println k:>10, ' = ', a.get(k);

Stacks and Queues

Java Objects/Arrays
In older versions of Judoscript, the “javanew” command was used to create Java objects or arrays. However, since the 2004-06-20 release, things have changed. Java classes are now just a namespace.

So the new way:

 a = new java::Hashtable;
 b = new java::int[4];
 c = java::Map;

 class MyClass extends java::HashMap { ... }

vs. the old way was:

 a = javanew java.util.Hashtable;
 b = javanew int[4];
 c = javaclass java.util.Map;

 class MyClass extendsjava HashMap { ... }

To access a static member in a Java class, use :: A Java class object can be used to create instances and access/invoke static members/methods. Static members are accessed like normal members.

Control Structures: Loops and Branches
Blocks in JudoScript are formed with { and } (Braces). These control (to some extent) variable scoping as well. Blocks can also have catch and finally clauses for exception handling (more below)

Do As: This is actually one of the most impressive things about JudoScript…. when it works. This “event-driven” statement style allows one to walk a data structure and react to events.

 do 'file' as lines
 do 'http:' as sgml

So, an HTML example:

 do '' as sgml {
  <a>:   if $_.href != null { println $_.href; }
  <img>: println $_.src;

Literally, you can walk a file or a URL in an event driven mode like a SAX parser and pull out tags or other useful stuff.

An XML example:

 do 'data.xml' as xml {
   <order>:       println '==============';
   TEXT<number>:  println 'Order #:   ', $_;
   TEXT<invoice>: println 'Invoice #: ', $_;

If Else
Big tricky thing here: the blocks following if, elif and else expressions do not define new scopes

 if foo() {
     println 'Foo is true!';
 }  elif foo()=TRUE and x=y {  /*Could also be Else If, your choice */
      println 'Foo is true, but there is more afoot...';
 } else {
       println 'Forget it, Foo is just not true.'

Note that you do not need an end if as in other scripting languages.

Case statement here is the SWITCH command. Only one clause can be true. The “else” here is default, which is the fallthrough.

Note that if case 0 is true, you NEED the break to get out of the loop, otherwise you will execute case 1 as well!!! (Yes, this is by design, as annoying as it is. Well, there are times when multiple cases share code, so I guess its handy… but just be careful!)

  switch x {
    case 0:  println 'zero'; break;
    case 1:  println 'uno';  break;
    default: println x;      break;

For statements
There are 3 kinds:
The Java/C++ kind:
for init(); cond(); postproc() {

for a=0; a<3; ++a {
println a;

The for-from-to loop:
for a from 3 to 5 { print a, ’ ‘; }
for a from 10 downto 5 step 2 { print a, ’ ‘; }

And the ever-handy for-in statement to iterate through collections, both JudoScript specific as well as Java natives.

 a = [ 1, 2, 3 ];
 for x in a {
   println loopIndex(), ': ', x;

 /* remember, nl is a newline */ 
 println nl, 'Iterating Java array:'; 
 a = new java::int[]{ 10, 20, 30 };
 for x in a {
   println loopIndex(), ': ', x;
 println nl, 'Iterating java.util.ArrayList:';
 a = new java::ArrayList;
 a.add(100); a.add(200); a.add(300);
 for x in a {
   println loopIndex(), ': ', x;
 a = [ 'elem1', 'elem2', 'elem3', 'elem4' ];
 for e in a                 { println e; }
 for e in a backward        { println e; }
 for e in a from 1          { println e; }
 for e in a to 1            { println e; }
 for e in a from 1 to 2     { println e; }
 for e in a from 2 downto 1 { println e; }
 for e in a downto 1        { println e; }

Sometimes the indices may be indented in addition to the elements, then use the for from to|downto step family statements:

 for a to 3                    { println a; }
 for a from 3 to 5             { println a; }
 for a from 3 to 10 step 2     { println a; }
 for a from 10 downto 5 step 2 { println a; 

And the repeat statement simply repeats a block:
repeat 16 {println ‘Hi!’};

While and Do-While

 a = 3;
 while a >= 0 {
   println a;

 do {
   println a;
 } while a < 2;

As seen with the Switch statement, you can use break and continue to skip out of loops. Continue is like a named goto; the name is a label with a colon…

   for i from 0 to 5 {
     for j from 1 to 5 {
       if i+j < 5 {
         continue aloop;
       } else if i+j >= 10 {
         break aloop;
       println i, '-', j;

If you need to know your current loop index, use loopIndex(). Give it a negative integer to discover the loop index of an outer loop.

Exception Handling
Instead of try/catch, implicit try. Catch, Resume, Finally, and throw. In the catch segment, the exception, whether from the JudoScript engine or Java, is stored in variable $_. It has these members: $_.message or $_.msg, $_.type (an integer), $, $_.line and $_.file. If type is 9, it is a Java exception,
and name is the Java class name of the exception.

Good example at

Functions are basically method calls on the implicit object that is the JudoScript script. That’s the “java-ish” explanation; functions are the missing way to simply change a variable.

Basically, function name parameters. The parentheses around parameters are not required; if parentheses are used, the right parenthesis must match the left one. Functions always return a value; the return statement can return a value and exit the function. If no return statements are called, the function code will fall out of scope and exit, returning undefined. Functions, like any declarations in JudoScript, can appear anywhere, that is, you can call a function before it is declared.

 cnt = 0;
 hanoiTower(4, 'A', 'B', 'C');
 function hanoiTower N, src, aux, dst {
   if N == 0 { return; }
   hanoiTower(N-1, src, dst, aux);
   println 'step ', ++cnt :>2, ':  ', src, ' => ', dst;
   hanoiTower(N-1, aux, src, dst);

BTW: Lambas, a big Groovy thing, are basically anonymous functions, and are here as well. Check it out.

A tableData is an m-by-n, two-dimensional data structure. It has column titles. Each row is referenced as if it’s an array element, but the data in that row can be accessed either via the column index (0-based) or via the column name. It has operations to sort, filter and get data in a column.

  // This makes a tableData with 2 columns, name and age.
  a = new tableData('name', 'age'); 

This is different from a nested array. That is,

  a[0] = [ 'Young Man', 28 ]; 

is the same as

  a[0,0] = 'Young Man';    // Adding in two steps
  a[0,1] = 28;                 // Is this same as the above?

Just printing a row (println ‘a3 = ‘, a3;) yields [Younger Daughter,2]

Data rows can easily be added, and specific cells can be set directly. TableData is particularly useful for short database query results, such as the database meta data. The query result object has a method, .getTableData(), that saves the returned query data into a tableData; a limit can be specified.

 // B becomes an array of column 2 
 //  (0 indexed, remember?)

 b = a.getColumn(1);

What’s the title of a column?

 a.getTitle(0);  // This is the title of the first column, the 0th column)

Which column is which?

  println 'Index for "name" is: ', a.getColumnIndex('name');  

Note that if you don’t use a.setTitleCaseSensitive(false); then the titles become case sensitive!!!

Filtering is using a lambda…

  println '------ Filter for Old and < 100 --------';
  filter = lambda x {
                 return'Old') && x.age < 100;
  printTD a.filter(filter);

  println '------ Sort on column-1 as number ------';
  printTD a.sortByColumnAsNumber(1,false); // false: descending

Printing a TableData is annoying, mostly because the built in functions cannot automatically populate the headings. So, here is a function I wrote to “do it right”. Our own printer function:WexPrint

 function printTD td {
   // Note that this version prints a row number.  That may be annoying.
   // Titles
   print '    ';
   for y to colcnt{
     print td.getTitle(y) :<20!;
   // Separator
   print '    ';
   for x to td.getTitles().length-1 {
     print '------------------- ';
   // Data
   for thisrow to rowcnt  {
     println 'Entering Data Loop';
     print thisrow:>3, ' ';
     rowvals = td[x];
     for y in rowvals {
        print y :<20!;
 } // end of function printTD

(One confusing thing:

    row = td[x]; // Row is now an array, 2 items, right?
    for y in row {
     print y :<20!;}  // What does this for do?  It doesn't separate the array!

Or, use the Judoscript built-in Table printer, printTable. This command winds up being more hassle than its worth b/c it requires manual creation of the column titles. Table data and query results can be easily printed in tabular format with the printTable statement. It does not print the column titles, since they are static and can be embelished to your hearts’ content. The headers should be visually consistent with the data formats for. The columns in this print statment can be the table data columns or expressions thereof and other expressions used as dividers.

 a = new tableData('Name', 'Language Type', 'Birthday');
 a.add('Java',       'System',    date(1996,5,23))
  .add('JudoScript', 'Scripting', date(2001,11,16));

 println 'Language  | Type      | Birthday';
 println '----------+-----------+---------';
 printTable a for column(0) :<10!, '| ',
                  column('Language Type') :<10!, '| ',

For large query results, you may not want to print them all. printTable allows you to skip certain number of rows and limit the numbers of rows printed:

printTable resultSet skip 1000 limit 250
  for ......

Can also print into a string:

 printTable <$myTableStr> myTable for
   column('name') :<20!,
   column('age') :>5!;

 println $myTableStr;

*ActiveX (Excel) Scripting *

Lots of functions on Built-In Object Type: simple

 Instead of lines, can do the usual:
 lineCnt = 0;
 f = openTextFile('');
 while true {
   if (line = f.readLine()) == eof { break; }
   . ++lineCnt :>3, ' ', line;

System Properties
In the class java.lang.System, its static method getProperties() returns a java.util.Properties, which is essentially a name-value pair map, that includes all the system properties. JudoScript’s built-in constant, #sysprops, refers to the system properties. JVM system properties are different from environment variables. The environment variables are for the operating system process that runs the current JVM. In JudoScript, there are two system functions, getenvs() and getenv(name). Alternatively, you can use the ${name} notation in place of getenv(name); tells more about this feature.

Much more detail at
When JudoScript starts, the JVM has an initial classpath called the system classpath. JudoScript also allows additional user classpaths. This is done through the predefined constant, #classpath object.

To add a user classpath component, which can be either a file system directory name or a zip or jar file, use the add() method of #classpath, which can add individual class path name or an array of them. When JudoScript tries to load a Java class or a resource, the classpaths are searched first; if the class or resource is not found, JudoScript tries the system classpath.

 println '---- User classpath components ----';
 for x in #classpath.userClasspaths {
   println x;
 println nl, '---- System classpath components ----';

 for x in #classpath.systemClasspaths {
   println x;


To print to a file, use the same print-family statements:

 function convertToHtml fileName
   outFile = openTextFile(fileName @ '.html', 'w'); // for write.
   . <outFile> '<html><body><pre>';
   do fileName as lines {
     . <outFile> $_.replace('&', '&')
                   .replace('<', '<');
   . <outFile> '
</body></html>'; outFile.close(); } </pre>

This is a function that creates an HTML file for any text file, typically source code. To print into a text file, first open it for write, then use that open file variable in the print statements. We used the string value’s replace() method to escape ‘&’ and ‘<’. String and numbers are simple values. They can be used interchangeably


!include ‘common.judi’
You can even use if to include different programs based on runtime values:
!include if ${LOCALE}==null ‘messages_en.judi’


Declared like functions:

  thread httpHandler req {
  while {
    start thread httpHandler(acceptHttp(ss));



 x = [[*
  Scripting is to do things easily, intuitively, obviously and
  accurately, so much so that when another person with the same
  domain knowledge sees a chunk of code, he immediately
  understands it without even a hint of reasoning (ideally). 

This example puts a chunk of text into a variable. The leading indentations are stripped, so the code can look nice and neat.



  do '' as sgml {
    <a>:   println 'web link: ', $_.href;
    <img>: println 'img link: ', $_.source;

Also, strings have urlEncode() (encodeUrl()), urlDecode() (decodeUrl()) methods.
parseUrl() method that parses a string into a number of URL parts, returned in a struct. Parts include: b.root; b.protocol; b.domain;;b.port; b.path; b.file_name; b.query_string; b.ref;

To send authorization, you’ll have to set the HTTP headers yourself like this:

 $http = httpGet($yourURL);
 $basic_cookie = encode('base64', 'myuser:mypass');
 $http.Authorization = 'Basic ' @ $basic_cookie);
 do $http.getInputStream() as html
  TEXT: flush $_;
  <>: flush $_; // all HTML tags
  <!>: flush $_; // comments, ...
  <?>: flush $_;

manually set a cookie = http.”cookie” = “COOKIE_LOGIN=1;COOKIE_GROUPID=management”;

To view headers:
run snooper.judo and access via http://localhost:8088/snoop: (examples/2.4-apps-internet/http_server/snooper.judo)
(this has other nice utilities…)


Program arguments are stored in the constant array #args. JudoScript supports a predefined format for command-line ptions.
If a parameter starts with / or -, then the rest of it becomes a name=value option pair; if no =, the value is defaulted to true.
When options are present on the command line, they are collected and put in a constant struct #options. The other
paremeters are stored in #args. #options may not be defined. In case you don’t like this format, the complete raw command line parameters are always in a constant array #cmd_args. The program name itself is in a constant string #prog.

Also, can access the classpath with #classpath
Also, can access system properties with #sysprops

 for x in #sysprops {println x;};

to see the properties, or to really see the names=values,

 for x in #sysprops.keys()
   { .x,' = ',#sysprops.(x);}


From the mailing list:
The “for in” statement handles 3 types of “arrays”: JudoScript
arrays, Java arrays (of Object’s or primitive types) and
java.util.List instances. That gives the impression that Java arrays
and List’s behave just like, well, arrays. Unfortunately it is not
the case outside of the “for in” statement AS YET. I will make this
behavior consistent in v1.0, i.e., any Java arrays and Lists should
share all the features of JudoScript arrays, not just the “for in”
statement. Thanks for pointing this out.


Scripting Apps
Nice examination of how to use Judoscript to script Excel

Additional Info:
(translation of page

* * *


  Textile Help
Please note that your email will be obfuscated via entities, so its ok to put a real one if you feel like it...

powered by Textpattern 4.0.4 (r1956)