Question

Somehow, System.String:Format exists but does not seem to works.

DEFINE VARIABLE strValue AS CHARACTER NO-UNDO.
strValue = "Sebastien".
MESSAGE System.String:Format("Hello {0}", strValue) VIEW-AS ALERT-BOX.

The result was "Hello C:\temp\run.p" instead of "Hello Sebastien".

So I decided to create an equivalent function.

How is it possible to declare a method with undetermined number of parameters?

Example:

METHOD PUBLIC INTEGER Calculate(
    INPUT iMultiply AS INTEGER
    ,INPUT iInt1 AS INTEGER
    ,INPUT iInt2 AS INTEGER
    ...
    ,INPUT iIntX AS INTEGER):

    RETURN iMultiply * (iInt1 + iInt2, ..., iIntX).

END METHOD.

DISPLAY Calculate(10, 1, 2, 3). /* Result: 60 */
DISPLAY Calculate(2, 1, 1, 1, 1, 1). /* Result: 10 */

Thank you! Sebastien

Was it helpful?

Solution

I'm not entirely sure what you are trying to accomplish here. For your first bit of code, you could simply do this:

DEFINE VARIABLE strValue AS CHARACTER NO-UNDO.
strValue = "Sebastien".
MESSAGE "Hello " + strValue VIEW-AS ALERT-BOX.

Or sometimes it is useful to use the SUBSTITUTE function...

DEFINE VARIABLE strValue AS CHARACTER NO-UNDO.
strValue = "Sebastien".
MESSAGE SUBSTITUTE("Hello &1", strValue) VIEW-AS ALERT-BOX.

When you used {0} in your code sample, you were using a run-time parameter (an argument, if you like. {0} is the name of the program, {1} is the first argument for the program, and so on. I don't recommend using run-time arguments - you can't compile that code.

With regards a variable number of parameters for a function, that cannot be done in the OpenEdge ABL. However, you can create classes with overloaded methods. It probably isn't as clean and elegant as you'd like, but it will work. You'd create a class with a bunch of overloaded methods like this:

METHOD PUBLIC VOID Calc(deValue1 AS DECIMAL):
    ...do some stuff...
END METHOD.

METHOD PUBLIC VOID Calc(deValue1 AS DECIMAL, deValue2 AS DECIMAL):
    ...do some stuff...
END METHOD.

METHOD PUBLIC VOID Calc(deValue1 AS DECIMAL, deValue2 AS DECIMAL, deValue3 AS DECIMAL):
    ...do some stuff...
END METHOD.

And so on. The code above will give you the same method (Calc()) with 1, 2, or 3 parameters.

Hope this helps.

OTHER TIPS

You cannot have a method with undetermined number of parameters in ABL.

You should not look for workarounds if you can fix the root cause.

This will work as expected:

MESSAGE System.String:Format("Hello ~{0~}", "Sebastien") VIEW-AS ALERT-BOX INFO BUTTONS OK.

The difference to your version are the tilde characters before the curly braces. The braces have a special meaning in OpenEdge because they are used for compile time functions (includes, preprocessor directives). {0} is replaced by the procedure name at compile time. The tilde is used to escape the curly braces.

This is from OpenEdge Help:

{ } Argument reference

References the value of an argument that a procedure passes to a called external procedure file or to an include file. ABL converts each argument to a character format. This conversion removes the surrounding double-quotes if the parameter was specified as a character string constant in the RUN statement or include file reference. When one procedure is called from another and arguments are used, ABL recompiles the called procedure, substituting the arguments that the calling procedure passes, and then runs the called procedure.

~ Special character

The tilde (~) is an escape character that causes the AVM to read the following character literally. A tilde followed by three octal digits represents a single character. Use it as a lead-in to enter the special characters shown in Table 2. In a procedure, a tilde followed by something other than the items in Table 2 is ignored. For example, "~abc" is treated as "abc". (This may not work as expected when passing parameters to an include file.) The items in Table 2 are case sensitive.

If all your parameters are of the same data type you could use an "indeterminate array". Define the method parameter like this:

METHOD PUBLIC VOID Calc(INPUT numberArray AS INTEGER EXTENT):
  DEFINE VARIABLE iEntriesInArray AS INTEGER NO-UNDO.
  DEFINE VARIABLE iCnt            AS INTEGER NO-UNDO.
  DEFINE VARIABLE iTemp           AS INTEGER NO-UNDO.
  iEntriesInArray = EXTENT(numberArray).
  DO iCnt = 1 TO iEntriesInArray:
    iTemp = numberArray[iCnt].
  END.
END METHOD.

And call it like this:

DEFINE VARIABLE numberArray AS INTEGER EXTENT NO-UNDO.
DEFINE VARIABLE arrayExtent AS INTEGER     NO-UNDO.
arrayExtent = 5.
EXTENT(numberArray) = arrayExtent.
myClass1:Calc (INPUT numberArray).
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top