[ Pobierz całość w formacie PDF ]

tyczne. Nowe metody dostępu również zapewne będą bardzo podobne. Czy nie dałoby
się tego jakoś zautomatyzować?
Sposób
W sieci CPAN dostępnych jest wiele modułów, które potrafią sobie poradzić z tym za-
daniem, każdy w odrobinę inny sposób. Tutaj przedstawię dwa przykłady takich mo-
dułów  jeden najbardziej wszechstronny, a drugi narzucający programiście najmniej-
sze ograniczenia.
Class::MethodMaker
Jednym z najstarszych takich modułów jest Class::MethodMaker, po raz pierwszy
opublikowany w 1996 roku. Posiada bardzo bogaty zestaw funkcji i choć jego doku-
mentacja pozostawia trochę do życzenia, z samego modułu korzysta się z łatwością. Aby
przekonwertować kod wcześniejszego pakietu My::Customer, należy napisać:
Sposoby na obiekty | 153
SPOSÓB
Automatyczne generowanie metod dostępu
50.
package My::Customer;
use strict;
use warnings;
use Class::MethodMaker[
new => [qw( new )],
scalar => [qw( first_name last_name )],];
sub full_name
{
my $self = shift;
return join ' ', $self->first_name( ), $self->last_name( );
}
Konstruktor, jak widać, jest bardzo prosty, ale co stało się z metodami first_name
i last_name? Argumenty przesłane modułowi Class::MethodMaker polecają mu utwo-
rzyć dwa komplety metody dostępu i metody modyfikującej dla dwóch wartości skalarnych.
Niemniej, mimo iż kod ten wygląda prawie identycznie, ma jednak znacznie większe
możliwości.
Załóżmy, że chcemy sprawdzić, czy ktoś już definiował wartość zmiennej first_name,
czy też ma przypisaną wartość undef:
print $cust->first_name_isset( ) ? 'true' : 'false';
Nawet jeśli zmienna imienia first_name ma wartość undef, metoda first_name()
zwróci wartość true(). Oczywiście, czasami wygodniej byłoby, aby zmienna miała
status zmiennej jeszcze nieokreślonej, nawet jeśli wcześniej przypisana była już jej jakaś
wartość. To również da się zrobić:
$cust->first_name( 'Ozymandias' );
print $cust->first_name_isset( ) ? 'true' : 'false'; # prawda - true
$cust->first_name_reset( );
print $cust->first_name_isset( ) ? 'true' : 'false'; # fałsz - false
Class::BuildMethods
Moduł Class::MethodMaker obsługuje również tablice, tablice asocjacyjne i wiele in-
nych użytecznych funkcji. Niemniej wymaga, aby w obiektach korzystać z błogosławio-
nych (za pomocą funkcji bless) tablic asocjacyjnych. Prawdę powiedziawszy, więk-
szość modułów z sieci CPAN, które tworzą metody dostępu, przyjmuje jakieś założenia
na temat wewnętrznej struktury naszych obiektów. Jednym z nielicznych wyjątków jest
moduł Class::BuildMethods.
Moduł Class::BuildMethods umożliwia programiście budowanie metod dostępu
dla tworzonej klasy niezależnie od tego, czy oparta jest ona na błogosławionej tablicy
asocjacyjnej, odwołaniu do tablicy, wyrażeniu regularnym, czy jeszcze czymś innym. Osiąga
to,  sięgając po trik wykorzystywany przy tworzeniu prawidłowo zamkniętych obiek-
tów [SposOb 43.]. Typowy kod tworzący z jego pomocą klasę będzie wyglądał mniej
więcej tak:
154 | Sposoby na obiekty
SPOSÓB
Automatyczne generowanie metod dostępu
50.
package My::Customer;
use strict;
use warnings;
use Class::BuildMethods qw(
first_name
last_name
);
# Warto zauważyć, że jeśli wolimy, możemy użyć odwołania do tablicy
sub new { bless [ ], shift }
sub full_name
{
my $self = shift;
return join ' ', $self->first_name( ), $self->last_name( );
}
1;
Z klasy tej korzysta się taka samo jak z każdej innej. Wewnętrznie indeksuje ona warto-
ści metod dostępu według adresu obiektu. Standardowo automatycznie zajmuje się
niszczeniem obiektu, niemniej pozwala też programiście zrobić to ręcznie, jeśli potrze-
bować będzie jakiegoś specjalnego zachowania w metodzie DESTROY (takiego jak na przy-
kład zdjęcie wcześniej założonych blokad).
Konstrukcja modułu Class::BuildMethods jest bardzo prosta. Podobnie jak więk-
szość innych modułów zajmujących się generowaniem metod dostępu dla obiektów, do-
starcza programiście kilku wygodnych funkcji, jednak tylko wtedy, gdy chodzi o domyślne
wartości i sprawdzanie danych:
use Class::BuildMethods
'imie',
gender => { default => 'mezczyzna' },
age => { validate => sub
{
my ($self, $age) = @_;
carp 'Nie możesz studiować, jeśli jesteś istotą niższą'
if ( $age is_emancipated( ) );
}};
W tym kodzie związana z płcią metoda gender() zwróci wartość male (mężczyzna),
chyba że ustawimy w zmiennej jakąś inną wartość. Związana z wiekiem metoda age()
demonstruje natomiast, jak przygotować elastyczny mechanizm sprawdzania wartości.
Ponieważ metoda validate() wskazuje do odwołania do procedury, a nie dostarcza
specjalnych procedur sprawdzających wartości, przyjęte przez autora założenia co do [ Pobierz całość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • sliwowica.opx.pl
  •