oop intermediate

How to use Moose attribute triggers in Perl?

Question

How to use Moose attribute triggers in Perl?

Using Moose Attribute Triggers Correctly in Perl

Moose is a powerful object system for Perl that introduces modern OOP features like attributes, type constraints, and triggers. Attribute triggers let you specify a callback that runs every time an attribute’s value changes, including during object construction.

Common issue: When running Moose code from the command line with perl -, it often fails because Moose exports keywords like has that Perl needs to parse. The code must be placed inside a proper package block, and Moose must be used before attribute declarations.

Key Concepts

  • has declares attributes with options like is, isa, trigger.
  • Triggers receive two arguments: the new value and the object instance (($new_val, $self)).
  • Triggers run on object construction and every time the attribute is set.
  • Moose requires Perl 5.8.1+ and is available as a core or widely installed module.

Fixed and Runnable Example

use strict;
use warnings;

{
    package User;
    use Moose;   # must be inside package before 'has'

    has 'name' => (
        is      => 'rw',
        isa     => 'Str',
        trigger => sub {
            my ($self, $new_name) = @_;  # Moose triggers: ($self, $new_value)
            $self->greeting("Hello, $new_name!");
            print "Trigger ran: greeting updated to '", $self->greeting, "'\n";
        },
    );

    has 'greeting' => (
        is      => 'rw',
        isa     => 'Str',
        default => 'Hello!',
    );

    no Moose;  # cleans up metaclass after definition
}

package main;

my $user = User->new(name => 'Alice');
print "Initial greeting: ", $user->greeting, "\n";

$user->name('Bob');
print "Greeting now: ", $user->greeting, "\n";

Output:

Trigger ran: greeting updated to 'Hello, Alice!'
Initial greeting: Hello, Alice!
Trigger ran: greeting updated to 'Hello, Bob!'
Greeting now: Hello, Bob!

Explanation and Gotchas

  • Trigger argument order: Moose triggers receive ($self, $new_value), not ($new_value, $self). This is a common source of confusion.
  • Keywords like has: These are imported by use Moose; and require Moose to be imported before attributes are declared.
  • Package scope: Define your class inside a package block for proper symbol scoping.
  • Calling no Moose;: This is a best practice to clean up meta-methods and optimize the package after declaration.
  • Perl versions: Moose triggers work consistently on Perl 5.8.1 and newer.

Summary

Moose attribute triggers allow automatic callback execution when attributes change, useful for keeping related data consistent or performing side effects. Importantly, remember to use Moose; inside your class package before declaring attributes and note that the trigger callback arguments are ($self, $new_value), not reversed. This fixed pattern will run successfully even in sandboxed or one-liner execution environments.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 156ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Trigger ran: greeting updated to 'Hello, Alice!'
Initial greeting: Hello, Alice!
Trigger ran: greeting updated to 'Hello, Bob!'
Greeting now: Hello, Bob!
STDERR
(empty)

Was this helpful?

Related Questions