úterý 24. listopadu 2009

A Python pitfall

Next day and a next error, actually in Python. And it is surprisingly close with the previous post about keyword arguments. Python as many other languages have default arguments, therefore it is possible to us default value of argument if no value for that argument is passed.

>>> def func(a=4):
>>> print a
>>> func(1)
1
>>> func()
4
But these arguments are assign only first time as can be seen on the next example. The number values cannot be modified thus they are save from following effects.

>>> def func(a=[]):
>>> a.append(1)
>>> print a
>>> func()
[1]
>>> func()
[1, 1]
>>> func()
[1, 1, 1]
As you can see, the default value is assigned only for the first time and for next calls it is permanently reused. It can be dangerous if you are not aware of it. The following design pattern can be used to avoid this danger.

def func(a, b=None, c=None):
if b is None:
b = []
if c is None:
c = {}
#the function body
The first few lines in the previous function will inicialize new empty values, which will be specific for the actual function call. When it is necessary to use more complicated default values which will be modified in function body, than these objects should be cloned immediate after function header.

It can be said that default argument values are variant of static variables for function and such property can be very surprising for many programmers.

neděle 22. listopadu 2009

A PHP pitfall (for a pythonist)

In python is quite natural to use keyword arguments in function calls, do not try that in PHP.
A header of PHP function function f1($a, $b, $c=3, $d=4) can lead to believe that it is allowed to address function arguments by theirs names in a function call. It is simply not true. What is worse, that following construction is in PHP in all ways correct.

f1($c=13, $d=14);

Because an assertion is an expression, the whole calling is semantic equivalent to:

$c=13
$d=14
f1(13, 14)

therefore f1 is called with $a=13, $b=14, $c=3, $d=4