uk_knight98 has asked for the wisdom of the Perl Monks concerning the following question:

I have a site search program that calls find.pl

It works fine on another site of mine yet when it gets called from this site it pulls up this error

Undefined subroutine "main'wanted" called at /usr/local/lib/perl/find.pl line 39.

Here is the script but I cant find whats wrong

# Usage: # require "find.pl"; # # &find('/foo','/bar'); # # sub wanted { ... } # where wanted does whatever you want. $dir contains the # current directory name, and $_ the current filename within # that directory. $name contains "$dir/$_". You are cd'ed # to $dir when the function is called. The function may # set $prune to prune the tree. # # This library is primarily for find2perl, which, when fed # # find2perl / -name .nfs\* -mtime +7 -exec rm -f {} \; -o -fstype nf +s -prune # # spits out something like this # sub wanted { /^\.nfs.*$/ && (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) && int(-M _) > 7 && unlink($_) || ($nlink || (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_))) & +& $dev < 0 && ($prune = 1); } sub find { chop($cwd = `pwd`); foreach $topdir (@_) { (($topdev,$topino,$topmode,$topnlink) = stat($topdir)) || (warn("Can't stat $topdir: $!\n"), next); if (-d _) { if (chdir($topdir)) { ($dir,$_) = ($topdir,'.'); $name = $topdir; &wanted; $topdir =~ s,/$,, ; &finddir($topdir,$topnlink); } else { warn "Can't cd to $topdir: $!\n"; } } else { unless (($dir,$_) = $topdir =~ m#^(.*/)(.*)$#) { ($dir,$_) = ('.', $topdir); } $name = $topdir; chdir $dir && &wanted; } chdir $cwd; } } sub finddir { local($dir,$nlink) = @_; local($dev,$ino,$mode,$subcount); local($name); # Get the list of files in the current directory. opendir(DIR,'.') || (warn "Can't open $dir: $!\n", return); local(@filenames) = readdir(DIR); closedir(DIR); if ($nlink == 2) { # This dir has no subdirectories. for (@filenames) { next if $_ eq '.'; next if $_ eq '..'; $name = "$dir/$_"; $nlink = 0; &wanted; } } else { # This dir has subdirectories. $subcount = $nlink - 2; for (@filenames) { next if $_ eq '.'; next if $_ eq '..'; $nlink = $prune = 0; $name = "$dir/$_"; &wanted; if ($subcount > 0) { # Seen all the subdirs? # Get link count and check for directoriness. ($dev,$ino,$mode,$nlink) = lstat($_) unless $nlink; if (-d _) { # It really is a directory, so do it recursively. if (!$prune && chdir $_) { &finddir($name,$nlink); chdir '..'; } --$subcount; } } } } } 1;

Replies are listed 'Best First'.
Re: Strange Error Message
by Juerd (Abbot) on Jan 03, 2002 at 15:36 UTC
    main'foo indicates you're using a VERY old version of perl. A single quote used to be the package delimiter, but now it's ::.
    Those old perls are no longer supported in any way, so your best bet is to install a newer perl.

    From perlmod:
    The old package delimiter was a single quote, but double colon is now the preferred delimiter, in part because it's more readable to humans, and in part because it's more readable to emacs macros. It also makes C++ programmers feel like they know what's going on--as opposed to using the single quote as separator, which was there to make Ada programmers feel like they knew what's going on. Because the old-fashioned syntax is still supported for backwards compatibility, if you try to use a string like "This is $owner's house", you'll be accessing $owner::s; that is, the $s variable in package "owner", which is probably not what you meant. Use braces to disambiguate, as in "This is ${owner}'s house".

    2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$

Re: Strange Error Message
by lachoy (Parson) on Jan 03, 2002 at 18:14 UTC

    You probably want to use the module version of this, File::Find. It's quite easy and you probably need only minimal modifications to your code. If you post it (or the relevant part of it) we might be able to help.

    Chris
    M-x auto-bs-mode