LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Perl (110) - Moose - meta API

Perl V Moose máme speciální aplikační rozhraní, díky němuž jsme schopni v jistém ohledu modifikovat samotný objektový systém.

16.5.2010 00:00 | Jiří Václavík | Články autora | přečteno 7646×

Pomocí rozhraní meta API lze nastavovat základní vlastnosti objektového systému a ovlivňovat věci jako chování metod, atributů a tříd.

Získání metadat

Základní metodou pro práci s vlastnostmi objektového systému je meta, která zpřístupňuje metadata dané třídy. Zde je příklad užití. Takto lze získat seznam metod nebo atributů s vlastnostmi.

  $meta = MojeTrida->meta();

  for $atribut ($meta->get_all_attributes){
      print "Atribut: ", $atribut->name(), " ";
      print $atribut->type_constraint->name if $atribut->has_type_constraint;
      print "\n";
  }

  for $method ($meta->get_all_methods){
      print $method->name," ";
  }

Poznamenejme, že namísto MojeTrida na prvním řádku můžeme použít slovo __PACKAGE__, které vyjadřuje jméno aktuálního balíku.

$meta = __PACKAGE__->meta;

Podobně lze získat metodou linearized_isa seznam rodičovských tříd a pomocí subclasses podtřídy.

Modifikace tříd pomocí metadat

Pro zajímavost uveďme, že třídy lze upravovat přímo pomocí změny metadat. Ukažme si, jak lze přidávat metody a atributy. Máme zde k dispozici metody add_method a add_attribute, kterým předáme příslušné parametry.

$meta = __PACKAGE__->meta;
$meta->add_method("nova_metoda" => sub{udelej_neco(@_)});
$meta->add_attribute(
    name => "novy_atribut",
    is   => "rw",
    isa  => "Int"
);

Toto chování lze vypnout pomocí metody make_immutable (případně zapnout pomocí make_mutable). V takovém případě bude při pokusu o změnu třídy pomocí metadat vyvolána výjimka.

$meta->make_immutable;

Fyzická reprezentace atributů

Atribut v Moose je ve skutečnosti objekt typu Moose::Meta::Attribute. To zásadně mění náš pohled na ně.

K těmto objektům lze samozřejmě přistupovat. K tomu slouží metoda get_attribute("jméno atributu"). Například objekt reprezentující atribut nazev získáme následovně.

$nazev = $meta->get_attribute("nazev")

Tento objekt má k dispozici několik metod. Pro příklad uvedeme metodu, která vrátí název datového typu.

print $nazev->type_constraint;

Abychom lépe nahlédli na strukturu, uvědomme si, že místo předchozích volání lze typ získat jedním příkazem.

print MojeTrida->meta->get_attribute("nazev")->type_constraint;

Modifikace fyzické reprezentace atributů, metaatributy

Celá situace je o to zajímavější, že strukturu třídy reprezentující atribut lze měnit. Můžeme například přidávat atributy k atributům. Jinými slovy chceme převzít řízení toho, jaký vliv na chování bude mít hash předávaný při vytváření atributu.

Ukážeme si, jak k atributu přidat popisek. Tedy chceme v řídícím hashi vytvořit nový klíč popisek. Názorněji, požadujeme, aby fungoval následující kód.

package MojeTrida::Main;
use Moose;

has "atribut_s_popiskem" => (
    is        => "rw",
    isa       => "Str",
    popisek   => "Toto je meta-popisek atributu atribut_s_popiskem",
);

Je dobré si zde uvědomit, že zde opravdu má smysl chtít vytvářet atributy. Popisek je totiž vlastností našeho atributu a proto by nemělo smysl ho uvádět kamkoliv jinam (například do metod naší třídy).

Této funkcionality se dosáhne tak, že definujeme vlastní metatřídu. Každý atribut je objekt typu Moose::Meta::Attribute. My ji potřebujeme přetížit. To znamená, že vytvoříme třídu, kterou nazveme MojeTrida::Meta::Attribute::Popisek, která bude dědit od Moose::Meta::Attribute. V této nové třídě definujeme nový atribut. Zároveň bude třeba někde uvést, že se daný atribut má řídit naší třídou MojeTrida::Meta::Attribute::Popisek (nikoliv standardní třídou Moose::Meta::Attribute).

Poslední požadavek (nastavení metatřídy) se vyřeší přidáním klíče metaclass. Definici našeho atributu tedy lehce upravíme tím, že přidáme jeden řádek.

has "atribut_s_popiskem" => (
    metaclass => "MojeTrida::Meta::Attribute::Popisek",
    is        => "rw",
    isa       => "Str",
    popisek   => "Toto je meta-popisek atributu atribut_s_popiskem",
);

Nyní již Moose ví, že chceme přetěžovat. Zbývá tedy pouze vytvořit třídu MojeTrida::Meta::Attribute::Popisek, která zdědí vše od Moose::Meta::Attribute. Vložíme sem navíc nový atribut popisek. Pomocí predicate=>je_popisek navíc přidáme detektor, protože bude časem potřeba.

package MojeTrida::Meta::Attribute::Popisek;
use Moose;
extends "Moose::Meta::Attribute";

has "popisek" => (
      is        => "rw",
      isa       => "Str",
      predicate => "je_popisek"
);

Nyní můžeme standardně pracovat s objekty typu MojeTrida::Main. Podívejme se pro zajímavost, jak získáme text popisku.

package main;
print MojeTrida::Main->meta->get_attribute("atribut_s_popiskem")->popisek;

Lze sem samozřejmě přistupovat i pomocí objektu.

$a = MojeTrida::Main->new(atribut_s_popiskem=>"hodnota");
print $a->meta->get_attribute("atribut_s_popiskem")->popisek;

Pro přehlednost napíšeme v MojeTrida::Main ještě metodu metainfo, která nám vytiskne informace o všech atributech a jejich popiscích. Odlišíme tak hodnotu atributu a popisek. Metoda metainfo může vypadat takto.

sub metainfo {
      my $self = shift;
      my $info = "";

      for my $a ($self->meta->get_attribute_list){
          my $atribut = $self->meta->get_attribute($a);
          $info .= $atribut->name. ":\n";
          $info .= "  popisek: ".$atribut->popisek."\n"
  if $atribut->isa("MojeTrida::Meta::Attribute::Popisek") and $atribut->je_popisek;
          $info .= "  hodnota: ". $self->{$atribut->get_read_method}. "\n";
      }

      return $info;
}

V našem příkladu bychom po zavolání print $a->metainfo; obdrželi následující výstup.

atribut_s_popiskem:
  popisek: Toto je meta-popisek atributu atribut_s_popiskem
  hodnota: hodnota

Více popisků pro atribut

Budeme-li chtít pro každý atribut vytvořit více různých atributů, pak se stává naznačený postup nečitelný - lze totiž sice podobně jako pro popisek vytvářet další a další podtřídy, avšak po jisté době se každý zamyslí, zda-li je kombinování nesourodých tříd opravdu nezbytné.

Řešení nabízejí role. Klíčové slovo has totiž přijímá jako parametr mimo jiné i traits=>[qw(role1 role2 ...)]. Trait je speciální role, která se použije na objekt a od běžných rolí se jinak ničím neliší.

Modifikujme tedy předchozí příklad tak, aby dělal to samé, ale využil přitom rolí.

Nejprve definujme parametry pro atribut_s_popiskem. Zde vložíme klíč traits, do kterého nyní zadáme pouze jednoprvkový seznam (ačkoliv bychom zde mohli použít více rolí).

has "atribut_s_popiskem" => (
    traits    => ["MojeTrida::Meta::Attribute::Trait::Popisek"],
    is        => "rw",
    isa       => "Str",
    popisek   => "Toto je meta-popisek atributu atribut_s_popiskem",
);

Podtřídu MojeTrida::Meta::Attribute::Popisek nahradíme naši novou rolí MojeTrida::Meta::Attribute::Trait::Popisek. Celkem bude vypadat následovně.

package MojeTrida::Meta::Attribute::Trait::Popisek;
use Moose::Role;

has "popisek" => (
      is        => "rw",
      isa       => "Str",
      predicate => "je_popisek"
);

V metodě metainfo pouze zaměníme volání metody isa na volání does. To proto, že metoda isa je vztah pro podtřídu, avšak nyní máme roli a tak použijeme does.

Vše ostatní může zůstat stejné. Nyní tedy pro přidání dalších atributů stačí do traits přidat MojeTrida::Meta::Attribute::Trait::Cokoliv a tuto roli implementovat podobně jako jsme to dělali u popisku.

Rozšíření Moose - MooseX

Jednou z aplikací meta API je též tzv. MooseX. Díky MooseX si každý může napsat vlastní Moose rozšíření. Řada rozšíření je již k dispozici na CPAN. Návod a možnosti pro rozšiřování je v dokumentaci.

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

20.5.2018 17:45 /Redakce Linuxsoft.cz
Ve čtvrtek 31. května 2018 připravuje webový magazín BusinessIT ve spolupráci s Best Online Média s.r.o. pátý ročník odborné konference Firemní informační systémy 2018. Akce proběhne v kongresovém centru Vavruška (palác Charitas), Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00 hod. dopoledne do cca 15 hod. odpoledne. Konference je zaměřena na efektivní využití firemních informačních systémů a na to, jak plně využít jejich potenciál. Podrobnější informace na webových stránkách konfrence.
Přidat komentář

14.5.2018 7:28 /František Kučera
Květnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 17. 5. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: Audio – zvuk v GNU/Linuxu.
Přidat komentář

7.5.2018 16:20 /František Kučera
Na stránkách spolku OpenAlt vyšla fotoreportáž Pražské srazy 2017 dokumentující srazy za uplynulý rok. Květnový pražský sraz na téma audio se bude konat 17. 5. 2018 (místo a čas ještě upřesníme).
Přidat komentář

17.4.2018 0:46 /František Kučera
Dubnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 4. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tématem tohoto srazu bude OpenStreetMap (OSM) aneb svobodné mapy.
Přidat komentář

16.3.2018 22:01 /František Kučera
Kulatý OpenAlt sraz v Praze oslavíme klasicky: u limonády a piva! Přijďte si posedět, dát si dobré jídlo a vybrat z mnoha piv do restaurace Kulový blesk, který najdete v centru Prahy nedaleko metra I. P. Pavlova na adrese Sokolská 13, Praha 2. Sraz se koná ve čtvrtek 22. března a začínáme v 18:00. Heslo: OpenAlt. Vezměte s sebou svoje hračky! Uvítáme, když si s sebou na sraz vezmete svoje oblíbené hračky. Jestli máte nějaký drobný projekt postavený na Arduinu, nějakou zajímavou elektronickou součástku, či třeba i pěkný úlovek z crowdfundingové akce, neváhejte. Oslníte ostatní a o zábavu bude postaráno.
Přidat komentář

13.2.2018 0:41 /František Kučera
Únorový pražský sraz OpenAltu se koná 15. 2. 2018 a tentokrát se vydáme na návštěvu do jednoho pražského datacentra. Sejdeme se v 17:50 v severovýchodní části nástupiště tramvajové zastávky Koh-I-Noor. Po exkurzi se přesuneme do restaurace U Pštrosa (Moskevská 49), kde probereme tradiční témata (svobodný software a hardware, DIY, CNC, SDR, 3D tisk…) a tentokrát bude k vidění i IoT brána od The Things Network.
Přidat komentář

11.2.2018 23:11 /Petr Ježek
Hledáte lehký a rychlý prolížeč PDF souborů? Pokud vás již omrzelo čekat na načítání stránek či jiné nešvary, zkuste xreader.
Přidat komentář

11.2.2018 20:35 /Redakce Linuxsoft.cz
Třetí ročník odborné IT konference na téma Cloud computing v praxi proběhne ve čtvrtek 1. března 2018 v konferenčním centru Vavruška, v paláci Charitas, Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00 hod. dopoledne do cca 16 hod. odpoledne. Konference o trendech v oblasti cloud computingu nabídne i informace o konkrétních možnostech využívání cloudů a řešení vybraných otázek souvisejících s provozem IT infrastruktury.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

20.2.2018 18:48 / Ivan Majer
portal

20.2.2018 15:57 / Jan Havel
Jak využíváte služby cloudu v podnikání?

16.1.2018 1:08 / Ivan Pittner
verejna ip od o2 ubuntu

15.1.2018 17:26 / Mira Harvalik
Re: Jak udělat HTML/Javascript swiping gallery do mobilu?

30.12.2017 20:16 / Michal Knoll
odmocnina

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2018) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze