Spec-Zone .ru
спецификации, руководства, описания, API
Spec-Zone .ru
спецификации, руководства, описания, API
Библиотека разработчика Mac Разработчик
Поиск

 

Эта страница руководства для  версии 10.9 Mac OS X

Если Вы выполняете различную версию  Mac OS X, просматриваете документацию локально:

Читать страницы руководства

Страницы руководства предназначаются как справочник для людей, уже понимающих технологию.

  • Чтобы изучить, как руководство организовано или узнать о синтаксисе команды, прочитайте страницу руководства для страниц справочника (5).

  • Для получения дополнительной информации об этой технологии, ищите другую документацию в Библиотеке Разработчика Apple.

  • Для получения общей информации о записи сценариев оболочки, считайте Shell, Пишущий сценарий Учебника для начинающих.



Moose::Cookbook::Basics::BankAccount_MethodModifiersAndSubclassing(3)ionunt_MethodModifiersAndSubclassing(3)



NAME
       Moose::Cookbook::Basics::BankAccount_MethodModifiersAndSubclassing - Demonstrates the use of method
       modifiers in a subclass

VERSION
       version 2.0604

SYNOPSIS
         package BankAccount;
         use Moose;

         has 'balance' => ( isa => 'Int', is => 'rw', default => 0 );

         sub deposit {
             my ( $self, $amount ) = @_;
             $self->balance( $self->balance + $amount );
         }

         sub withdraw {
             my ( $self, $amount ) = @_;
             my $current_balance = $self->balance();
             ( $current_balance >= $amount )
                 || confess "Account overdrawn";
             $self->balance( $current_balance - $amount );
         }

         package CheckingAccount;
         use Moose;

         extends 'BankAccount';

         has 'overdraft_account' => ( isa => 'BankAccount', is => 'rw' );

         before 'withdraw' => sub {
             my ( $self, $amount ) = @_;
             my $overdraft_amount = $amount - $self->balance();
             if ( $self->overdraft_account && $overdraft_amount > 0 ) {
                 $self->overdraft_account->withdraw($overdraft_amount);
                 $self->deposit($overdraft_amount);
             }
         };

DESCRIPTION
       The first recipe demonstrated how to build very basic Moose classes, focusing on creating and
       manipulating attributes. The objects in that recipe were very data-oriented, and did not have much in
       the way of behavior (i.e. methods). In this recipe, we expand upon the concepts from the first recipe
       to include some real behavior. In particular, we show how you can use a method modifier to implement
       new behavior for a method.

       The classes in the SYNOPSIS show two kinds of bank account. A simple bank account has one attribute,
       the balance, and two behaviors, depositing and withdrawing money.

       We then extend the basic bank account in the CheckingAccount class. This class adds another
       attribute, an overdraft account. It also adds overdraft protection to the withdraw method. If you try
       to withdraw more than you have, the checking account attempts to reconcile the difference by
       withdrawing money from the overdraft account. (1)

       The first class, BankAccount, introduces a new attribute feature, a default value:

         has 'balance' => ( isa => 'Int', is => 'rw', default => 0 );

       This says that a BankAccount has a "balance" attribute, which has an "Int" type constraint, a
       read/write accessor, and a default value of 0. This means that every instance of BankAccount that is
       created will have its "balance" slot initialized to 0, unless some other value is provided to the
       constructor.

       The "deposit" and "withdraw" methods should be fairly self-explanatory, as they are just plain old
       Perl 5 OO. (2)

       As you know from the first recipe, the keyword "extends" sets a class's superclass. Here we see that
       CheckingAccount "extends" BankAccount. The next line introduces yet another new attribute feature,
       class-based type constraints:

         has 'overdraft_account' => ( isa => 'BankAccount', is => 'rw' );

       Up until now, we have only seen the "Int" type constraint, which (as we saw in the first recipe) is a
       builtin type constraint. The "BankAccount" type constraint is new, and was actually defined the
       moment we created the BankAccount class itself. In fact, Moose creates a corresponding type
       constraint for every class in your program (3).

       This means that in the first recipe, constraints for both "Point" and "Point3D" were created. In this
       recipe, both "BankAccount" and "CheckingAccount" type constraints are created automatically. Moose
       does this as a convenience so that your classes and type constraint can be kept in sync with one
       another. In short, Moose makes sure that it will just DWIM (4).

       In CheckingAccount, we see another method modifier, the "before" modifier.

         before 'withdraw' => sub {
             my ( $self, $amount ) = @_;
             my $overdraft_amount = $amount - $self->balance();
             if ( $self->overdraft_account && $overdraft_amount > 0 ) {
                 $self->overdraft_account->withdraw($overdraft_amount);
                 $self->deposit($overdraft_amount);
             }
         };

       Just as with the "after" modifier from the first recipe, Moose will handle calling the superclass
       method (in this case "BankAccount->withdraw").

       The "before" modifier will (obviously) run before the code from the superclass is run. Here, "before"
       modifier implements overdraft protection by first checking if there are available funds in the
       checking account. If not (and if there is an overdraft account available), it transfers the amount
       needed into the checking account (5).

       As with the method modifier in the first recipe, we could use "SUPER::" to get the same effect:

         sub withdraw {
             my ( $self, $amount ) = @_;
             my $overdraft_amount = $amount - $self->balance();
             if ( $self->overdraft_account && $overdraft_amount > 0 ) {
                 $self->overdraft_account->withdraw($overdraft_amount);
                 $self->deposit($overdraft_amount);
             }
             $self->SUPER::withdraw($amount);
         }

       The benefit of taking the method modifier approach is we do not need to remember to call
       "SUPER::withdraw" and pass it the $amount argument when writing "CheckingAccount->withdraw".

       This is actually more than just a convenience for forgetful programmers. Using method modifiers helps
       isolate subclasses from changes in the superclasses. For instance, if BankAccount->withdraw were to
       add an additional argument of some kind, the version of CheckingAccount->withdraw which uses
       "SUPER::withdraw" would not pass that extra argument correctly, whereas the method modifier version
       would automatically pass along all arguments correctly.

       Just as with the first recipe, object instantiation uses the "new" method, which accepts named
       parameters.

         my $savings_account = BankAccount->new( balance => 250 );

         my $checking_account = CheckingAccount->new(
             balance           => 100,
             overdraft_account => $savings_account,
         );

       And as with the first recipe, a more in-depth example can be found in the
       t/recipes/moose_cookbook_basics_recipe2.t test file.

CONCLUSION
       This recipe expanded on the basic concepts from the first recipe with a more "real world" use case.

FOOTNOTES
       (1) If you're paying close attention, you might realize that there's a circular loop waiting to
           happen here. A smarter example would have to make sure that we don't accidentally create a loop
           between the checking account and its overdraft account.

       (2) Note that for simple methods like these, which just manipulate some single piece of data, it is
           often not necessary to write them at all.  For instance, "deposit" could be implemented via the
           "inc" native delegation for counters - see Moose::Meta::Attribute::Native::Trait::Counter for
           more specifics, and Moose::Meta::Attribute::Native for a broader overview.

       (3) In reality, this creation is sensitive to the order in which modules are loaded. In more
           complicated cases, you may find that you need to explicitly declare a class type before the
           corresponding class is loaded.

       (4) Moose does not attempt to encode a class's is-a relationships within the type constraint
           hierarchy. Instead, Moose just considers the class type constraint to be a subtype of "Object",
           and specializes the constraint check to allow for subclasses. This means that an instance of
           CheckingAccount will pass a "BankAccount" type constraint successfully. For more details, please
           refer to the Moose::Util::TypeConstraints documentation.

       (5) If the overdraft account does not have the amount needed, it will throw an error. Of course, the
           overdraft account could also have overdraft protection. See note 1.

ACKNOWLEDGMENT
       The BankAccount example in this recipe is directly taken from the examples in this chapter of
       "Practical Common Lisp":

       http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html
       <http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html>

AUTHOR
       Moose is maintained by the Moose Cabal, along with the help of many contributors. See "CABAL" in
       Moose and "CONTRIBUTORS" in Moose for details.

COPYRIGHT AND LICENSE
       This software is copyright (c) 2012 by Infinity Interactive, Inc..

       This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5
       programming language system itself.



perl v5.16.2                           Moose::Coo2012-09-19ics::BankAccount_MethodModifiersAndSubclassing(3)

Сообщение о проблемах

Способ сообщить о проблеме с этой страницей руководства зависит от типа проблемы:

Ошибки содержания
Ошибки отчета в содержании этой документации со ссылками на отзыв ниже.
Отчеты об ошибках
Сообщите об ошибках в функциональности описанного инструмента или API через Генератор отчетов Ошибки.
Форматирование проблем
Отчет, форматирующий ошибки в интерактивной версии этих страниц со ссылками на отзыв ниже.