On 09/19/2016 09:32 PM, derr...@thecopes.me wrote:
I am working on the book Wicked Cool Perl Scripts as a learning tool to hely me 
get from beginner to intermmediate perl. The second script of the book is 
giving me lots of
trouble. Notably the part below. I realize he creating a hash and is using the 
$File::Find::name object which may be a bit over my head. Can someone explain 
to me what he is doing?

my %files;      # Files indexed by size

     # Go through the file tree and find all
     # files with a similar size
     find( sub
     {
            -f &&
File::Find sets $_ to each file it finds before it calls this sub. so -f is acting on $_ and just checks for a regular file. if so, it then does the next thing after the &&.

i would code it differently. i would do:

    return unless -f ;

that is less confusing about the early exit than the && op IMNSHO.
push @{$files{(stat(_))[7]}}, $File::Find::name
that can be broken down easily. first, $File::Find::name is not an object but just a fully qualified scalar which is set to the full file name of the current file being looked at (the short name is in $_ and the current dir is also changed to the path part stored in $File::Find::name. so that is what is being pushed into the $files hash (actually an array ref in that hash). the key is the [7] (8th) element in the result of the stat() call which is the size of the file. the file arg there is _ which is a shortcut to the last used file in any file operator which was the aforementioned -f operator. the -s file op would do the same and be MUCH clearer. so we now have the file size as a key. the outer wrapping of @{} around that hash entry says this is an array reference but perl will autovivify it since the first time through the entry for this file size will be undef. the next time through there will an an array ref in there. so if you have more then one file of the same size, there will be an array ref holding all those file paths keyed by that size. works for one file of a given size too.

this is that line redone to make it clearer:

    push @{ $files{ -s _ } }, $File::Find::name ;

white space is your friend!

$File::Find::name

        }, @dir_list
     );

BTW, am I sending this email to the correct place?
yes.

thanx,

uri


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to