This Week on p5p 2001/08/27
This Week on P5P
Please send corrections and additions to perl-thisweek-YYYYMM@simon-cozens.org where YYYYMM is the current year and month. Changes and additions to the perl5-porters biographies are particularly welcome.
$] and v-strings
John Peacock sought to make vstrings and ordinary strings that look like version numbers compare equal; this lead to some problems, and a lot of hasty and misunderstood explanations. The nub of the problem seemed to be that there is essentially no semantic difference between a vstring and an ordinary string, as was angrily pointed out by… uh, someone or other:
VSTRINGS ARE REALLY SIMPLE. vx.y.z == join '', map ord, x, y, z THAT'S ALL. NOTHING ELSE.
(Of course, I meant
chr instead of
ord. Oh, the embarrassment.)
John’s self-stated “overriding goal” is laudable: “make sure that all comparisons of versions happen in a consistent fashion”. However, I’m far from convinced that this is possible. My beef with it is that
v49.46.49, under the above definition, looks rather a lot like
"1.1" to Perl, if not to you. (John disagreed with this, but that’s OK; he wants to catch it while the tokeniser still sees it in the
v49.46.49 compare equal to
"1.1", or both? Or neither? Which would be consistent? Does it, in the end, matter?
Callbacks in the core
David Lloyd had three goes at getting callback support into core; he’s still trying. His
Async::Callback module, which previously featured here and is still really great, plugs in a new
runops routine to Perl to allow other routines to be run as a callback after every operation. However, to avoid having to change it every time Perl changed, he wanted the ability to add custom callbacks to runops to be the default in core. A nice idea, but after a couple of iterations of patches, he still had a slowdown of 7% on programs which didn’t even use any callbacks. This was obviously unacceptable, (especially since a mere three modules -
Async::Callback being one of them - use the pluggable runops functionality) but he’s going to have another go at speeding it up.
Nicholas Clark suggested an alternative: have several runops functions - a standard one, a signal-aware one, and so on - and have them plugged in when they’re called for. Whenever someone touched
%SIG, the signal-aware loop would be substituted in, and so on. The only problem was the fact that a runops routine does not end until the end of the program; but I have some ideas to fix that…
CvMETHOD and ->can()
Geoffery Young asked whether or not we should set
CvMETHOD on the coderefs returned by
can so that “XS routines can know whether to use
perl_call_sv on it”. Artur pointed out that this was a bit of a waste of time:
When you have a coderef, why not just call
perl_call_svand push the object as the first argument. Since can already found the correct method, we don’t need to search again using
There was some to-and-fro before Nick Ing-Simmons came along and told us what
CvMETHOD was really for:
CvMETHODcorresponds to the
: methodattribute you can give to subs. Its original use was for Malcolm’s original thread locking scheme. A sub which had
: methodlocked the object; one which just had
: lockedlocked the CV itself.
One could make a case that
->canshould fail unless sub had
: methodattribute - but I won’t ‘cos lots of OO perl code (including mine) does not annotate methods.
Oh, and speaking of
can, Tony Bowden added some tests and documentation for a confusing property. In his words:
cancannot know whether an object will be able to provide a method through AUTOLOAD, so a return value of undef does not necessarily mean the object will not be able to handle the method call. To get around this some module authors use a forward declaration for methods they will handle via AUTOLOAD. For such ‘dummy’ subs,
canwill still return a code reference, which, when called, will fall through to the AUTOLOAD. If no suitable AUTOLOAD is provided, calling the coderef will cause an error.
Coderefs in @INC (again)
Rafael Garcia-Suarez is this week’s hero, for documenting this feature which has been long dormant. (Though I’ve often called for people to document it.)
Doug Wilson found an absolutely horrific problem in
New which can’t be adequately resolved without a speed hit, as far as I can see.
You’ll like this.
Assume I say something like
$#var1 = 2_147_483_647;
Now, internally, Perl allocates space for that many SVs in the array by making a call to
New, something like this:
New(0, my_array, 2147483647, SV*)
New is implemented like this:
#define New(x,v,n,t) (v = (t*)safemalloc((MEM_SIZE)((n)*sizeof(t))))
Now, what happens if
n is very large? You guessed it, the multiplication overflows, and we end up with a small number of bytes being allocated - but the allocation doesn’t fail, so we think we’ve got the lot. The result is spectacular.
Nobody said anything about Doug’s find or his patch.
Artur copied out this handy discovery from “Programming with POSIX threads”
Jeff Okamoto, a rather excellent HP hacker, announced that unfortunately he’s had to stop working on Perl’s IPv6 support because he’s been laid off and needs a new job. I wonder if anyone would like to do something about that.
Robin Houston announced his wonderful Want module, which can only be described as
wantarray on steroids. Check it out.
Paul Kulchenko dropped in a module which uses regular expressions to parse XML, and I defy anyone to tell him he shouldn’t do that. But look, we’ve now got a pure-Perl XML parser! Life is good!
MJD reported from comp.lang.perl.misc that someone had found a bug in
Carp; if overloaded objects where thrown, and the resulting stringification called
carp, a rather nasty recursion would ensue. Michael Schwern pointed out that this has already been fixed.
Nicholas Clark asked whether or not
BOOT: was threadsafe - would two interpreter threads both try loading a dynamic module? Artur didn’t know, but hoped not. Nicholas also provided a massive patch to division to make it preserve IVs if possible, and some tests for
binmode, which Michael Schwern subverted into yet another
I threw in a patch to provide support for adding your own ops to Perl at runtime. Now I’ve got to go write the supporting modules for it, so until next week I remain, your humble and obedient servant,
Something wrong with this article? Help us out by opening an issue or pull request on GitHub