Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^2: Moose is lovely

by revdiablo (Prior)
on Feb 29, 2008 at 06:42 UTC ( #671113=note: print w/ replies, xml ) Need Help??


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; }, ); }


Comment on Re^2: Moose is lovely
Select or Download Code
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 Mse once bit my sister
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.

    -stvn
        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.

        -stvn
        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; ... }
        -nuffin
        zz zZ Z Z #!perl
      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.

        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.

        -stvn

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://671113]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (10)
As of 2014-08-20 09:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (109 votes), past polls