Safe-Isa-1.000004/000755 000767 000024 00000000000 12216477067 013616 5ustar00etherstaff000000 000000 Safe-Isa-1.000004/Changes000644 000767 000024 00000000622 12216476766 015116 0ustar00etherstaff000000 000000 Revision history for Safe-Isa 1.000004 2013-09-18 - fixed slightly mangled metadata from last release 1.000003 2013-03-25 - fix NAME in Makefile.PL (RT#84212) 1.000002 2012-07-19 - Document why we don't try and handle class namesZ - Missed another stupid doc typo (thanks MJD) 1.000001 2012-07-18 - Fix stupid doc typo (thanks miyagawa) 1.000000 2012-07-18 - Initial release Safe-Isa-1.000004/lib/000755 000767 000024 00000000000 12216477066 014363 5ustar00etherstaff000000 000000 Safe-Isa-1.000004/maint/000755 000767 000024 00000000000 12216477066 014725 5ustar00etherstaff000000 000000 Safe-Isa-1.000004/Makefile.PL000644 000767 000024 00000001572 12216476761 015575 0ustar00etherstaff000000 000000 use strict; use warnings FATAL => 'all'; use 5.008001; use ExtUtils::MakeMaker; (do 'maint/Makefile.PL.include' or die $@) unless -f 'META.yml'; WriteMakefile( NAME => 'Safe::Isa', VERSION_FROM => 'lib/Safe/Isa.pm', PREREQ_PM => { 'Exporter' => '5.57', 'Scalar::Util' => 0, }, -f 'META.yml' ? () : ( META_MERGE => { 'meta-spec' => { version => 2 }, dynamic_config => 0, resources => { # r/w: p5sagit@git.shadowcat.co.uk:Safe-Isa.git repository => { url => 'git://git.shadowcat.co.uk/p5sagit/Safe-Isa.git', web => 'http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/Safe-Isa.git', type => 'git', }, bugtracker => { mailto => 'bug-Safe-Isa@rt.cpan.org', web => 'https://rt.cpan.org/Public/Dist/Display.html?Name=Safe-Isa', }, }, }, ), ); Safe-Isa-1.000004/MANIFEST000644 000767 000024 00000000530 12216477067 014745 0ustar00etherstaff000000 000000 Changes lib/Safe/Isa.pm maint/Makefile.PL.include Makefile.PL MANIFEST This list of files t/safe_isa.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) README README file (added by Distar) Safe-Isa-1.000004/META.json000644 000767 000024 00000002357 12216477066 015245 0ustar00etherstaff000000 000000 { "abstract" : "Call isa, can, does and DOES safely on things that may not be objects", "author" : [ "mst - Matt S. Trout (cpan:MSTROUT) " ], "dynamic_config" : 0, "generated_by" : "ExtUtils::MakeMaker version 6.76, CPAN::Meta::Converter version 2.132510", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Safe-Isa", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Exporter" : "5.57", "Scalar::Util" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "mailto" : "bug-Safe-Isa@rt.cpan.org", "web" : "https://rt.cpan.org/Public/Dist/Display.html?Name=Safe-Isa" }, "repository" : { "type" : "git", "url" : "git://git.shadowcat.co.uk/p5sagit/Safe-Isa.git", "web" : "http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/Safe-Isa.git" } }, "version" : "1.000004" } Safe-Isa-1.000004/META.yml000644 000767 000024 00000001240 12216477066 015063 0ustar00etherstaff000000 000000 --- abstract: 'Call isa, can, does and DOES safely on things that may not be objects' author: - 'mst - Matt S. Trout (cpan:MSTROUT) ' build_requires: ExtUtils::MakeMaker: 0 dynamic_config: 0 generated_by: 'ExtUtils::MakeMaker version 6.76, CPAN::Meta::Converter version 2.132510' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Safe-Isa no_index: directory: - t - inc requires: Exporter: 5.57 Scalar::Util: 0 resources: bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=Safe-Isa repository: git://git.shadowcat.co.uk/p5sagit/Safe-Isa.git version: 1.000004 Safe-Isa-1.000004/README000644 000767 000024 00000007202 12216477067 014477 0ustar00etherstaff000000 000000 NAME Safe::Isa - Call isa, can, does and DOES safely on things that may not be objects SYNOPSIS use strict; use warnings; { package Foo; sub new { bless({}, $_[0]) } } { package Bar; our @ISA = qw(Foo); sub bar { 1 } } my $foo = Foo->new; my $bar = Bar->new; my $blam = [ 42 ]; # basic isa usage - $foo->isa('Foo'); # true $bar->isa('Foo'); # true $blam->isa('Foo'); # BOOM $foo->can('bar'); # false $bar->can('bar'); # true $blam->can('bar'); # BOOM # Safe::Isa usage - use Safe::Isa; $foo->$_isa('Foo'); # true $bar->$_isa('Foo'); # true $blam->$_isa('Foo'); # false, no boom today $foo->$_can('bar'); # false $bar->$_can('bar'); # true $blam->$_can('bar'); # false, no boom today Similarly: $maybe_an_object->$_does('RoleName'); # true or false, no boom today $maybe_an_object->$_DOES('RoleName'); # true or false, no boom today And just in case we missed a method: $maybe_an_object->$_call_if_object(name => @args); Or to re-use a previous example for purposes of explication: $foo->$_call_if_object(isa => 'Foo'); # true $bar->$_call_if_object(isa => 'Foo'); # true $blam->$_call_if_object(isa => 'Foo'); # false, no boom today DESCRIPTION How many times have you found yourself writing: if ($obj->isa('Something')) { and then shortly afterwards cursing and changing it to: if (Scalar::Util::blessed($obj) and $obj->isa('Something')) { Right. That's why this module exists. Since perl allows us to provide a subroutine reference or a method name to the -> operator when used as a method call, and a subroutine doesn't require the invocant to actually be an object, we can create safe versions of isa, can and friends by using a subroutine reference that only tries to call the method if it's used on an object. So: my $isa_Foo = $maybe_an_object->$_call_if_object(isa => 'Foo'); is equivalent to my $isa_Foo = do { if (Scalar::Util::blessed($maybe_an_object)) { $maybe_an_object->isa('Foo'); } else { undef; } }; Note that we don't handle trying class names, because many things are valid class names that you might not want to treat as one (like say "Matt") - the "is_module_name" function from Module::Runtime is a good way to check for something you might be able to call methods on if you want to do that. EXPORTS $_isa $maybe_an_object->$_isa('Foo'); If called on an object, calls "isa" on it and returns the result, otherwise returns nothing. $_can $maybe_an_object->$_can('Foo'); If called on an object, calls "can" on it and returns the result, otherwise returns nothing. $_does $maybe_an_object->$_does('Foo'); If called on an object, calls "does" on it and returns the result, otherwise returns nothing. $_DOES $maybe_an_object->$_DOES('Foo'); If called on an object, calls "DOES" on it and returns the result, otherwise returns nothing. $_call_if_object $maybe_an_object->$_call_if_object(method_name => @args); If called on an object, calls "method_name" on it and returns the result, otherwise returns nothing. AUTHOR mst - Matt S. Trout (cpan:MSTROUT) CONTRIBUTORS None yet. Well volunteered? :) COPYRIGHT Copyright (c) 2012 the Safe::Isa "AUTHOR" and "CONTRIBUTORS" as listed above. LICENSE This library is free software and may be distributed under the same terms as perl itself. Safe-Isa-1.000004/t/000755 000767 000024 00000000000 12216477066 014060 5ustar00etherstaff000000 000000 Safe-Isa-1.000004/t/safe_isa.t000644 000767 000024 00000002005 12216352371 016003 0ustar00etherstaff000000 000000 use strict; use warnings FATAL => 'all'; use Test::More tests => 15; { package Foo; sub new { bless({}, $_[0]) } } { package Bar; our @ISA = qw(Foo); sub bar { 1 } } my $foo = Foo->new; my $bar = Bar->new; my $blam = [ 42 ]; # basic isa usage - ok($foo->isa('Foo'), 'foo isa Foo'); ok($bar->isa('Foo'), 'bar isa Foo'); ok(!eval { $blam->isa('Foo'); 1 }, 'blam goes blam'); ok(!$foo->can('bar'), 'foo !can bar'); ok($bar->can('bar'), 'bar can bar'); ok(!eval { $blam->can('bar'); 1 }, 'blam goes blam'); use Safe::Isa; ok($foo->$_isa('Foo'), 'foo $_isa Foo'); ok($bar->$_isa('Foo'), 'bar $_isa Foo'); ok(eval { $blam->$_isa('Foo'); 1 }, 'no boom today'); ok(!$foo->$_can('bar'), 'foo !$_can bar'); ok($bar->$_can('bar'), 'bar $_can bar'); ok(eval { $blam->$_can('bar'); 1 }, 'no boom today'); ok($foo->$_call_if_object(isa => 'Foo'), 'foo $_call_if_object(isa => Foo)'); ok($bar->$_call_if_object(isa => 'Foo'), 'bar $_call_if_object(isa => Foo)'); ok(eval { $blam->$_call_if_object(isa => 'Foo'); 1 }, 'no boom today'); Safe-Isa-1.000004/maint/Makefile.PL.include000644 000767 000024 00000000406 12216476761 020322 0ustar00etherstaff000000 000000 BEGIN { -e 'Distar' or system("git clone git://git.shadowcat.co.uk/p5sagit/Distar.git") } use lib 'Distar/lib'; use Distar; use ExtUtils::MakeMaker 6.68; # ensure meta-spec v2 compatibility author 'mst - Matt S. Trout (cpan:MSTROUT) '; 1; Safe-Isa-1.000004/lib/Safe/000755 000767 000024 00000000000 12216477066 015241 5ustar00etherstaff000000 000000 Safe-Isa-1.000004/lib/Safe/Isa.pm000644 000767 000024 00000007653 12216476761 016327 0ustar00etherstaff000000 000000 package Safe::Isa; use strict; use warnings FATAL => 'all'; use Scalar::Util qw(blessed); use Exporter 5.57 qw(import); our $VERSION = '1.000004'; our @EXPORT = qw($_call_if_object $_isa $_can $_does $_DOES); our $_call_if_object = sub { my ($obj, $method) = (shift, shift); return unless blessed($obj); return $obj->$method(@_); }; our ($_isa, $_can, $_does, $_DOES) = map { my $method = $_; sub { my $obj = shift; $obj->$_call_if_object($method => @_) } } qw(isa can does DOES); =head1 NAME Safe::Isa - Call isa, can, does and DOES safely on things that may not be objects =head1 SYNOPSIS use strict; use warnings; { package Foo; sub new { bless({}, $_[0]) } } { package Bar; our @ISA = qw(Foo); sub bar { 1 } } my $foo = Foo->new; my $bar = Bar->new; my $blam = [ 42 ]; # basic isa usage - $foo->isa('Foo'); # true $bar->isa('Foo'); # true $blam->isa('Foo'); # BOOM $foo->can('bar'); # false $bar->can('bar'); # true $blam->can('bar'); # BOOM # Safe::Isa usage - use Safe::Isa; $foo->$_isa('Foo'); # true $bar->$_isa('Foo'); # true $blam->$_isa('Foo'); # false, no boom today $foo->$_can('bar'); # false $bar->$_can('bar'); # true $blam->$_can('bar'); # false, no boom today Similarly: $maybe_an_object->$_does('RoleName'); # true or false, no boom today $maybe_an_object->$_DOES('RoleName'); # true or false, no boom today And just in case we missed a method: $maybe_an_object->$_call_if_object(name => @args); Or to re-use a previous example for purposes of explication: $foo->$_call_if_object(isa => 'Foo'); # true $bar->$_call_if_object(isa => 'Foo'); # true $blam->$_call_if_object(isa => 'Foo'); # false, no boom today =head1 DESCRIPTION How many times have you found yourself writing: if ($obj->isa('Something')) { and then shortly afterwards cursing and changing it to: if (Scalar::Util::blessed($obj) and $obj->isa('Something')) { Right. That's why this module exists. Since perl allows us to provide a subroutine reference or a method name to the -> operator when used as a method call, and a subroutine doesn't require the invocant to actually be an object, we can create safe versions of isa, can and friends by using a subroutine reference that only tries to call the method if it's used on an object. So: my $isa_Foo = $maybe_an_object->$_call_if_object(isa => 'Foo'); is equivalent to my $isa_Foo = do { if (Scalar::Util::blessed($maybe_an_object)) { $maybe_an_object->isa('Foo'); } else { undef; } }; Note that we don't handle trying class names, because many things are valid class names that you might not want to treat as one (like say "Matt") - the C function from L is a good way to check for something you might be able to call methods on if you want to do that. =head1 EXPORTS =head2 $_isa $maybe_an_object->$_isa('Foo'); If called on an object, calls C on it and returns the result, otherwise returns nothing. =head2 $_can $maybe_an_object->$_can('Foo'); If called on an object, calls C on it and returns the result, otherwise returns nothing. =head2 $_does $maybe_an_object->$_does('Foo'); If called on an object, calls C on it and returns the result, otherwise returns nothing. =head2 $_DOES $maybe_an_object->$_DOES('Foo'); If called on an object, calls C on it and returns the result, otherwise returns nothing. =head2 $_call_if_object $maybe_an_object->$_call_if_object(method_name => @args); If called on an object, calls C on it and returns the result, otherwise returns nothing. =head1 AUTHOR mst - Matt S. Trout (cpan:MSTROUT) =head1 CONTRIBUTORS None yet. Well volunteered? :) =head1 COPYRIGHT Copyright (c) 2012 the Safe::Isa L and L as listed above. =head1 LICENSE This library is free software and may be distributed under the same terms as perl itself. =cut