Bumping version to 1.000008
[p5sagit/Safe-Isa.git] / lib / Safe / Isa.pm
CommitLineData
e6995dc6 1package Safe::Isa;
2
3use strict;
4use warnings FATAL => 'all';
29153068 5use Scalar::Util ();
7b1885ee 6use Exporter 5.57 qw(import);
e6995dc6 7
d3136db0 8our $VERSION = '1.000008';
e6995dc6 9
ff5366db 10our @EXPORT = qw($_call_if_object $_isa $_can $_does $_DOES $_call_if_can);
e6995dc6 11
12our $_call_if_object = sub {
13 my ($obj, $method) = (shift, shift);
f3335392 14 # This is intentionally a truth test, not a defined test, otherwise
15 # we gratuitously break modules like Scalar::Defer, which would be
16 # un-perlish.
29153068 17 return unless Scalar::Util::blessed($obj);
de8d80ef 18 return $obj->isa(@_) if lc($method) eq 'does' and not $obj->can($method);
e6995dc6 19 return $obj->$method(@_);
20};
21
22our ($_isa, $_can, $_does, $_DOES) = map {
23 my $method = $_;
24 sub { my $obj = shift; $obj->$_call_if_object($method => @_) }
25} qw(isa can does DOES);
26
ff5366db 27our $_call_if_can = sub {
28 my ($obj, $method) = (shift, shift);
2e029f31 29 return unless $obj->$_call_if_object(can => $method);
30 return $obj->$method(@_);
ff5366db 31};
32
b19500df 331;
34__END__
35
36=pod
37
e6995dc6 38=head1 NAME
39
40Safe::Isa - Call isa, can, does and DOES safely on things that may not be objects
41
42=head1 SYNOPSIS
43
44 use strict;
45 use warnings;
46
47 { package Foo; sub new { bless({}, $_[0]) } }
48 { package Bar; our @ISA = qw(Foo); sub bar { 1 } }
49
50 my $foo = Foo->new;
51 my $bar = Bar->new;
52 my $blam = [ 42 ];
53
54 # basic isa usage -
55
56 $foo->isa('Foo'); # true
57 $bar->isa('Foo'); # true
58 $blam->isa('Foo'); # BOOM
59
60 $foo->can('bar'); # false
61 $bar->can('bar'); # true
62 $blam->can('bar'); # BOOM
63
64 # Safe::Isa usage -
65
66 use Safe::Isa;
67
68 $foo->$_isa('Foo'); # true
69 $bar->$_isa('Foo'); # true
70 $blam->$_isa('Foo'); # false, no boom today
71
72 $foo->$_can('bar'); # false
73 $bar->$_can('bar'); # true
74 $blam->$_can('bar'); # false, no boom today
75
76Similarly:
77
78 $maybe_an_object->$_does('RoleName'); # true or false, no boom today
79 $maybe_an_object->$_DOES('RoleName'); # true or false, no boom today
80
ff5366db 81And just in case we missed a method or two:
e6995dc6 82
83 $maybe_an_object->$_call_if_object(name => @args);
ff5366db 84 $maybe_an_object->$_call_if_can(name => @args);
e6995dc6 85
86Or to re-use a previous example for purposes of explication:
87
ff9518c5 88 $foo->$_call_if_object(isa => 'Foo'); # true
89 $bar->$_call_if_object(isa => 'Foo'); # true
90 $blam->$_call_if_object(isa => 'Foo'); # false, no boom today
e6995dc6 91
92=head1 DESCRIPTION
93
94How many times have you found yourself writing:
95
96 if ($obj->isa('Something')) {
97
98and then shortly afterwards cursing and changing it to:
99
100 if (Scalar::Util::blessed($obj) and $obj->isa('Something')) {
101
102Right. That's why this module exists.
103
104Since perl allows us to provide a subroutine reference or a method name to
105the -> operator when used as a method call, and a subroutine doesn't require
106the invocant to actually be an object, we can create safe versions of isa,
107can and friends by using a subroutine reference that only tries to call the
108method if it's used on an object. So:
109
110 my $isa_Foo = $maybe_an_object->$_call_if_object(isa => 'Foo');
111
112is equivalent to
113
114 my $isa_Foo = do {
115 if (Scalar::Util::blessed($maybe_an_object)) {
116 $maybe_an_object->isa('Foo');
117 } else {
118 undef;
119 }
120 };
121
fca38ff4 122Note that we don't handle trying class names, because many things are valid
123class names that you might not want to treat as one (like say "Matt") - the
124C<is_module_name> function from L<Module::Runtime> is a good way to check for
f94f3bbb 125something you might be able to call methods on if you want to do that.
fca38ff4 126
2e029f31 127We are careful to make sure that scalar/list context is preserved for the
128method that is eventually called.
129
e6995dc6 130=head1 EXPORTS
131
132=head2 $_isa
133
134 $maybe_an_object->$_isa('Foo');
135
136If called on an object, calls C<isa> on it and returns the result, otherwise
137returns nothing.
138
139=head2 $_can
140
141 $maybe_an_object->$_can('Foo');
142
143If called on an object, calls C<can> on it and returns the result, otherwise
144returns nothing.
145
146=head2 $_does
147
148 $maybe_an_object->$_does('Foo');
149
150If called on an object, calls C<does> on it and returns the result, otherwise
151returns nothing.
152
153=head2 $_DOES
154
155 $maybe_an_object->$_DOES('Foo');
156
157If called on an object, calls C<DOES> on it and returns the result, otherwise
158returns nothing.
159
4703f64c 160=head2 $_call_if_object
e6995dc6 161
4703f64c 162 $maybe_an_object->$_call_if_object(method_name => @args);
e6995dc6 163
164If called on an object, calls C<method_name> on it and returns the result,
165otherwise returns nothing.
166
ff5366db 167=head2 $_call_if_can
168
169 $maybe_an_object->$_call_if_can(name => @args);
170
171If called on an object, calls C<can> on it; if that returns true, then
172calls C<method_name> on it and returns the result; if any condition is false
173returns nothing.
174
91dfd937 175=head1 SEE ALSO
176
177I gave a lightning talk on this module (and L<curry> and L<Import::Into>) at
178L<YAPC::NA 2013|https://www.youtube.com/watch?v=wFXWV2yY7gE&t=46m05s>.
179
e6995dc6 180=head1 AUTHOR
181
182mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
183
184=head1 CONTRIBUTORS
185
186None yet. Well volunteered? :)
187
188=head1 COPYRIGHT
189
190Copyright (c) 2012 the Safe::Isa L</AUTHOR> and L</CONTRIBUTORS>
191as listed above.
192
193=head1 LICENSE
194
195This library is free software and may be distributed under the same terms
196as perl itself.
197
198=cut