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

Reply via email to