]> git.vpit.fr Git - perl/modules/subs-auto.git/blobdiff - lib/subs/auto.pm
Use B::Keywords
[perl/modules/subs-auto.git] / lib / subs / auto.pm
index e507c5c71aafed9d24140a8a8528a13796ec91b1..3657b1d3b6dbc7e4de61a54778fef9cde0a357ce 100644 (file)
@@ -5,6 +5,8 @@ use 5.010;
 use strict;
 use warnings;
 
+use B::Keywords;
+
 use Carp qw/croak/;
 use Symbol qw/gensym/;
 
@@ -16,11 +18,11 @@ subs::auto - Read barewords as subroutine names.
 
 =head1 VERSION
 
-Version 0.04
+Version 0.05
 
 =cut
 
-our $VERSION = '0.04';
+our $VERSION = '0.05';
 
 =head1 SYNOPSIS
 
@@ -65,39 +67,19 @@ BEGIN {
  croak 'uvar magic not available' unless Variable::Magic::VMG_UVAR;
 }
 
-my @core = qw/abs accept alarm atan2 bind binmode bless break caller chdir
-              chmod chomp chop chown chr chroot close closedir connect
-              continue cos crypt dbmclose dbmopen default defined delete die
-              do dump each endgrent endhostent endnetent endprotoent endpwent
-              endservent eof eval exec exists exit exp fcntl fileno flock fork
-              format formline getc getgrent getgrgid getgrnam gethostbyaddr
-              gethostbyname gethostent getlogin getnetbyaddr getnetbyname
-              getnetent getpeername getpgrp getppid getpriority getprotobyname
-              getprotobynumber getprotoent getpwent getpwnam getpwuid
-              getservbyname getservbyport getservent getsockname getsockopt
-              given glob gmtime goto grep hex index int ioctl join keys kill
-              last lc lcfirst length link listen local localtime lock log
-              lstat map mkdir msgctl msgget msgrcv msgsnd my next no oct open
-              opendir ord our pack package pipe pop pos print printf prototype
-              push quotemeta rand read readdir readline readlink readpipe recv
-              redo ref rename require reset return reverse rewinddir rindex
-              rmdir say scalar seek seekdir select semctl semget semop send
-              setgrent sethostent setnetent setpgrp setpriority setprotoent
-              setpwent setservent setsockopt shift shmctl shmget shmread
-              shmwrite shutdown sin sleep socket socketpair sort splice split
-              sprintf sqrt srand stat state study sub substr symlink syscall
-              sysopen sysread sysseek system syswrite tell telldir tie tied
-              time times truncate uc ucfirst umask undef unlink unpack unshift
-              untie use utime values vec wait waitpid wantarray warn when
-              write/;
-push @core,qw/not __LINE__ __FILE__ DATA/;
-
 my %core;
-@core{@core} = ();
+@core{
+ @B::Keywords::Barewords,
+ @B::Keywords::Functions,
+ 'DATA',
+} = ();
 delete @core{qw/my local/};
-undef @core;
 
-my $tag = wizard data => sub { 1 };
+BEGIN {
+ *_REFCNT_PLACEHOLDERS = eval 'sub () { ' . ($] < 5.011002 ? 0 : 1) . '}'
+}
+
+my $tag = wizard data => sub { \(my $data = _REFCNT_PLACEHOLDERS ? 2 : 1) };
 
 sub _reset {
  my ($pkg, $func) = @_;
@@ -107,7 +89,9 @@ sub _reset {
   no warnings 'once';
   *$fqn{CODE};
  };
- if ($cb and getdata(&$cb, $tag)) {
+ if ($cb and defined(my $data = getdata(&$cb, $tag))) {
+  $$data--;
+  return if $$data > 0;
   no strict 'refs';
   my $sym = gensym;
   for (qw/SCALAR ARRAY HASH IO FORMAT/) {
@@ -128,16 +112,22 @@ sub _fetch {
   my $mod = $func . '.pm';
   if (not exists $INC{$mod}) {
    my $fqn = $data->{pkg} . '::' . $func;
-   if (do { no strict 'refs'; not *$fqn{CODE} || *$fqn{IO}}) {
-    my $cb = sub {
-     my ($file, $line) = (caller 0)[1, 2];
-     ($file, $line) = ('(eval 0)', 0) unless $file && $line;
-     die "Undefined subroutine &$fqn called at $file line $line\n";
-    };
-    cast &$cb, $tag;
-    no strict 'refs';
-    *$fqn = $cb;
+   my $cb = do { no strict 'refs'; *$fqn{CODE} };
+   if ($cb) {
+    if (_REFCNT_PLACEHOLDERS and defined(my $data = getdata(&$cb, $tag))) {
+     ++$$data;
+    }
+    return;
    }
+   return if do { no strict 'refs'; *$fqn{IO} };
+   $cb = sub {
+    my ($file, $line) = (caller 0)[1, 2];
+    ($file, $line) = ('(eval 0)', 0) unless $file && $line;
+    die "Undefined subroutine &$fqn called at $file line $line\n";
+   };
+   cast &$cb, $tag;
+   no strict 'refs';
+   *$fqn = $cb;
   }
  } else {
   _reset($data->{pkg}, $func);
@@ -212,6 +202,8 @@ L<Carp> (standard since perl 5), L<Symbol> (since 5.002).
 
 L<Variable::Magic> with C<uvar> magic enabled (this should be assured by the required perl version).
 
+L<B::Keywords>.
+
 =head1 AUTHOR
 
 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.