Re: Doubt regarding an array of references... [message #177508 is a reply to message #177507] |
Tue, 03 April 2012 11:39 |
M. Strobel
Messages: 386 Registered: December 2011
Karma:
|
Senior Member |
|
|
Am 03.04.2012 11:02, schrieb "Álvaro G. Vicario":
> El 02/04/2012 18:17, Leonardo Azpurua escribió/wrote:
>> I am coding a simple parser, where a construct is made of a fixed number
>> sequence of varIDs or quoted literals that may or may not be separated by
>> punctuators.
>>
>> In order to avoid a repetition of similar statements, I decided to try if I
>> could store the references of the variables where each value should be
>> stored and then perform a loop in order to extract and store the symbols.
>>
>> The try was this little program:
>
> As a general rule, I suggest you debug with var_dump(). Plain echos cast everything
> to string and hide most of the subtleties you are interested in when debugging.
>
>>
>> $a = $b = $c = "nil";
>> echo "a = $a, b = $b, c = $c<br>\n";
>>
>> $d = array(&$a,&$b,&$c);
>> for ($n = 0; $n< count($d); $n++) $d[$n] = $n;
>> echo "a = $a, b = $b, c = $c<br>\n";
>>
>> for ($n = 0; $n< count($d); $n++) $d[$n] = ($n + 100);
>> echo "a = $a, b = $b, c = $c<br>\n";
>>
>> $n = 200;
>> foreach ($d as&$nx) $nx = $n++;; // why&$nx ?
>
> Why «&$nx»? Because the foreach() construct does not create references by itself. This:
>
> foreach($foo as $bar){
> $bar = 'New value';
> }
>
> ... is roughly equivalent to:
>
> for($i=0; $i<count($foo); $i++){
> $bar = $foo[$i]; // Good old copy, not reference
> $bar = 'New value'; // $foo[$i] keeps old value
> }
>
> (Please note we are talking about arrays and scalars; PHP objects follow their own
> rules).
>
>> echo "a = $a, b = $b, c = $c<br>\n";
>
> Last but not least, an additional important bit -- Every time you use references in a
> foreach() construct, don't forget to unset the temporary variable. Otherwise, you'll
> face unexpected side effects if you use the same variable name in another loop. Run
> and compare this:
>
> $foo = range(1, 10);
> foreach($foo as &$bar){
> $bar *= 100;
> }
>
> var_dump($foo);
> foreach($foo as $bar){
> }
> var_dump($foo);
>
> ... and this:
>
> $foo = range(1, 10);
> foreach($foo as &$bar){
> $bar *= 100;
> }
> unset($bar); // <--
>
> var_dump($foo);
> foreach($foo as $bar){
> }
> var_dump($foo);
>
> (In case you didn't see it, there's a full chapter dedicated to references [1])
>
> [1] http://www.php.net/manual/en/language.references.php
My 2¢:
The problem with the counted for-loop is tedious writing, and off-by-one error.
The problem with the foreach-loop is: don't forget to use the key when you want to
change values!
This works:
#--------------------------------
strobel@s114-intel:~> php -a
Interactive shell
php > $a = array(1,2,3);
php > foreach ($a as $k=>$v) { $a[$k]++; }
php > var_dump($a);
array(3) {
[0]=>
int(2)
[1]=>
int(3)
[2]=>
int(4)
}
php > foreach ($a as $k=>$v) { $a[$k]*=4; }
php > var_dump($a);
array(3) {
[0]=>
int(8)
[1]=>
int(12)
[2]=>
int(16)
}
php >
#--------------------------
I see references in PHP as "a can of worms", in PHP5 they are only necessary in very
special cases.
/Str.
|
|
|