Re: Here there be cammels!
by BrowserUk (Patriarch) on Feb 28, 2015 at 22:31 UTC
|
I have tried setting $. and $ARGV,
If you are retaining enough information to be able to set $. and $ARGV, you have enough information to add:
my $place = " at $file line $line";
...
print ....., $place;
Expending energies to trick the system into producing something so simple on your behalf is a waste of time.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
| [reply] [d/l] |
Re: Here there be camels!
by LanX (Saint) on Feb 28, 2015 at 22:01 UTC
|
A bit cryptic, I need to guess what you mean.
You want to throw warnings, but with different line number and file reported?
update
I think there should be more straight forward methods, but neither warn nor Carp mention "line".
So, here a hack, till someone comes with something cleaner.
sub warn_from {
my ($line,$file,$text) =@_;
eval <<"__CODE__";
#line $line $file;
warn \$text;
__CODE__
}
warn_from(42,'captain.pl', "I say what!");
-->
/usr/bin/perl -w /home/lanx/warn_new.pl
I say what! at captain.pl; line 42.
| [reply] [d/l] [select] |
|
|
foreach(<>){
warn $_;
}
you get
<text> at dummy.pl line 5, <> line 6
I want to do that. | [reply] [d/l] [select] |
|
|
| [reply] |
|
|
|
|
Re: Here there be cammels!
by AppleFritter (Vicar) on Feb 28, 2015 at 22:09 UTC
|
Howdy, and welcome to the Monastery!
Perl's internal warning mechanism only relates to the code that Perl is executing, i.e. your script, and (probably) cannot be repurposed for the code your compiler will be processing. You'll have to roll your own, or look at CPAN for suitable modules. (Other monks may be able to provide pointers.)
| [reply] |
Re: Here there be cammels!
by Anonymous Monk on Feb 28, 2015 at 22:19 UTC
|
$ perl -wMstrict
#line 123 "foobar.pl"
warn "ACK!";
__END__
ACK! at foobar.pl line 123.
See also variable based #line directives? | [reply] [d/l] [select] |
|
|
#line is fun I paticularly like it in embeded scripts, but I want both line numbers.
#!/bin/bash
lineno=$LINENO;perl='#line '"$LINENO"' "'"$0"'"
warn 'error';
'
perl -e "$perl"
| [reply] [d/l] |
|
|
| [reply] |
Re: Here there be cammels!
by Anonymous Monk on Feb 28, 2015 at 22:39 UTC
|
use IO::Handle;
my $filename = "/etc/passwd";
open my $fh, '<', $filename or die $!;
my $customerr = sub {
my $msg = shift;
$msg =~ s/\.?\s*$//;
return "$msg ($filename line ".$fh->input_line_number.")\n";
};
local $SIG{__WARN__} = sub { warn $customerr->(shift) };
local $SIG{__DIE__} = sub { die $customerr->(shift) };
while (<$fh>) {
warn "BEEP!" if /root/;
die "ACK!" if /nobody/;
}
close $fh;
__END__
BEEP! at - line 12, <$fh> line 1 (/etc/passwd line 1)
ACK! at - line 13, <$fh> line 7 (/etc/passwd line 7)
It may be a little more work than using Perl's built-in mechanisms, but it works great in other cases too - for example if you're going over the rows of a spreadsheet, you can include the row number in the error message. | [reply] [d/l] |
Re: Here there be cammels!
by Anonymous Monk on Feb 28, 2015 at 23:36 UTC
|
Apparently the extra "<$fh> line X" message is added by Perl_mess_sv in util.c and is based on PL_last_in_gv. Apparently that is only set by readline, tell, eof and seek. If the file you want to report the line numbers on is closed, it doesn't seem like trying to trick/hack Perl into generating that extra message for you is worth it, and it's much cleaner to implement a message yourself.
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
open my $fa, '<', '/etc/passwd' or die $!;
open my $fb, '<', '/etc/group' or die $!;
<$fa>; $.=9; <$fa>; warn "One";
<$fb>; $.=17; <$fb>; warn "Two";
seek $fa,256,1; warn "Three";
seek $fb,256,1; warn "Four";
<$fa>; warn "Five";
<$fb>; warn "Six";
__END__
One at - line 3, <$fa> line 10.
Two at - line 4, <$fb> line 18.
Three at - line 5, <$fa> line 10.
Four at - line 6, <$fb> line 18.
Five at - line 7, <$fa> line 11.
Six at - line 8, <$fb> line 19.
See pp_sysseek in pp_sys.c. | [reply] [d/l] [select] |
Re: Here there be cammels!
by Anonymous Monk on Feb 28, 2015 at 23:46 UTC
|
I have tried setting $.
Interestingly:
while (<DATA>) { chomp; warn "<$_>"; }
warn "One";
$. = 123;
warn "Two";
close DATA;
warn "Three";
$. = 456;
warn "Four";
__DATA__
Zero
Gives:
<Zero> at - line 1, <DATA> line 1.
One at - line 2, <DATA> line 1.
Two at - line 4, <DATA> line 123.
Three at - line 6.
Four at - line 8, <DATA> line 456.
And yet, it's a hack. Better to implement the message yourself. | [reply] [d/l] [select] |
|
|
> And yet, it's a hack.
Looks like a bug for me, though DATA is closed it's reported at FOUR.
Only b/c a line-number is set.
> Better to implement the message yourself.
Well, yeah, undocumented behavior. :)
| [reply] |
|
|
I do not think is a bug: is a edge case of use of very particular features...
diamond <> never close the handle and __DATA__ is very near to be $0 in this case (if i remember you can seek it and print the main program too). Because you can adjust $. and you had not closed DATA handle you end with the beahviour observed.
from perldata
Text after __DATA__ may be read via the filehandle PACKNAME::DATA , where PACKNAME is the package that was current when the __DATA__ token was encountered. The filehandle is left open pointing to the line after __DATA__. The program should close DATA when it is done reading from it.
PS. thanks for the line directive hint: never eard about.. L*
There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
| [reply] [d/l] |
|
|