Menu

#60 Overloading object methods

None
open
nobody
Classes (154)
5
2012-08-22
2005-04-29
No

OO Rexx should include the ability to allow multiple
methods of the same name with a different number of
arguments. Java and C++ allow for method overloading
where you can have an object with multiple methods of
the same name but having a different number (or type)
(but this wouldnt apply here since all rexx variables are
strings) of arguments. Example:

lotdata~update(lotform, budgetform, phaseform)
lotdata~update(lotform)

In method1 the lotdata object will initialize not only itself
but other associated objects. In method2 lotdata only
initializes its own data (lotform) This can be done within
the method but it would be nice to be able to separate
the two types of functionality in two different methods.

Discussion

  • Hagrinas

    Hagrinas - 2007-12-02

    Logged In: YES
    user_id=1796550
    Originator: NO

    This limitation is something that I noticed pretty early on into learning ooRexx. I've had a number of times when I've thought that method overloading would be a cleaner approach to what I was doing. A workaround is to create methods with case constructs that call private methods. But it's a mess when you did not write the methods to begin with.

    An "update" method that has Select; when... then ...~update1(...) ; when... ~update2(...) ; otherwise... would get things working. The problem is that an existing update method would probably need to be renamed. But the calling program would not care. It's not exactly clean though.

    The big reason that I never rushed to make an RFE is the fundamental differences between compiled heavily typed languages, and interpreted languages that often don't care about an object's type. The binding time issues are addressed in fundamentally different ways, and in c++, you are telling your member function explicitly to expect certain parameters of a given types and to return a given type of object. Plus, there are header files that make this easier.

    In your example, there are a different number of parameters. That would be an easy case to implement, and it might not be hard to have a single method that handles it anyway. In C++, you might have a method that accepts a single parameter that's a list, and another method with the same name that accepts a single vector. Or you might want to use a template to avoid needing two methods, and end up mimicking what ooRexx might already do by working with either.

    Here's what I would propose. Implement a command to check parameters' types, or add the capability to the USE ARG command.

    For example, Use arg .mymeth1(obj1),obj2,obj3=123,.array(obj4)=(.array~of(1,2,3))

    In this hypothetical example, I'd be saying that the first arg must be a mymeth1 object, the second will be whatever object obj2 happens to be, the 3rd would be whatever object is passed, or 123 if nothing is passed, and obj4 would have to be an array, and if not passed it would be an array of 1,2,3. Any parm that starts with a dot would be the type of object, and the name of the parm in parentheses. The rest would be the same as now. Alternatives might be to change how the methods directive works, have an "accepts" parameter, or a separate command. Since ooRexx does not have header files to map this all out, it would have to be done in such a way that Rexx could find the methods' expectations easily up front.

    If such a command were implemented, and a method had multiple versions, Rexx would have to start off with a version that has type checking, and not allow an overloaded method unless rexx could use type checking unambiguously. To keep old code from breaking, it could allow one version of any overloaded method that does not need type checking, and would be the last in line. If the parms did not match when an object is called, the code could go on to the next method with the same name, until all such methods are exhausted, and then raise a condition (i.e. throw an exception) if nothing suitable is found.

    The justification would be that it would allow certain problems to be addressed more easily. For example, many of the ooDialog methods expect stems. I might want to use arrays. A method with the same name could take an array and create a stem object. It could then send a message to a method with its own name, but with a stem object instead. Rexx would recognize that it needs a different version of the method instead of a recursive call, and I'd have a trivial solution with little coding.

    A programmer would also be able to make code more robust with less effort by telling methods what to expect up front. Currently, even with some of the library methods, there's no such checking. A program might blow up with an error that's 500 lines into some library, while an up front check would have made debugging almost trivial. Writing conditional logic that raises exceptions could be done right now, but it's a lot more work.

    And finally, I'd be able to write more than one method with the same name to avoid method sprawl. I've had things get messy when a program originally needed a string, and eventually was best suited to receiving an object with attributes that were other objects. Some of the original places that used the method might not have had a need to create an entire object of a certain type just to pass a string, and having methods with different names might not be clear.

    Another big advantage is that people with different oo backgrounds might already expect this to be there. Why disappoint them?

     
  • Nobody/Anonymous

    Logged In: NO

    It occurred to me that you can accomplish something pretty close without any changes to the language.

    If method abcd version 1 takes three parameters and you want to overload it, rename abcd to abcd1 and make it a private method. Create a new abcd public method that consists of a Select;
    If Arg()=3 then return self~abcd1(arg1,arg2,arg3), or whatever makes sense based on the parameters passed. If arg(2)~objectname = "an Array", you might return abcdArrayVersion(arg1,arg2,etc) which is also a private method.

    Typically, overloaded methods are listed in sequence anyway, so it won't make the code harder to read. And the person calling the object's methods from the outside can treat it just like any other overloaded method. Programs that called abcd before you overloaded it will still work, and you won't need a slew of new method names when one method name makes sense.

    If anything, a section could be added to the user's guide to explain this, so C++ or Java programmers can have some examples.

     

Anonymous
Anonymous

Add attachments
Cancel