21.2.13

Output as Argument

Considere a simple mathematical function like add() or multiply() for a simple 2D point object. How would you implement it in case you cannot overload operators?

Do you manipulate the values of the caller with those from the argument, like a += b?
Do you make it a static methode and require 2 argumets? Do you instantiate and return a new object?

a = { x:1 };
b = { x:2 };

// a.x += b.x
a.add( b );   // a.x = 3; b.x = 2;
b.add( a );   // a.x = 1; b.x = 3;

// c.x = a.x + b.x
c = a.add( b );  // a.x = 1; b.x = 2; c.x = 3;
c = M.add( a, b );  // same but static
I would favor the last. A static operation or at least a function that is caller independent as it is slightly better to read. Especially if you have operations where the order matters, like matrix multiplication. But its also nice to manipulate the object directly as you don't end up instantiating objects you might end up ignoring / replacing anyway.

An elegant solution to this is to provide an additional argument where the solution will be stored.
public static function add( a:Object, b:Object, ?output:Object ):Object
{
 if ( output == null ) output = new Object();
 // do your math
 
 return output;
}
This way you can call M.add( a, b, a ) and get the same as a.add( b ) would. You could leave it empty to get a new object or provide one from a pool or temporary variable you want to reuse. Returning the output aswell as setting it has the benefit to allow methode chaining.

Although I like it, it is also unusual to read and I end up using the return value in order to assign it back to the very same object I just passed as the output argument. Its easier that way to see where the solution ends up, but I guess I'll still stick to it just because its a bit more flexible.

No comments:

Post a Comment