Reputation: 6041
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.
Upvotes: 1
Views: 519
Reputation: 5104
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;
}
Upvotes: 0
Reputation: 86764
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, ...
Upvotes: 13
Reputation: 53966
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";
}
Upvotes: 6
Reputation: 6041
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
}
}
Upvotes: 1
Reputation: 11923
I'd use File::Basename instead of rolling my own. It allows you to parse file paths into their directory, filename and suffix.
Upvotes: 5