{
    "mode": "perldoc",
    "parameter": "Moose::Cookbook::Legacy::Labeled_AttributeMetaclass",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/Moose%3A%3ACookbook%3A%3ALegacy%3A%3ALabeled_AttributeMetaclass/json",
    "generated": "2026-06-16T10:16:41Z",
    "synopsis": "package MyApp::Meta::Attribute::Labeled;\nuse Moose;\nextends 'Moose::Meta::Attribute';\nhas label => (\nis        => 'rw',\nisa       => 'Str',\npredicate => 'haslabel',\n);\npackage Moose::Meta::Attribute::Custom::Labeled;\nsub registerimplementation {'MyApp::Meta::Attribute::Labeled'}\npackage MyApp::Website;\nuse Moose;\nhas url => (\nmetaclass => 'Labeled',\nis        => 'rw',\nisa       => 'Str',\nlabel     => \"The site's URL\",\n);\nhas name => (\nis  => 'rw',\nisa => 'Str',\n);\nsub dump {\nmy $self = shift;\nmy $meta = $self->meta;\nmy $dump = '';\nfor my $attribute ( map { $meta->getattribute($) }\nsort $meta->getattributelist ) {\nif (   $attribute->isa('MyApp::Meta::Attribute::Labeled')\n&& $attribute->haslabel ) {\n$dump .= $attribute->label;\n}\nelse {\n$dump .= $attribute->name;\n}\nmy $reader = $attribute->getreadmethod;\n$dump .= \": \" . $self->$reader . \"\\n\";\n}\nreturn $dump;\n}\npackage main;\nmy $app = MyApp::Website->new( url => \"http://google.com\", name => \"Google\" );",
    "sections": {
        "NAME": {
            "content": "Moose::Cookbook::Legacy::LabeledAttributeMetaclass - A meta-attribute,\nattributes with labels\n",
            "subsections": []
        },
        "VERSION": {
            "content": "version 2.2200\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "package MyApp::Meta::Attribute::Labeled;\nuse Moose;\nextends 'Moose::Meta::Attribute';\n\nhas label => (\nis        => 'rw',\nisa       => 'Str',\npredicate => 'haslabel',\n);\n\npackage Moose::Meta::Attribute::Custom::Labeled;\nsub registerimplementation {'MyApp::Meta::Attribute::Labeled'}\n\npackage MyApp::Website;\nuse Moose;\n\nhas url => (\nmetaclass => 'Labeled',\nis        => 'rw',\nisa       => 'Str',\nlabel     => \"The site's URL\",\n);\n\nhas name => (\nis  => 'rw',\nisa => 'Str',\n);\n\nsub dump {\nmy $self = shift;\n\nmy $meta = $self->meta;\n\nmy $dump = '';\n\nfor my $attribute ( map { $meta->getattribute($) }\nsort $meta->getattributelist ) {\n\nif (   $attribute->isa('MyApp::Meta::Attribute::Labeled')\n&& $attribute->haslabel ) {\n$dump .= $attribute->label;\n}\nelse {\n$dump .= $attribute->name;\n}\n\nmy $reader = $attribute->getreadmethod;\n$dump .= \": \" . $self->$reader . \"\\n\";\n}\n\nreturn $dump;\n}\n\npackage main;\n\nmy $app = MyApp::Website->new( url => \"http://google.com\", name => \"Google\" );\n",
            "subsections": []
        },
        "SUMMARY": {
            "content": "WARNING: Subclassing metaclasses (as opposed to providing metaclass\ntraits) is strongly discouraged. This recipe is provided solely for\nreference when encountering older code that does this.\n\nIn this recipe, we begin to delve into the wonder of meta-programming.\nSome readers may scoff and claim that this is the arena of only the most\ntwisted Moose developers. Absolutely not! Any sufficiently twisted\ndeveloper can benefit greatly from going more meta.\n\nOur goal is to allow each attribute to have a human-readable \"label\"\nattached to it. Such labels would be used when showing data to an end\nuser. In this recipe we label the \"url\" attribute with \"The site's URL\"\nand create a simple method showing how to use that label.\n\nThe proper, modern way to extend attributes (using a role instead of a\nsubclass) is described in Moose::Cookbook::Meta::Recipe3, but that\nrecipe assumes you've read and at least tried to understand this one.\n",
            "subsections": []
        },
        "META-ATTRIBUTE OBJECTS": {
            "content": "All the attributes of a Moose-based object are actually objects\nthemselves. These objects have methods and attributes. Let's look at a\nconcrete example.\n\nhas 'x' => ( isa => 'Int', is => 'ro' );\nhas 'y' => ( isa => 'Int', is => 'rw' );\n\nInternally, the metaclass for \"Point\" has two Moose::Meta::Attribute.\nThere are several methods for getting meta-attributes out of a\nmetaclass, one of which is \"getattributelist\". This method is called\non the metaclass object.\n\nThe \"getattributelist\" method returns a list of attribute names. You\ncan then use \"getattribute\" to get the Moose::Meta::Attribute object\nitself.\n\nOnce you have this meta-attribute object, you can call methods on it\nlike this:\n\nprint $point->meta->getattribute('x')->typeconstraint;\n=> Int\n\nTo add a label to our attributes there are two steps. First, we need a\nnew attribute metaclass that can store a label for an attribute. Second,\nwe need to create attributes that use that attribute metaclass.\n",
            "subsections": []
        },
        "RECIPE REVIEW": {
            "content": "We start by creating a new attribute metaclass.\n\npackage MyApp::Meta::Attribute::Labeled;\nuse Moose;\nextends 'Moose::Meta::Attribute';\n\nWe can subclass a Moose metaclass in the same way that we subclass\nanything else.\n\nhas label => (\nis        => 'rw',\nisa       => 'Str',\npredicate => 'haslabel',\n);\n\nAgain, this is standard Moose code.\n\nThen we need to register our metaclass with Moose:\n\npackage Moose::Meta::Attribute::Custom::Labeled;\nsub registerimplementation { 'MyApp::Meta::Attribute::Labeled' }\n\nThis is a bit of magic that lets us use a short name, \"Labeled\", when\nreferring to our new metaclass.\n\nThat was the whole attribute metaclass.\n\nNow we start using it.\n\npackage MyApp::Website;\nuse Moose;\nuse MyApp::Meta::Attribute::Labeled;\n\nWe have to load the metaclass to use it, just like any Perl class.\n\nFinally, we use it for an attribute:\n\nhas url => (\nmetaclass => 'Labeled',\nis        => 'rw',\nisa       => 'Str',\nlabel     => \"The site's URL\",\n);\n\nThis looks like a normal attribute declaration, except for two things,\nthe \"metaclass\" and \"label\" parameters. The \"metaclass\" parameter tells\nMoose we want to use a custom metaclass for this (one) attribute. The\n\"label\" parameter will be stored in the meta-attribute object.\n\nThe reason that we can pass the name \"Labeled\", instead of\n\"MyApp::Meta::Attribute::Labeled\", is because of the\n\"registerimplementation\" code we touched on previously.\n\nWhen you pass a metaclass to \"has\", it will take the name you provide\nand prefix it with \"Moose::Meta::Attribute::Custom::\". Then it calls\n\"registerimplementation\" in the package. In this case, that means Moose\nends up calling\n\"Moose::Meta::Attribute::Custom::Labeled::registerimplementation\".\n\nIf this function exists, it should return the *real* metaclass package\nname. This is exactly what our code does, returning\n\"MyApp::Meta::Attribute::Labeled\". This is a little convoluted, and if\nyou don't like it, you can always use the fully-qualified name.\n\nWe can access this meta-attribute and its label like this:\n\n$website->meta->getattribute('url')->label()\n\nMyApp::Website->meta->getattribute('url')->label()\n\nWe also have a regular attribute, \"name\":\n\nhas name => (\nis  => 'rw',\nisa => 'Str',\n);\n\nThis is a regular Moose attribute, because we have not specified a new\nmetaclass.\n\nFinally, we have a \"dump\" method, which creates a human-readable\nrepresentation of a \"MyApp::Website\" object. It will use an attribute's\nlabel if it has one.\n\nsub dump {\nmy $self = shift;\n\nmy $meta = $self->meta;\n\nmy $dump = '';\n\nfor my $attribute ( map { $meta->getattribute($) }\nsort $meta->getattributelist ) {\n\nif (   $attribute->isa('MyApp::Meta::Attribute::Labeled')\n&& $attribute->haslabel ) {\n$dump .= $attribute->label;\n}\n\nThis is a bit of defensive code. We cannot depend on every\nmeta-attribute having a label. Even if we define one for every attribute\nin our class, a subclass may neglect to do so. Or a superclass could add\nan attribute without a label.\n\nWe also check that the attribute has a label using the predicate we\ndefined. We could instead make the label \"required\". If we have a label,\nwe use it, otherwise we use the attribute name:\n\nelse {\n$dump .= $attribute->name;\n}\n\nmy $reader = $attribute->getreadmethod;\n$dump .= \": \" . $self->$reader . \"\\n\";\n}\n\nreturn $dump;\n}\n\nThe \"getreadmethod\" is part of the Moose::Meta::Attribute API. It\nreturns the name of a method that can read the attribute's value, *when\ncalled on the real object* (don't call this on the meta-attribute).\n",
            "subsections": []
        },
        "CONCLUSION": {
            "content": "You might wonder why you'd bother with all this. You could just hardcode\n\"The Site's URL\" in the \"dump\" method. But we want to avoid repetition.\nIf you need the label once, you may need it elsewhere, maybe in the\n\"asform\" method you write next.\n\nAssociating a label with an attribute just makes sense! The label is a\npiece of information *about* the attribute.\n\nIt's also important to realize that this was a trivial example. You can\nmake much more powerful metaclasses that *do* things, as opposed to just\nstoring some more information. For example, you could implement a\nmetaclass that expires attributes after a certain amount of time:\n\nhas sitecache => (\nmetaclass     => 'TimedExpiry',\nexpiresafter => { hours => 1 },\nrefreshwith  => sub { get( $[0]->url ) },\nisa           => 'Str',\nis            => 'ro',\n);\n\nThe sky's the limit!\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\nthe same terms as the Perl 5 programming language system itself.\n",
            "subsections": []
        }
    },
    "summary": "Moose::Cookbook::Legacy::LabeledAttributeMetaclass - A meta-attribute, attributes with labels",
    "flags": [],
    "examples": [],
    "see_also": []
}