What about function packages?

--
Shmuel (Seymour J.) Metz
http://mason.gmu.edu/~smetz3
עַם יִשְׂרָאֵל חַי
נֵ֣צַח יִשְׂרָאֵ֔ל לֹ֥א יְשַׁקֵּ֖ר

________________________________________
From: IBM Mainframe Discussion List <[email protected]> on behalf of 
Rony G. Flatscher <[email protected]>
Sent: Tuesday, July 2, 2024 6:34 AM
To: [email protected]
Subject: Rexx command handlers implemented in Java and in ooRexx (Re: Rexx is 
quite cool, flexible, powerful, feature-rich, thank you! (Re: z/OS 3.1 
Enhancements & Support News

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 [email protected] with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

Reply via email to