---
name: "Moose::Cookbook::Basics::Recipe10"
section: "3pm"
platform: "linux"
package: "libmoose-perl"
version: "1.09-2"
release: "Debian 6.0 (Squeeze)"
platforms: ["linux"]
url: "https://new.carta.tech/Moose::Cookbook::Basics::Recipe10"
---

# Moose::Cookbook::Basics::Recipe10(3pm)

Using BUILDARGS and BUILD to hook into object construction

## NAME

Moose::Cookbook::Basics::Recipe10 - Using BUILDARGS and BUILD to hook into object construction

## SYNOPSIS

```
  package Person;
  has 'ssn' => (
      is        => 'ro',
      isa       => 'Str',
      predicate => 'has_ssn',
  );
  has 'country_of_residence' => (
      is      => 'ro',
      isa     => 'Str',
      default => 'usa'
  );
  has 'first_name' => (
      is  => 'ro',
      isa => 'Str',
  );
  has 'last_name' => (
      is  => 'ro',
      isa => 'Str',
  );
  around BUILDARGS => sub {
      my $orig = shift;
      my $class = shift;
      if ( @_ == 1 && ! ref $_[0] ) {
          return $class->$orig(ssn => $_[0]);
      }
      else {
          return $class->$orig(@_);
      }
  };
  sub BUILD {
      my $self = shift;
      if ( $self->country_of_residence eq 'usa' ) {
          die 'Cannot create a Person who lives in the USA without an ssn.'
              unless $self->has_ssn;
      }
  }
```

## DESCRIPTION

This recipe demonstrates the use of `"BUILDARGS"` and `"BUILD"`. By defining these methods, we can hook into the object construction process without overriding `"new"`.

The `"BUILDARGS"` method is called *before* an object has been created. It is called as a class method, and receives all of the parameters passed to the `"new"` method. It is expected to do something with these arguments and return a hash reference. The keys of the hash must be attribute `"init_arg"`s.

The primary purpose of `"BUILDARGS"` is to allow a class to accept something other than named arguments. In the case of our `"Person"` class, we are allowing it to be called with a single argument, a social security number:

```
  my $person = Person->new('123-45-6789');
```

The key part of our `"BUILDARGS"` is this conditional:

```
      if ( @_ == 1 && ! ref $_[0] ) {
          return $class->$orig(ssn => $_[0]);
      }
```

By default, Moose constructors accept a list of key-value pairs, or a hash reference. We need to make sure that `$_[0]` is not a reference before assuming it is a social security number.

We call the original `"BUILDARGS"` method to handle all the other cases. You should always do this in your own `"BUILDARGS"` methods, since Moose::Object provides its own `"BUILDARGS"` method that handles hash references and a list of key-value pairs.

The `"BUILD"` method is called *after* the object is constructed, but before it is returned to the caller. The `"BUILD"` method provides an opportunity to check the object state as a whole. This is a good place to put logic that cannot be expressed as a type constraint on a single attribute.

In the `"Person"` class, we need to check the relationship between two attributes, `"ssn"` and `"country_of_residence"`. We throw an exception if the object is not logically consistent.

## MORE CONSIDERATIONS

This recipe is made significantly simpler because all of the attributes are read-only. If the `"country_of_residence"` attribute were settable, we would need to check that a Person had an `"ssn"` if the new country was `"usa"`. This could be done with a `"before"` modifier.

## CONCLUSION

We have repeatedly discouraged overriding `"new"` in Moose classes. This recipe shows how you can use `"BUILDARGS"` and `"BUILD"` to hook into object construction without overriding `"new"`

The `"BUILDARGS"` method lets us expand on Moose's built-in parameter handling for constructors. The `"BUILD"` method lets us implement logical constraints across the whole object after it is created.

## AUTHOR

Dave Rolsky \<autarch@urth.org\>

## COPYRIGHT AND LICENSE

Copyright 2006-2010 by Infinity Interactive, Inc.

\<http://www.iinteractive.com\>

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