{
    "mode": "perldoc",
    "parameter": "Moose::Cookbook::Roles::Comparable_CodeReuse",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/Moose%3A%3ACookbook%3A%3ARoles%3A%3AComparable_CodeReuse/json",
    "generated": "2026-10-22T12:13:16Z",
    "synopsis": "package Eq;\nuse Moose::Role;\nrequires 'equalto';\nsub notequalto {\nmy ( $self, $other ) = @;\nnot $self->equalto($other);\n}\npackage Comparable;\nuse Moose::Role;\nwith 'Eq';\nrequires 'compare';\nsub equalto {\nmy ( $self, $other ) = @;\n$self->compare($other) == 0;\n}\nsub greaterthan {\nmy ( $self, $other ) = @;\n$self->compare($other) == 1;\n}\nsub lessthan {\nmy ( $self, $other ) = @;\n$self->compare($other) == -1;\n}\nsub greaterthanorequalto {\nmy ( $self, $other ) = @;\n$self->greaterthan($other) || $self->equalto($other);\n}\nsub lessthanorequalto {\nmy ( $self, $other ) = @;\n$self->lessthan($other) || $self->equalto($other);\n}\npackage Printable;\nuse Moose::Role;\nrequires 'tostring';\npackage US::Currency;\nuse Moose;\nwith 'Comparable', 'Printable';\nhas 'amount' => ( is => 'rw', isa => 'Num', default => 0 );\nsub compare {\nmy ( $self, $other ) = @;\n$self->amount <=> $other->amount;\n}\nsub tostring {\nmy $self = shift;\nsprintf '$%0.2f USD' => $self->amount;\n}",
    "sections": {
        "NAME": {
            "content": "Moose::Cookbook::Roles::ComparableCodeReuse - Using roles for code reuse\n",
            "subsections": []
        },
        "VERSION": {
            "content": "version 2.2207\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "package Eq;\nuse Moose::Role;\n\nrequires 'equalto';\n\nsub notequalto {\nmy ( $self, $other ) = @;\nnot $self->equalto($other);\n}\n\npackage Comparable;\nuse Moose::Role;\n\nwith 'Eq';\n\nrequires 'compare';\n\nsub equalto {\nmy ( $self, $other ) = @;\n$self->compare($other) == 0;\n}\n\nsub greaterthan {\nmy ( $self, $other ) = @;\n$self->compare($other) == 1;\n}\n\nsub lessthan {\nmy ( $self, $other ) = @;\n$self->compare($other) == -1;\n}\n\nsub greaterthanorequalto {\nmy ( $self, $other ) = @;\n$self->greaterthan($other) || $self->equalto($other);\n}\n\nsub lessthanorequalto {\nmy ( $self, $other ) = @;\n$self->lessthan($other) || $self->equalto($other);\n}\n\npackage Printable;\nuse Moose::Role;\n\nrequires 'tostring';\n\npackage US::Currency;\nuse Moose;\n\nwith 'Comparable', 'Printable';\n\nhas 'amount' => ( is => 'rw', isa => 'Num', default => 0 );\n\nsub compare {\nmy ( $self, $other ) = @;\n$self->amount <=> $other->amount;\n}\n\nsub tostring {\nmy $self = shift;\nsprintf '$%0.2f USD' => $self->amount;\n}\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "Roles have two primary purposes: as interfaces, and as a means of code reuse. This recipe\ndemonstrates the latter, with roles that define comparison and display code for objects.\n\nLet's start with \"Eq\". First, note that we've replaced \"use Moose\" with \"use Moose::Role\". We\nalso have a new sugar function, \"requires\":\n\nrequires 'equalto';\n\nThis says that any class which consumes this role must provide an \"equalto\" method. It can\nprovide this method directly, or by consuming some other role.\n\nThe \"Eq\" role defines its \"notequalto\" method in terms of the required \"equalto\" method. This\nlets us minimize the methods that consuming classes must provide.\n\nThe next role, \"Comparable\", builds on the \"Eq\" role. We include \"Eq\" in \"Comparable\" using\n\"with\", another new sugar function:\n\nwith 'Eq';\n\nThe \"with\" function takes a list of roles to consume. In our example, the \"Comparable\" role\nprovides the \"equalto\" method required by \"Eq\". However, it could opt not to, in which case a\nclass that consumed \"Comparable\" would have to provide its own \"equalto\". In other words, a\nrole can consume another role *without* providing any required methods.\n\nThe \"Comparable\" role requires a method, \"compare\":\n\nrequires 'compare';\n\nThe \"Comparable\" role also provides a number of other methods, all of which ultimately rely on\n\"compare\".\n\nsub equalto {\nmy ( $self, $other ) = @;\n$self->compare($other) == 0;\n}\n\nsub greaterthan {\nmy ( $self, $other ) = @;\n$self->compare($other) == 1;\n}\n\nsub lessthan {\nmy ( $self, $other ) = @;\n$self->compare($other) == -1;\n}\n\nsub greaterthanorequalto {\nmy ( $self, $other ) = @;\n$self->greaterthan($other) || $self->equalto($other);\n}\n\nsub lessthanorequalto {\nmy ( $self, $other ) = @;\n$self->lessthan($other) || $self->equalto($other);\n}\n\nFinally, we define the \"Printable\" role. This role exists solely to provide an interface. It has\nno methods, just a list of required methods. In this case, it just requires a \"tostring\"\nmethod.\n\nAn interface role is useful because it defines both a method and a *name*. We know that any\nclass which does this role has a \"tostring\" method, but we can also assume that this method has\nthe semantics we want. Presumably, in real code we would define those semantics in the\ndocumentation for the \"Printable\" role. (1)\n\nFinally, we have the \"US::Currency\" class which consumes both the \"Comparable\" and \"Printable\"\nroles.\n\nwith 'Comparable', 'Printable';\n\nIt also defines a regular Moose attribute, \"amount\":\n\nhas 'amount' => ( is => 'rw', isa => 'Num', default => 0 );\n\nFinally we see the implementation of the methods required by our roles. We have a \"compare\"\nmethod:\n\nsub compare {\nmy ( $self, $other ) = @;\n$self->amount <=> $other->amount;\n}\n\nBy consuming the \"Comparable\" role and defining this method, we gain the following methods for\nfree: \"equalto\", \"greaterthan\", \"lessthan\", \"greaterthanorequalto\" and\n\"lessthanorequalto\".\n\nThen we have our \"tostring\" method:\n\nsub tostring {\nmy $self = shift;\nsprintf '$%0.2f USD' => $self->amount;\n}\n",
            "subsections": []
        },
        "CONCLUSION": {
            "content": "Roles can be very powerful. They are a great way of encapsulating reusable behavior, as well as\ncommunicating (semantic and interface) information about the methods our classes provide.\n",
            "subsections": []
        },
        "FOOTNOTES": {
            "content": "(1) Consider two classes, \"Runner\" and \"Process\", both of which define a \"run\" method. If we\njust require that an object implements a \"run\" method, we still aren't saying anything about\nwhat that method *actually does*. If we require an object that implements the \"Executable\"\nrole, we're saying something about semantics.\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::Cookbook::Roles::ComparableCodeReuse - Using roles for code reuse",
    "flags": [],
    "examples": [],
    "see_also": []
}