{
    "mode": "perldoc",
    "parameter": "Moose::Manual::BestPractices",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/Moose%3A%3AManual%3A%3ABestPractices/json",
    "generated": "2026-06-12T13:12:30Z",
    "sections": {
        "NAME": {
            "content": "Moose::Manual::BestPractices - Get the most out of Moose\n",
            "subsections": []
        },
        "VERSION": {
            "content": "version 2.2200\n",
            "subsections": []
        },
        "RECOMMENDATIONS": {
            "content": "Moose has a lot of features, and there's definitely more than one way to do it. However, we\nthink that picking a subset of these features and using them consistently makes everyone's life\neasier.\n\nOf course, as with any list of \"best practices\", these are really just opinions. Feel free to\nignore us.\n\n\"namespace::autoclean\" and immutabilize\nWe recommend that you remove the Moose sugar and end your Moose class definitions by making your\nclass immutable.\n\npackage Person;\n\nuse Moose;\nuse namespace::autoclean;\n\n# extends, roles, attributes, etc.\n\n# methods\n\nPACKAGE->meta->makeimmutable;\n\n1;\n\nThe \"use namespace::autoclean\" bit is simply good code hygiene, as it removes imported symbols\nfrom your class's namespace at the end of your package's compile cycle, including Moose\nkeywords. Once the class has been built, these keywords are not needed. (This is preferred to\nplacing \"no Moose\" at the end of your package).\n\nThe \"makeimmutable\" call allows Moose to speed up a lot of things, most notably object\nconstruction. The trade-off is that you can no longer change the class definition.\n\nNever override \"new\"\nOverriding \"new\" is a very bad practice. Instead, you should use a \"BUILD\" or \"BUILDARGS\"\nmethods to do the same thing. When you override \"new\", Moose can no longer inline a constructor\nwhen your class is immutabilized.\n\nThere are two good reasons to override \"new\". One, you are writing a MooseX extension that\nprovides its own Moose::Object subclass *and* a subclass of Moose::Meta::Method::Constructor to\ninline the constructor. Two, you are subclassing a non-Moose parent.\n\nIf you know how to do that, you know when to ignore this best practice ;)\n\nAlways call the original/parent \"BUILDARGS\"\nIf you \"override\" the \"BUILDARGS\" method in your class, make sure to play nice and call\n\"super()\" to handle cases you're not checking for explicitly.\n\nThe default \"BUILDARGS\" method in Moose::Object handles both a list and hashref of named\nparameters correctly, and also checks for a *non-hashref* single argument.\n\nProvide defaults whenever possible, otherwise use \"required\"\nWhen your class provides defaults, this makes constructing new objects simpler. If you cannot\nprovide a default, consider making the attribute \"required\".\n\nIf you don't do either, an attribute can simply be left unset, increasing the complexity of your\nobject, because it has more possible states that you or the user of your class must account for.\n\nUse \"builder\" instead of \"default\" most of the time\nBuilders can be inherited, they have explicit names, and they're just plain cleaner.\n\nHowever, *do* use a default when the default is a non-reference, *or* when the default is simply\nan empty reference of some sort.\n\nAlso, keep your builder methods private.\n\nBe \"lazy\"\nLazy is good, and often solves initialization ordering problems. It's also good for deferring\nwork that may never have to be done. Make your attributes \"lazy\" unless they're \"required\" or\nhave trivial defaults.\n",
            "subsections": [
                {
                    "name": "Consider keeping clearers and predicates private",
                    "content": "Does everyone *really* need to be able to clear an attribute? Probably not. Don't expose this\nfunctionality outside your class by default.\n\nPredicates are less problematic, but there's no reason to make your public API bigger than it\nhas to be.\n\nAvoid \"lazybuild\"\nAs described above, you rarely actually need a clearer or a predicate. \"lazybuild\" adds both to\nyour public API, which exposes you to use cases that you must now test for. It's much better to\navoid adding them until you really need them - use explicit \"lazy\" and \"builder\" options\ninstead.\n"
                },
                {
                    "name": "Default to read-only, and consider keeping writers private",
                    "content": "Making attributes mutable just means more complexity to account for in your program. The\nalternative to mutable state is to encourage users of your class to simply make new objects as\nneeded.\n\nIf you *must* make an attribute read-write, consider making the writer a separate private\nmethod. Narrower APIs are easy to maintain, and mutable state is trouble.\n\nIn order to declare such attributes, provide a private \"writer\" parameter:\n\nhas pizza => (\nis     => 'ro',\nisa    => 'Pizza',\nwriter => 'pizza',\n);\n"
                },
                {
                    "name": "Think twice before changing an attribute's type in a subclass",
                    "content": "Down this path lies great confusion. If the attribute is an object itself, at least make sure\nthat it has the same interface as the type of object in the parent class.\n\nDon't use the \"initializer\" feature\nDon't know what we're talking about? That's fine.\n\nUse Moose::Meta::Attribute::Native traits instead of \"autoderef\"\nThe \"autoderef\" feature is a bit troublesome. Directly exposing a complex attribute is ugly.\nInstead, consider using Moose::Meta::Attribute::Native traits to define an API that only exposes\nthe necessary pieces of functionality.\n\nAlways call \"inner\" in the most specific subclass\nWhen using \"augment\" and \"inner\", we recommend that you call \"inner\" in the most specific\nsubclass of your hierarchy. This makes it possible to subclass further and extend the hierarchy\nwithout changing the parents.\n"
                },
                {
                    "name": "Namespace your types",
                    "content": "Use some sort of namespacing convention for type names. We recommend something like\n\"MyApp::Type::Foo\". We also recommend considering MooseX::Types.\n"
                },
                {
                    "name": "Do not coerce Moose built-ins directly",
                    "content": "If you define a coercion for a Moose built-in like \"ArrayRef\", this will affect every\napplication in the Perl interpreter that uses this type.\n\n# very naughty!\ncoerce 'ArrayRef'\n=> from Str\n=> via { [ split /,/ ] };\n\nInstead, create a subtype and coerce that:\n\nsubtype 'My::ArrayRef' => as 'ArrayRef';\n\ncoerce 'My::ArrayRef'\n=> from 'Str'\n=> via { [ split /,/ ] };\n"
                },
                {
                    "name": "Do not coerce class names directly",
                    "content": "Just as with Moose built-in types, a class type is global for the entire interpreter. If you add\na coercion for that class name, it can have magical side effects elsewhere:\n\n# also very naughty!\ncoerce 'HTTP::Headers'\n=> from 'HashRef'\n=> via { HTTP::Headers->new( %{$} ) };\n\nInstead, we can create an \"empty\" subtype for the coercion:\n\nsubtype 'My::HTTP::Headers' => as classtype('HTTP::Headers');\n\ncoerce 'My::HTTP::Headers'\n=> from 'HashRef'\n=> via { HTTP::Headers->new( %{$} ) };\n"
                },
                {
                    "name": "Use coercion instead of unions",
                    "content": "Consider using a type coercion instead of a type union. This was covered in\nMoose::Manual::Types.\n"
                },
                {
                    "name": "Define all your types in one module",
                    "content": "Define all your types and coercions in one module. This was also covered in\nMoose::Manual::Types.\n"
                }
            ]
        },
        "BENEFITS OF BEST PRACTICES": {
            "content": "Following these practices has a number of benefits.\n\nIt helps ensure that your code will play nice with others, making it more reusable and easier to\nextend.\n\nFollowing an accepted set of idioms will make maintenance easier, especially when someone else\nhas to maintain your code. It will also make it easier to get support from other Moose users,\nsince your code will be easier to digest quickly.\n\nSome of these practices are designed to help Moose do the right thing, especially when it comes\nto immutabilization. This means your code will be faster when immutabilized.\n\nMany of these practices also help get the most out of meta programming. If you used an\noverridden \"new\" to do type coercion by hand, rather than defining a real coercion, there is no\nintrospectable metadata. This sort of thing is particularly problematic for MooseX extensions\nwhich rely on introspection to do the right thing.\n",
            "subsections": []
        },
        "AUTHORS": {
            "content": "*   Stevan Little <stevan@cpan.org>\n\n*   Dave Rolsky <autarch@urth.org>\n\n*   Jesse Luehrs <doy@cpan.org>\n\n*   Shawn M Moore <sartak@cpan.org>\n\n*   יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>\n\n*   Karen Etheridge <ether@cpan.org>\n\n*   Florian Ragwitz <rafl@debian.org>\n\n*   Hans Dieter Pearcey <hdp@cpan.org>\n\n*   Chris Prather <chris@prather.org>\n\n*   Matt S Trout <mstrout@cpan.org>\n",
            "subsections": []
        },
        "COPYRIGHT AND LICENSE": {
            "content": "This software is copyright (c) 2006 by Infinity Interactive, Inc.\n\nThis is free software; you can redistribute it and/or modify it under the same terms as the Perl\n5 programming language system itself.\n",
            "subsections": []
        }
    },
    "summary": "Moose::Manual::BestPractices - Get the most out of Moose",
    "flags": [],
    "examples": [],
    "see_also": []
}