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

introducing $! equivalent for non-errno error messages

0 views
Skip to first unread message

Stas Bekman

unread,
Apr 15, 2004, 4:53:43 AM4/15/04
to The Perl5 Porters Mailing List
Those who followed a recent thread on attempting to extend $! to support
custom error message, know that it didn't reach any resolution.

At the moment if your module wants to provide a custom error message, which
doesn't map to POSIX errno codes you must create your own variable and teach
the user to use that. So we have $DBI::err, DBI::errstr and similar for each
project that needs that API. This is not user friendly as you have to remember
which namespace to use and some other modules won't even call the error
variables in the same way.

So I propose that perl reserves a name for a new variable which is identical
to $! in being a dual var, but not tied to errno/strerror and settable by
users (e.g. XS extensions). Perl itself doesn't need to do anything besides
reserving a nice short variable and provide a few macros to set this variable,
which can then be added to PPPort and voila this new variable can be used with
any old perls.

It's quite possible that Perl itself may find a good use for this variable,
but that's not important. What's important for me is a short and known name,
so I won't accidentally trip over someone's variable name if I have to choose
it by myself.

I'm not sure what's the best name, but something like $E::err will do.
Unfortunately we can't use anything like $!! since older perls won't accept
it. And nothing in the main:: namespace since we most certainly going to trip
over someone's variable.

Once we have it, DBI's 2 generation which Tim is working on could adopt it and
so could other projects. and over time that new variable will be just as known
and used as $!.

__________________________________________________________________
Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:st...@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org http://ticketmaster.com

Rafael Garcia-Suarez

unread,
Apr 15, 2004, 4:58:25 AM4/15/04
to perl5-...@perl.org
Stas Bekman wrote:
> At the moment if your module wants to provide a custom error message, which
> doesn't map to POSIX errno codes you must create your own variable and teach
> the user to use that. So we have $DBI::err, DBI::errstr and similar for each
> project that needs that API. This is not user friendly as you have to remember
> which namespace to use and some other modules won't even call the error
> variables in the same way.
>
> So I propose that perl reserves a name for a new variable which is identical
> to $! in being a dual var, but not tied to errno/strerror and settable by
> users (e.g. XS extensions). Perl itself doesn't need to do anything besides
> reserving a nice short variable and provide a few macros to set this variable,
> which can then be added to PPPort and voila this new variable can be used with
> any old perls.

So that's just a matter of convention and documentation ? (I don't
see what would go in your macros to manipulate this new variable.)

Why not using the name ${^ERROR} ? probably not used, global, no need to
qualify it with a package name.

Stas Bekman

unread,
Apr 15, 2004, 5:11:06 AM4/15/04
to Rafael Garcia-Suarez, perl5-...@perl.org
Rafael Garcia-Suarez wrote:
> Stas Bekman wrote:
>
>>At the moment if your module wants to provide a custom error message, which
>>doesn't map to POSIX errno codes you must create your own variable and teach
>>the user to use that. So we have $DBI::err, DBI::errstr and similar for each
>>project that needs that API. This is not user friendly as you have to remember
>>which namespace to use and some other modules won't even call the error
>>variables in the same way.
>>
>>So I propose that perl reserves a name for a new variable which is identical
>>to $! in being a dual var, but not tied to errno/strerror and settable by
>>users (e.g. XS extensions). Perl itself doesn't need to do anything besides
>>reserving a nice short variable and provide a few macros to set this variable,
>>which can then be added to PPPort and voila this new variable can be used with
>>any old perls.
>
>
> So that's just a matter of convention and documentation ?

Yes

> (I don't
> see what would go in your macros to manipulate this new variable.)

this (not a real code):

#define set_my_error(code, message) do { \
GV *gv = gv_fetchpv("^ERROR", GV_ADDMULTI, SVt_IV); \
SVIV(GvSV(gv)) = code; \
SVPV(GvSV(gv)) = message; \
and set it to IOK and POK \
} while (0)

and probably macros to set just one or the other slot.

> Why not using the name ${^ERROR} ? probably not used, global, no need to
> qualify it with a package name.

Dunno. Too hard to type? but possible.

Tassilo Von Parseval

unread,
Apr 15, 2004, 5:16:23 AM4/15/04
to Stas Bekman, The Perl5 Porters Mailing List
On Thu, Apr 15, 2004 at 01:53:43AM -0700 Stas Bekman wrote:

> Those who followed a recent thread on attempting to extend $! to support
> custom error message, know that it didn't reach any resolution.
>
> At the moment if your module wants to provide a custom error message, which
> doesn't map to POSIX errno codes you must create your own variable and
> teach the user to use that. So we have $DBI::err, DBI::errstr and similar
> for each project that needs that API. This is not user friendly as you have
> to remember which namespace to use and some other modules won't even call
> the error variables in the same way.
>
> So I propose that perl reserves a name for a new variable which is
> identical to $! in being a dual var, but not tied to errno/strerror and
> settable by users (e.g. XS extensions). Perl itself doesn't need to do
> anything besides reserving a nice short variable and provide a few macros
> to set this variable, which can then be added to PPPort and voila this new
> variable can be used with any old perls.
>
> It's quite possible that Perl itself may find a good use for this variable,
> but that's not important. What's important for me is a short and known
> name, so I won't accidentally trip over someone's variable name if I have
> to choose it by myself.
>
> I'm not sure what's the best name, but something like $E::err will do.
> Unfortunately we can't use anything like $!! since older perls won't accept
> it. And nothing in the main:: namespace since we most certainly going to
> trip over someone's variable.

Is there anything wrong with releasing such a thing as a module to the
CPAN? I am not sure it is needed in the core and neither do I think that
it makes such a difference. If we have it as a core module, older perls
wont have it and therefore people will have to install it when they want
to install a module using $E::err on older perls.

Encouraging its use could happen by mentioning the module in the FAQs
and/or perlmod.pod.

With the last paragraph however I do acknowledge that the Perl core
should be made aware of such a module if it ever should hit the CPAN.
When it isn't mentioned in the docs, it's hardly ever going to be used.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

Tim Bunce

unread,
Apr 15, 2004, 9:18:27 AM4/15/04
to Stas Bekman, The Perl5 Porters Mailing List
On Thu, Apr 15, 2004 at 01:53:43AM -0700, Stas Bekman wrote:
> Those who followed a recent thread on attempting to extend $! to support
> custom error message, know that it didn't reach any resolution.
>
> At the moment if your module wants to provide a custom error message, which
> doesn't map to POSIX errno codes you must create your own variable and
> teach the user to use that.

It seems to me that the only 'problem' with $! is that you can only
assign numbers to it (and then the string gets set using strerrno()).

If there was an interface that let you assign both a number and a string
to $! then there wouldn't be much need for anything else.

Given a (hypothetical) set_errno function then:

set_errno(42, "No question");
printf "Error %d: %s\n", $!, $!;

would print

Error 42: No question

A convention of using numbers >= 10_000, say, would avoid any
ambiguity with 'real' errno values.

Tim.

p.s. $DBI::err and $DBI::errstr have auto-resetting semantics and so
aren't appropriate examples.


p.p.s Taking the idea one, slightly magical, step further... assigning a
non-numeric string to $! currently treats it as a number (generating
an ''Argument "..." isn't numeric'' warning if warnings are enabled).

If the first character of the string is a + then we could silence
the warning, assign the number, and then use any remaining string,
after skipping whitespace, as the message instead of using strerrno().
Thus:

$! = "+42 No question";
printf "Error %d: %s\n", $!, $!;

would print

Error 42: No question

Can't get much simpler than that!

Obviously backwards compatibility is an issue. The example above
still sets $! to 42 on old perls, and using { local $^W; $! = ... }
would silence the warning. Having a set_errno() function in a
module (Scalar::Util?) would work for code that needs greater
backwards compatibility.

Umm, perhaps Scalar::Util's dualvar($num, $str) could take an optional
third argument for setting an _exisiting_ value to a dualvar. Then

dualvar($num, $str, $!)

would serve that purpose.

Stas Bekman

unread,
Apr 15, 2004, 2:12:09 PM4/15/04
to tassilo....@post.rwth-aachen.de, The Perl5 Porters Mailing List

There is nothing wrong with creating such a module on CPAN, at least to ensure
that the namespace for $E::err, or whatever the chosen namespace/name will be,
is reserved.

> Encouraging its use could happen by mentioning the module in the FAQs
> and/or perlmod.pod.

Yes.

> With the last paragraph however I do acknowledge that the Perl core
> should be made aware of such a module if it ever should hit the CPAN.
> When it isn't mentioned in the docs, it's hardly ever going to be used.

Correct, again.

So the remaining issue is to choose a nice short name for it. I originally
came with $dollar::err :)

Stas Bekman

unread,
Apr 15, 2004, 2:21:32 PM4/15/04
to Tim Bunce, The Perl5 Porters Mailing List
Tim Bunce wrote:
> On Thu, Apr 15, 2004 at 01:53:43AM -0700, Stas Bekman wrote:
>
>>Those who followed a recent thread on attempting to extend $! to support
>>custom error message, know that it didn't reach any resolution.
>>
>>At the moment if your module wants to provide a custom error message, which
>>doesn't map to POSIX errno codes you must create your own variable and
>>teach the user to use that.
>
>
> It seems to me that the only 'problem' with $! is that you can only
> assign numbers to it (and then the string gets set using strerrno()).
>
> If there was an interface that let you assign both a number and a string
> to $! then there wouldn't be much need for anything else.
>
> Given a (hypothetical) set_errno function then:
>
> set_errno(42, "No question");
> printf "Error %d: %s\n", $!, $!;
>
> would print
>
> Error 42: No question
>
> A convention of using numbers >= 10_000, say, would avoid any
> ambiguity with 'real' errno values.

I just thought that p5p wasn't in favor of extending $!'s functionality. So I
started to take the alternative road.

> p.s. $DBI::err and $DBI::errstr have auto-resetting semantics and so
> aren't appropriate examples.

In general it should not matter if you reset them or not, I think. As long as
everybody is following a common approach, i.e. set these only when an error
occurs and make the function return undef, users shouldn't have a problem of
getting a lingering error message. The problem is that some APIs like DBI
operate on true/false success/failure logic, which is not defined/!defined. In
many other APIs returning 0 is a proper thing to do and shouldn't not indicate
an error. But since true/false is a sub-group of defined/!defined, I guess
there is no problem here.

> p.p.s Taking the idea one, slightly magical, step further... assigning a
> non-numeric string to $! currently treats it as a number (generating
> an ''Argument "..." isn't numeric'' warning if warnings are enabled).
>
> If the first character of the string is a + then we could silence
> the warning, assign the number, and then use any remaining string,
> after skipping whitespace, as the message instead of using strerrno().
> Thus:
>
> $! = "+42 No question";
> printf "Error %d: %s\n", $!, $!;
>
> would print
>
> Error 42: No question
>
> Can't get much simpler than that!
>
> Obviously backwards compatibility is an issue. The example above
> still sets $! to 42 on old perls, and using { local $^W; $! = ... }
> would silence the warning. Having a set_errno() function in a
> module (Scalar::Util?) would work for code that needs greater
> backwards compatibility.
>
> Umm, perhaps Scalar::Util's dualvar($num, $str) could take an optional
> third argument for setting an _exisiting_ value to a dualvar. Then
>
> dualvar($num, $str, $!)
>
> would serve that purpose.

Cool idea, Tim. But in my case, we need to support older perls so it's not
applicable. And I need to move on with a solution for an API of some 400
methods now.

Nick Ing-Simmons

unread,
Apr 16, 2004, 4:39:18 AM4/16/04
to Tim....@pobox.com, Stas Bekman, The Perl5 Porters Mailing List
Tim Bunce <Tim....@pobox.com> writes:
>On Thu, Apr 15, 2004 at 01:53:43AM -0700, Stas Bekman wrote:
>> Those who followed a recent thread on attempting to extend $! to support
>> custom error message, know that it didn't reach any resolution.
>>
>> At the moment if your module wants to provide a custom error message, which
>> doesn't map to POSIX errno codes you must create your own variable and
>> teach the user to use that.
>
>It seems to me that the only 'problem' with $! is that you can only
>assign numbers to it (and then the string gets set using strerrno()).
>
>If there was an interface that let you assign both a number and a string
>to $! then there wouldn't be much need for anything else.
>
>Given a (hypothetical) set_errno function then:
>
> set_errno(42, "No question");
> printf "Error %d: %s\n", $!, $!;
>
>would print
>
> Error 42: No question

So something in perl calls

set_errno(10042,"Camel saddle loose");

does that set the real errno?
Then when we stringify $! we compare numeric value
and if it matches use string from set_errno() else
(OS has changed errno since) use strerror()

Then when system changes errno we need to compare
errno now vs errno for which SvPV is set?


>
>A convention of using numbers >= 10_000, say, would avoid any
>ambiguity with 'real' errno values.

I think various systems are using high numbers already.

Stas Bekman

unread,
Apr 16, 2004, 5:49:32 PM4/16/04
to Tim Bunce, The Perl5 Porters Mailing List
So I'm not sure how to proceed from here. So far we have ${^ERROR} and $E::err
proposals. Anybody else can throw in an opinion, or should I take it to the
module-authors list? I posted here in first place, thinking that the core
people will care about that equivalent $! variable's name/namespace as it has
a good chance to be used in the core. Apparently besides Tim, who has a need
for this feature in DBI, no one else has.

Tim Bunce

unread,
Apr 16, 2004, 5:14:40 PM4/16/04
to Nick Ing-Simmons, Tim....@pobox.com, Stas Bekman, The Perl5 Porters Mailing List

Good point. Yes, and yes.

[Slight tangent: there has been talk in the past of disconnecting $!
from errno and having perl internals set $! explicitly only when
returning an error to the application.]

> >A convention of using numbers >= 10_000, say, would avoid any
> >ambiguity with 'real' errno values.
>
> I think various systems are using high numbers already.

Umm, okay, but I doubt any are using negative ones.

Tim.

Tels

unread,
Apr 17, 2004, 5:54:47 AM4/17/04
to Stas Bekman, Tim Bunce, perl5-...@perl.org
-----BEGIN PGP SIGNED MESSAGE-----

Moin,

>So I'm not sure how to proceed from here. So far we have ${^ERROR} and
>$E::err proposals. Anybody else can throw in an opinion, or should I take
> it to the module-authors list? I posted here in first place, thinking that
> the core people will care about that equivalent $! variable's name/
>namespace as it has a good chance to be used in the core. Apparently
> besides Tim, who has a need for this feature in DBI, no one else has.

I have used something like this in a quite some places, and always invented
a $object->error() method to retrieve it. Upside is: no global var
neccessary and each object has a different error (or not!). Downside is
that you need to know about it and that different classes might name it
differently.

However, this is tied (not "tied"!) to OO usage and usage of classes, that
trip over something (like: singleton, and it's resource is not available
(example: driver class for some hardware finds the hardware unavailable or
another object which does not like the input params to new()).

I am not sure whether a global var would help, because you would have to
look up the doc for a module to know that it uses it.

Anyway, some name proposals:

$^LE (for Last Error)
$^L (or this)
$LAST_ERROR (with english module)

Best wishes,

Tels

- --
Signed on Sat Apr 17 11:43:34 2004 with key 0x93B84C15.
Visit my photo gallery at http://bloodgate.com/photos/
PGP key on http://bloodgate.com/tels.asc or per email.

"To be beautiful is enough! If a woman can do that well who should demand
more from her? You don't want a rose to sing." -- Thackeray

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2-rc1-SuSE (GNU/Linux)
Comment: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

iQEVAwUBQID+8HcLPEOTuEwVAQHkYgf+PEKjfUIMNbpYrQMEPlLN1lVWN7OqpfSy
rl6cugF2g1QYRaDUk5MPwx8Z6KX/YnKAOGgTyvCGQkMXis/w/QaCr/4s26AUalF8
sEFp1kB90e+tzCl1pctUGGJ4CU7zjxd5qECsgPxZJI1iEKNeXYjxbdwPP+Jq1qGj
kIt9PQhxMDjhdvUEz78efqLCqLUUBOpFEbxrgXRix8QccFBGIkCllE/KgxBcQ0tK
9gQT4Dmi4gZXOy+uU9Osj+Q8FXNl50g9+uM84aDUkMEC6MmeCRGns7ST2/S/IS+e
6eLwGYbLH0COYIqN1uc+aqPq42G4huMTUIh53OQf9kznbFYnpszY8w==
=epDp
-----END PGP SIGNATURE-----

Stas Bekman

unread,
Apr 17, 2004, 1:57:19 PM4/17/04
to Tels, Tim Bunce, perl5-...@perl.org
Tels wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
>
> Moin,
>
>
>>So I'm not sure how to proceed from here. So far we have ${^ERROR} and
>>$E::err proposals. Anybody else can throw in an opinion, or should I take
>>it to the module-authors list? I posted here in first place, thinking that
>>the core people will care about that equivalent $! variable's name/
>>namespace as it has a good chance to be used in the core. Apparently
>>besides Tim, who has a need for this feature in DBI, no one else has.
>
>
> I have used something like this in a quite some places, and always invented
> a $object->error() method to retrieve it. Upside is: no global var
> neccessary and each object has a different error (or not!). Downside is
> that you need to know about it and that different classes might name it
> differently.
>
> However, this is tied (not "tied"!) to OO usage and usage of classes, that
> trip over something (like: singleton, and it's resource is not available
> (example: driver class for some hardware finds the hardware unavailable or
> another object which does not like the input params to new()).

In our case we can't use an object.

> I am not sure whether a global var would help, because you would have to
> look up the doc for a module to know that it uses it.
>
> Anyway, some name proposals:
>
> $^LE (for Last Error)

That won't work w/o {} as in ${^LE}, which is not convenient if you have to
type it a lot.

> $^L (or this)

You can't use that var, it's:

$^L What formats output as a form feed. Default is \f.

Ideally, that would be $^ERR or similar, but you can't have this variable w/o
adjusting perl (or using curly braces).

Also there is $^E which is similar to $! but gives some extra info. May be we
could hijack that variable. I wonder if it's used at all.

Glenn Linderman

unread,
Apr 17, 2004, 3:14:40 PM4/17/04
to Tim Bunce, Nick Ing-Simmons, Stas Bekman, The Perl5 Porters Mailing List
On approximately 4/16/2004 2:14 PM, came the following characters from
the keyboard of Tim Bunce:

Fractional errors seem unused as yet. One could allocation a particular
number to a subsystem, and it could use all the fractions it wanted!

--
Glenn -- http://nevcal.com/
===========================
The best part about procrastination is that you are never bored,
because you have all kinds of things that you should be doing.

Yitzchak Scott-Thoennes

unread,
Apr 18, 2004, 12:22:10 PM4/18/04
to Stas Bekman, Tim Bunce, The Perl5 Porters Mailing List
On Fri, Apr 16, 2004 at 02:49:32PM -0700, Stas Bekman <st...@stason.org> wrote:
> So I'm not sure how to proceed from here. So far we have ${^ERROR} and
> $E::err proposals. Anybody else can throw in an opinion, or should I take
> it to the module-authors list? I posted here in first place, thinking that
> the core people will care about that equivalent $! variable's
> name/namespace as it has a good chance to be used in the core. Apparently
> besides Tim, who has a need for this feature in DBI, no one else has.

${^ERROR} or nothing; I don't see any need to in essence reserve a
whole package name "E" just for one variable. ${^ERROR} also has the
advantage of always being in package main even if used in another
package.

Nick Ing-Simmons

unread,
Apr 19, 2004, 9:30:23 AM4/19/04
to st...@stason.org, Tim Bunce, The Perl5 Porters Mailing List
Stas Bekman <st...@stason.org> writes:
>So I'm not sure how to proceed from here. So far we have ${^ERROR} and $E::err
>proposals. Anybody else can throw in an opinion, or should I take it to the
>module-authors list? I posted here in first place, thinking that the core
>people will care about that equivalent $! variable's name/namespace as it has
>a good chance to be used in the core. Apparently besides Tim, who has a need
>for this feature in DBI, no one else has.

For what it is worth - Tk (another "platform" module) doesn't use $!.
Rather it "dies" and so sets $@. (This is mainly because that is
how Tcl/Tk tends to work.)

This exception-throwing style is of course different to the

try_sometthing() || die "...$!";

paradigm but does avoid this issue ;-)

Stas Bekman

unread,
Apr 19, 2004, 4:44:23 PM4/19/04
to Nick Ing-Simmons, Tim Bunce, The Perl5 Porters Mailing List

Yup, thanks Nick, I've tried that. But users don't seem to be happy with
wrapping each call in eval {} and check $@ :(

I think, I'm going to grab some easy to remember and short and easy to type
namespace, reserve it on CPAN and use it. Hopefully others and perl itself
will use it too. I just need to think of a good name, that won't steal some
useful project name, as Yitzchak suggested that stealing E:: might not be the
brightest idea. May be $Z::err is a better one :) (Mnemonic: Zee error)

Feel free to email me your ideas offlist, if you think they aren't suitable
for this forum.

Thanks.

Matt Sergeant

unread,
Apr 20, 2004, 2:37:11 AM4/20/04
to Stas Bekman, Tim Bunce, The Perl5 Porters Mailing List, Nick Ing-Simmons
On 19 Apr 2004, at 21:44, Stas Bekman wrote:

> Nick Ing-Simmons wrote:
>> Stas Bekman <st...@stason.org> writes:
>>> So I'm not sure how to proceed from here. So far we have ${^ERROR}
>>> and $E::err proposals. Anybody else can throw in an opinion, or
>>> should I take it to the module-authors list? I posted here in first
>>> place, thinking that the core people will care about that equivalent
>>> $! variable's name/namespace as it has a good chance to be used in
>>> the core. Apparently besides Tim, who has a need for this feature in
>>> DBI, no one else has.
>> For what it is worth - Tk (another "platform" module) doesn't use $!.
>> Rather it "dies" and so sets $@. (This is mainly because that is how
>> Tcl/Tk tends to work.)
>> This exception-throwing style is of course different to the
>> try_sometthing() || die "...$!";
>> paradigm but does avoid this issue ;-)
>
> Yup, thanks Nick, I've tried that. But users don't seem to be happy
> with wrapping each call in eval {} and check $@ :(

If they think they have to do that then someone has been teaching them
wrong.

Perhaps they should be pointed at the Exceptions tutorial I gave at
OSCon in 2002.
http://axkit.org/docs/presentations/tpc2002/exceptions.pdf

(though I agree that for mod_perl this would be too big a change from
the current API).

Matt.

0 new messages