in reply to Re: Moose is lovely in thread Moose is lovely
Sure! I've omitted the _fetch routines here, because they're not particularly relevant to the Moose portions of the code, and the size would be a bit unmanageable.
{
package LT::Library;
use Moose;
has 'catalog' => (is => 'ro', required => 1);
has 'address' => (
is => 'ro',
default => sub {
my ($self) = @_;
return "http://www.librarything.com/catalog/"
. $self->catalog;
}
);
has 'books' => (
is => 'ro',
isa => 'ArrayRef[LT::Book]',
lazy => 1,
default => sub {
my ($self) = @_;
my @book_addrs = _fetch_book_addrs($self->address);
my @books = map { LT::Book->new(address => $_) }
@book_addrs;
return \@books;
},
);
}
{
package LT::Book;
use Moose;
has 'address' => (is => 'ro', required => 1);
has 'work' => (
is => 'ro',
isa => 'LT::Work',
lazy => 1,
default => sub {
my ($self) = @_;
my ($work_address) = $self->address =~ m{(.*/work/\d+)};
return LT::Work->new(address => $work_address);
},
);
}
{
package LT::Work;
use Moose;
has 'address' => (is => 'ro', required => 1);
has 'title' => (
is => 'ro',
isa => 'Maybe[Str]',
lazy => 1,
default => sub {
my ($self) = @_;
return _fetch_title($self->address);
}
);
has 'author' => (
is => 'ro',
isa => 'Maybe[Str]',
lazy => 1,
default => sub {
my ($self) = @_;
return _fetch_author($self->address);
}
);
has 'series' => (
is => 'ro',
isa => 'Maybe[LT::Series]',
lazy => 1,
default => sub {
my ($self) = @_;
my $series_addr = _fetch_series_addr($self->address);
return defined $series_addr
? LT::Series->new(address => $series_addr)
: ();
}
);
}
{
package LT::Series;
use Moose;
has 'address' => (is => 'ro', required => 1);
has 'title' => (
is => 'ro',
isa => 'Maybe[Str]',
lazy => 1,
default => sub {
my ($self) = @_;
return _fetch_title($self->address);
}
);
has 'works' => (
is => 'ro',
isa => 'ArrayRef[LT::Work]',
lazy => 1,
default => sub {
my ($self) = @_;
my @work_addrs = _fetch_work_addrs($self->address);
my @works = map { LT::Work->new(address => $_) }
@work_addrs;
return \@works;
},
);
}
Re^3: Moose is lovely
by stvn (Monsignor) on Feb 29, 2008 at 17:29 UTC
|
Very nice, I am glad you are enjoying Moose :)
Just one suggestion, if your "default" subs get large, it is usualy a good idea to convert them to 'builder' methods instead. You can find this feature documented in Class::MOP::Attribute. This:
has 'foo' => (
builder => 'build_foo'
);
is basically a shortcut for:
has 'foo' => (
default => sub { (shift)->build_foo }
);
It also gives the added benefit that any subclasses can easily override 'build_foo' themselves to get additional behavior.
| [reply] [d/l] [select] |
|
Just one suggestion, if your "default" subs get large, it is usualy a good idea to convert them to 'builder' methods instead.
Oh, very cool. I'd missed the builder bits while reading the docs. It does seem like a nice shortcut, and I kind of like the additional semantic alignment. I'm actually building the value, not setting a default value. Granted, it doesn't make a practical difference. But when there're two ways to do something, and one of them is a better semantic match, I usually choose that one.
| [reply] [d/l] |
|
Oh, very cool. I'd missed the builder bits while reading the docs. It
Unfortunately, it is not as well documented as it could be, we just completed a big refactoring of the type and role systems and some of the new features have not gotten documented well enough yet. The next few releases should be mostly doc updates, which should remedy this situation.
| [reply] |
|
Does it play well with lazy?
| [reply] |
|
Does it play well with lazy?
Yes, in fact the motivation for putting it in Class::MOP was to support the 'lazy_build' option in Moose (which is sort of documented in Moose::Meta::Attribute under "is_lazy_build", more docs to come, patches welcome and all that).
In general if an option does not play well with another option, we consider it a "syntax" error and throw an exception at compile time.
| [reply] |
|
Wonderfully. There's even a shortcut for that: lazy_build => 1. It works like this:
has foo => (
...
lazy_build => 1,
);
sub _build_foo {
my $self = shift;
...
}
| [reply] [d/l] [select] |
Re^3: Moose is lovely
by meraxes (Friar) on Feb 29, 2008 at 17:27 UTC
|
You are my new hero.
I was at the to.pm meeting last night and I asked "has anyone used Moose?" The answer was no but talexb suggest I post to perlmonks to see if anyone knew of some real-world examples on CPAN. So here I am and here this is ready and waiting for me!
I admit, I don't quite grok it despite looking at merlyn's articles on the subject. But something keeps telling me "this is good stuff, you should learn it".
Methinks you are a little psychic. My thanks.
--
meraxes
-- A Møøse once bit my sister
| [reply] |
|
... suggest I post to perlmonks to see if anyone knew of some real-world examples on CPAN ...
Well, this is far from a comprehensive listing, these are just modules I know about (or wrote). Of course there is also a lot of Moose code not on CPAN that has been written for people's jobs (we have at least 5 apps in prod at my $work).
Some of my Moose related modules ...
... and modules written by others
You might always want to look in the MooseX:: namespace for the various extensions for Moose that have been written. And since Moose is meta-circular, most of these extensions to Moose have themselves been written with Moose.
| [reply] |
|
|