Hi
I’ve gotten very excited about passing data in a procedure call via a jsonClass. It is very flexible and easy to work with - almost like working with an api. I realize that the type control is a bit loose.
The question is whether it is wise to use the same procedure name with different parameters in the prototype instead of a jsonClass.
What you are referring to is called overloading and it is very common. Take a look at Capsoft’s xFiles. You may see multiple different flavors of the Init method. It is a powerful way of adding flexibility to a Class. Here’s what the Clarion help says about it:
"Procedure Overloading means allowing multiple PROCEDURE definitions to use the same name. This is one form of polymorphism. In order to allow this each PROCEDURE using a shared name must receive different parameters so the compiler can decide, based on the parameters passed which PROCEDURE to call.
The idea here is to allow more than one procedure of the same name, but with different prototypes, so separate (but usually similar) operations can occur on different data types. From an efficiency viewpoint, Procedure Overloading is much more efficient than coding a single procedure with omittable parameters, for those cases where you may or may not receive multiple parameters."
The only con that I know of is if you use the AppGen, there is no procedure overloading for the template procedures.
And you do have to be careful not to be ambiguous with your parameters. Usually the compiler will catch that. E.G. you can’t say MyFunc(STRING pMyString) and MyFunc(LONG pMyLong).
An overload I often like is having both of these String types overloaded (that appears ambigous):
( STRING) - Literal or Expression like ('Hello') or (clip(Fname)&' '&Lname)
(*STRING) - String Variable like (Cus:Name)
Class.Append PROCEDURE(string StrLiteralOrExpression)
code
self.Append(StrLiteralOrExpression) !<--- call (*STRING)
return
Class.Append PROCEDURE(*string StrVariable)
code
if StrVariable ... etc
... more code to work on StrVariable ...
return
The (*STRING) passing by address should be faster. The trick is to have the (STRING) method call the (*STRING) like above so the real processing code is just in one place.
Passing by * Address has the risk the Procedure may modify the Variable when it should not. There is a feature that you can add CONST to the prototype so (CONST *String StrVariable) to indicate it may not be changed. The compiler will spot code that modifies and error “Variable Expected”. I wish it said something more obvious like “Variable is CONST so cannot be changed”.
One problem I have is using SIZE(StrVariable) on a CONST variable will error “Invalid Size Parameter” and “Variable expected”. I would call that a compiler bug, maybe @anon77170705 can comment?
I would not like to comment this because it was assumed that the C12 compiler will have many new features in passing and processing functions’ parameters, for example, formal parameters of CSTRING types without necessity to have the RAW attribute. CONSTant parameters of string-like types were among things with slightly other processing. I don’t know current plans regarding changes in the future CLW compiler.
The current CLW compiler passes both address and size parts of the STRING values as a parameter of the CONST *STRING type. So, I don’t see reasons to use it rather than the *STRING type.
The compiler wont catch iirc, but I’m sure @also will correct me.
MyFunc(LONG pMyLong)
MyFunc(BYTE pMyByte1, BYTE pMyByte2, BYTE pMyByte3, BYTE pMyByte4)
Which is handy when trying to decipher some windows API’s and you dont know how the data is being sent/received, because you can pause the clarion debugger in assembler view on the api call and see just what Windows is trying to pass.