develooper Front page | perl.perl5.porters | Postings from February 2013

[perl #116973] [PATCH] e465e1d perlfunc require: fix example subroutine

Thread Previous | Thread Next
From:
David Golden
Date:
February 28, 2013 01:32
Subject:
[perl #116973] [PATCH] e465e1d perlfunc require: fix example subroutine
Message ID:
rt-3.6.HEAD-31961-1362015116-1343.116973-75-0@perl.org
# New Ticket Created by  David Golden 
# Please include the string:  [perl #116973]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=116973 >


This is a bug report for perl from dagolden@cpan.org,
generated with the help of perlbug 1.39 running under perl 5.16.1.

>From e465e1dfe1f23ed525ca2f1f130de671a9720fb9 Mon Sep 17 00:00:00 2001
From: David Golden <dagolden@cpan.org>
Date: Wed, 27 Feb 2013 18:05:10 -0500
Subject: [PATCH] perlfunc require: fix example subroutine
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------1.7.9.6 (Apple Git-31.1)"

This is a multi-part message in MIME format.
--------------1.7.9.6 (Apple Git-31.1)
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit


The semantics of require are reasonably complex.  The perlfunc entry
gives an example saying "has semantics similar to the following".
Unfortunately, that example leaves out a lot, which could mislead people
who -- for whatever reason -- want to try to emulate CORE::require.

This patch makes the following changes to bring the "sub require" example
closer to the actual behavior of CORE::require.

- Loads the filename with the correct calling package

- Corrects the phrasing of the error message when a file is not found

- Uses croak to show that errors are issued from the caller's
  perspective

- Shows (crudly) how to check if a version number has been passed as an
  argument instead of a filename

Things that are omitted:

- The core parses for version numbers in a way that distinguishes
  numbers from strings: C<< require 6 >> is not the same as
  C<< require "6" >>. A pure perl require can't do that, so I
  ignore that distinction and treat anything that looks like a version
  as a version

- There is no localization of %^H, as I'm led to believe this is
  unnecessary since Perl 5.12
---
 pod/perlfunc.pod |   28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)


--------------1.7.9.6 (Apple Git-31.1)
Content-Type: text/x-patch; name="0001-perlfunc-require-fix-example-subroutine.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0001-perlfunc-require-fix-example-subroutine.patch"

diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index 2c1e5f4..e4882c6 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -5745,13 +5745,24 @@ Otherwise, C<require> demands that a library file be included if it
 hasn't already been included.  The file is included via the do-FILE
 mechanism, which is essentially just a variety of C<eval> with the
 caveat that lexical variables in the invoking script will be invisible
-to the included code.  Has semantics similar to the following subroutine:
+to the included code.  If it were implemented in pure Perl, it
+would have semantics similar to the following:
+
+    use Carp 'croak';
+    use version;
 
     sub require {
        my ($filename) = @_;
+       if ( my $version = eval { version->parse($filename) } ) {
+           if ( $version > $^V ) {
+               my $vn = $version->normal;
+               croak "Perl $vn required--this is only $^V, stopped";
+           }
+           return 1;
+       }
        if (exists $INC{$filename}) {
            return 1 if $INC{$filename};
-           die "Compilation failed in require";
+           croak "Compilation failed in require";
        }
        my ($realfilename,$result);
        ITER: {
@@ -5759,18 +5770,23 @@ to the included code.  Has semantics similar to the following subroutine:
                $realfilename = "$prefix/$filename";
                if (-f $realfilename) {
                    $INC{$filename} = $realfilename;
-                   $result = do $realfilename;
+                   my $caller = caller;
+                   my $do_as_caller = eval qq{
+                       package $caller;
+                       sub { do \$_[0] }
+                   };
+                   $result = $do_as_caller->($realfilename);
                    last ITER;
                }
            }
-           die "Can't find $filename in \@INC";
+           croak "Can't locate $filename in \@INC";
        }
        if ($@) {
            $INC{$filename} = undef;
-           die $@;
+           croak $@;
        } elsif (!$result) {
            delete $INC{$filename};
-           die "$filename did not return true value";
+           croak "$filename did not return true value";
        } else {
            return $result;
        }

--------------1.7.9.6 (Apple Git-31.1)--


---
Flags:
    category=docs
    severity=low
---
Site configuration information for perl 5.16.1:

Configured by david at Tue Aug 28 18:58:19 EDT 2012.

Summary of my perl5 (revision 5 version 16 subversion 1) configuration:
   
  Platform:
    osname=darwin, osvers=12.1.0, archname=darwin-2level
    uname='darwin metis.local 12.1.0 darwin kernel version 12.1.0: tue aug 14 13:29:55 pdt 2012; root:xnu-2050.9.2~1release_x86_64 x86_64 '
    config_args='-de -Duserelocatableinc -Dprefix=/Users/david/perl5/perlbrew/perls/perl-5.16.1 -Aeval:scriptdir=/Users/david/perl5/perlbrew/perls/perl-5.16.1/bin'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe -fstack-protector -I/opt/local/include',
    optimize='-O3',
    cppflags='-fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe -fstack-protector -I/opt/local/include'
    ccversion='', gccversion='4.2.1 Compatible Apple Clang 4.0 ((tags/Apple/clang-421.0.60))', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -fstack-protector -L/opt/local/lib'
    libpth=/opt/local/lib /usr/lib
    libs=-ldbm -ldl -lm -lutil -lc
    perllibs=-ldl -lm -lutil -lc
    libc=, so=dylib, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -L/opt/local/lib -fstack-protector'

Locally applied patches:
    

---
@INC for perl 5.16.1:
    /Users/david/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/darwin-2level
    /Users/david/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1
    /Users/david/perl5/perlbrew/perls/perl-5.16.1/lib/5.16.1/darwin-2level
    /Users/david/perl5/perlbrew/perls/perl-5.16.1/lib/5.16.1
    .

---
Environment for perl 5.16.1:
    DYLD_LIBRARY_PATH (unset)
    HOME=/Users/david
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LC_COLLATE=C
    LC_CTYPE=en_US.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/Users/david/perl5/perlbrew/bin:/Users/david/perl5/perlbrew/perls/perl-5.16.1/bin:/opt/tarsnap/bin:/Users/david/git/utility-scripts:/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/usr/local/git/bin
    PERLBREW_BASHRC_VERSION=0.58
    PERLBREW_HOME=/Users/david/.perlbrew
    PERLBREW_MANPATH=/Users/david/perl5/perlbrew/perls/perl-5.16.1/man
    PERLBREW_PATH=/Users/david/perl5/perlbrew/bin:/Users/david/perl5/perlbrew/perls/perl-5.16.1/bin
    PERLBREW_PERL=perl-5.16.1
    PERLBREW_ROOT=/Users/david/perl5/perlbrew
    PERLBREW_VERSION=0.58
    PERL_BADLANG (unset)
    PERL_EXTUTILS_AUTOINSTALL=--defaultdeps
    SHELL=/bin/bash


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About