Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: [perl #77384] Passing a ref to warn doesn't append file and line

33 views
Skip to first unread message

Zefram

unread,
Aug 23, 2010, 6:12:04 PM8/23/10
to perl5-...@perl.org
Ben Morrow wrote:
>Passing a ref to warn no longer adds file and line in blead:

It's up to the ref to stringify itself in a suitable manner for use
as a warning message. Anything that can't do this (including refs to
unblessed objects) shouldn't be used as a warning. You are, of course,
free to explicitly stringify a ref, if you actually want to use the
default stringification as a warning.

Note that the same issue already existed for die:

$ perl5.10.0 -lwe 'die []'; echo foo
ARRAY(0x817f880)foo
$

-zefram

Ben Morrow

unread,
Aug 23, 2010, 2:12:22 PM8/23/10
to bugs-bi...@rt.perl.org
# New Ticket Created by Ben Morrow
# Please include the string: [perl #77384]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=77384 >


Passing a ref to warn no longer adds file and line in blead:

~/src/perl/perl% ./perl -e'warn []; warn "foo"'
ARRAY(0x283061c0)foo at -e line 1.

This is a regression from 5.12; it seems to have been introduced by
c5df309... SV-based interfaces for dieing and warning. I can certainly
see the benefit of keeping a ref a ref for as long as possible, but the
final 'print to STDERR' handler needs to say where the warning came
from.

Ben

Ben Morrow

unread,
Aug 23, 2010, 7:12:27 PM8/23/10
to zef...@fysh.org, perl5-...@perl.org
Quoth zef...@fysh.org (Zefram):

> Ben Morrow wrote:
> >Passing a ref to warn no longer adds file and line in blead:
>
> It's up to the ref to stringify itself in a suitable manner for use
> as a warning message. Anything that can't do this (including refs to
> unblessed objects) shouldn't be used as a warning.

No. warn takes a string argument, so should stringify a ref. If you want
to abuse it to pass objects to $SIG{__WARN__} the onus is on you to
preserve externally-visible behaviour. It would probably be better to do
whatever it is you're trying to do some other way.

> You are, of course,
> free to explicitly stringify a ref, if you actually want to use the
> default stringification as a warning.

I do want to, all the time. I *never* want an object to be preserved in
$SIG{__WARN__}; I consider any use of that %SIG entry a nasty hack for
catching warnings from code that doesn't give you a better interface.

More generally, *any* time someone changes a builtin to be polymorphic
in the types of its arguments, it causes problems: the bitwise ops,
SvUTF8, the 'numish' entry in the smartmatch table... Perl (5) has typed
operators for a reason, and adding more builtins that don't coerce
properly only makes the language more confusing.

> Note that the same issue already existed for die:
>
> $ perl5.10.0 -lwe 'die []'; echo foo
> ARRAY(0x817f880)foo
> $

I know, and I think that's a problem, though almost certainly not one
that can be fixed at this point. Please don't make it worse.

Ben

Zefram

unread,
Aug 23, 2010, 7:30:34 PM8/23/10
to perl5-...@perl.org
Ben Morrow wrote:
>No. warn takes a string argument,

Not any more, and that's a deliberate change. We've been successfully
using structured exception objects with die for some time, and warn was
feeling left out. I don't share your distaste for $SIG{__WARN__}.

>More generally, *any* time someone changes a builtin to be polymorphic
>in the types of its arguments, it causes problems:

Perl certainly does have a problem, with trying to have polymorphism
both ways. I generally oppose making the operators any more polymorphic.
But since we added structured exceptions (back in 5.005) it has not been
sensible to view die and warn as strictly string operations.

-zefram

Ben Morrow

unread,
Aug 23, 2010, 8:25:45 PM8/23/10
to zef...@fysh.org, perl5-...@perl.org
Quoth zef...@fysh.org (Zefram):

> Ben Morrow wrote:
> >No. warn takes a string argument,
>
> Not any more, and that's a deliberate change. We've been successfully
> using structured exception objects with die for some time, and warn was
> feeling left out. I don't share your distaste for $SIG{__WARN__}.

I don't know about 'successfully'. There are some things that work, and
a lot more that don't. Fixing those that don't would be a good thing,
and I wouldn't object to seeing string exceptions get a little more
awkward to use if that was the easiest way to fix object exceptions; but
that has nothing to do with warn.

Warn has always taken a string argument, and has always been the correct
way of doing debugging output. I don't see any need at all to change it
to take an object: since it has no effect on flow control, how is warn
with a __WARN__ handler any different from an ordinary sub call? If you
must, write a module that exports an overriden warn sub that does
whatever you want, but leave CORE::warn alone.

(I note that perlvar explicitly says (and always has)

Due to an implementation glitch, the $SIG{__DIE__} hook is
called even inside an eval(). Do not use this to rewrite a
pending exception in $@, or as a bizarre substitute for
overriding "CORE::GLOBAL::die()". This strange action at a
distance may be fixed in a future release so that $SIG{__DIE__}
is only called if your program is about to exit, as was the
original intent. Any other use is deprecated.

and to my mind the same applies to __WARN__ and CORE::GLOBAL::warn.)

> >More generally, *any* time someone changes a builtin to be polymorphic
> >in the types of its arguments, it causes problems:
>
> Perl certainly does have a problem, with trying to have polymorphism
> both ways.

Perl only tries to have polymorphism both ways when people forget they
shouldn't be doing that. By design Perl was very careful to avoid it,
what with == vs eq and . vs + (mistakes other dynamic languages have
fallen into, to their detriment). Fixing problems that have been
accidentally introduced in the past may be tricky; that's not a good
reason to introduce more now.

> I generally oppose making the operators any more polymorphic.
> But since we added structured exceptions (back in 5.005) it has not been
> sensible to view die and warn as strictly string operations.

What do the 5005 changes to die have to do with warn? warn is not a
flow-control operator and isn't suppressed by eval {}, it just prints a
message to STDERR.

I would agree that the G_KEEPERR behaviour of invoking warn with a
stringified exception object is somewhat useless, and would be better
changed into something else (pushing onto @@ would be my favourite
option, if the scoping can be got right), but this isn't better.

Ben

Father Chrysostomos via RT

unread,
Feb 6, 2011, 4:59:47 PM2/6/11
to zef...@fysh.org, je...@fsck.com, perl5-...@perl.org
On Mon Jan 31 06:17:01 2011, jesse wrote:
> I've just had a chat with Zefram about the intentionality here. He gave
> me permission to post the log:
>
> 09:06 <Zefram> we've got a historical problem that warn and die used to
> be pure string operations, then they got extended to handle refs in some
> situations, but the consequences weren't fully thought through
> 09:08 <Zefram> in recent changes I've been trying to build a consistent
> behaviour that mostly maintains the old behaviour on strings while also
> giving sensible behaviour on refs
> 09:08 <Zefram> stringifying a ref is usually not sensible
> 09:08 <obra> Except it's pretty standard behavior when it's being
> printed
> 09:08 <obra> which is what die and warn do by default.
> 09:08 <Zefram> yes, but that happens at the last stage, just before
> actual output
> 09:09 <obra> and, if it's stringified and has no trailing newline, we
> should be printing the line number, right?
> 09:09 <Zefram> if your exceptions are refs then there are much more
> interesting things you can do than print them
> 09:09 <obra> I don't disagree with that statement
> 09:10 <obra> But if you _are_ printing them, they should behave like
> strings have always behaved and get line numbers, no?
> 09:10 <Zefram> a ref to a blessed object has the opportunity to
> stringify to something sensible for printing
> 09:10 <obra> Right. And we have a well-accepted convention for how to
> decide whether to add line numbers once something is a string.
> 09:11 <obra> admittedly it's a kind of icky convention. but it's well
> accepted
> 09:11 <Zefram> the printing behaviour is certainly up for debate, and we
> can distinguish between overloaded and non-overloaded cases if we think
> that's a good idea
> 09:11 <Zefram> but line numbers are difficult to do selectively
> 09:11 <Zefram> with a string exception, the line number gets appended
> *first*, and then the printing of an uncaught exception is just plain
> printing
> 09:12 <Zefram> with a ref, if you don't immediately stringify it to
> append the line number, then you soon lose track of the line number and
> it's not at all straightforward to apply it later just before printing
> 09:13 <obra> "It's hard to do it 'right'" is different from "We
> shouldn't even want to do that"
> 09:13 <Zefram> indeed
> 09:13 <obra> Do you feel that we shouldn't want to do that?
> 09:13 <Zefram> no, I think it's a sane desire
> 09:14 <Zefram> but afaics the best way to do it is to put that behaviour
> in the exception object

But what if the reference is not an object?

If I simply go ahead and append file and line number whenever an error
is printed, in what cases will the they be off? Will it be harmful?

My main concern is that ‘warn $foo’ is not going to work for me any more
(I use it mostly for debugging), since STDOUT and STDERR will no longer
come out in the right order, making test scripts difficult to debug.
(Yes, ‘warn "$foo"’ is another solution, but it is sufficiently annoying
that I would probably avoid upgrading instead.)

Zefram

unread,
Feb 7, 2011, 12:12:07 PM2/7/11
to perl5-...@perl.org
Father Chrysostomos via RT wrote:
>But what if the reference is not an object?

Then it's strange to use it as an exception.

>If I simply go ahead and append file and line number whenever an error
>is printed, in what cases will the they be off? Will it be harmful?

It'll be wrong if the exception has been caught by an eval and then
rethrown. This could happen because it's not the kind of exception that
that eval was meant to catch. Could also happen with an eval catching and
rethrowing everything, to (say) log the exception in flight. Also would
mean that the logging eval block wouldn't see any line number on the
exception, whereas currently whatever it logs will match what later
gets printed by the core. Some of these failure modes also apply to a
$SIG{__WARN__} handler, some don't.

Actually, the fact that the line number would *ever* be correct if handled
this way is just an accident of implementation: that an exception destined
to terminate the entire program prints *before* unwinding the stack.
I wouldn't like to build in a rule that we can't ever change that.

>(Yes, ???warn "$foo"??? is another solution, but it is sufficiently annoying


>that I would probably avoid upgrading instead.)

It seems strange that you would find this so painful, when what you
actually want is the stringification of the ref.

-zefram

Father Chrysostomos via RT

unread,
Feb 13, 2011, 9:28:34 PM2/13/11
to perl5-...@perl.org, zef...@fysh.org, je...@fsck.com
On Mon Feb 07 09:12:34 2011, zef...@fysh.org wrote:
> Father Chrysostomos via RT wrote:
> >But what if the reference is not an object?
>
> Then it's strange to use it as an exception.

But what is passed to warn is a diagnostic, not an exception.

>
> >If I simply go ahead and append file and line number whenever an
> error
> >is printed, in what cases will the they be off? Will it be harmful?
>
> It'll be wrong if the exception has been caught by an eval and then
> rethrown. This could happen because it's not the kind of exception
> that
> that eval was meant to catch. Could also happen with an eval catching
> and
> rethrowing everything, to (say) log the exception in flight. Also
> would
> mean that the logging eval block wouldn't see any line number on the
> exception, whereas currently whatever it logs will match what later
> gets printed by the core. Some of these failure modes also apply to a
> $SIG{__WARN__} handler, some don't.

In those cases that apply to __WARN__, having it wrong in rare
circumstances would be better than nothing, wouldn’t it? (The same
already happens when die is used when croak is appropriate, for instance.)

We could even attach the line and file to the scalar with magic,
couldn’t we?

I’m not too concerned about die (which was changed years ago), but,
though your changes to warn do make sense, they are nonetheless
incompatible changes that will cause surprises for heavy warn users like
me, and possibly break some code, too.

>
> Actually, the fact that the line number would *ever* be correct if
> handled
> this way is just an accident of implementation: that an exception
> destined
> to terminate the entire program prints *before* unwinding the stack.
> I wouldn't like to build in a rule that we can't ever change that.

We could always change the implementation to cope, if we change that, by
using magic, global variables, or whatever.

Father Chrysostomos via RT

unread,
Feb 20, 2011, 5:30:46 PM2/20/11
to perl5-...@perl.org, zef...@fysh.org, je...@fsck.com
With the hope of finally resolving this for 5.14:

I propose that we make warn() stringify the argument if there is not
$SIG{__WARN__} handler (and leave die() alone for now). It may not be
the ideal long-term solution, but it leaves Zefram’s
$SIG{__WARN__}-getting-a-reference in place, and restores the file and
line number to warnings (that happen to be references) most of the time.

The patch will probably be about two lines long.

Any thoughts?

(Since this is in the list of blockers [and has been ever since that
list was made], is it exempt from the ‘User-visible changes’ freeze?)

Jesse Vincent

unread,
Feb 28, 2011, 5:20:01 PM2/28/11
to perl5-...@perl.org, zef...@fysh.org

Father Chrysostomos via RT <perlbug-...@perl.org> wrote:

>With the hope of finally resolving this for 5.14:
>
>I propose that we make warn() stringify the argument if there is not
>$SIG{__WARN__} handler (and leave die() alone for now). It may not be
>the ideal long-term solution, but it leaves Zefram’s
>$SIG{__WARN__}-getting-a-reference in place, and restores the file and
>line number to warnings (that happen to be references) most of the
>time.
>
>The patch will probably be about two lines long.
>
>Any thoughts?

Works for me.


>
>(Since this is in the list of blockers [and has been ever since that
>list was made], is it exempt from the ‘User-visible changes’ freeze?)


Yes
--
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

Tatsuhiko Miyagawa

unread,
Mar 7, 2011, 8:46:50 PM3/7/11
to perlbug-...@perl.org, perl5-...@perl.org, zef...@fysh.org, je...@fsck.com
On Sun, Feb 20, 2011 at 2:30 PM, Father Chrysostomos via RT
<perlbug-...@perl.org> wrote:
> With the hope of finally resolving this for 5.14:

I just wanted to express my +1 to resolve this for 5.14 and it is good
to know that this is considered a blocker.

> (Since this is in the list of blockers [and has been ever since that
> list was made], is it exempt from the ‘User-visible changes’ freeze?)

--
Tatsuhiko Miyagawa

Jesse Vincent

unread,
Mar 9, 2011, 2:47:28 PM3/9/11
to Tatsuhiko Miyagawa, perlbug-...@perl.org, perl5-...@perl.org, zef...@fysh.org


On Mon 7.Mar'11 at 17:46:50 -0800, Tatsuhiko Miyagawa wrote:
> On Sun, Feb 20, 2011 at 2:30 PM, Father Chrysostomos via RT
> <perlbug-...@perl.org> wrote:
> > With the hope of finally resolving this for 5.14:
>
> I just wanted to express my +1 to resolve this for 5.14 and it is good
> to know that this is considered a blocker.
>

I'd thought I'd +1ed this a while ago, but don't see it in my archives.
Consider it +1ed by me.

0 new messages