[Bps-public-commit] Class-Load branch, master, updated. f04f8f08a569e15cf0727f1f182136b4e0d548a1
sartak at bestpractical.com
sartak at bestpractical.com
Wed Sep 2 06:17:28 EDT 2009
The branch, master has been updated
via f04f8f08a569e15cf0727f1f182136b4e0d548a1 (commit)
from b578d8a54a7b15109774ebf9bb4280d0d78de59f (commit)
Summary of changes:
lib/Class/Load.pm | 69 +++++++++++++++++++++++++++++++++++++---------
t/001-is-class-loaded.t | 9 +-----
t/002-try-load-class.t | 2 +-
t/003-load-class.t | 2 +-
4 files changed, 58 insertions(+), 24 deletions(-)
- Log -----------------------------------------------------------------
commit f04f8f08a569e15cf0727f1f182136b4e0d548a1
Author: Shawn M Moore <sartak at bestpractical.com>
Date: Wed Sep 2 06:17:14 2009 -0400
Cargo cult CMOP's old pure-perl is_class_loaded
diff --git a/lib/Class/Load.pm b/lib/Class/Load.pm
index ff41387..4beb8ab 100644
--- a/lib/Class/Load.pm
+++ b/lib/Class/Load.pm
@@ -14,6 +14,12 @@ our %EXPORT_TAGS = (
our $ERROR;
+BEGIN {
+ *IS_RUNNING_ON_5_10 = ($] < 5.009_005)
+ ? sub () { 0 }
+ : sub () { 1 };
+}
+
sub load_class {
my $class = shift;
@@ -47,30 +53,63 @@ sub try_load_class {
return 0;
}
+sub _is_valid_class_name {
+ my $class = shift;
+
+ return 0 if ref($class);
+ return 0 unless defined($class);
+ return 0 unless length($class);
+
+ return 1 if $class =~ /^\w+(?:::\w+)*$/;
+
+ return 0;
+}
+
sub is_class_loaded {
my $class = shift;
- # is the module's file in %INC?
- my $file = (join '/', split '::', $class) . '.pm';
- return 1 if $INC{$file};
+ return 0 unless _is_valid_class_name($class);
- # any interesting symbols in this module's symbol table?
- my $table = do {
+ # walk the symbol table tree to avoid autovififying
+ # \*{${main::}{"Foo::"}} == \*main::Foo::
+
+ my $pack = \*::;
+ foreach my $part (split('::', $class)) {
+ return 0 unless exists ${$$pack}{"${part}::"};
+ $pack = \*{${$$pack}{"${part}::"}};
+ }
+
+ # We used to check in the package stash, but it turns out that
+ # *{${$$package}{VERSION}{SCALAR}} can end up pointing to a
+ # reference to undef. It looks
+
+ my $version = do {
no strict 'refs';
- \%{ $class . '::' };
+ ${$class . '::VERSION'};
};
- # ..such as @ISA?
- return 1 if exists $table->{ISA};
+ return 1 if ! ref $version && defined $version;
+ # Sometimes $VERSION ends up as a reference to undef (weird)
+ return 1 if ref $version && reftype $version eq 'SCALAR' && defined ${$version};
- # ..such as $VERSION?
- return 1 if exists $table->{VERSION};
+ return 1 if exists ${$$pack}{ISA}
+ && defined *{${$$pack}{ISA}}{ARRAY};
- # ..or a method?
- for my $glob (values %$table) {
- return 1 if *{$glob}{CODE};
+ # check for any method
+ foreach ( keys %{$$pack} ) {
+ next if substr($_, -2, 2) eq '::';
+
+ my $glob = ${$$pack}{$_} || next;
+
+ # constant subs
+ if ( IS_RUNNING_ON_5_10 ) {
+ return 1 if ref $glob eq 'SCALAR';
+ }
+
+ return 1 if defined *{$glob}{CODE};
}
+ # fail
return 0;
}
@@ -155,6 +194,8 @@ C<if (eval "require $module"; 1)>.
Shawn M Moore, C<< <sartak at bestpractical.com> >>
+The implementation if C<is_class_loaded> has been taken from L<Class::MOP>.
+
=head1 BUGS
Please report any bugs or feature requests to
@@ -163,7 +204,7 @@ L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Class-Load>.
=head1 COPYRIGHT & LICENSE
-Copyright 2008 Best Practical Solutions.
+Copyright 2008-2009 Best Practical Solutions.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
diff --git a/t/001-is-class-loaded.t b/t/001-is-class-loaded.t
index 2da9302..3aacdc5 100644
--- a/t/001-is-class-loaded.t
+++ b/t/001-is-class-loaded.t
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
use strict;
use warnings;
-use Test::More tests => 11;
+use Test::More tests => 10;
use Class::Load 'is_class_loaded';
@@ -31,13 +31,6 @@ do {
};
ok(is_class_loaded('Class::Load::WithVERSION'), "class that defines \$VERSION is loaded");
# }}}
-# @VERSION (yes, sadly) {{{
-do {
- package Class::Load::WithArrayVERSION;
- our @VERSION = "1.0";
-};
-ok(is_class_loaded('Class::Load::WithArrayVERSION'), "class that defines \@VERSION is loaded");
-# }}}
# method (yes) {{{
do {
package Class::Load::WithMethod;
diff --git a/t/002-try-load-class.t b/t/002-try-load-class.t
index 7a600f7..94e2bb8 100644
--- a/t/002-try-load-class.t
+++ b/t/002-try-load-class.t
@@ -19,7 +19,7 @@ like($Class::Load::ERROR, qr{^Missing right curly or square bracket at });
ok(is_class_loaded('Class::Load::OK'));
ok(!is_class_loaded('Class::Load::Nonexistent'));
-ok(is_class_loaded('Class::Load::SyntaxError'));
+ok(!is_class_loaded('Class::Load::SyntaxError'));
do {
package Class::Load::Inlined;
diff --git a/t/003-load-class.t b/t/003-load-class.t
index 983e0d1..183de51 100644
--- a/t/003-load-class.t
+++ b/t/003-load-class.t
@@ -24,7 +24,7 @@ like($Class::Load::ERROR, qr{^Missing right curly or square bracket at });
ok(is_class_loaded('Class::Load::OK'));
ok(!is_class_loaded('Class::Load::Nonexistent'));
-ok(is_class_loaded('Class::Load::SyntaxError'));
+ok(!is_class_loaded('Class::Load::SyntaxError'));
do {
package Class::Load::Inlined;
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list