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

Greetings all,

I have a question pertaining to File::Find, but more generally about callbacks.

How can I pass the $days_ago parameter into the callback function "&findNewerThan"? I seem to lose the value of File::Find::name when I pass in a parameter...

Eventually, I'll do a stat on the current file to get the modification time, and then accept or reject the filename

I'll also have other callback functions, some which accept parameters, and others that don't. I'll use a hash of coderefs for this

Thanks in advance for your help!

#!/usr/bin/perl -w use strict; use Data::Dumper; use File::Find; # Global array for the accumulated files... my @files = (); # Any directory will suffice here... my $file_dir_root = "/var/log"; #------------------------------------------------ sub findNewerThan { #------------------------------------------------ # my $days_ago = shift; my $filename = $File::Find::name; return unless -f $filename; # Now stat the file to compare its modification time # with the days_ago parameter... push(@files, $filename); } #------------------------------------------------ sub days($) { #------------------------------------------------ my $days = shift; my $oneday = 60 * 60 * 24; return $days * $oneday; } #------------------------------------------------ # MAIN #------------------------------------------------ my $func = \&findNewerThan; #find($func->(days(5)), ($file_dir_root) ); find($func, ($file_dir_root) ); print Dumper(\@files);
Where do you want *them* to go today?

Replies are listed 'Best First'.
Re: Passing a parameter to a callback
by ikegami (Patriarch) on Jul 19, 2006 at 21:24 UTC
    Create a function that calls your function with the correct argument, and pass a reference to that function instead.
    find(sub { findNewerThan(days(5)) }, $file_dir_root);
    or
    my $days = days(5); find(sub { findNewerThan($days) }, $file_dir_root);

    Update: I accidently changed days(5) into 5. Fixed.

Re: Passing a parameter to a callback
by runrig (Abbot) on Jul 19, 2006 at 21:36 UTC
    or you can have your FindNewerThan sub return a sub:
    sub findNewerThan { my $days_ago = days(shift); return sub { my $filename = $File::Find::name; return unless -f $filename; #...do something with $days_ago push(@files, $filename); } } find( findNewerThan(5), $file_dir_root );
Re: Passing a parameter to a callback
by diotalevi (Canon) on Jul 19, 2006 at 21:33 UTC

    Your indentation of comments sucks. When you indent, indent everything in that block. You've destroyed the visual look of indentation and removed it as a tool to see code structure. Don't do that. Here's your code run through perltidy.

    #!/usr/bin/perl -w use strict; use Data::Dumper; use File::Find; # Global array for the accumulated files... my @files = (); # Any directory will suffice here... my $file_dir_root = "/var/log"; #------------------------------------------------ sub findNewerThan { #------------------------------------------------ # my $days_ago = shift; my $filename = $File::Find::name; return unless -f $filename; # Now stat the file to compare its modification time # with the days_ago parameter... push( @files, $filename ); } #------------------------------------------------ sub days($) { #------------------------------------------------ my $days = shift; my $oneday = 60 * 60 * 24; return $days * $oneday; } #------------------------------------------------ # MAIN #------------------------------------------------ my $func = \&findNewerThan; #find($func->(days(5)), ($file_dir_root) ); find( $func, ($file_dir_root) ); print Dumper( \@files );

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      I'm not sure I follow what you're trying to say here. I didn't do any special indentations... in my submitted source code *none* of the comments were indented.

      Please explain further...

      Where do you want *them* to go today?

        The comments diotalevi is referring to are the lines below the function definitions, which (I assume) are meant to highlight the function names. He is saying that those lines, being unindented after a '{' defining a new code block, are wrong (would he like it more if the "{" came after the comment line? I don't know). I would disagree since highlighting the function name like that is a somewhat common practice (though I wouldn't do it), so I'd say it's somewhat acceptable, although perltidy doesn't have an option to handle it, so you will lose the formatting if your program is ever run through perltidy. I've seen the practice a lot in other languages (that don't use {} for blocks mostly) but not much in perl.

        The other unindented comment is where you have "# Now stat the file to compare its modification time", which I assume is a temporary placemarker for actual code and so I wouldn't really worry about that either since making markers like that ugly make them easy to find when you need to replace them.

        Yes, that's the problem. I've just told you that the way your formatted your code isn't any good. It destroyed important information. It's as close to having no indentation as is possible while still having some.

        ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

          A reply falls below the community's threshold of quality. You may see it by logging in.