On Tue, Nov 10, 2009 at 05:09:59PM -0600, Markx.Allen wrote: > I've read through almost all of the Moose docs I could find on CPAN and > several of the Moose slide decks floating around the Interwebs. > > That being said I have some basic questions that probably have simple > answers. Maybe I didn't read the fine manuals closely enough, so if I did > overlook something, please point me toward the right spot in the docs and > I'll figure it out. > > That being said here are my questions: > > 1) In the "old style" OO (which I have used for a long time now) I would do > something like this: > > I would make a file called "Account.pm" and try to encapsulate all of the > functionality of accounts in that one file. > > I would make another file called Server.pm and encapsulate functionality > around servers in the other file. Then if Account and Server have a > relationship, I would do this: > > package Account; > > use Server; > > I found that if I do this: > > package Server; # (in a file called Server.pm) > use Moose; > > has 'name' => { > is => 'ro', > isa => 'Str', > }; > > # etc > > package Account; # (in a file called Account.pm) > use Moose; > use Server; > > has 'server' => { > is => 'ro', > isa => 'Server', > }; > > perl -wc Account.pm throws an error > > but if I change "use" to "require Server;" I do not get an error. > > Why doesn't use work?
The example you gave here doesn't error, so I don't know what the exact problem is, but putting "use" lines for other classes in the middle of your class definition is bad practice in general. What happens is that the Server class here is being created while the Account class is only half-built (since use statements happen at compile time, and use Moose initializes a new empty class). A lot of times the use statement isn't even necessary (for instance, if it's just used for a type constraint like in this example), but if it is, require is probably a better option (possibly putting it closer to where it's actually used, so something like "require Server; my $server = Server->new;"). Alternatively, you can load all of your classes from some top-level module. > 2) Maybe I haven't really grokked the Moose Way yet, but what's the best way > to implement a collection of Moose Objects? > > In the old style OO, I would implement an object as, say, Account.pm and then > I would create a collection class of that object type called XXXCollection or > AccountCollection.pm in this case. I usually stored individual objects as a > hash of hashes, using the object name as the key. > > I suspect that Roles and Traits can help me write a Collection class > trivially where I will get a lot of functionality "for free" but I'm just not > quite sure I understand the docs well enough to put it all together. A trivial container class would just have an attribute like has foos => ( is => 'ro', isa => 'ArrayRef[Foo]', ); and then you can write whatever methods you want to manipulate that. The native attribute traits can simplify the generation of a lot of these methods (Moose::Meta::Attribute::Native has the docs for this), and you can also abstract a lot of the collection manipulation out into roles, so you can use it on many different types of objects (see MooseX::Role::Matcher for an example). -doy