Subject: | ScalarRef does not allow refs to refs. |
While working on 50857 I discovered that refs to refs are not considered
ScalarRefs. This is because ref() returns "REF" rather than "SCALAR".
I presume this is just an oversight. If [[]] is kosher for an ArrayRef
I don't see why nested scalar refs aren't for ScalarRef. ScalarRef
doesn't say anything about the content of the ScalarRef.
Patch attached.
Subject: | 0001-Fix-ScalarRef-so-it-accepts-nested-scalar-refs.patch |
From a460331bbfb74ac4a51283a1929d90fb5f9e04de Mon Sep 17 00:00:00 2001
From: Michael G. Schwern <schwern@pobox.com>
Date: Wed, 28 Oct 2009 18:03:54 -0700
Subject: [PATCH] Fix ScalarRef so it accepts nested scalar refs
---
lib/Moose/Util/TypeConstraints.pm | 2 +-
.../Util/TypeConstraints/OptimizedConstraints.pm | 2 +-
.../003_util_std_type_constraints.t | 4 +++-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/Moose/Util/TypeConstraints.pm b/lib/Moose/Util/TypeConstraints.pm
index 377772e..8384d40 100644
--- a/lib/Moose/Util/TypeConstraints.pm
+++ b/lib/Moose/Util/TypeConstraints.pm
@@ -672,7 +672,7 @@ subtype 'Num' => as 'Str' =>
subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } =>
optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
-subtype 'ScalarRef' => as 'Ref' => where { ref($_) eq 'SCALAR' } =>
+subtype 'ScalarRef' => as 'Ref' => where { ref($_) eq 'SCALAR' || ref($_) eq 'REF' } =>
optimize_as
\&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef;
subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
diff --git a/lib/Moose/Util/TypeConstraints/OptimizedConstraints.pm b/lib/Moose/Util/TypeConstraints/OptimizedConstraints.pm
index d6fe17e..68b2ded 100644
--- a/lib/Moose/Util/TypeConstraints/OptimizedConstraints.pm
+++ b/lib/Moose/Util/TypeConstraints/OptimizedConstraints.pm
@@ -20,7 +20,7 @@ sub Num { !ref($_[0]) && looks_like_number($_[0]) }
sub Int { defined($_[0]) && !ref($_[0]) && $_[0] =~ /^-?[0-9]+$/ }
-sub ScalarRef { ref($_[0]) eq 'SCALAR' }
+sub ScalarRef { ref($_[0]) eq 'SCALAR' or ref($_[0]) eq 'REF' }
sub ArrayRef { ref($_[0]) eq 'ARRAY' }
sub HashRef { ref($_[0]) eq 'HASH' }
sub CodeRef { ref($_[0]) eq 'CODE' }
diff --git a/t/040_type_constraints/003_util_std_type_constraints.t b/t/040_type_constraints/003_util_std_type_constraints.t
index 7c3dae6..f6b2b91 100644
--- a/t/040_type_constraints/003_util_std_type_constraints.t
+++ b/t/040_type_constraints/003_util_std_type_constraints.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use Test::More tests => 297;
+use Test::More tests => 298;
use Test::Exception;
use Scalar::Util ();
@@ -13,6 +13,7 @@ BEGIN {
}
my $SCALAR_REF = \(my $var);
+my $NESTED_SCALAR_REF = \$SCALAR_REF;
no warnings 'once'; # << I *hates* that warning ...
my $GLOB = *GLOB_REF;
@@ -188,6 +189,7 @@ ok(!defined ScalarRef([]), '... ScalarRef rejects anything which i
ok(!defined ScalarRef({}), '... ScalarRef rejects anything which is not a ScalarRef');
ok(!defined ScalarRef(sub {}), '... ScalarRef rejects anything which is not a ScalarRef');
ok(defined ScalarRef($SCALAR_REF), '... ScalarRef accepts anything which is a ScalarRef');
+ok(defined ScalarRef($NESTED_SCALAR_REF),'... ScalarRef accepts anything which is a ScalarRef');
ok(!defined ScalarRef($GLOB), '... ScalarRef rejects anything which is not a ScalarRef');
ok(!defined ScalarRef($GLOB_REF), '... ScalarRef rejects anything which is not a ScalarRef');
ok(!defined ScalarRef($fh), '... ScalarRef rejects anything which is not a ScalarRef');
--
1.6.5