Diskuze k článku: Jednoduchost programovacího jazyka
(počet příspěvků: 16 , poslední: 24. 7. 2008 10:19)
*Redakce si vyhrazuje právo moderovat příspěvky s vulgárním obsahem, urážlivé nebo jiným způsobem nevhodné.
jablka a hrusky | od:
iky
S temi deskriptory si autor clanku plete jablka s hruskama.
PHP metody __get, __set, __delete a __call muzou delat maximalne to, co delaji v pythonu metody __getattr__, __setattr__ a __delattr__. Tyto magicke metody jsou ale, co do funkcnosti a moznosti, jenom uzkou podmnozinou cele implementace pythonich deskriptoru.
Neplest PHPkovsky __get s pythonim __get__ apod. (a uz vubec neplest PHPkovsky __call s Pythonim __call__!:)
Metody se sice jmenuji stejne, ale v kazdem z techto jazyku delaji neco jineho.
A co se tyce autorovo porovnani? Vzdyt Python je z jineho sveta, nez je PHP. Netvari se jako objektovy jazyk, ale jazykem objektovym je.
Moznosti vyuziti techto jazyku se prekryvaji maximalne v oblasti webovych aplikaci. Jinde neni pro PHP misto.
Z čeho usuzujete, že pletu __get a __get__? Deskriptory se v Pythonu dají použít k tomu, aby se při přístupu k vlastnosti zavolala metoda. K vyřešení stejného problému se v PHP dá použít přetěžování. Funguje to jinak, ale dá se to využít k témuž.
Zavadejici je prirovnavat k deskriptory k moznostem __get() / __getattr__().
__get() a __getattr__() plni v php resp. pythonu opravdu tu samou ulohu.
Naproti tomu magie ukryta v deskriptorech jde uplne opacnym smerem a z toho plyne pouziti v naprosto jinych situacich. A presne pro ty schazi v PHP elagatni reseni zkratka proto, ze PHP ekvivalent pythonich deskriptoru neimplementuje,
<?php
class Desc {
function get($obj) {
return $obj->x + 10;
}
}
class A {
var $x;
private $descriptors = array();
function __construct($x) {
$this->x = $x;
$this->descriptors["plus_ten"] = new Desc;
}
function __get($name) {
if (isset($this->descriptors[$name])) {
return $this->descriptors[$name]->get($this);
}
}
}
$a = new A(5);
echo "$a->x\n";
echo "$a->plus_ten\n";
?>
Mno a tady narazime na zasadni problem: V tvem PHP priklade trida "A" (tedy rodic) MUSI vedet, ze existuji nejake "pseudo-deskriptory" a dokonce ktere to jsou. Mno a v momente, kdy nutim rodicovskou tridu, aby znala a explicitne volala moje rozhrani, ztracim temer veskerou krasu a uzitecnost pythonich deskriptoru.
Je totiz treba si uvedomit rozdil mezi __get__ a __getattr__. Pokud se budu drzet tveho prikladu kde A() ma vlastnosti typu Desc(), pak:
- A.__getattr__ pouziju v pripade, kdyz chci ovlivnovat chovani tridy A() pro volani z vnejsku.
- Desc.__get__ (tedy dekriptor) ovlivnuje chovani Desc() z pohledu tridy A().
To je dost vyznamny rozdil, pripady, ktere se daji efektivne i elegantne resit obema cestama je opravdu minimalne, proto se mi zda trochu matouci, kdyz zamenujes jedno za druhe.
Promiň, ale teď mícháš jablka a hrušky pro změnu ty. Jednak nevím, proč třídě A říkáš rodič. Ale hlavně tvrdíš, že v Pythonu nemusí třída A znát deskriptor. To přeci není pravda - třída A rozhodně musí vědět o existenci deskriptoru a ve správný okamžik ho použít:
class A(object):
plus_ten = Desc()
Pravdu máš jen s existencí implicitního zavolání deskriptoru v Pythonu (v předdefinované metodě __getattribute__). To by se v PHP dalo vyřešit zděděním třídy z rodiče, který by definoval vlastnost $descriptors a základní formu metody __get.
Uznávám, že v PHP musíš pro využití myšlenky deskriptorů napsat o pět řádek víc (kvůli chybějícímu implicitnímu zavolání deskriptorů), princip popsaného řešení je ale totožný jako v Pythonu, jen méně přímočarý.
Ano. S nespravnym pouziti terminu "rodic" mas pravdu. To je moje chyba.
Za zbytkem si celkem stojim. Trida A() nemusi o descriptorech a jejich specialnich vlastnostich nic vedet. Napada me jak pythoni property(), tak mozna models.ForeignKey() z djanga. Oboje jsou velmi ruznymi ale velmi hezkymi priklady pouziti deskriptoru, o kterych nadrazena trida nemusi vedet nic a veskerou "magii" si obstaraji samy. Nedaji se rozumne nahradit __getattr__()/__get().
Jak rikas, A() muze dedit z neceho, co castecne nahradi funkcnost __getattribute__(). Problem nastava v tom, kdy A je nejaka hotova trida, kterou chci vyuzit, nastavit ji objekt jako vlastnost/deskriptor a pak mit pristup k udalostem set/get - pak jsem v PHP nahranej. Jak udelat v PHP ekvivalent pythoni property()?? Jak se nastavit jako vlastnost nejake cizi tridy a ovlivnit chovani podle dane instance nadrazene tridy?? To jsou vazne veci, ktere v PHP trivialne nevyresis, ani pres __get a __set. To je prave to michani jablek s hruzkama o kterych mluvil Iky a ktere prisuzujes mne - prosim nezamenovat __getattr__ s __get__, oboje je ovoce, ale jedno jsou jablka a jedno hrusky, chutnaji uplne jinak.
Možná bude nejlepší, když sem vložíš ukázku kódu v Pythonu, jehož obdobu ty osobně neumíš naprogramovat v PHP. Ale nezaměňuj to prosím nadále s tím, že to v PHP nejde (nebo že někdo míchá hrušky a jablka), protože už jsem dvakrát ukázal, že jak deskriptory, tak property v PHP udělat poměrně přímočaře lze.
<?php
class Property {
protected $fget;
function __construct($fget) {
$this->fget = $fget;
}
function get($obj) {
$fget = $this->fget;
return $obj->$fget();
}
}
class NewStyle {
protected $descriptors = array();
function __get($name) {
if (isset($this->descriptors[$name])) {
return $this->descriptors[$name]->get($this);
}
}
}
class A extends NewStyle {
private $_x;
function __construct() {
$this->descriptors["x"] = new Property('getx');
}
function getx() {
return $this->_x;
}
}
$a = new A;
echo "$a->x\n";
?>
Jediný rozdíl mezi Pythonem a PHP je v tom, že v PHP nejsou třídy Property a NewStyle předdefinované.
A argumentovat tím, že v PHP musí třída využívající deskriptory z něčeho dědit? V Pythonu přeci také - konkrétně z třídy object.
Jednoduchost programovacího jazyka
Diskuze k článku: Jednoduchost programovacího jazyka
(počet příspěvků: 16 , poslední: 24. 7. 2008 10:19)
*Redakce si vyhrazuje právo moderovat příspěvky s vulgárním obsahem, urážlivé nebo jiným způsobem nevhodné.
jablka a hrusky | od: iky
S temi deskriptory si autor clanku plete jablka s hruskama.
PHP metody __get, __set, __delete a __call muzou delat maximalne to, co delaji v pythonu metody __getattr__, __setattr__ a __delattr__. Tyto magicke metody jsou ale, co do funkcnosti a moznosti, jenom uzkou podmnozinou cele implementace pythonich deskriptoru.
Neplest PHPkovsky __get s pythonim __get__ apod. (a uz vubec neplest PHPkovsky __call s Pythonim __call__!:)
Metody se sice jmenuji stejne, ale v kazdem z techto jazyku delaji neco jineho.
A co se tyce autorovo porovnani? Vzdyt Python je z jineho sveta, nez je PHP. Netvari se jako objektovy jazyk, ale jazykem objektovym je.
Moznosti vyuziti techto jazyku se prekryvaji maximalne v oblasti webovych aplikaci. Jinde neni pro PHP misto.
(IP: 213.197.167.xxx)
odpovědět | 10. 7. | 23:56Jakub Vrána
Z čeho usuzujete, že pletu __get a __get__? Deskriptory se v Pythonu dají použít k tomu, aby se při přístupu k vlastnosti zavolala metoda. K vyřešení stejného problému se v PHP dá použít přetěžování. Funguje to jinak, ale dá se to využít k témuž.
(IP: 193.85.202.xxx)
odpovědět | 11. 7. | 12:07al3x
Zavadejici je prirovnavat k deskriptory k moznostem __get() / __getattr__().
__get() a __getattr__() plni v php resp. pythonu opravdu tu samou ulohu.
Naproti tomu magie ukryta v deskriptorech jde uplne opacnym smerem a z toho plyne pouziti v naprosto jinych situacich. A presne pro ty schazi v PHP elagatni reseni zkratka proto, ze PHP ekvivalent pythonich deskriptoru neimplementuje,
(IP: 217.11.255.xxx)
odpovědět | 11. 7. | 13:21Jakub Vrána
Obdoba deskriptorů v PHP pomocí __get():
<?php
class Desc {
function get($obj) {
return $obj->x + 10;
}
}
class A {
var $x;
private $descriptors = array();
function __construct($x) {
$this->x = $x;
$this->descriptors["plus_ten"] = new Desc;
}
function __get($name) {
if (isset($this->descriptors[$name])) {
return $this->descriptors[$name]->get($this);
}
}
}
$a = new A(5);
echo "$a->x\n";
echo "$a->plus_ten\n";
?>
(IP: 194.228.68.xxx)
odpovědět | 21. 7. | 23:26al3x
Mno a tady narazime na zasadni problem: V tvem PHP priklade trida "A" (tedy rodic) MUSI vedet, ze existuji nejake "pseudo-deskriptory" a dokonce ktere to jsou. Mno a v momente, kdy nutim rodicovskou tridu, aby znala a explicitne volala moje rozhrani, ztracim temer veskerou krasu a uzitecnost pythonich deskriptoru.
Je totiz treba si uvedomit rozdil mezi __get__ a __getattr__. Pokud se budu drzet tveho prikladu kde A() ma vlastnosti typu Desc(), pak:
- A.__getattr__ pouziju v pripade, kdyz chci ovlivnovat chovani tridy A() pro volani z vnejsku.
- Desc.__get__ (tedy dekriptor) ovlivnuje chovani Desc() z pohledu tridy A().
To je dost vyznamny rozdil, pripady, ktere se daji efektivne i elegantne resit obema cestama je opravdu minimalne, proto se mi zda trochu matouci, kdyz zamenujes jedno za druhe.
(IP: 89.24.5.xxx)
odpovědět | 22. 7. | 23:45Jakub Vrána (jakub@vrana.cz)
Promiň, ale teď mícháš jablka a hrušky pro změnu ty. Jednak nevím, proč třídě A říkáš rodič. Ale hlavně tvrdíš, že v Pythonu nemusí třída A znát deskriptor. To přeci není pravda - třída A rozhodně musí vědět o existenci deskriptoru a ve správný okamžik ho použít:
class A(object):
plus_ten = Desc()
Pravdu máš jen s existencí implicitního zavolání deskriptoru v Pythonu (v předdefinované metodě __getattribute__). To by se v PHP dalo vyřešit zděděním třídy z rodiče, který by definoval vlastnost $descriptors a základní formu metody __get.
Uznávám, že v PHP musíš pro využití myšlenky deskriptorů napsat o pět řádek víc (kvůli chybějícímu implicitnímu zavolání deskriptorů), princip popsaného řešení je ale totožný jako v Pythonu, jen méně přímočarý.
(IP: 193.85.202.xxx)
odpovědět | 23. 7. | 15:56al3x
Ano. S nespravnym pouziti terminu "rodic" mas pravdu. To je moje chyba.
Za zbytkem si celkem stojim. Trida A() nemusi o descriptorech a jejich specialnich vlastnostich nic vedet. Napada me jak pythoni property(), tak mozna models.ForeignKey() z djanga. Oboje jsou velmi ruznymi ale velmi hezkymi priklady pouziti deskriptoru, o kterych nadrazena trida nemusi vedet nic a veskerou "magii" si obstaraji samy. Nedaji se rozumne nahradit __getattr__()/__get().
Jak rikas, A() muze dedit z neceho, co castecne nahradi funkcnost __getattribute__(). Problem nastava v tom, kdy A je nejaka hotova trida, kterou chci vyuzit, nastavit ji objekt jako vlastnost/deskriptor a pak mit pristup k udalostem set/get - pak jsem v PHP nahranej. Jak udelat v PHP ekvivalent pythoni property()?? Jak se nastavit jako vlastnost nejake cizi tridy a ovlivnit chovani podle dane instance nadrazene tridy?? To jsou vazne veci, ktere v PHP trivialne nevyresis, ani pres __get a __set. To je prave to michani jablek s hruzkama o kterych mluvil Iky a ktere prisuzujes mne - prosim nezamenovat __getattr__ s __get__, oboje je ovoce, ale jedno jsou jablka a jedno hrusky, chutnaji uplne jinak.
(IP: 89.24.4.xxx)
odpovědět | 24. 7. | 7:55Jakub Vrána
Možná bude nejlepší, když sem vložíš ukázku kódu v Pythonu, jehož obdobu ty osobně neumíš naprogramovat v PHP. Ale nezaměňuj to prosím nadále s tím, že to v PHP nejde (nebo že někdo míchá hrušky a jablka), protože už jsem dvakrát ukázal, že jak deskriptory, tak property v PHP udělat poměrně přímočaře lze.
(IP: 193.85.202.xxx)
odpovědět | 24. 7. | 10:19Jakub Vrána
Jak udělat v PHP ekvivalent Pythoní property():
<?php
class Property {
protected $fget;
function __construct($fget) {
$this->fget = $fget;
}
function get($obj) {
$fget = $this->fget;
return $obj->$fget();
}
}
class NewStyle {
protected $descriptors = array();
function __get($name) {
if (isset($this->descriptors[$name])) {
return $this->descriptors[$name]->get($this);
}
}
}
class A extends NewStyle {
private $_x;
function __construct() {
$this->descriptors["x"] = new Property('getx');
}
function getx() {
return $this->_x;
}
}
$a = new A;
echo "$a->x\n";
?>
Jediný rozdíl mezi Pythonem a PHP je v tom, že v PHP nejsou třídy Property a NewStyle předdefinované.
A argumentovat tím, že v PHP musí třída využívající deskriptory z něčeho dědit? V Pythonu přeci také - konkrétně z třídy object.
(IP: 217.195.170.xxx)
odpovědět | 24. 7. | 8:53