LINUXZONE






 >> Hlavní stránka

(1713/30.07.2010)


 >> Administrace

(160/29.07.2010)


 >> Literatura

(305/28.07.2010)


 >> Bezpečnost

(340/30.07.2010)


 >> Programování

(307/19.04.2010)


 >> Distribuce

(97/09.06.2010)


 >> Síťování

(86/03.06.2010)


 >> Lokalizace

(10/15.09.2004)


 >> Aplikace

(175/12.04.2010)


 >> Multimedia

(32/31.03.2006)


 >> Hardware

(45/02.03.2007)


 >> Začínáme

(228/24.06.2010)


 >> Aktuálně

(556/27.07.2010)


 >> RELAX

(201/26.07.2010)


 >> Jinde vyšlo

přehled ostatních serverů




 Přihlášení




Login:
Heslo:
 uložit v prohlížeči


Nejste-li ješte zaregistrováni, můžete tak učinit zde.





 Vyhledávání




Hledaný výraz:
v klíčových slovech
v titulku
v anotaci
v textu








 Reklama









 Servis




*   Vaše náměty a připomínky
Máte k Linuxzone.cz nějaké připomínky nebo náměty? Našli jste na stránkách chybu? Dejte nám o tom vědět pomocí formuláře nebo v diskuzi.
Komentářů: 30
*   Podpořte Linuxzone.cz
Chcete podpořit náš server umístěním odkazu nebo zveřejněním backendu? Zde najdete vše potřebné.
*   Pište pro Linuxzone.cz
Máte zájem podílet se na obsahu Linuxzone.cz ať už jako redaktoři nebo i jinak? Dejte nám o sobě vědět!





 Aktuálně z bezpečnosti




-- 
6.12.2005, 19:01
Na serveru informit.com vyšla ukázková kapitola týkající se práce s řetězci z knihy Secure Coding in C and C++. (lz)

-- 
3.12.2005, 12:34
Bugtraq: Format String Vulnerabilities in Perl Programs. (lz)

-- 
3.12.2005, 12:32
Linux Advisory Watch December 2nd 2005. (lz)

-- 
23.10.2005, 13:28
Rozhovor na téma klasické zálohování versus CDP. (lz)

-- 
23.10.2005, 13:24
Linux Advisory Watch October 21st 2005. (lz)

další >>





 Aktuálně o software




-- 
6.12.2005, 19:07
Potřebujete-li pod linuxem rozchodit bezdrát založený na čipsetech Broadcom 43xx, konečně existuje linuxový ovladač. (lz)

-- 
6.12.2005, 19:04
Byla uvolněna verze Xen 3.0.0 virtualizační technologie XEN. (lz)

-- 
6.12.2005, 18:59
Byla uvolněna verze X11R6.9/X11R7 RC 3 grafickérho rozhraní X Window System. (lz)

-- 
3.12.2005, 12:45
Co je nového okolo projektu Amanda (open source zálohovací software)? Více na osnews.com. (lz)

-- 
3.12.2005, 12:40
Jak to akuálně v linuxu vypadá s podporou SATA.. (lz)

další >>





 Aktuálně z IT




-- 
3.12.2005, 12:51
Novellu se daří prodej linuxových produktů, oproti loňskému roku se Novell dočkal výrazného nárůstu. (lz)

-- 
3.12.2005, 12:48
Třetí verzi licence GPL by měla být publikována během jara 2007. (lz)

-- 
23.10.2005, 13:20
V Peru nyní mají zákon, který umožňuje nasazení open source software ve vládní správě. (lz)

-- 
23.10.2005, 13:14
Proč se Microsoft bojí Google? (lz)

-- 
27.9.2005, 22:01
Peru má zákon podporující free software. (lz)

další >>





 Nejčtenější články




-- 
Hurd včera dnes a zítra

-- 
XEN aneb virtualizujeme (3/6)

-- 
Security Digest (15/2010)

-- 
Fotografický ateliér

-- 
XEN aneb virtualizujeme (4/6)

-- 
Novinky ze světa svobodného software (16/2010)

-- 
Gamesárium [138]

-- 
Proč používat svobodný software?

-- 
Velká kniha sportovní fotografie

-- 
Security Digest (16/2010)






 Nejlepší články




-- 
Gamesárium [138]

-- 
XEN aneb virtualizujeme (4/6)

-- 
Datové struktury bez předchozích znalostí

-- 
XEN aneb virtualizujeme (3/6)

-- 
Security Digest (16/2010)

-- 
Novinky ze světa svobodného software (17/2010)

-- 
Velká kniha sportovní fotografie

-- 
XEN aneb virtualizujeme (5/6)

-- 
Security Digest (15/2010)

-- 
Proč používat svobodný software?






 Anketa




Používáte nějaké rozšíření bezpečnostního modelu linuxového jádra?

Openwall (18%)

LIDS (12%)

Pax/Grsecurity (3%)

SELinux (6%)

RSBAC (1%)

jiné (1%)

používám standardní jádro (59%)







Linuxzone.cz - server o Linuxu pro programátory, administrátory a fanoušky.
Provozuje společnost Impossible.
ISSN: 1213-8738





CLOS -- objektově orientované programování v Lispu

Common Lisp byl jedním z prvních programovacích jazyků, který měl objektově orientované programování zakotveno ve svém ANSI standardu. Standardizovaný objektový systém CLOS je při prvním přiblížení jednoduchý a snadno zvládnutelný a přitom nabízí rysy v mnoha jiných prostředích neobvyklé. A pod slupkou rozhraní nejvyšší úrovně se skrývají zajímavé rysy, činící z CLOSu, jak se na Lisp sluší, nesmírně mocný nástroj.

Co je CLOS

Lisp je ze své podstaty rozšiřitelný programovací jazyk. Proto když přišlo objektově orientované programování, nebylo třeba navrhovat nový programovací jazyk, nýbrž stačilo objektově orientované programování do Lispu implementovat. V důsledku toho vzniklo několik různých a nezávislých systémů objektově orientovaného programování v Lispu. V 80. letech, kdy se pracovalo na ANSI standardu Common Lispu, byl jako standardní objektový systém přijat CLOS (Common Lisp Object System). Názory na vhodnost této volby se liší, nicméně CLOS zde již pro jednou máme a jedná se o systém nesporně zajímavý a mocný.

Třídy a metody

Na rozdíl od většiny objektově orientovaných programovacích jazyků, CLOS má daleko volnější vazbu mezi třídami a metodami. Definuje-li se třída, definují se pouze její parametry, tj. zejména seznam poděděných tříd, sloty (v jiných jazycích nazývané například proměnné třídy, atributy nebo políčka) a jejich vlastnosti, přístupové metody ke slotům, dokumentace a metatřída.

Místo metod vázaných na jedinou konkrétní třídu CLOS používá generické funkce, aplikované na jednu nebo více instancí tříd. Pokud tedy například chceme definovat funkci vykreslující grafický prvek na výstupní zařízení, nespojujeme tuto funkci ani s třídou grafického prvku ani s třídou výstupního zařízení, nýbrž s oběma třídami. Tento mechanismus je obecnější a při zavádění nových prvků a nových výstupních zařízení umožňuje přidávat potřebnou funkcionalitu bez zásahů do původního kódu.

Představme si že máme generickou funkci render-element s parametry element a device

  (defgeneric render-element (element device))

a její metodu pro konkrétní třídy triangle grafického prvku a screen výstupního zařízení

  (defmethod render-element ((element triangle) (device screen)))

S pomocí této metody můžeme snadno definovat metodu vykreslující čtverce, nezávislou na konkrétním výstupním zařízení:

  (defmethod render-element ((element square) device)
    (render-element (square-triangle-left-top element) device)
    (render-element (square-triangle-right-bottom element) device))

Dále můžeme definovat metodu vykreslující trojúhelníky na černobílé zařízení, využívající volání metody předka prostřednictvím funkce call-next-method:

  (defmethod render-element ((element triangle) (device black-and-white-device))
    (call-next-method (convert-to-black-and-white element) device))

Vykreslení černobílého čtverce daného proměnnou the-square obsahující instanci třídy square na výstupní zařízení dané proměnnou the-black-and-white-device obsahující instanci třídy black-and-white-device pak dosáhneme přirozeným voláním

  (render-element the-square the-black-and-white-device)

Automaticky se vyvolají obě výše uvedené konverzní metody a kýženého je dosaženo. V jazycích s metodami vázanými na jedinou třídu, jako jsou například C++, Java nebo Python, je dosažení podobně elegantního řešení složitější.

Pořadí dědičnosti

Aby výše uvedené dobře fungovalo, musí být rozumně definováno pravidlo pro pořadí volání metod předků v případě vícenásobné dědičnosti. Některé objektově orientované jazyky používají prohledávání seznamu předků do hloubky. Common Lisp místo toho používá poněkud komplikovanější třídění seznamu předků, které je možno neformálními pravidly vyjádřit takto:

  • V seznamu dědičnosti od nejspecializovanější třídy po nejobecnější mají vždy přednost potomci před svými předky (to je nejvýznamnější rozdíl oproti prohledávání do hloubky).
  • Není-li mezi třídami vztah potomek-předek, mají přednost třídy umístěné v hierarchii dědičnosti více "vlevo".
  • Není-li mezi třídami ani "vertikální" ani "horizontální" vztah, mají přednost potomci níže postavených předků.

Příklad: Je-li mezi třídami A až F vztah daný následujícím diagramem, přičemž předci jsou v diagramu níže pod svými potomky,

     F
  / / \ \
 E  D C  A
    \ / 
     B

je pořadí dědičnosti třídy následující: F, E, D, C, B, A. Požádáme-li v metodě jednoho argumentu, kterým je instance třídy F, aplikované na třídu E o zavolání metody předka, zavolá se metoda aplikovaná na třídu D. Pro jakékoliv volání metody bezprostředně následující v hierarchii dědičnosti přitom stačí zapsat prosté

  (call-next-method)

bez argumentů a CLOS už se postará o vše potřebné včetně předání argumentů. Kdo někdy udržoval hierarchii tříd a měnil v ní během vývoje jména tříd, hierarchii dědičnosti a argumenty metod, tak toto zautomatizované volání velmi ocení.

Uvedená pravidla pořadí dědění tříd je mnohem praktičtější, přestože na pochopení mírně složitější, než dědění do hloubky. O tom svědčí i skutečnost, že programovací jazyk Python přešel od své verze 2.2 z pořadí dědičnosti daného prohledáváním do hloubky na způsob dědičnosti bližší CLOSu, používaný v jednom ze starších systémů objektově orientovaného programování v Lispu.

Přizpůsobení metod

Jedním z poměrně unikátních a přitom velmi užitečných rysů CLOSu jsou pomocné metody, nazývané before, after a around methods, umožňující definovat kód provedený před zavoláním, po zavolání nebo místo zavolání určité metody pro konkrétní seznam tříd. To umožňuje provádět modifikaci definovaných metod bez nutnosti asistence a dostatečné předvídavosti jejich původního autora.

Představme si, že bychom chtěli počítat počet vykreslených primitivních trojúhelníků v metodách uvedených výše. Je to velmi jednoduché:

  (defmethod render-element :after ((element triangle) device)
    (incf number-of-triangles))

(incf je makro inkrementující hodnotu proměnné.) Chceme-li mít ještě k tomu statistiku o počtu vykreslených černobílých trojúhelníků, přidáme navíc:

  (defmethod render-element :after ((element triangle)
    (device black-and-white-device)) (incf number-of-black-and-white-triangles))

Metoda počítání všech trojúhelníků zůstává v platnosti, definice jsou vzhledem k odlišnému seznamu tříd, na který jsou aplikovány, nezávislé. V hierarchii dědičnosti si lze pomocné metody představit přibližně jako slupky cibule.

Obalovací, around, metody můžeme využít třeba následujícím způsobem pro hlídání přílišného využívání výstupního zařízení:

  (defmethod render-element :around ((element triangle) device)
    (if (< number-of-triangles triangle-limit)
        (call-next-method)
        (error "Sorry, too many triangles!")))

V případě dosažení limitu na počet vykreslených trojúhelníků metoda ohlásí chybu, jinak zavolá metodu obalenou.

Všechny výše uvedené příklady ilustrují jednu důležitou vlastnost: Veškeré změny jsou i přes svou jednoduchost a přirozenost prováděny bez jakéhokoliv zásahu do stávajícího kódu.

Kombinace metod

Volá-li se metoda předka pro instance tříd, obvyklým postupem je vyvolání první metody ze seznamu všech stejnojmenných metod předků uspořádaného dle pravidel dědičnosti. To je také standardní chování CLOSu. Kromě tohoto implicitního mechanismu však CLOS nabízí i možnost aplikovat jakoukoliv operaci nad seznamem všech stejnojmenných metod předků, pomocí mechanismu zvaného kombinace metod (method combination). Předdefinovanými operacemi jsou například součet hodnot vrácených metodami předků, maximum z vrácených hodnot či spojení vrácených seznamů. Pokud to programátorovi nestačí, může si nadefinovat libovolnou vlastní metodu.

K čemu je to dobré? Pokud například hierarchie tříd reprezentuje hierarchii různorodých objektů, umožňuje kombinace metod snadno kombinovat jejich vlastnosti. Pokud bychom například reprezentovali státy světa, jejich administrativní jednotky, světadíly, atd. odpovídající hierarchií tříd, umožňuje nám kombinace metod snadno definovat metody počítající například celkové počty úředníků v kterékoliv jednotce uvedené hierarchie.

Metaobject Protocol (MOP)

CLOS klade na každou standardu odpovídající implementaci Common Lispu určitou množinu požadavků, které umožňují používat programátorské konstrukce, o kterých jsme se zmiňovali. Přesto je občas užitečné mít možnost zasahovat do systému na ještě nižší úrovni, například chceme-li si definovat speciální režim přístupu ke slotům instancí nebo zavést transparentní perzistenci objektů.

CLOS záměrně nejde až na nejnižší úroveň, aby implementátoři jazyka nebyli nutně stavěni před příliš náročné implementační úkoly, ať už po stránce množství požadovaných rysů nebo kvůli svazování rukou při hledání efektivní implementace. I velmi náročné programátorské požadavky však uspokojí Metaobject Protocol (MOP). MOP definuje přístupový protokol k třídám, instancím, generickým funkcím i metodám do velmi podrobných detailů a dává tak programátorům možnost zasahovat prakticky do čehokoliv.

Nevyhovují vám pravidla pro dědičnost v CLOSu? MOP je umožňuje změnit. Chcete definovat přístupová práva ke slotům instancí tříd analogickým způsobem, jako je používá Java? MOP to opět umožní. Změny v CLOSu můžete dělat dvojím způsobem: využitím zmíněných pomocných metod (before/after/around) nebo specializací metod CLOSu a MOPu pro různé metatřídy. (V pokročilých systémech objektově orientovaného programování je každá třída instancí nějaké jiné třídy, sloužící právě k definici tříd, tyto definiční třídy se nazývají metatřídy. Lze-li zařídit, aby nějaká třída byla instancí jiné metatřídy než implicitní, je prostřednictvím takového mechanismu možné měnit obecné vlastnosti tříd, jako jsou například pravidla pro tvorbu seznamu předků.)

MOP není součástí ANSI standardu Common Lispu. Jeho de facto definicí je vynikající kniha The Art of Metaobject Programming, kterou lze doporučit všem, bez ohledu na jejich vztah k Lispu, kteří se zajímají o vrstvené programové systémy a přístupové protokoly k objektům. Kniha obsahuje výkladovou a referenční část a její součástí je také ukázka jednoduché implementace CLOSu včetně MOP.

Ze svobodných common lispových systémů podporují MOP CMU Common Lisp a SBCL a podporují jej i mnohé proprietární systémy.

Objektové systémy příbuzných jazyků

Myšlenky obsažené v CLOSu se promítly i do Lispu příbuzných programovacích jazyků. Pro Guile (GNU implementace jazyka Scheme míněná jako rozšiřující jazyk GNU aplikací) existuje systém GOOPS velmi podobný CLOSu a implementující i některé funkce metaobjektového protokolu. Implementace jednoduchého systému podobného CLOSu existuje též pro Emacs Lisp, navíc standardní součástí Emacs Lispu jsou tzv. advices, nabízející možnost definovat before/after/around kód pro kterékoliv funkce.

Závěr

Objektově orientované programování v Common Lispu je nejen významným a mocným programovacím nástrojem pro lispové programátory, nýbrž i zdrojem nápadů a poučení pro zájemce o programování obecně. Podobně jako v případě funkcionálního nebo logického programování lze bližší seznámení se s ním doporučit všem zvídavým zájemcům o programovací techniky, bez ohledu na to jaké konkrétní prostředí používají.

CLOS má další rysy, o kterých jsme se zde nezmínili. Nezabývali jsme se například vůbec možnostmi dynamického přidávání a modifikace tříd a metod nebo prostředky usnadňujícími rychlé prototypování. Chcete-li se s CLOSem seznámit podrobněji, můžete využít následující odkazy:

Autor: Milan Zamazal, 16. 04. 2003, 00:00
Sekce Programování, Komentářů: 4
Průměrné hodnocení: 2,88

o Poslat e-mailem
o Tisk článku
o Uložit do profilu


 Přispějte nám




Líbil se Vám tento článek? Můžete ho ocenit zavoláním na tel. číslo 906 460 134.
Cena hovoru za 1 minutu je 46 Kč.





 Hodnocení článku




Článek hodnotím jako:  [1] výborný   [2] dobrý   [3] průměr   [4] špatný   [5] hrůza  





 Komentáře




--

Milan Zamazal, 16. 04. 2003 14:05
Re: Elisp CLOS?












--

Jirka, 16. 04. 2003 13:52
ELISP CLOS?












--

Milan Zamazal, 16. 04. 2003 10:39
Re: Grahamova kniha












--

 - , 16. 04. 2003 09:58
Grahamova kniha















PŘIDAT KOMENTÁŘ ZOBRAZ VŠE >>










2002 © Impossible, s.r.o.   >> Kontaktujte redakci >> Právní upozornění >> Reklama