Harry Putnam wrote:
The program I'll post below is really only a test of a subroutine I
want to use in a larger program.  Trying to get the subroutine ironed
out in this test script below so there is a little extra bumping
around to get it executed as sub routine, but It fails with these
errors:

  Variable "$rgx" will not stay shared at ./test line 30.

perldoc perldiag
[ snip ]

    Variable "%s" will not stay shared
        (W closure) An inner (nested) named subroutine is referencing a
        lexical variable defined in an outer subroutine.

        When the inner subroutine is called, it will probably see the
        value of the outer subroutine’s variable as it was before and
        during the *first* call to the outer subroutine; in this case,
        after the first call to the outer subroutine is complete, the
        inner and outer subroutines will no longer share a common value
        for the variable.  In other words, the variable will no longer
        be shared.

        Furthermore, if the outer subroutine is anonymous and references
        a lexical variable outside itself, then the outer and inner
        subroutines will never share the given variable.

        This problem can usually be solved by making the inner
        subroutine anonymous, using the "sub {}" syntax.  When inner
        anonymous subs that reference variables in outer subroutines are
        called or referenced, they are automatically rebound to the
        current values of such variables.


  Global symbol "$finddir" requires explicit package name at ./test line
  19.

perldoc perldiag
[ snip ]

    Global symbol "%s" requires explicit package name
        (F) You’ve said "use strict vars", which indicates that all
        variables must either be lexically scoped (using "my"), declared
        beforehand using "our", or explicitly qualified to say which
        package the global variable is in (using "::").


  Execution of ./test aborted due to compilation errors.

I don't understand why that happens. ------- 8< snip --------
#!/usr/local/bin/perl

use strict;
use warnings;

my $flag = shift;

checkfile($flag);
sub checkfile {
  use File::Find;
  use File::MMagic;
  use FileHandle;

use() happens at compile time so there is no point, but no harm, to put these inside a subroutine.


  my ($rgx,$use,@finddir);
  $use = shift @_;
$rgx = qr/(^|:)$use /;

You are using capturing parentheses but you never use the string thus captured so you may want to use non-capturing parentheses instead.


@finddir = "/usr/portage/profiles";

You can declare and define at the same time:

  my $use = shift @_;
  my $rgx = qr/(^|:)$use /;
  my @finddir = "/usr/portage/profiles";


  find(\&wanted, @finddir) or die "   Failed to open
  finddir <$finddir>: $!";

@finddir and $finddir are two different variables and $finddir does not exist yet. File::Find::find() does not explicitly return a value so testing for its failure is superfluous, and if it did, by coincidence, return a value then it would do so after all files had already been processed by the 'wanted' subroutine and it could be any random value. In other words, the value that may be returned by File::Find::find() has no relation to the success or failure of File::Find::find().


  sub wanted {

Subroutine names are in package scope so defining a named subroutine inside another named subroutine makes little sense.


    my ($mm,$res,$testfile);
    $testfile = $_;
    $mm = new File::MMagic;       # use internal magic file
    $res = $mm->checktype_filename($testfile);

Again, you can declare and define at the same time:

    my $testfile = $_;
    my $mm = new File::MMagic;       # use internal magic file
    my $res = $mm->checktype_filename($testfile);


    if ($res =~ /^plain\/text/) {
open(FILE,"<$File::Find::dir") or die "Can't open <$File::Find::dir>: $!";

$File::Find::dir is the current directory where the file name in $_ is found and open() will only open files, not directories. If you want to open a directory you have to use opendir() instead, but that is pointless as File::Find::find() is already providing you with all the file names via $_.


    }
while(<FILE>) { if (/$rgx/) {
         print "  $File::Find::dir\n";
         print "  $_\n";
       }
} } }



John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order.                            -- Larry Wall


--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to