Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Contact Us
Online Help
Domain Status
Man Pages

Virtual Servers

Topology Map

Server Agreement
Year 2038

USA Flag



Man Pages


.ds Aq ’


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



version 2.1605


  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 ) {


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, <B>BankAccountB>, introduces a new attribute feature, a default value:

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

This says that a <B>BankAccountB> 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 <B>BankAccountB> 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. \fIs0(2)

As you know from the first recipe, the keyword extends sets a class’s superclass. Here we see that <B>CheckingAccountB> extends <B>BankAccountB>. 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 <B>BankAccountB> 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 \fIs0(4).

In <B>CheckingAccountB>, 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 ) {

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 ) {

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 <B>BankAccount->withdrawB> were to add an additional argument of some kind, the version of <B>CheckingAccount->withdrawB> 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/basics_bankaccount_methodmodifiersandsubclassing.t test file.


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


(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 <B>CheckingAccountB> 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.


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



o Stevan Little <>
o Dave Rolsky <>
o Jesse Luehrs <>
o Shawn M Moore <>
o XXXX XXXXX (Yuval Kogman) <>
o Karen Etheridge <>
o Florian Ragwitz <>
o Hans Dieter Pearcey <>
o Chris Prather <>
o Matt S Trout <>


This software is copyright (c) 2006 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.

Search for    or go to Top of page |  Section 3 |  Main Index


Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with manServer 1.07.