#!/usr/bin/perl -- package QuackLog; use Moose; use namespace::autoclean; use strict; my @log_string_parts = qw(timestamp foo bar baz qux norf quack honk woof meow blerf); has $_=> ( is => 'rw' ) for @log_string_parts; has qw/ log_string is rw isa Str lazy 1 builder _get_log_string /; sub _get_log_string { my ($self) = shift; my $str = join ' ', map {; my $str = $self->$_; length $str ? $str : '' } @log_string_parts; return $self->log_string( $str ); } sub set_log_string { my ( $self, $s ) = @_; my @part_values = split / /, $s; for my $method (@log_string_parts) { $self->can($method); $self->$method( shift @part_values ); } return $self->_get_log_string; } __PACKAGE__->meta->make_immutable(); package main; use strict; use warnings; my $ql = QuackLog->new ; dd( empty => $ql ); $ql->qux('qux'); dd( single => $ql ); dd( single => $ql->log_string ); dd( double => $ql ); dd( full => $ql->set_log_string( q/timestamp foo bar baz qux norf quack honk woof meow blerf/ ) ); dd( full => $ql->log_string ); $ql->qux('XXXXXX'); ## uh oh, log_string not updated dd( full => $ql , $ql->log_string ); __END__ ("empty", bless({}, "QuackLog")) ("single", bless({ qux => "qux" }, "QuackLog")) ("single", " qux ") ( "double", bless({ log_string => " qux ", qux => "qux" }, "QuackLog"), ) ( "full", "timestamp foo bar baz qux norf quack honk woof meow blerf", ) ( "full", "timestamp foo bar baz qux norf quack honk woof meow blerf", ) ( "full", bless({ bar => "bar", baz => "baz", blerf => "blerf", foo => "foo", honk => "honk", log_string => "timestamp foo bar baz qux norf quack honk woof meow blerf", meow => "meow", norf => "norf", quack => "quack", qux => "XXXXXX", timestamp => "timestamp", woof => "woof", }, "QuackLog"), "timestamp foo bar baz qux norf quack honk woof meow blerf", )