views:

790

answers:

4

In order to extend my "grep" emulator in Perl I have added support for a -r switch which enables recursive searching in sub-directories. Now the command line invocation looks something like this:

perl pgrep.pl -r <directory> <expression>

Both -r and the directory arguments are optional (directory defaults to '.'). As of now I simply check if the first argument is -r and if yes set the appropriate flag, and scan in the rest two arguments using the shift operation. This obviously would be a problem if -r were to appear at the end of the argument list or worse still - in between the directory name and the search expression.

One workaround would be to simply delete the -r item from the @ARGV array so that I can simply shift-in the remaining arguments, but I can't figure out a way to do it without getting an 'undef' in an odd position in my array. Any suggestions or different strategies that you might have used are welcome.

+1  A: 
  • Add a -d switch for your directory. My opinion is, "if a command is optional it should have a switch to enable it."
  • Also I would remove the switches(and their arguments) from the array as I read them, leaving just my "expression". If there's more than 1 element in that array, someone wrote something wrong.
J.J.
How would you remove the elements from the array? Use 'shift' to go through and process the arguments or something else?
muteW
since i want to be as free to move around as possible I would probably use splice. http://perldoc.perl.org/functions/splice.html It can be extremely useful. my $switch = splice(@ARGV, $offset, 1);
J.J.
Thanks a lot, splice is exactly what I was looking for.
muteW
+20  A: 

You should be using GetOpt::Long. This will do everything you need as described.

dsm
http://search.cpan.org/perldoc?Getopt::Long
Brad Gilbert
Is that link more up to date or different in a significant way?
dsm
@dsm: The "perldoc?" link is better because it returns the latest version. It has been discused here: http://stackoverflow.com/questions/43758/how-should-i-link-to-cpan-modules-in-answers
sebthebert
+3  A: 
use Getopt::Std;

our $opt_r; # will be set to its value if used.
getopts('r:'); # -r has an option.
Brian Carlton
A: 

My chapter on "Configuration" in Mastering Perl goes through several possibilities for command-line switch processing, from perl's -s to the popular modules for handling these. For your example, I'd probably start with Getopt::Std and convert to Getopt::Long if I needed it later.

Good luck, :)

brian d foy