Archive for the ‘Programming’ Category

php foreach by reference

Saturday, June 13th, 2009

Here’s an interesting “feature” (bug?) for php. Recent PHP versions support this syntax for foreach:

foreach ($myarray as &$v)
  $v['koko']=’lala’;

This allows easy changes to the actual table by using references and not acting on a copy.

- but -

If you do this:

$myarray=array(array('a'=>1), array('a'=>2), array('a'=>3));

foreach ($myarray as &$v)
  $v['b']=1;

foreach ($myarray as $v);

print_r($myarray);

You manage to remove the last element of $myarray (!!!). This is the output:

Array
(
    [0] => Array
        (
            [a] => 1
            [b] => 1
        )

    [1] => Array
        (
            [a] => 2
            [b] => 1
        )

    [2] => Array
        (
            [a] => 2
            [b] => 1
        )

)

Now, if you change the code to:

$myarray=array(array('a'=>1), array('a'=>2), array('a'=>3));

foreach ($myarray as &$v)
  $v['b']=1;

foreach ($myarray as $v2);

print_r($myarray);

The bug is gone. The output is correct:

Array
(
    [0] => Array
        (
            [a] => 1
            [b] => 1
        )

    [1] => Array
        (
            [a] => 2
            [b] => 1
        )

    [2] => Array
        (
            [a] => 3
            [b] => 1
        )
)

To my knowledge, this happens because $v is kept as a reference to the last element when the first foreach is finished. Then, when the second foreach is ran, some assignments are performed to $v, destroying its last element.

KAutostart and python

Saturday, March 7th, 2009

This one took me many hours to debug:

For KDE 4 and python there can be a hard to debug problem with KAutostart usage.

Suppose you have a window class

class MyWindow(KDialig, Ui_Dialog):
  def __init__(self):
    self.kas = KAutostart('myapp')
    self.kas.setAutostarts(True)

You may find that the setAutostarts() doesn’t actually work. This is because MyWindow references kas and kas references MyWindow (as the parent object) (or the application - I’m not sure). The problem is that KAutostart() stores the information when it is deleted (in it’s destructor) and since it is never deleted it won’t store anything.

You need to understand that the destructors won’t be called even when the program exits, because of the circular reference.

To solve the problem call:

self.kas=None

at some point.

Have a look here for more on python and its destructors.