Minor cleanup of ::Optional::Dependencies innards
Peter Rabbitson [Mon, 30 Aug 2010 03:17:35 +0000 (05:17 +0200)]
lib/DBIx/Class/Optional/Dependencies.pm
xt/optional_deps.t

index 5cb513b..6d4ed6f 100644 (file)
@@ -215,9 +215,7 @@ sub req_ok_for {
   croak "req_ok_for() expects a requirement group name"
     unless $group;
 
-  $class->_check_deps ($group) unless $req_availability_cache{$group};
-
-  return $req_availability_cache{$group}{status};
+  return $class->_check_deps($group)->{status};
 }
 
 sub req_missing_for {
@@ -226,9 +224,7 @@ sub req_missing_for {
   croak "req_missing_for() expects a requirement group name"
     unless $group;
 
-  $class->_check_deps ($group) unless $req_availability_cache{$group};
-
-  return $req_availability_cache{$group}{missing};
+  return $class->_check_deps($group)->{missing};
 }
 
 sub req_errorlist_for {
@@ -237,44 +233,49 @@ sub req_errorlist_for {
   croak "req_errorlist_for() expects a requirement group name"
     unless $group;
 
-  $class->_check_deps ($group) unless $req_availability_cache{$group};
-
-  return $req_availability_cache{$group}{errorlist};
+  return $class->_check_deps($group)->{errorlist};
 }
 
 sub _check_deps {
   my ($class, $group) = @_;
 
-  my $deps = $class->req_list_for ($group);
+  return $req_availability_cache{$group} ||= do {
+
+    my $deps = $class->req_list_for ($group);
+
+    my %errors;
+    for my $mod (keys %$deps) {
+      my $req_line = "require $mod;";
+      if (my $ver = $deps->{$mod}) {
+        $req_line .= "$mod->VERSION($ver);";
+      }
+
+      eval $req_line;
+
+      $errors{$mod} = $@ if $@;
+    }
+
+    my $res;
 
-  my %errors;
-  for my $mod (keys %$deps) {
-    if (my $ver = $deps->{$mod}) {
-      eval "use $mod $ver ()";
+    if (keys %errors) {
+      my $missing = join (', ', map { $deps->{$_} ? "$_ >= $deps->{$_}" : $_ } (sort keys %errors) );
+      $missing .= " (see $class for details)" if $reqs->{$group}{pod};
+      $res = {
+        status => 0,
+        errorlist => \%errors,
+        missing => $missing,
+      };
     }
     else {
-      eval "require $mod";
+      $res = {
+        status => 1,
+        errorlist => {},
+        missing => '',
+      };
     }
 
-    $errors{$mod} = $@ if $@;
-  }
-
-  if (keys %errors) {
-    my $missing = join (', ', map { $deps->{$_} ? "$_ >= $deps->{$_}" : $_ } (sort keys %errors) );
-    $missing .= " (see $class for details)" if $reqs->{$group}{pod};
-    $req_availability_cache{$group} = {
-      status => 0,
-      errorlist => { %errors },
-      missing => $missing,
-    };
-  }
-  else {
-    $req_availability_cache{$group} = {
-      status => 1,
-      errorlist => {},
-      missing => '',
-    };
-  }
+    $res;
+  };
 }
 
 sub req_group_list {
@@ -310,7 +311,7 @@ sub _gen_pod {
     or die "Hrmm? No sqlt dep?";
 
   my @chunks = (
-    <<"EOC",
+    <<'EOC',
 #########################################################################
 #####################  A U T O G E N E R A T E D ########################
 #########################################################################
@@ -323,7 +324,7 @@ EOC
     '=head1 NAME',
     "$class - Optional module dependency specifications (for module authors)",
     '=head1 SYNOPSIS',
-    <<EOS,
+    <<"EOS",
 Somewhere in your build-file (e.g. L<Module::Install>'s Makefile.PL):
 
   ...
@@ -385,10 +386,10 @@ EOD
     '=head1 METHODS',
     '=head2 req_group_list',
     '=over',
-    '=item Arguments: $none',
+    '=item Arguments: none',
     '=item Returns: \%list_of_requirement_groups',
     '=back',
-    <<EOD,
+    <<'EOD',
 This method should be used by DBIx::Class packagers, to get a hashref of all
 dependencies keyed by dependency group. Each key (group name) can be supplied
 to one of the group-specific methods below.
@@ -399,7 +400,7 @@ EOD
     '=item Arguments: $group_name',
     '=item Returns: \%list_of_module_version_pairs',
     '=back',
-    <<EOD,
+    <<'EOD',
 This method should be used by DBIx::Class extension authors, to determine the
 version of modules a specific feature requires in the B<current> version of
 DBIx::Class. See the L</SYNOPSIS> for a real-world
@@ -411,14 +412,17 @@ EOD
     '=item Arguments: $group_name',
     '=item Returns: 1|0',
     '=back',
-    'Returns true or false depending on whether all modules required by C<$group_name> are present on the system and loadable',
+    <<'EOD',
+Returns true or false depending on whether all modules required by
+C<$group_name> are present on the system and loadable.
+EOD
 
     '=head2 req_missing_for',
     '=over',
     '=item Arguments: $group_name',
     '=item Returns: $error_message_string',
     '=back',
-    <<EOD,
+    <<"EOD",
 Returns a single line string suitable for inclusion in larger error messages.
 This method would normally be used by DBIx::Class core-module author, to
 indicate to the user that he needs to install specific modules before he will
index 5e35930..11ef4d1 100644 (file)
@@ -5,7 +5,7 @@ no warnings qw/once/;
 use Test::More;
 use lib qw(t/lib);
 use Scalar::Util; # load before we break require()
-use Carp ();      # Carp is not used in the test, but we want to have it loaded for proper %INC comparison
+use Carp ();   # Carp is not used in the test, but we want to have it loaded for proper %INC comparison
 
 # a dummy test which lazy-loads more modules (so we can compare INC below)
 ok (1);
@@ -33,25 +33,26 @@ is_deeply (
 );
 
 # make module loading impossible, regardless of actual libpath contents
-@INC = (sub { die('Optional Dep Test') } );
-
-ok (
-  ! DBIx::Class::Optional::Dependencies->req_ok_for ('deploy'),
-  'deploy() deps missing',
-);
-
-like (
-  DBIx::Class::Optional::Dependencies->req_missing_for ('deploy'),
-  qr/^SQL::Translator \>\= \d/,
-  'expected missing string contents',
-);
-
-like (
-  DBIx::Class::Optional::Dependencies->req_errorlist_for ('deploy')->{'SQL::Translator'},
-  qr/Optional Dep Test/,
-  'custom exception found in errorlist',
-);
-
+{
+  local @INC = (sub { die('Optional Dep Test') } );
+
+  ok (
+    ! DBIx::Class::Optional::Dependencies->req_ok_for ('deploy'),
+    'deploy() deps missing',
+  );
+
+  like (
+    DBIx::Class::Optional::Dependencies->req_missing_for ('deploy'),
+    qr/^SQL::Translator \>\= \d/,
+    'expected missing string contents',
+  );
+
+  like (
+    DBIx::Class::Optional::Dependencies->req_errorlist_for ('deploy')->{'SQL::Translator'},
+    qr/Optional Dep Test/,
+    'custom exception found in errorlist',
+  );
+}
 
 #make it so module appears loaded
 $INC{'SQL/Translator.pm'} = 1;
@@ -83,5 +84,4 @@ is_deeply (
   'expected empty errorlist',
 );
 
-
 done_testing;