Dynamic Arguments To Procedures

Reading on stackoverflow.com I saw the desire to have parameters like substitute() - that is, an unlimited number of parameters, but only when they are needed. Since Progress already has discovered a need for a tool like this, I'm surprised they haven't made such a thing available to the ABL/4GL. Even I have found myself needing a set of parameters to go to a procedure and frankly, did not do it.

NOT ANYMORE! TODAY I WORKED ON n NUMBER OF PARAMETERS TO GO TO A PROCEDURE!

Personally I would not have done it this if the 4GL was programmer adaptable, but you work with what you got and can.

Implementation

So, basically one works like this:

display Powers ("A 10 as int,B 2 as int").
        

I want to have two parameters and they are both integer type. As you can see, it all goes into a specially formatted string to the function. This adaptation can go after one puts in normal parameters - or all can go into the parameter.


function Powers returns decimal(input Arg as character):
?
? define variable DynArg as DynArgs no-undo.
? define variable A as integer no-undo.
? define variable B as integer no-undo.
?
? DynArg = new DynArgs(Arg).
?
? assign
? A = integer(DynArg:ByName("A"))
? B = integer(DynArg:ByName("B"))
? .
?
? return exp(A,B).
?        
end.
        

So above one can see all the parameters go into a string (32K limit) or a longchar (really constrained by memory size!)

We have an object named DynArgs() which will feed information from the inputs.

There are two ways of feeding the functions arguments:

define variable D as DynArgs no-undo.

D = new DynArgs("").
        

display Powers(D:SetParameter("A", "10", "int") + "," + D:SetParameter("B", "2", "int")).        

or the more understandable

display Powers ("A 10 as int,B 2 as int").        

Both of them can be used. Any type can be made, but the coding is a little weak for character strings. (That can be fixed in a later edition of this!)

Seeing from the above function definition one can use the following to nab the args from the common string:

? define variable A as integer no-undo.
? define variable B as integer no-undo.

  assign
? A = integer(DynArg:ByName("A"))
? B = integer(DynArg:ByName("B"))        
? .
  .
        

This is the heart of the coding for implementing - it simply pulls out the data and gives A and B their values.

But how does the object get the arguments?

function Powers returns decimal(input Arg as character)

? define variable DynArg as DynArgs no-undo.

? DynArg = new DynArgs(Arg).        

From the above we pass in the definable character string as Arg. This then acts as the input to the object, which will break it into pieces to get the arguments from.

It only returns characters for the values so one will need a function to make them the actual value. (A weakness in OOP programming, only one type can be returned.)

After A and B are returned, we send them into exp() for use.

The basics for the class are shown below:

using Progress.Lang.*.

block-level on error undo, throw.

class DynArgs:

? define temp-table Args
??? field TheName as character
??? field TheValue as character
??? field TheType as character.
?? ?
? define property NumberOfParameter as integer get. set.
? define property TheArgs as character get. set.
?
? //? A 5 as int, B 6 as int
? constructor public DynArgs (input A as character):
?? ?
??? define variable Iter as integer no-undo.
??? define variable TheParameter as character no-undo.
?????? ?
??? NumberOfParameter = num-entries(A, ",").
??? TheArgs = A.
?? ?
??? do Iter = 1 to NumberOfParameter:
???? ?
????? TheParameter = trim(entry(Iter, A)). // Help with spacing issues
???? ?
????? message TheParameter.
???? ?
????? create Args.
???? ?
????? assign
????? Args.TheName = entry(1, TheParameter, " ").
????? Args.TheValue = entry(2, TheParameter, " ").
????? Args.TheType = entry(4, TheParameter, " ").
????? .
???? ?
??? end. // do
??? //message "Done".
? end constructor.

? method public void ShowParameter():
?? ?
??? for each Args:
????? display Args.
??? end.
?? ?
? end.
?
? method public character ByName (ValueName as character):
?
??? find Args no-lock
??? where Args.TheName = ValueName
??? no-error.
?? ?
??? if available Args then return Args.TheValue.
?? ?
??? return ?.
?? ?
? end.? // ByName
?
? method public character TheType (ValueName as character):
?? ?
??? find Args no-lock
??? where Args.TheName = ValueName
??? no-error.
?? ?
??? if available Args then return Args.TheType.
?? ?
??? return ?.
?? ?
? end. // TheType
?
? method public character SetParameter (VarName as character, VarValue as character, VarType as character):
?? ?
??? return VarName + " " + VarValue + " as " + VarType.
?? ?
? end.
?        
end class. // DynArgs        

And the implementation as a whole:

function Powers returns decimal(input Arg as character):
?
? define variable DynArg as DynArgs no-undo.
? define variable A as integer no-undo.
? define variable B as integer no-undo.
?
? DynArg = new DynArgs(Arg).
?
? assign
? A = integer(DynArg:ByName("A"))
? B = integer(DynArg:ByName("B"))
? .
?
? return exp(A,B).
?
end.

define variable D as DynArgs no-undo.

D = new DynArgs("").

display Powers ("A 10 as int,B 2 as int").
        
display Powers(D:SetParameter("A", "10", "int") + "," + D:SetParameter("B", "2", "int")).        

Pretty good for a starting point!

I'm not at my computer (because vacation) but what makes this better than having a plain string with comma sep values? For the power function I could also pass in "10,2" to have the function calculate 10^2. In both cases knowledge of what ispassed into the function is needed in both caller and callee.?Additionally, (again, I cannot test it right now) is it possible to pass an object to a function? If so, wouldn't it be just as handy to pass the object? One could "new" the object in the call and have methods to add the parameters. If the methods would return themselves as object, one could also concatenate "add" calls, something like this:message calcPower? ?( new args() ? ? ? ? :addInteger("A", 10) ? ? ? ? :addInteger("B",2) ? ? ) view-as alert-box info

要查看或添加评论,请登录

Scott Augé的更多文章

  • Useful Tool: PHP Wiki (mediawiki)

    Useful Tool: PHP Wiki (mediawiki)

    So many times programmers (or other) want a tool that can be a quick document for work out there. Something to answer…

    1 条评论
  • Management Article: What is quality software?

    Management Article: What is quality software?

    (This is from a E-Zine for developing in Progress. URLs and such are out dated.

  • Menus And The Like On PHP Programs

    Menus And The Like On PHP Programs

    Since it is snowy out today and I have experienced four stokes so don't mind the spelling if it you see an error, I…

  • GetValue() for form/url nvp and cookies with PHP

    GetValue() for form/url nvp and cookies with PHP

    When dealing with PHP and you have Webspeed experience (https://progress.com), it might be useful to create a GetValue()…

  • PHP to 4GL/ABL

    PHP to 4GL/ABL

    Added Entry() and NumEntries() to PHP code for a string of comma delimited substrings like the ABL/4GL has. Also…

  • PHP Code and Dictionary Help Tools

    PHP Code and Dictionary Help Tools

    There are a lot of times when a form on a web app wants information already in the database. Such as the example below:…

  • Queue in PHP (Code)

    Queue in PHP (Code)

    Of course if I write about Stacks(1) (LIFO - Last In, First Out), then I got to write about Queues(1) (FIFO - First In,…

  • Simple stack in PHP (Code)

    Simple stack in PHP (Code)

    Here is a class called Stack that implements a stack. A stack is one of the basic data structures one learns in college.

  • Simple stack in PHP/Maria (Dictionary)

    Simple stack in PHP/Maria (Dictionary)

    This is a dictionary used for a simple stack code in an upcoming article. First of all, what is a stack? Well, it is…

  • HTML/JAVASCRIPT Validating Inputs (using Workbench)

    HTML/JAVASCRIPT Validating Inputs (using Workbench)

    Had a question: How do you validate inputs? (I do pay attention to my comments!) A good question (and gives me the…

社区洞察

其他会员也浏览了