On Thu, Mar 4, 2010 at 5:55 PM, Karen Etheridge <p...@froods.org> wrote: > > On Wed, Mar 03, 2010 at 12:52:56PM -0800, Darren Duncan wrote: >> Now, perhaps a bigger question that one might ask, is why wouldn't Moose >> use MooseX::StrictConstructor's semantics by default? >> >> The main reason I can think of for the current behavior is that you may >> want objects to have constructor parameters that don't correspond to >> attributes, and you would be using BUILD to map them. > > I've wondered this myself. I don't want arbitrary fields springing into > existence in my object, even if they don't have the overhead of a > full-blown attribute. For that matter, I don't want a field on my object > without the attribute interface -- one of the reasons for attribute > accessors is so I never have to type $obj->{fieldname} again. So I don't > want data being put there in a plain old hash key; if I wanted it, I'd have > made an attribute for it, wouldn't I? > > FWIW, I also really like the approach used in MooseX::SlurpyConstructor, > where all "extra" constructor arguments are stored together in a slurpy > attribute. I see a strict constructor as a simple extension of a slurpy > one, using the base case of zero slurpy fields being allowed. > > tl;dr version: I'm all in favour of strict construction being the default, > and slurpiness being the next best thing for the remaining cases.
First: Stevan has used the Moose version of a Rule 1 and said "This is not going to be default." So having gotten that out of the way. Let me ramble on for a second. You can feel free to ignore me now. Objects are a mixture of things: State (attributes), Behavior (methods), Type (classes in Moose), and Identity (instances). One of the big ideas of Object Oriented Design is encapsulation, that is making it easy to swap between the State and Behavior so the consumers of the Object will never know the difference. We use Accessors to direct hash introspection, replacing direct slot access with validation behavior. More radically we create replace attributes with delegates to a Native::Attribute handler or a sub-object via handles. This is I believe what Stevan means when he says that the Attribute Protocol is one of the most powerful features of Moose. The way I see it StrictConstructors favors State over Behavior by saying "if I wanted it, I'd have made an attribute for it, wouldn't I?". I see the current Moose default as more encapsulating, saying "if I wanted you to know what the valid attributes were, I'd tell you." WIth the current behavior, if I decide to change something, removing an `elements` ArrayRef attribute and folding it into a Set::Object delegate, (ie changing from from State to Behavior) I don't suddenly break all of my existing code because an parameter that used to be legal suddenly now isn't. You can get this with StrictConstructors and BUILDARGS/BUILD, but I personally find that needing BUILDARGS/BUILD, can be a bit of a code smell. To me it signals that I missed something in my model and I've got some confusion between Behavior and State that probably could use sorting out somewhere. SlurpyConstructors is a neat way to change the default behavior from "drop on the floor" to "drop into this shoebox over here". Generally it falls into that same category as BUILDARGS/BUILD to me, if you need it you should probably re-think your design a bit more. -Chris