Re: perl not going to error path
by stevieb (Canon) on Jan 23, 2016 at 17:47 UTC
|
Did you try the answer you got over at StackOverflow
When cross-posting, please say so in your post, and link to it (on both sites). This prevents people from duplicating work.
To answer your question, seek requires a file handle as its first argument. Note how the seek call has $fh (a file handle) as its first argument, and not the file name (copy/pasted from SO, comments mine):
use strict;
use warnings;
my $offset = 1;
# create a file handle from the file name
open my $fh, '<', 'DCMFReport.txt' or die $!;
# call seek, with the new file handle we just created
seek $fh, $offset, 0 or die "Report seek error, offset:$offset - $!";
Also, please put your code into <code></code> tags. As you can see in your post, it's not very readable as is. Review Markup in the Monastery.
| [reply] [d/l] [select] |
|
use strict;
use warnings;
my $offset = 1;
# create a file handle from the file name
open my $fh, '<', $filename or die $!;
# call seek, with the new file handle we just created
seek $fh, $offset, 0 or die "Report seek error,
offset:$offset - $!";
Now when i pass a non numeric offset, i get an error that says argument non numeric but i dont get the die error message and the exit value is 0. If i pass a numeric offset things work ok. If i put the file handle inside quotes like the below
seek "$fh", $offset, 0 or die "Report seek error,
offset:$offset - $!";
now when i pass a non numeric offset, the script dies and throws the die error message and the exit value is non zero. this is what i want but i don't understand why i need the quotes. | [reply] [d/l] [select] |
|
"Now when i pass a non numeric offset, i get an error that says argument non numeric but i dont get the die error message"
That's because seek is effectively calling die() before you get a chance to. It's saying "pass in an integer or I'll proceed no further. This is an error, and I'm killing all processes".
It's hard to get seek to fail when your argument is an integer, because (at least on Unix), it allows you to seek past the end of the file.
This sounds like an XY Problem. Why don't you tell us what it is you're trying to do? seek() as you've noticed, handles its own errors.
UPDATE:
"now when i pass a non numeric offset, the script dies and throws the die error message and the exit value is non zero. this is what i want but i don't understand why i need the quotes."
Well, you didn't include the error message from $!, but I'll bet it's something along these lines: "Bad file descriptor...". You've hit your die, but it's because quoted "$fh" is no longer a valid file handle anymore. It's pretty much saying that it can't open the file.
Again, tell us what you're really trying to do in the bigger picture.
| [reply] [d/l] [select] |
|
| [reply] [d/l] |
Re: perl not going to error path
by choroba (Archbishop) on Jan 23, 2016 at 18:24 UTC
|
I can't replicate the behaviour with "non numeric" equal to string, reference, or object:
#!/usr/bin/perl
use warnings;
use strict;
my $filename = __FILE__;
my %offset_type = ( number => 1,
string => 'abc',
reference => { a => 23 },
object => bless do { \ my $object }, 'Class'
);
for my $type (keys %offset_type) {
my $offset = $offset_type{$type};
open my $FH, '<', $filename or die $!;
eval {
warn "$type without quotes\n";
seek $FH, $offset, 0 or die "Report error - $!";
warn "quoted $type\n";
seek "$FH", $offset, 0 or die "Report error - $!";
1 } or warn $@;
}
Update: Adding output:
number without quotes
quoted number
seek() on unopened filehandle at ./1.pl line 21.
Report error - Bad file descriptor at ./1.pl line 21.
reference without quotes
quoted reference
seek() on unopened filehandle at ./1.pl line 21.
Report error - Bad file descriptor at ./1.pl line 21.
string without quotes
Argument "abc" isn't numeric in seek at ./1.pl line 19.
quoted string
seek() on unopened filehandle at ./1.pl line 21.
Report error - Bad file descriptor at ./1.pl line 21.
object without quotes
quoted object
seek() on unopened filehandle at ./1.pl line 21.
Report error - Bad file descriptor at ./1.pl line 21.
Please, read Short, Self Contained, Correct Example on how to post helpful code.
If you need to check whether something is a number, use Scalar::Util's looks_like_number.
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
|
| [reply] [d/l] |
|
References are converted to their addresses so you can check object identity:
if ($obj1 == $obj2) {
print "The same object.\n";
}
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
Re: perl not going to error path
by Anonymous Monk on Jan 23, 2016 at 18:05 UTC
|
Non-numeric strings evaluate as zero when used in arithmetic.
$ perl -lwe 'use strict; print int "NANNY"; print int "non-numeric";'
Argument "NANNY" isn't numeric in int at -e line 1.
nan
Argument "non-numeric" isn't numeric in int at -e line 1.
0
That is to say: perl did not error out in seek() because the seek to zero offset was successful.
What is the reason for passing non-numeric offset? You will have to check the passed value yourself, or, better yet, fix the program logic to not pass a string where a number is expected!
| [reply] |
|
Oh my, i thought putting the quote around the file handle works but it does not. even when i send a numeric offset putting a quote around file handle goes to die. I guess i should not put quote around file handle. So i should check to make sure that the value is numeric before passing it to seek.
hopefully there is a way to check and die if it is non numeric with a non zero exit code. I will look around. thanks
| [reply] |
|
my $offset = 'blah';
if ($offset =~ /^[0-9]+$/){
seek $fh, $offset, 0;
}
else {
die "offset needs to be numeric";
}
| [reply] [d/l] |