{
    "content": [
        {
            "type": "text",
            "text": "# MooseX::Role::Parameterized::Tutorial (perldoc)\n\n## NAME\n\nMooseX::Role::Parameterized::Tutorial - why and how\n\n## Sections\n\n- **NAME**\n- **VERSION**\n- **MOTIVATION**\n- **USAGE**\n- **USES**\n- **SUPPORT**\n- **AUTHOR**\n- **COPYRIGHT AND LICENSE**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "MooseX::Role::Parameterized::Tutorial",
        "section": "",
        "mode": "perldoc",
        "summary": "MooseX::Role::Parameterized::Tutorial - why and how",
        "synopsis": null,
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "VERSION",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "MOTIVATION",
                "lines": 17,
                "subsections": []
            },
            {
                "name": "USAGE",
                "lines": 57,
                "subsections": []
            },
            {
                "name": "USES",
                "lines": 108,
                "subsections": []
            },
            {
                "name": "SUPPORT",
                "lines": 10,
                "subsections": []
            },
            {
                "name": "AUTHOR",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "COPYRIGHT AND LICENSE",
                "lines": 5,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "MooseX::Role::Parameterized::Tutorial - why and how\n",
                "subsections": []
            },
            "VERSION": {
                "content": "version 1.11\n",
                "subsections": []
            },
            "MOTIVATION": {
                "content": "Roles are composable units of behavior. They are useful for factoring out functionality common\nto many classes from any part of your class hierarchy. See\nMoose::Cookbook::Roles::ComparableCodeReuse for an introduction to Moose::Role.\n\nWhile combining roles affords you a great deal of flexibility, individual roles have very little\nin the way of configurability. Core Moose provides \"-alias\" for renaming methods and \"-excludes\"\nfor ignoring methods. These options are primarily for resolving role conflicts. Depending on how\nmuch of a purist you are, these options are *solely* for resolving role conflicts. See\nMoose::Cookbook::Roles::RestartableAdvancedComposition for more about \"-alias\" and \"-excludes\".\n\nBecause roles serve many different masters, they usually provide only the least common\ndenominator of functionality. To empower roles further, more configurability than \"-alias\" and\n\"-excludes\" is required. Perhaps your role needs to know which method to call when it is done\nprocessing. Or what default value to use for its \"url\" attribute.\n\nParameterized roles offer a solution to these (and other) kinds of problems.\n",
                "subsections": []
            },
            "USAGE": {
                "content": "\"with\"\nThe syntax of a class consuming a parameterized role has not changed from the standard \"with\".\nYou pass in parameters just like you pass in \"-alias\" and \"-excludes\" to ordinary roles (though\nyour custom parameters do not get hyphens, since these are not core Moose composition\nparameters):\n\nwith 'MyRole::InstrumentMethod' => {\nmethodname => 'dbhdo',\nlogto      => 'query.log',\n};\n\nYou can still combine parameterized roles. You just need to specify parameters immediately after\nthe role they belong to:\n\nwith (\n'My::Parameterized::Role' => {\nneedsbetterexample => 1,\n},\n'My::Other::Role',\n);\n\nWe, like Moose itself, use Data::OptList to make sure that a list of role names and associated\nparameters is handled correctly.\n\n\"parameter\"\nInside your parameterized role, you specify a set of parameters. This is exactly like specifying\nthe attributes of a class. Instead of \"has\" in Moose you use the keyword \"parameter\", but your\nparameters can use any options to \"has\".\n\nparameter 'delegation' => (\nisa       => 'HashRef|ArrayRef|RegexpRef',\npredicate => 'hasdelegation',\n);\n\nYou do have to declare what parameters you accept, just like you have to declare what attributes\nyou accept for regular Moose objects.\n\nOne departure from \"has\" is that we create a reader accessor for you by default. In other words,\nwe assume \"is => 'ro'\". We create this reader for convenience because generally the\nparameterized role is the only consumer of the parameters object, so data hiding is not as\nimportant than in the general case of \"has\" in Moose. If you do not want an accessor, you can\nuse \"is => 'bare'\".\n\n\"role\"\n\"role\" takes a block of code that will be used to generate your role with its parameters bound.\nHere is where you declare components that depend on parameters. You can declare attributes,\nmethods, modifiers, etc. The first argument to the \"role\" is an object containing the parameters\nspecified by \"with\". You can access the parameters just like regular attributes on that object.\n\nEach time you compose this parameterized role, the \"role {}\" block will be executed. It will\nreceive a new parameter object and produce an entirely new role. That's the whole point, after\nall.\n\nDue to limitations inherent in Perl, you must declare methods with \"method name => sub { ... }\"\ninstead of the usual \"sub name { ... }\". Your methods may, of course, close over the parameter\nobject. This means that your methods may use parameters however they wish!\n",
                "subsections": []
            },
            "USES": {
                "content": "Ideally these will become fully-explained examples in something resembling Moose::Cookbook. But\nfor now, only a brain dump.\n\nConfigure a role's attributes\nYou can rename methods with core Moose, but now you can rename attributes. You can now also\nchoose type, default value, whether it's required, traits, etc.\n\nparameter traits => (\nisa     => 'ArrayRef',\ndefault => sub { [] },\n);\n\nparameter type => (\nisa     => 'Str',\ndefault => 'Any',\n);\n\nrole {\nmy $p = shift;\n\nhas action => (\ntraits => $p->traits,\nisa    => $p->type,\n...\n);\n};\n\nInform a role of your class' attributes and methods\nCore roles can only require methods with specific names chosen by the role. Now your roles\ncan demand that the class specifies a method name you wish the role to instrument, or which\nattributes to dump to a file.\n\nparameter instrumentmethod => (\nisa      => 'Str',\nrequired => 1,\n);\n\nrole {\nmy $p = shift;\naround $p->instrumentmethod => sub { ... };\n};\n\nArbitrary execution choices\nYour role may be able to provide configuration in how the role's methods operate. For\nexample, you can tell the role whether to save intermediate states.\n\nparameter saveintermediate => (\nisa     => 'Bool',\ndefault => 0,\n);\n\nrole {\nmy $p = shift;\nmethod process => sub {\n...\nif ($p->saveintermediate) { ... }\n...\n};\n};\n\nDeciding a backend\nYour role may be able to freeze and thaw your instances using YAML, JSON, Storable. Which\nbackend to use can be a parameter.\n\nparameter format => (\nisa     => (enum ['Storable', 'YAML', 'JSON']),\ndefault => 'Storable',\n);\n\nrole {\nmy $p = shift;\nif ($p->format eq 'Storable') {\nmethod freeze => \\&Storable::freeze;\nmethod thaw   => \\&Storable::thaw;\n}\nelsif ($p->format eq 'YAML') {\nmethod freeze => \\&YAML::Dump;\nmethod thaw   => \\&YAML::Load;\n}\n...\n};\n\nAdditional validation\nOrdinary roles can require that its consumers have a particular list of method names. Since\nparameterized roles have direct access to its consumer, you can inspect it and throw errors\nif the consumer does not meet your needs.\n\nrole {\nmy $p    = shift;\nmy %args = @;\nmy $consumer = $args{consumer};\n\n$consumer->findattributebyname('stack')\nor confess \"You must have a 'stack' attribute\";\n\nmy $push = $consumer->findmethodbyname('push')\nor confess \"You must have a 'push' method\";\n\nmy $params = $push->parsedsignature->positionalparams->params;\n@$params == 1\nor confess \"Your push method must take a single parameter\";\n\n$params->[0]->sigil eq '$'\nor confess \"Your push parameter must be a scalar\";\n\n...\n};\n",
                "subsections": []
            },
            "SUPPORT": {
                "content": "Bugs may be submitted through the RT bug tracker\n<https://rt.cpan.org/Public/Dist/Display.html?Name=MooseX-Role-Parameterized> (or\nbug-MooseX-Role-Parameterized@rt.cpan.org <mailto:bug-MooseX-Role-Parameterized@rt.cpan.org>).\n\nThere is also a mailing list available for users of this distribution, at\n<http://lists.perl.org/list/moose.html>.\n\nThere is also an irc channel available for users of this distribution, at \"#moose\" on\n\"irc.perl.org\" <irc://irc.perl.org/#moose>.\n",
                "subsections": []
            },
            "AUTHOR": {
                "content": "Shawn M Moore <code@sartak.org>\n",
                "subsections": []
            },
            "COPYRIGHT AND LICENSE": {
                "content": "This software is copyright (c) 2008 by Shawn M Moore.\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": []
            }
        }
    }
}