{
    "content": [
        {
            "type": "text",
            "text": "# Safe::Isa (perldoc)\n\n## NAME\n\nSafe::Isa - Call isa, can, does and DOES safely on things that may not be objects\n\n## SYNOPSIS\n\nuse strict;\nuse warnings;\n{ package Foo; sub new { bless({}, $[0]) } }\n{ package Bar; our @ISA = qw(Foo); sub bar { 1 } }\nmy $foo = Foo->new;\nmy $bar = Bar->new;\nmy $blam = [ 42 ];\n# basic isa usage -\n$foo->isa('Foo');  # true\n$bar->isa('Foo');  # true\n$blam->isa('Foo'); # BOOM\n$foo->can('bar');  # false\n$bar->can('bar');  # true\n$blam->can('bar'); # BOOM\n# Safe::Isa usage -\nuse Safe::Isa;\n$foo->$isa('Foo');  # true\n$bar->$isa('Foo');  # true\n$blam->$isa('Foo'); # false, no boom today\n$foo->$can('bar');  # false\n$bar->$can('bar');  # true\n$blam->$can('bar'); # false, no boom today\nSimilarly:\n$maybeanobject->$does('RoleName'); # true or false, no boom today\n$maybeanobject->$DOES('RoleName'); # true or false, no boom today\nAnd just in case we missed a method or two:\n$maybeanobject->$callifobject(name => @args);\n$maybeanobject->$callifcan(name => @args);\nOr to re-use a previous example for purposes of explication:\n$foo->$callifobject(isa => 'Foo');  # true\n$bar->$callifobject(isa => 'Foo');  # true\n$blam->$callifobject(isa => 'Foo'); # false, no boom today\n\n## DESCRIPTION\n\nHow many times have you found yourself writing:\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION**\n- **EXPORTS**\n- **SEE ALSO**\n- **AUTHOR**\n- **CONTRIBUTORS**\n- **COPYRIGHT**\n- **LICENSE**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "Safe::Isa",
        "section": "",
        "mode": "perldoc",
        "summary": "Safe::Isa - Call isa, can, does and DOES safely on things that may not be objects",
        "synopsis": "use strict;\nuse warnings;\n{ package Foo; sub new { bless({}, $[0]) } }\n{ package Bar; our @ISA = qw(Foo); sub bar { 1 } }\nmy $foo = Foo->new;\nmy $bar = Bar->new;\nmy $blam = [ 42 ];\n# basic isa usage -\n$foo->isa('Foo');  # true\n$bar->isa('Foo');  # true\n$blam->isa('Foo'); # BOOM\n$foo->can('bar');  # false\n$bar->can('bar');  # true\n$blam->can('bar'); # BOOM\n# Safe::Isa usage -\nuse Safe::Isa;\n$foo->$isa('Foo');  # true\n$bar->$isa('Foo');  # true\n$blam->$isa('Foo'); # false, no boom today\n$foo->$can('bar');  # false\n$bar->$can('bar');  # true\n$blam->$can('bar'); # false, no boom today\nSimilarly:\n$maybeanobject->$does('RoleName'); # true or false, no boom today\n$maybeanobject->$DOES('RoleName'); # true or false, no boom today\nAnd just in case we missed a method or two:\n$maybeanobject->$callifobject(name => @args);\n$maybeanobject->$callifcan(name => @args);\nOr to re-use a previous example for purposes of explication:\n$foo->$callifobject(isa => 'Foo');  # true\n$bar->$callifobject(isa => 'Foo');  # true\n$blam->$callifobject(isa => 'Foo'); # false, no boom today",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 48,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 35,
                "subsections": []
            },
            {
                "name": "EXPORTS",
                "lines": 35,
                "subsections": []
            },
            {
                "name": "SEE ALSO",
                "lines": 3,
                "subsections": []
            },
            {
                "name": "AUTHOR",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "CONTRIBUTORS",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "COPYRIGHT",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "LICENSE",
                "lines": 2,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "Safe::Isa - Call isa, can, does and DOES safely on things that may not be objects\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "use strict;\nuse warnings;\n\n{ package Foo; sub new { bless({}, $[0]) } }\n{ package Bar; our @ISA = qw(Foo); sub bar { 1 } }\n\nmy $foo = Foo->new;\nmy $bar = Bar->new;\nmy $blam = [ 42 ];\n\n# basic isa usage -\n\n$foo->isa('Foo');  # true\n$bar->isa('Foo');  # true\n$blam->isa('Foo'); # BOOM\n\n$foo->can('bar');  # false\n$bar->can('bar');  # true\n$blam->can('bar'); # BOOM\n\n# Safe::Isa usage -\n\nuse Safe::Isa;\n\n$foo->$isa('Foo');  # true\n$bar->$isa('Foo');  # true\n$blam->$isa('Foo'); # false, no boom today\n\n$foo->$can('bar');  # false\n$bar->$can('bar');  # true\n$blam->$can('bar'); # false, no boom today\n\nSimilarly:\n\n$maybeanobject->$does('RoleName'); # true or false, no boom today\n$maybeanobject->$DOES('RoleName'); # true or false, no boom today\n\nAnd just in case we missed a method or two:\n\n$maybeanobject->$callifobject(name => @args);\n$maybeanobject->$callifcan(name => @args);\n\nOr to re-use a previous example for purposes of explication:\n\n$foo->$callifobject(isa => 'Foo');  # true\n$bar->$callifobject(isa => 'Foo');  # true\n$blam->$callifobject(isa => 'Foo'); # false, no boom today\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "How many times have you found yourself writing:\n\nif ($obj->isa('Something')) {\n\nand then shortly afterwards cursing and changing it to:\n\nif (Scalar::Util::blessed($obj) and $obj->isa('Something')) {\n\nRight. That's why this module exists.\n\nSince perl allows us to provide a subroutine reference or a method name to the -> operator when\nused as a method call, and a subroutine doesn't require the invocant to actually be an object,\nwe can create safe versions of isa, can and friends by using a subroutine reference that only\ntries to call the method if it's used on an object. So:\n\nmy $isaFoo = $maybeanobject->$callifobject(isa => 'Foo');\n\nis equivalent to\n\nmy $isaFoo = do {\nif (Scalar::Util::blessed($maybeanobject)) {\n$maybeanobject->isa('Foo');\n} else {\nundef;\n}\n};\n\nNote that we don't handle trying class names, because many things are valid class names that you\nmight not want to treat as one (like say \"Matt\") - the \"ismodulename\" function from\nModule::Runtime is a good way to check for something you might be able to call methods on if you\nwant to do that.\n\nWe are careful to make sure that scalar/list context is preserved for the method that is\neventually called.\n",
                "subsections": []
            },
            "EXPORTS": {
                "content": "$isa\n$maybeanobject->$isa('Foo');\n\nIf called on an object, calls \"isa\" on it and returns the result, otherwise returns nothing.\n\n$can\n$maybeanobject->$can('Foo');\n\nIf called on an object, calls \"can\" on it and returns the result, otherwise returns nothing.\n\n$does\n$maybeanobject->$does('Foo');\n\nIf called on an object, calls \"does\" on it and returns the result, otherwise returns nothing. If\nthe \"does\" method does not exist, returns nothing rather than failing.\n\n$DOES\n$maybeanobject->$DOES('Foo');\n\nIf called on an object, calls \"DOES\" on it and returns the result, otherwise returns nothing. On\nperl versions prior to 5.10.0, the built in core \"DOES\" method doesn't exist. If the method\ndoesn't exist, this will fall back to calling \"isa\" just like the core \"DOES\" method.\n\n$callifobject\n$maybeanobject->$callifobject(methodname => @args);\n\nIf called on an object, calls \"methodname\" on it and returns the result, otherwise returns\nnothing.\n\n$callifcan\n$maybeanobject->$callifcan(name => @args);\n\nIf called on an object, calls \"can\" on it; if that returns true, then calls \"methodname\" on it\nand returns the result; if any condition is false returns nothing.\n",
                "subsections": []
            },
            "SEE ALSO": {
                "content": "I gave a lightning talk on this module (and curry and Import::Into) at YAPC::NA 2013\n<https://www.youtube.com/watch?v=wFXWV2yY7gE&t=46m05s>.\n",
                "subsections": []
            },
            "AUTHOR": {
                "content": "mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>\n",
                "subsections": []
            },
            "CONTRIBUTORS": {
                "content": "None yet. Well volunteered? :)\n",
                "subsections": []
            },
            "COPYRIGHT": {
                "content": "Copyright (c) 2012 the Safe::Isa \"AUTHOR\" and \"CONTRIBUTORS\" as listed above.\n",
                "subsections": []
            },
            "LICENSE": {
                "content": "This library is free software and may be distributed under the same terms as perl itself.\n",
                "subsections": []
            }
        }
    }
}