2010-10-01 15 views
5

Jestem absolutnym początkującym dla Moose i do tej pory przeczytałem Moose i większość Cookbook.Jak mogę uzyskać dostęp do atrybutów obiektów Moose tylko do odczytu?

Jest kilka rzeczy, których nie otrzymuję. I stworzył następujący pakiet:

package MyRange; 

use Moose; 
use namespace::autoclean; 

has [ 'start', 'end' ] => (
    is  => 'ro', 
    isa  => 'Int', 
    required => 1, 
); 

__PACKAGE__->meta->make_immutable; 

1; 

wówczas:

use MyRange;  
my $br = MyRange->new(
    start    => 100, 
    end     => 180 
); 

Teraz mogę uzyskać dostępu do pól przy użyciu np $br->{start}, ale mogę również je modyfikować (chociaż są one "tylko do odczytu") za pomocą np. $br->{start}=5000. Mogę też dodać nowe klucze, takie jak $br->{xxx}=111.

Czy brakuje mi czegoś? Czy obiekt nie jest w jakiś sposób chroniony? Jakie jest znaczenie ro?

Odpowiedz

14

Kiedy powiedziałeś is => 'ro' powiedziałeś Moose, że utworzysz dla ciebie dostęp do odczytu, czyli metodę odczytu. Nazywasz że

$br->start; 

lub

$br->end; 

Ustawianie atrybutów przy użyciu tych metod spowoduje wyjątek:

$br->start(42); 

Jeśli użył is => 'rw', to powyższe będzie działać i zaktualizuj wartość atrybutu.

To, co robisz, to bezpośredni dostęp do haszyszu obiektu, który narusza hermetyzację i nie powinien być nigdy potrzebny podczas używania łosia.

Podręcznik łosia, tj. Wszystkie dokumenty w obszarze nazw Moose::Manual wyjaśniają to szczegółowo. Dobrym punktem wyjścia dla takich pytań jest prawdopodobnie Moose::Manual::Attributes.

+0

+1 Dziękujemy! Kontynuacja, jeśli mogę: mam kilka pól, które nie są wymagane. Jeśli nie są ustawione i próbuję uzyskać dostęp do tych wartości 'undef', chciałbym uzyskać błąd. Czy powinienem ustawić czytnik dla każdego z nich? A może użyć jakiejś podobnej do '' '' '' '' '' '' '' '' '' '' '' '' '' ' –

+1

Możesz utworzyć nowe pytanie, aby uzyskać bardziej szczegółową odpowiedź na ten temat, ale: Czy masz projekt, w którym początkowo wartości nie są wymagane, ale użytkownik może je później wypełnić za pomocą metod pisarza i musi to zrobić przed wywołaniem niektóre funkcje, które go używają? Przez większość czasu powinieneś przemyśleć swój projekt, ale w rzadkich przypadkach, gdy ma to sens, moje rozszerzenie 'MooseX :: LazyRequire' może być pomocne.Wszystko, co robi, to uczynienie wymaganego atrybutu, ale odroczenie wyjątku od czasu budowy do czasu dostępu do atr. – rafl

+0

Zauważ też, że możesz poprosić Moose'a o wygenerowanie dla ciebie metod 'predicate'. Te, których można użyć do jawnego sprawdzenia, czy wartość została ustawiona dla jakiegoś atrybutu za pomocą metod konstruktora lub programu piszącego. Jest to szczególnie przydatne w przypadku atrybutów, które nie są wymagane i dla których 'undef' jest poprawną wartością. – rafl

3

Po uzyskaniu dostępu do atrybutu za pomocą $br->{start} omijasz narzędzie uzyskujące dostęp i jesteś bezpośrednio adresatem implementacji protokołu Moose. Możesz to zrobić, ale nie powinieneś. Ponadto, jeśli Moose zmieni implementację, twój kod zostanie złamany.

Należy zamiast dostęp atrybut za pomocą metody dostępowej:

my $start = $br->start; 

Kiedy mówisz, że atrybut jest „RO”, to znaczy, że nie mogą zmienić wartość atrybutu pomocą akcesor:

$br->start(32); 
Powiązane problemy