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
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.
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.
> 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
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.
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 :)
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.
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.
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.
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-----
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.
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.
${^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.
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 $@ :(
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.
> 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.