This code works - It takes an array of full txt file paths and strips them so that when $exam_nums[$x]
is called, it returns the file name
for (0..$#exam_nums)
{
$exam_nums[$_] =~ s/\.txt$//; #remove extension
$exam_nums[$_] =~ s/$dir//g; #remove path
}
When I try to do this for a single variable, it doesn't work. I'm calling a subroutine and sending it a present, but the variable is empty at the end. (It is getting into the if statement block, because the other lines in there run fine.) 开发者_高级运维 Here's the code:
Call to the sub:
notify($_);
The $_
is from a foreach(@files)
loop that works
The sub:
sub notify
{
if(shift)
{
$ex_num = shift;
$ex_num =~ s/\.txt$//; #remove extension
$ex_num =~ s/$dir//g; #remove path
print $ex_num;
print "\nanything";
}
}
I tried taking out the $
in the "remove extension" portion of the regex, but that didn't help.
You're shifting TWICE. The first shift in the if statement removes the value, the second shift gets nothing. shift
has a side-effect of actually modifying @_
. in addition to returning the first element, it removes the first element permanently from @_
.
EDIT: from man perlfunc
shift ARRAY shift Shifts the first value of the array off and returns it, shortening the array by 1 and moving everything down. If there are no elements in the array, returns the undefined value. If ARRAY is omitted, shifts the @_ array within the lexical scope of subroutines and formats, ...
You are attempting to extract your ex_num
argument from @_
(the argument list) twice: shift
(which alters @_
) is not the same as $_[0]
(which just looks at the first element of @_
but does not alter it). See perldoc -f shift.
Also, your function is closing over $dir
, which may or may not be your intent. (See perldoc perlfaq7 for more information about closures.) I've taken that out and added it as an additional function parameter:
sub notify
{
my ($ex_num, $dir) = @_;
return unless $ex_num;
$ex_num =~ s/\.txt$//; # remove extension
$ex_num =~ s/$dir//g; # remove path
print $ex_num . "\n";
}
I'd use File::Basename instead of rolling my own. It allows you to parse file paths into their directory, filename and suffix.
As per Jim Garrison's info, I pulled a switch to fix the problem:
sub notify
{
$ex_num = shift;
if($ex_num)
{
$ex_num =~ s/\.txt$//; #remove extension
$ex_num =~ s/$dir//g; #remove path
}
}
Uses a core module, local variables and Perl 5.10.
use 5.010;
use File::Basename;
sub notify {
my $ex_num = shift;
my $name = basename($ex_num, '.txt');
say $name;
}
精彩评论