Check out The Dynamic Duo --or-- Holy Getopt::Long, Pod::UsageMan! and GetOpt::Long usage style. Put together they're how I do all my script writing.

Here are some minor points I'd do differently. (I'll be using my variables instead of your $opts hash, because that affords me the safety of strict. See aforementioned link.)

foreach (@ARGV) { usagedie() if (!-f || !-d); }
I'd prefer to write this as
usagedie() if grep not( -f or -d ), @ARGV;
The following is needlessly repetitive:
find(\&fileop, $opts{'directory'}) unless @ARGV; find(\&fileop, @ARGV) if @ARGV;
It could be written simpler like so:
find( \&fileop, @ARGV ? @ARGV : $opt_directory );
In this part you're checking -f and -d three or four times per entry, and you're repeating yourself in the conditionals. You also print the directory or file names, even if the corresponding mode option was not set, and they were therefor not touched — probably a minor bug.
sub fileop { #set the right permissions based on if a file or a directory #only set permissions of the mode is set chmod oct($opts{'filemode'}), $_ if -f && $opts{'filemode'}; chmod oct($opts{'dirmode'}), $_ if -d && $opts{'dirmode'}; print $File::Find::name . "\n" if $opts{'verbose'} && (-f || -d); }
How about the following? It's longer, but less redundant — there is only one location at which to update or add any single condition.
sub fileop { if( -f and $opt_filemode ) { chmod oct( $opt_filemode ), $_; } elsif( -d and $opt_dirmode ) { chmod oct( $opt_dirmode ), $_; } else { return; # avoid falling thru to print() } print $File::Find::name, "\n" if $opt_verbose; }
Finally, instead of pulling the values through oct every time through the function, I'd do that once at the beginning of the script, as part of input validation that should check whether they're valid modes. Something like
sub check_perm { my ( $mode, $perm ) = @_; if( defined $perm ) { return ( $perm =~ /^[0-7]{3}$/ ) ? oct( $perm ) : die "Malformed $mode mode $perm\n"; } return; } $opt_filemode = check_perm file => $opt_filemode; $opt_dirmode = check_perm directory => $opt_dirmode;

Makeshifts last the longest.


In reply to Re: How would you go about it? by Aristotle
in thread How would you go about it? by pcassell

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.