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

use strict; use warnings; sub file_handler { my ($abs_filename) = @_; if ((($current_mth == 1) && ($last_day_current_mth == 31)) threeYrExpiration($abs_filename); } # End of sub file_handler sub threeYrExpiration ($) { my $abs_filename = $_[0]; my $unlinkStatus = unlink("$abs_filename"); if ($unlinkStatus == 1) { $unlinkCountTotal++; $abs_filename =~ s#.*WORKAREA\/[^\/]*##; push (@deleted_files, $abs_filename); $task->AddFile("$abs_filename", "Deleted by content expiration + report"); $logger->info("File to be deleted added to job: $abs_filename" +); } else { $logger->info("File to be deleted \"$abs_filename\" failed. Re +ceived $unlinkStatus instead of 1."); $task->CallBack(1, "Error Deleting expired file"); } }

gives me this error message / faulty output:

Mon Nov 29 10:21:34 2010 : INFO : expiration_report.ipl : ************ +******************************************************************* Mon Nov 29 10:21:34 2010 : INFO : expiration_report.ipl : File to be d +eleted added to job: /committees/comm_wkgrps/inactive/cold_snap_tf/eu +ropepass.pdf Mon Nov 29 10:21:34 2010 : INFO : expiration_report.ipl : File to be d +eleted "/iwmnt/default/main/internet/WORKAREA/home/committees/comm_wk +grps/inactive/cold_snap_tf/europepass.pdf" failed. Received 0 instead + of 1.

I'm trying to unlink (delete) a file by calling sub threeYrExpiration from within sub file_handler

If I move code from threeYrExpiration to file_hander it works (return 1 for unlink status). I need this to work as I have other sub which I wanted to include in file_handler sub to be called also.p>

Replies are listed 'Best First'.
Re: Delete file from sub call within another sub
by kennethk (Abbot) on Nov 29, 2010 at 16:58 UTC
    While it is good that you posted code, you need to make sure that posted code compiles and gives the output you state. When I attempt to execute your code, I get the following output on STDERR:

    Bareword found where operator expected at fluff.pl line 10, near ") threeYrExpiration" (Missing operator before threeYrExpiration?) Global symbol "$current_mth" requires explicit package name at fluff.p +l line 8. Global symbol "$last_day_current_mth" requires explicit package name a +t fluff.pl line 8. syntax error at fluff.pl line 10, near ") threeYrExpiration" Global symbol "$unlinkCountTotal" requires explicit package name at fl +uff.pl line 21. Global symbol "@deleted_files" requires explicit package name at fluff +.pl line 23. Global symbol "$task" requires explicit package name at fluff.pl line +24. Global symbol "$logger" requires explicit package name at fluff.pl lin +e 25. Global symbol "$logger" requires explicit package name at fluff.pl lin +e 27. Global symbol "$task" requires explicit package name at fluff.pl line +28. Execution of fluff.pl aborted due to compilation errors.

    where I have named my script fluff.pl. This tells me this is not the code that is giving you trouble, particularly as one of the errors is a missing block ({}). If I can't replicate your issue, then I can't identify it. There is nothing obviously wrong with your logic. Please post code that compiles that recreates your issue; see How do I post a question effectively?.

    As a helpful side comment, if your actual code works when you copy/paste threeYrExpiration into file_handler, maybe you should leave it in there and modify file_handler to look more like:

    sub file_handler { my ($abs_filename) = @_; return unless $current_mth == 1; return unless $last_day_current_mth == 31; threeYrExpiration($abs_filename); } # End of sub file_handler

      Hi Kenneth,

      Thanks for your advice. However, I think you missed my point. If I change my code to:

      sub threeYrExpiration { my $abs_filename = $_[0]; my $unlinkStatus = unlink("$abs_filename"); if ($unlinkStatus == 1) { $unlinkCountTotal++; $abs_filename =~ s#.*WORKAREA\/[^\/]*##; push (@deleted_files, $abs_filename); $task->AddFile("$abs_filename", "Deleted by content expiration + report"); $logger->info("File to be deleted added to job: $abs_filename" +); } else { $logger->info("File to be deleted \"$abs_filename\" failed. Re +ceived $unlinkStatus instead of 1."); $task->CallBack(1, "Error Deleting expired file"); } }

      It works, which is good. However, I have another sub which does similar (using same variables) but has differences in processing. Hence the reason for wanting to use another method calling sub from within another sub as seen below. So basically using the 2 subs code would look similar to:

      sub file_handler { my ($abs_filename) = @_; if ((($current_mth == 1) && ($last_day_current_mth == 31)) { + threeYrExpiration($abs_filename); } else { sevenYrExpiration($abs_filename); } } # End of sub file_handler sub threeYrExpiration { my $abs_filename = $_[0]; my $unlinkStatus = unlink("$abs_filename"); if ($unlinkStatus == 1) { $unlinkCountTotal++; $abs_filename =~ s#.*WORKAREA\/[^\/]*##; push (@deleted_files, $abs_filename); $task->AddFile("$abs_filename", "Deleted by content expiration + report"); $logger->info("File to be deleted added to job: $abs_filename" +); } else { $logger->info("File to be deleted \"$abs_filename\" failed. Re +ceived $unlinkStatus instead of 1."); $task->CallBack(1, "Error Deleting expired file"); } } sub sevenYrExpiration { ... ... }
        I think you missed my point. Unless you can post a script that will compile and execute on my machine as is and replicates your issue, I cannot help you debug. Possible errors might be related to extensive use of closures/globals, that your original script does not actually use strict; (globals again) or that you've implemented prototyping incorrectly - personally, I suspect the first possibility. But without code, I can't really say any more. Perhaps this link would be helpful: Basic debugging checklist.
Re: Delete file from sub call within another sub
by locked_user sundialsvc4 (Abbot) on Nov 29, 2010 at 17:53 UTC

    Not quite sure what this script is supposed to be doing, but one “little warning bell” does go-off here, which might be helpful.

    As a general rule, don’t try to modify the structure of a filesystem while you are scanning it.   Instead, assemble an in-memory list of the files that you intend to process.   After the scan is finished, walk through the list.

    Microsoft Windows, in particular, has serious problems with this ... and it always has.   (Doesn’t matter whether you are using Perl or not.)

      Thanks Sudial for your advice. Guys This strange how my code flow is going shown for code and error below which works different when code from sub threeYrExpiration is in sub file_handler directly. My code actually deletes the file then goes to beginning of sub then file cannot be found because it was already deleted. Can't figure out why this is happening. Logic seems to be correct.
      sub threeYrExpiration($) { my $abs_filename = $_[0]; $logger->debug("abs_filename: $abs_filename"); # delete expired file my $unlinkStatus = unlink("$abs_filename"); $logger->debug("unlinkStatus: $unlinkStatus"); if ($unlinkStatus == 1) { $unlinkCountTotal++; $abs_filename =~ s#.*WORKAREA\/[^\/]*##; push (@deleted_files, $abs_filename); $task->AddFile("$abs_filename", "Deleted by content expiration + report"); $logger->debug("File to be deleted added to job: $abs_filename +"); #deleted files updateCriterionReports($criteria[1],$abs_filename,$meta_exp_da +te); $logger->debug("unlinkStatus: $unlinkStatus"); } else { $logger->debug("unlinkStatus: $unlinkStatus"); # shows error description, reason for failure $logger->warn("Failed to delete '$abs_filename': <$!>"); # $logger->debug("File to be deleted \"$abs_filename\" failed. +Received $unlinkStatus instead of 1."); $task->CallBack(1, "Error Deleting expired file"); exit(1); } }

      Mon Nov 29 14:35:13 2010 : INFO : expiration_report.ipl : File to be deleted added to job: /committees/comm_wkgrps/inactive/cold_snap_tf/europepass.pdf

      Mon Nov 29 14:35:13 2010 : DEBUG : expiration_report.ipl : abs_filename: /iwmnt/default/main/internet/WORKAREA/home/committees/comm_wkgrps/inactive/cold_snap_tf/europepass.pdf

      Mon Nov 29 14:35:13 2010 : DEBUG : expiration_report.ipl : unlinkStatus: 0

      Mon Nov 29 14:35:13 2010 : DEBUG : expiration_report.ipl : unlinkStatus: 0

      Mon Nov 29 14:35:13 2010 : WARN : expiration_report.ipl : Failed to delete '/iwmnt/default/main/internet/WORKAREA/home/committees/comm_wkgrps/inactive/cold_snap_tf/europepass.pdf': <No such file or directory>