Prolog: it seems that the mailer has distorted the code and made it illegible, hence resending the
mail, now with the code preformatted in the hope that than the mailer does not reflow the code.
Sorry about this inconvenience. ---rony
On 01.07.2024 20:45, Phil Smith III wrote:
Paul Gilmartin wrote:
Lack of closure: I don't believe a function package, much less a
command environment can be coded in REXX. those must be coded in
another language, therefore less portable.
Well, that's a good point. OORexx makes that somewhat better, but not like P/P.
But I could imagine writing an interface to enable this. The tricky part with
Classic Rexx would be variable passing, but Pipes demonstrates that it's quite
doable. I think it'd be easier with OORexx, no?
You can implement Rexx command handlers for ooRexx e.g. in C, C++, Java and ...
ooRexx.
The Java bindings for ooRexx has a sample demonstrating how to do that in ooRexx only, see
"samples\Java\handlers\commandHandlers\30_java_starter850\rexxonly". This is what index.html in that
directory says about this sample:
RunRexxProgram.rex
An ooRexx program that configures another Rexx interpreter to use its
two command handlers
named |ONE| and |DEUX| for the Rexx program it runs.
The companion Rexx program sending commands to the command handlers is:
testPreconfiguredCommandHandlers.rex. The two preconfigured command
handlers understand the
following commands:
* HELLO
* INFO
* PING
To run enter the following command on the command line:
rexx RunRexxProgram testPreconfiguredCommandHandlers.rex
In case anyone is curious how such an ooRexx implemented command handler looks like that also takes
advantage of ooRexx features like creating multiple Rexx interpreter instances that can be
differently configured and define two different command handlers (that for demonstration purposes do
the same but can be addressed independently of each other and in parallel) in ooRexx:
parse arg rexxProgram if rexxProgram="" then do say "You must supply the
name of a Rexx program
to run." exit -1 end mgr = .bsf~new("org.apache.bsf.BSFManager") re =
mgr~loadScriptingEngine("rexx") rexxconf = re~getRexxConfiguration say
"default
rexxconf="pp(rexxconf~toString) rhOne = .OneCommandHandler~new jhOne =
BsfCreateRexxProxy(rhOne,
, "org.rexxla.bsf.engines.rexx.AbstractDirectCommandHandler")
rexxconf~addCommandHandler("ONE",
jhOne) rhDeux = .DeuxCommandHandler~new jhDeux = BsfCreateRexxProxy(rhDeux, ,
"org.rexxla.bsf.engines.rexx.AbstractRedirectingCommandHandler")
rexxconf~addCommandHandler("DEUX", jhDeux)
rexxconf~setInitialAddressEnvironment("ONE"); say say
"after configuration:" say "edited rexxconf="pp(rexxconf~toString) say "now
running the Rexx
program you supplied in file """rexxProgram""":" -- Rexx code to run rexxCode=
"call
"""rexxProgram""" ;" - "::requires BSF.CLS ;" -- get ooRexx support
(camouflage Java as ooRexx)
say "rexxCode="pp(rexxCode) signal on syntax -- invoke the interpreter and
call the Rexx program
in the supplied file name re~apply(rexxProgram, 0, 0, rexxCode, .nil, .nil)
mgr~terminate --
make sure that the Rexx interpreter instance gets terminated! exit syntax:
co=condition('o') say
ppJavaExceptionChain(co,.true) say "---" raise propagate ::requires BSF.CLS
-- get ooRexx
support (camouflage Java as ooRexx) ::class OneCommandHandler ::method
handleCommand use arg
slot, address, command, slotDir say "[OneCommandHandler] address="pp(address)
"command="pp(command) parse upper var command cmd . -- carrying out received
commands, return
values set the RC variable in Rexx select case cmd when "HELLO" then return
"Hello, ooRexx! This
is your Rexx (!) OneCommandHandler greeting you!" when "INFO" then return
slotDir~javaObject~toString(slot,address) when "PING" then return "Pong!"
otherwise -- unknown
command received create a failure jarr =
bsf.createJavaArrayOf("java.lang.String", "Unknown
command" pp(command) ) slotDir~javaObject~raiseCondition(slot, "Failure", command,
jarr, "-1")
return .nil end ::class DeuxCommandHandler ::method handleCommand use arg
slot, address,
command, slotDir say "[DeuxCommandHandler] address="pp(address)
"command="pp(command) parse
upper var command cmd . -- carrying out received commands, return values set
the RC variable in
Rexx select case cmd when "HELLO" then return "Hello, ooRexx! This is your
Rexx (!)
DeuxCommandHandler greeting you!" when "INFO" then return
slotDir~javaObject~toString(slot,address) when "PING" then return "Pong!"
otherwise -- unknown
command received create a failure jarr =
bsf.createJavaArrayOf("java.lang.String", "Unknown
command" pp(command) ) slotDir~javaObject~raiseCondition(slot, "Failure", command,
jarr, "-1")
return .nil end
And here the Java version (cf. "samples\Java\handlers\commandHandlers\30_java_starter850") of the
same Rexx command handlers:
import org.apache.bsf.BSFManager; import org.rexxla.bsf.engines.rexx.*;
public class
RunRexxProgram { public static void main (String args[]) { if
(args.length==0) {
System.err.println("You must supply the name of a Rexx program to run.");
System.exit(-1); } try
{ BSFManager mgr= new BSFManager(); RexxEngine re = (RexxEngine)
mgr.loadScriptingEngine("rexx"); RexxConfiguration
rexxconf=re.getRexxConfiguration();
System.err.println("default rexxconf=["+rexxconf+"]\n");
rexxconf.addCommandHandler("ONE" , new
OneCommandHandler()); rexxconf.addCommandHandler("DEUX" , new
DeuxCommandHandler());
rexxconf.setInitialAddressEnvironment("ONE"); System.err.println("\nafter
configuration:");
System.err.println("edited rexxconf=["+rexxconf+"]\n");
System.err.println("now running the Rexx
program you supplied in file \""+args[0]+"\":"); // Rexx code to run String
rexxCode= "call
\""+args[0]+"\" ;" + "::requires BSF.CLS ;" ; // get ooRexx support
(camouflage Java as ooRexx)
// invoke the interpreter and call the Rexx program in the supplied file
name re.apply (args[0],
0, 0, rexxCode, null, null); mgr.terminate(); // make sure that the Rexx
interpreter instance
gets terminated! } catch (Throwable t) { t.printStackTrace();
System.err.println("\n"+t); }
System.exit(0); // exit Java } public static class OneCommandHandler
implements
RexxCommandHandler { public Object handleCommand(Object slot, String
address, String command) {
System.err.println("[OneCommandHandler] address=["+address+"]
"+"command=["+command+"]"); //
split at (and consume) whitespace String [] arrCommand =
command.split("\\p{javaWhitespace}+");
String cmd = ""; if (arrCommand.length>0) { cmd=arrCommand[0].toUpperCase();
// get command,
uppercase it } // excercise the default methods from
RexxRedirectingCommandHandler or
RexxHandler switch (cmd) { case "HELLO": // return values set the RC
variable in Rexx return
"Hello, ooRexx! This is your Java OneCommandHandler greeting you!"; case
"INFO": // return
information about this handler return toString(slot,address); case "PING":
// return values set
the RC variable in Rexx return "Pong!"; default: // unknown command received
create a failure
String [] strAdditional = new String[]{ "Unknown command ["+command+"]" };
// RC:
raiseCondition(slot, "Failure", command, strAdditional, "-1"); return null;
// uses fourth
argument of raiseCondition as RC } } } public static class
DeuxCommandHandler implements
RexxRedirectingCommandHandler { public Object handleCommand(Object slot,
String address, String
command) { System.err.println("[DeuxCommandHandler] address=["+address+"]
"+"command=["+command+"]"); // split at (and consume) whitespace String []
arrCommand =
command.split("\\p{javaWhitespace}+"); String cmd = ""; if
(arrCommand.length>0) {
cmd=arrCommand[0].toUpperCase(); // get command, uppercase it } // excercise
the default methods
from RexxRedirectingCommandHandler or RexxHandler switch (cmd) { case
"HELLO": // return values
set the RC variable in Rexx return "Hello, ooRexx! This is your Java
DeuxCommandHandler greeting
you!"; case "INFO": // return information about this handler return
toString(slot,address); case
"PING": // return values set the RC variable in Rexx return "Pong!";
default: // unknown command
received create a failure String [] strAdditional = new String[]{ "Unknown
command
["+command+"]" }; // RC: raiseCondition(slot, "Failure", command, strAdditional,
"-1"); return
null; // uses fourth argument of raiseCondition as RC } } } }
---
BTW, the ooRexx Java bindings comes with a full implementation of a Rexx command handler implemented
in Java making all of Java2D available as Rexx commands. To see a simple example and the graphic it
creates with Rexx commands see <https://wi.wu.ac.at/rgf/rexx/misc/jdor_doc.tmp/jdor_doc.html>.
Anyone here can probably understand without any further information what happens there.
One of my business administration students is currently creating an ooRexx package for business
graphics that exploits this Java2D Rexx command handler for a Bachelor thesis. It is just
unbelievable how fast he came up with a proof of concept with nice looking bar, line and pie charts,
within a week, believe it or not! The productivity of Rexx, ooRexx and Rexx command handlers allow
for, is just stunning.
... cut ...
---rony
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN