Page 1 of 2

argument order

Posted: Mon Jun 18, 2007 11:30 pm
by Benjamin
Are there any documents which discuss the order in which arguments should be sent to functions/methods in?

Any of you have any preferences, best practices?

Posted: Mon Jun 18, 2007 11:42 pm
by feyd
The only rule is optional arguments go after required ones. Generally speaking, the more frequently used arguments should come first.

Posted: Tue Jun 19, 2007 12:28 am
by Benjamin
I find that only being able to have ending arguments as options is a weak area in PHP.

For example..

Code: Select all

function arguments($a = 1, $b = 2, $c = 3, $d = 4)
{
    echo "a= $a<br/>";
    echo "b= $b<br/>";
    echo "c= $c<br/>";
    echo "d= $d<br/>";
}

arguments(,2,3,4);
causes a [s]fatal[/s] parse error.

There are reasons behind my opinion on this, and the __construct not being able to "decide" what object it wants to return. Not anything I really want to get into at this point.

I don't think adding this functionality would take someone more than an hour or two.

Posted: Tue Jun 19, 2007 12:36 am
by feyd
Considering that's not how most other languages work, it probably wouldn't go over well.

If you want something to choose what object to return you need a Factory.

Posted: Tue Jun 19, 2007 6:01 am
by superdezign
astions wrote:I don't think adding this functionality would take someone more than an hour or two.
As long as PHP is a typeless language, if they were to add overloading, it would be flawed and based purely on the amount of arguments. The language would have to add set data types before that implementation would even make sense. Until then, we've already got overloading based on arguments, just not in the traditional sense.

And in you're example, what'd you'd want (PHP-wise) is:

Code: Select all

function arguments($a = NULL, $b = 2, $c = 3, $d = 4)
{
    if($a == NULL) a = 1;

    echo "a= $a<br/>";
    echo "b= $b<br/>";
    echo "c= $c<br/>";
    echo "d= $d<br/>";
}

arguments(NULL,2,3,4);

Posted: Tue Jun 19, 2007 10:49 am
by Benjamin
I don't understand what your saying or what the problem is. The way I see it is if you set a default value for an argument that is optional, and you don't pass that argument through when you call the function, it should set it to the default value.

PHP is saying that there is a parse error because there is a comma without an argument before it. This is a missing argument and should be treated as one because the function clearly indicates the argument is optional.

Passing through NULL is the same as passing through a value... a NULL value.

Posted: Tue Jun 19, 2007 11:14 am
by superdezign
Right, but that's only if you MUST have that variable first. Like feyd said, the optional variables should come last, and the most used ones first.

Posted: Tue Jun 19, 2007 3:50 pm
by stereofrog
astions wrote:
I don't think adding this functionality would take someone more than an hour or two.
Adding "elisions" ( ,, ) would require slightly more work because there must be a way for the engine to distinguish between "null" or "empty" and "skipped" arguments.

Much more useful would be ability to handle key arguments, like:

Code: Select all

function printPersonalData($name, $age, $state) {
   ....
}

#call

printPersonalData('name' => 'joe', 'state' => 'NY, 'age' => 30);

Posted: Tue Jun 19, 2007 3:59 pm
by feyd
stereofrog wrote:Much more useful would be ability to handle key arguments, like:

Code: Select all

function printPersonalData($name, $age, $state) {
   ....
}

#call

printPersonalData('name' => 'joe', 'state' => 'NY, 'age' => 30);
I don't know if I could agree it's all that useful. Certainly at times it could be, but I'd rather have overloading. :)

Posted: Tue Jun 19, 2007 4:46 pm
by kyberfabrikken
stereofrog wrote: Much more useful would be ability to handle key arguments, like:

Code: Select all

function printPersonalData($name, $age, $state) {
   ....
}

#call

printPersonalData('name' => 'joe', 'state' => 'NY', 'age' => 30);
That would be nice indeed. Until that happens, it's still possible to use an associative array, to achieve about the same thing.

Code: Select all

function printPersonalData($args) {
  $name = $args['name'];
  $age = $args['age'];
  $state = $args['state'];
   ....
}

printPersonalData(Array('name' => 'joe', 'state' => 'NY', 'age' => 30));

Posted: Tue Jun 19, 2007 8:16 pm
by Benjamin
Some other things that have annoyed me is that you can't do things like..

Code: Select all

class blah
{
    private $var = 'x';

    function some_method($x = $this->var)
    {

    }
}
And you also can't do this..

Code: Select all

function some_function($a = array())
{

}

Posted: Tue Jun 19, 2007 8:41 pm
by feyd
astions wrote:

Code: Select all

class blah
{
    private $var = 'x';

    function some_method($x = $this->var)
    {

    }
}
This can't be done in any language that I know.. nor would I want it.
astions wrote:

Code: Select all

function some_function($a = array())
{

}
Considering it's not scalar, i.e. requires evaluation... yeah.

Posted: Tue Jun 19, 2007 8:48 pm
by superdezign
astions wrote:

Code: Select all

function some_function($a = array())
{

}
I could have sworn I've seen this done before...

Posted: Tue Jun 19, 2007 8:54 pm
by Benjamin
Probably in the function call, and not in the actual function.

Posted: Wed Jun 20, 2007 2:35 am
by Chris Corbyn
No OO language would ever let you do things like

Code: Select all

function foo($x = $this->x)
{

}
$this->x is not a fixed value so the method signature could be different every time you call it. That would very quickly create a nice mess. The proper thing to do is explicitly evaluate at runtime.

Code: Select all

function foo($x=null)
{
    if ($x === null) $x = $this->x;
    //
}
In fact, until you're inside the curly braces you're not in scope of $this anyway...

EDIT | I should point out that when we are referring to constant values it will work fine:

Code: Select all

public function foo($x = self::SOME_CONSTANT)
{
  //
}