Inspirován programátorskými hádankami Reného Steina bych rád podobnou kratochvíli dopřál i znalcům PHP. Pro začátek takový chyták: Co vypíše příkaz echo?
class Foo {
var $self;
var $bar = 11;
// constructor
function Foo() {
$this->self = & $this;
}
}
$foo = new Foo();
$foo->bar = 22;
echo $foo->self->bar;
Komentáře
Dero #1
Dvaadvacet?
formanet #2
#1 Dero, 11
Prochaine #3
$bar je přeci konstanta, takže 11. Vyzkoušeno na PHP4.
David Grudl #4
#3 Prochaine, $bar není konstanta, ale před-inicializovaná proměnná, kterou je možné měnit.
Jsou nějaké nápady, PROČ je to 11 nebo 22 ?
Martin Kopta #5
Protože hodnota $bar se přiřadí do $foo->self->bar až ve chvíli, kdy je echovaná?
Havran #6
Preto lebo & pred priradenim $this sposobi ze sa neurobi kopia $this ale sa len odkaze nan – cize vlastne $self === $foo (take volaco :D)
Havran #7
Ale je zaujimave co urobi toto $foo->self->self->bar = 22; :D Btw. print_r($foo) toho vela ukaze…
David Grudl #8
Tak tedy: v čem je chyták? V tom, že PHP verze 4 vrací 11 a verze 5 vrací 22.
Jak správně píše Havran #6 Havran, přiřazení
$this->self = &$this;
nevytvoří kopii objektu, ale referenci (něco jako odkaz). Tedy logicky by po nastavení$foo->bar=22;
mělo mít hodnotu 22 i$foo->self->bar
, neboť$foo
a$foo->self
je totéž.Proč tedy PHP verze 4 vypíše 11? Zrada se skrývá v
$foo=new Foo()
. Tady přiřazením vznikne kopie objektu! To je místo, ve kterém duplikování objektu ani španělskou inkvizici nikdo nečeká. Takže$foo
obsahuje jinou instanci objektu, než na jakou referuje$foo->self
.Aby k nevhodnému duplikování nedošlo a kód vypsal očekávatelných 22, je třeba před
new
přidat&
. Tedy:$foo = &new Foo()
.Závěr: v PHP4 před klíčovým slovem new VŽDYCKY pište &.
Petr #9
Na rozdíl od Reného hádanek u této nějak postrádám smysl.
bear #10
#9 Petře, hlavně že tys odpověď hned věděl, že?
Programátor nemůže hádat, co tak krátký a jasný kód udělá, musí to vědět! A jak vidíš, nevěděl to nikdo. A raděj se takovou věc naučím hádanlou, než tím, že budu tři hodiny hledat chybu v tisíci řádkách programu.
Petr #11
#10 beare, Odpověď jsem hned nevěděl a ani mě nezajímá. Je to teoretický konstrukt, který kdyby použil nějaký člen mého programátorského týmu, tak to bude mít nepříznivý vliv na jeho výplatu (tím chci říct, že by se v praxi nemělo stát, že tisíce řádek kódu nebudou fungovat kvůli exhibici nějakého potrhlého programátora).
David Grudl #12
#11 Petře, Petře, je mi líto, že Vás hádanka nezaujala, příště bude třeba lepší 🙂
Určitě ale nesouhlasím s tím, že jde o teoretický konstrukt. Vždyť v příkladu jde jen o užití objektu a reference. Tedy dvou nejčastěji používaných prostředků OOP programátora. A je dobré znát jejich limity.
martinpav #13
Ja som odpoved vedel (vinimocne :) ), len som sa sem dostavil trosku neskoro. Nejake dalsie info sa da najst tu: https://web.archive.org/…/developers/…
Havran #14
#8 Davide Grudle, Ahaaa :) Ze mi to hned nedoslo… Nevadi aspon som sa poucil.
Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.