I don't see how a tied hash (ref) is a special case.
use strict;
use warnings;
package Nothing;
sub isa { 0 }
package NotHash;
use overload '%{}' => sub { {} };
sub new { bless [], shift }
package OverHash;
use overload '%{}' => sub { {} };
sub new { bless {}, shift }
package main;
use Tie::Memoize;
use Test::More;
my @test_cases = ( { name => 'unblessed hash',
test => {},
is_hash => 1, },
{ name => 'unblessed array',
test => [],
is_hash => 0, },
{ name => q{hash blessed as 'HASH'},
test => bless( {}, 'HASH' ),
is_hash => 1, },
{ name => q{array blessed as 'HASH'},
test => bless( [], 'HASH' ),
is_hash => 0, },
{ name => q{hash blessed as 'ARRAY'},
test => bless( {}, 'ARRAY' ),
is_hash => 1, },
{ name => 'hash in package 0',
test => bless( {}, '0' ),
is_hash => 1, },
{ name => 'array in package 0',
test => bless( [], '0' ),
is_hash => 0, },
{ name => 'hash with ->isa overridden',
test => bless( {}, 'Nothing' ),
is_hash => 1, },
{ name => 'blessed array with %{} overloaded',
test => NotHash->new(),
is_hash => 1, },
{ name => 'blessed hash with %{} overloaded',
test => OverHash->new(),
is_hash => 1, },
{ name => 'tied hash',
test => get_tied_hash(),
is_hash => 1, },
{ name => 'not a reference',
test => 'HASH',
is_hash => 0, },
);
sub get_tied_hash {
tie my %h, 'Tie::Memoize', sub {};
return \%h;
}
plan 'tests' => scalar @test_cases;
foreach my $test ( @test_cases ) {
is( !!isHash( $test->{test} ), !!$test->{is_hash}, $test->{name});
}
use Scalar::Util qw( reftype blessed );
sub isHash {
my $suspected_hash = shift;
return 0 if '' eq ref $suspected_hash;
return 1 if 'HASH' eq reftype $suspected_hash;
if ( blessed $suspected_hash
&& overload::Method( $suspected_hash, '%{}' ) ) {
return 1;
}
return 0;
}
The code for isHash is based heavily on blokhead's from "Is it a hashref" vs "Can I use it like a hashref?"
Have I missed an important test case here?
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.