&checkDir('/usr/tmp', '-w'); #or...
&checkDir('/usr/tmp', '-r')
sub checkDir {
my ($dir, $perm) = @_;
### Check if output dir exists
if (! defined $path) {
LOG ("The path where to save the output is not defined using temp instead...", 1);
$path = '/var/tmp/';
}
if (! -d $path) {
die LOG ("$path is not a valid directory...", 0);
}
if (! $perm $path) {
die LOG ("You do not have $perm to $path directory...", 0);
}
LOG ("Using $path as output directory...", 2);
}
I have tried to deref the $perm var, but it does not help either. Is it possible at all to pass an operator as an argument??
Cheers and thanks
Pär
The following test code works fine. Alter it to demonstrate your problem:
use warnings;
use strict;
checkDir('/usr/tmp', '-w'); #or...
checkDir('/usr/tmp', '-r');
sub checkDir {
my ($dir, $perm) = @_;
print "Dir: $dir, Perm: $perm\n";
}
Prints:
Dir: /usr/tmp, Perm: -w Dir: /usr/tmp, Perm: -r
Bah, read the code!
Ok, better answer - to the actual question:
use warnings;
use strict;
my $testDir = '.';
checkDir($testDir, '-w');
checkDir($testDir, '-r');
sub checkDir {
my ($dir, $perm) = @_;
if (eval "$perm '$dir'") {
print "Can $perm $dir\n";
} else {
print "Can $perm $dir\n";
}
}
Prints:
Can -w . Can -r .
This may be a bad idea if the call passes in user supplied text is is not from a trusted place!
Probably the safest way is to use a hash dispatch table. There are only a small number of possible hyphen-operators anyway. Another alternative would be to use the "quote" version of eval, but that just exposes you to too much potential for an eternity in outer darkness... so stick with a dispatch table.
Dave
use warnings;
use strict;
my %h = (
-r => sub { -r shift },
-w => sub { -w shift },
);
my $testDir = '/tmp/';
checkDir( $testDir, '-w' );
checkDir( $testDir, '-r' );
sub checkDir {
my ( $dir, $perm ) = @_;
die '???' unless exists $h{$perm};
if ( $h{$perm}($dir) ) {
print "Can $perm $dir\n";
}
else {
print "Can not $perm $dir\n";
}
}
Rather than passing an operator per se, I'd pass a code reference that uses the operator...
checkDir('/usr/tmp', sub { -w shift }); # need write permission.
checkDir('/usr/tmp', sub { -r shift }); # need read permission.
checkDir('/usr/tmp', sub { my $x = shift; -r $x and -w $x; }); # need both.
checkDir('/usr/tmp', sub { my $x = shift; not $x =~ /\.\./; }); # safety check.
sub checkDir {
my ($path, $perm) = @_;
### Check if output dir exists
if (! defined $path) {
LOG ("Output path not defined; using temp instead...", 1);
$path = '/var/tmp/';
}
if (! -d $path) {
die LOG ("$path is not a valid directory...", 0);
}
if (! $perm->($path)) {
die LOG ("Test failed on $path, not able to use it.", 0);
}
LOG ("Using $path as output directory...", 2);
}
While I like this idea, a couple of minor comments. First, there's an awful lot of shifting going on. For things like this, the topicaliser, $_, is very useful. So you'd be able to set things up as:
checkdir('/usr/tmp', sub { -w $_ });
checkdir('/usr/tmp', sub { -r $_ });
checkdir('/usr/tmp', sub { -r $_ and -w $_ });
At this point, I want to point out my second minor comment. This is what _ is for.
# now it's:
checkdir('/usr/tmp', sub { -r $_ and -w _ });
checkdir('/usr/tmp', sub { !/\.\./ });
Again, my next minor comment: I'm not sure what this is supposed to be checking. I'm guessing you're looking for a directory named ".." somewhere in there. However, I'm guessing that "/usr/blah..foo" should be permitted? Regexes are powerful, but with power comes great respon... er, complexity ;-) Rather than use a regex, I would actually suggest doing exactly what a human would do: split the path elements up, and then look that none of them are equal to "..". If that's what you really want. (On unix, I claim that this is almost never what you want, due to symlinks.)
use List::MoreUtils qw/none/;
use File::Spec;
checkdir('/usr/tmp', sub {
none { $_ eq '..' } File::Spec->splitdir($_)
});
With those minor comments, here's the minor change to checkDir:
sub checkDir {
my ($path, $perm) = @_;
### Check if output dir exists
if (! defined $path) {
LOG ("Output path not defined; using temp instead...", 1);
$path = '/var/tmp/';
}
if (! -d $path) {
die LOG ("$path is not a valid directory...", 0);
}
if (! do { local $_ = $path; $perm->() }) {
die LOG ("Test failed on $path, not able to use it.", 0);
}
LOG ("Using $path as output directory...", 2);
}
A bit more convoluted internally, but I think a much more perlish exterior.
perlmonks.org content © perlmonks.org and borisz, davido, GrandFather, jonadab, kurreburre, Tanktalus
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03