This Week on p5p 2001/08/27

Notes

This Week on P5P

$] and v-strings

Callbacks in the core

CvMETHOD and ->can()

Coderefs in @INC (again)

Malloc Madness

Various

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 v... form.)

Should v49.46.49 compare equal to "49.46.49", "1.1", or both? Or neither? Which would be consistent? Does it, in the end, matter?

Urgh.

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_method or 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_sv and push the object as the first argument. Since can already found the correct method, we don’t need to search again using call_method.

There was some to-and-fro before Nick Ing-Simmons came along and told us what CvMETHOD was really for:

CvMETHOD corresponds to the : method attribute you can give to subs. Its original use was for Malcolm’s original thread locking scheme. A sub which had : locked and : method locked the object; one which just had : locked locked the CV itself.

One could make a case that ->can should 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:

can cannot 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.)

Here’s the original description from the digest; Nicholas Clark points to original discussion of it here. Raphael’s documentation is here.

Malloc Madness

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.

Various

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 Test::Simple test.

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,


Simon Cozens

Tags

Feedback

Something wrong with this article? Help us out by opening an issue or pull request on GitHub