Programming with Moose/Syntax/has

The most important Moose keyword is arguably "has", which is essentially the most beefed up accessor-generator ever devised. Many of these features can be found in the accompanying docs of Moose, and Class::MOP::Accessor.

Attributes of has
Below you can find all of the attributes of. Asterisk represents the default.

isa
The second most essential attribute of  is. is pronounced "Is a", and essentially does little more than tell what the attribute can be set with.

 Any Item Bool Undef Defined Value Num Int Str ClassName Ref ScalarRef ArrayRef HashRef CodeRef RegexpRef GlobRef FileHandle Object Role

These are the default choices for. In addition to them  can be set to any class name, for instance , or.

Moose v0.26 introduces parameterized types —no one knows what they really do, but they gave the ability to do such things as:

Now when you try to store to, you had better only add URI elements to the ArrayRef, or you will.

is
The heart of the attribute generating  is the attribute. If something is  the user has a getter (read-only accessor) by the specified name. Conversely, if the value supplied is  the user has a getter/setter hybrid (read-write accessor).

The default value is to not generate an accessor of either kind at all.

coerce
The   attribute to has is significantly more complex than  and. It tells Moose, "Hey dude, it would be really l33t if you could get this value into the datatype I want it to be without being a pain in the ass all the time."

Moose generally listens when you talk to it as such.

To use  you must have a supplied a subtype which can coerce.

weak_ref
You cannot use, if you set  

Weak_ref stops the refcount held in the attribute from being incremented by the object. This means if you have one copy of something, and a hundred objects use it with, you can successfully destroy their copies by  'ing your one copy. Perl's garbage collector will destroy the item when its reference count reaches zero. With  your object will never increase the reference count. This prevents circular recursion, but leaves you susceptible to having the rug pulled out from under you, so to speak.

does
This will accept the name of a role which the value stored in this attribute is expected to have consumed.

required
That which is required is. All things required must have a value specified in a hash whose ref is sent to.

lazy
Don't want something to happen at compile time... Defer it! Lazy necessitates a default: you must supply one.

This one attribute introduces a whole new way to model problems. It brings a new mentality, don't do work, until it needs to get done. About time computer programs grew the ability to procrastinate without stressing me out. I'd hate to restrict a luxury of that caliber to myself.

Think of the lazy/default combination in terms of a sub that stores its return value so it doesn't have to recompute it on subsequent calls.

In this example, does not get set until you ask for it; and, in this example it pulls down a webpage, and thus we would not want to do this possibly time-consuming operation until we know we need the result.

auto_deref
Auto_deref is a tricky and deceitful little fellow. It doesn't fix perl, it only makes things slightly more simple. This attribute simply returns an expanded Array for an ArrayRef, or a Hash for a HashRef. To use auto_deref you must have, or   or a Parameterized type of one of the two:

What did I mean by deceitful well auto_deref still just simply passes by copy.

default
Default has two radically different functions:
 * 1) set a default static value.
 * 2) set a dynamic lazy  default value on the first call to the accessor

The first and most simple application of default, does nothing more than set a fall-back static value:

The second implementation of default is much more complex. Using this method, you state the attribute as  (do nothing at compile-time), and then you point the default to a function such as. When the function is called, it sees the slot is unset (fails a predicate test) and the  pointed to by default is called setting the slot with the return value. This value is cached away and will not be recomputed unless the slot again becomes unset—as in the case of calling clearer.

clearer
If you ever need to undo all changes made to a value clearer is a great way to go about it. Let's say you have made the first call to a lazy => 1 attribute, which sets the initial value to the corresponding default. Let's assume you don't like this value, and you want to reset it as if it was never called. Calling the clearer-specified method in this context will accomplish that. Internally,  deletes the slot.

If you call an accessor on a ed value it will return undef, unless there is a lazy/default</tt> combo specified. In which case it will reinitilize as if it was the first call. If you call <tt>clearer</tt> on a regular <tt>default</tt>, the value might appear to be set to <tt>undef</tt>. In effect the slot is not existence. To test for this see predicate.

Use of uninitialized value in print at test.pl line 22.

Don't ever access a Moose object's underlying hash unless writing fugly examples for books. Moose is supposed to abstract away what it is blessed. Don't remind people that the hash even exists.

predicate
All predicate does is create a sub that returns true (1) if the attribute's respective slot exists, and false (0) if it doesn't. It's a simple convenience attribute. Without, you would not easily be able to discern whether or not the slot exists without violating the black-box tenet of Object Orientation. Predicate makes this step easy, and allows you to continue without peering into the Moose internals. Predicate is only useful for:


 * Inter-operating with its family-function —which deletes the slot. Predicate can be though of as clearer_test in this context.
 * Testing to see if a non-required attribute was supplied to the constructor.
 * Testing to see if a  with a   has fired yet

Predicate takes a string which it uses to generate the predicate-sub's name:

Here we will see it in action:

trigger
A trigger is a function that gets called after you write to an accessor or when you set a value using the constructor. However, as of the time of writing they do not fire on attributes set with <tt>lazy_build</tt>, <tt>default</tt>, or <tt>builder</tt>. A trigger is set with a <tt>CodeRef</tt>, which receives the following values: $self, $value, $oldValue.

If you want a <tt>trigger</tt> to only execute when you run the setter try something more on the lines of:

If you want a trigger to fire on something that is built from a builder/default/lazy_build you will either have to explicitly unroll the trigger in the builder/default/lazy_build code, or hack a wrapper around the builder. This is because the trigger can presume the attribute is set and read from it. But, Moose only sets the attribute after the builder has returned—so you can't simply call the trigger from within the builder.

init_arg
This attribute serves two distinct purposes:
 * It can alter the key from the constructor's hash that Moose will use use to set your attribute.
 * You can ignore any values sent in the constructor by setting to it to undef.

You can tell Moose to use a different key in the constructor's hash by explicitly setting <tt>init_arg</tt> to something other than the attribute name. For example:

Or, you can have Moose ignore the constructor's hash. This will even work with a default.

This attribute can not be inherited and modified with +attr:

initializer
This feature assists in initializing (setting the slot). It fires when one of the following are met:
 * A default is present
 * A value is sent in the constructor
 * A value is computed from lazy_build
 * A value is computed from a builder
 * Or, a triggering through the meta such as <tt>Class::MOP::Attribute</tt>'s <tt>set_initial_value</tt>

If you don't set the slot in the initializer, the slot will effectively be set to <tt>undef</tt>, assuming the type system permits it.

The initializer sub receives four values: $self, $value, $writerSubRef, $attributeMeta. With $attributeMeta probably being an instance of Class::MOP::Attribute. The $writerSub is not a method.

One very important point about an initializer is it fires *after* the type system. The value must pass through a type coercion or be a valid type prior to the initializer firing.

lazy_build
Lazy_build is an attribute that is made to simplify quick construction of a class. Here is what comprises it:

handles
This feature provides another way to delegate methods to a different module.

The <tt>handles</tt> attribute can be configured in a different ways with varying degrees of syntactic sugar:
 * Array
 * Hash
 * Regex

Here is an example from HTML::TreeBuilderX::ASP_NET which uses the Regex configuration: A good and general use case is <tt>handles => qr/.*/</tt>, which tells Moose to defer to the module specified in <tt>isa</tt> for all functions which it declares and aren't overridden in your package. This will often allow you to avoid subclassing and munging ->new.

traits
Traits, or more specifically Attribute Traits, are a mechanism for expanding the functionality of attributes.

An example of this would be the Moose functionality provided by the <tt>Native</tt> traits. These will provide helper methods for all container types: <tt>Hash</tt>, <tt>Array</tt>; as well as the strongly typed <tt>Number</tt>, <tt>String</tt>, <tt>Bool</tt>, <tt>Couter</tt>, and <tt>Code</tt>. The Native traits have functionality that can be turned on as required through an additional <tt>handles</tt> attribute.

initializer vs default
Initializers are part of the default process. The layer that sets the <tt>default</tt>, is the same layer that fires the <tt>initializer</tt>. A default value initializes a slot to a set value. The fire order of <tt>defined</tt> and <tt>initializer</tt> is defined for an attribute; but, totally undefined amongst all of the modules attributes.

Defined for an attribute:

Undefined for set of attributes: one attribute (foo) might fire its initialer, write to another attribute (bar), just to have (bar) overwritten by its own default.

initializer vs trigger
Arguments:

Both <tt>trigger</tt> and <tt>initializer</tt> utilize $self, $value, and $attributeMeta.


 * trigger: $self, $value, $attributeMeta.
 * initializer: $self, $value, $writerSub, $attributeMeta.

Firing order:

It might be considered a bug that triggers do not fire in any event that writes to a slot.

Coexisting:

If a <tt>trigger</tt> is available, <tt>initializer</tt> will always fire before the trigger. However, it still does not fire when a value is explicitly set to the slot in runtime.

You can use <tt>trigger</tt> to have a sub fire when a value is explicitly provided in runtime. The downside to this approach is a double fire when the value is constructor-provided: one from <tt>trigger</tt>, one from <tt>initializer</tt>.