"It ain't enough that we meet as strangers
I can't set you free
So will you turn your back forever
On what you mean to me?"
-- The Alan Parsons Project
Trini, on #parrot was complaining about the length of the Perl 6 Coding Standards (< 800 lines) being a "bar to entry" on hacking on Parrot. Better than the 120,000+ line "bar to entry" that is the Perl 5 source code. That's a little harsh, I guess. The Perl 5 source is quite elegant in a perverse sort of way, extremely compact if you understand it, and it's amazing the speed that the Perl Porters are able to negotiate it. I'm only just now (having lurked and poked for two years) just getting to the point where I can pretty much read it, and find things I'm looking for. That was the biggest reason to get involved in Perl 6 - a clean, white sheet of paper. But I've always kept it as a goal to contribute something semi-significant to Perl 5. (I'm oh-for-umpteen with proposed solutions and patches to Perl 5 and Perl/Tk so far.)
So I've been trying off and on (more of the former than the latter) for the last couple months to fix a dynamic scoping bug with local variables used in the conditional expressions of an if, unless, or elsif construct. I came close a couple times, but there's always something minor that breaks. Unless something major breaks. (The fixes centered around perly.[cy] rule tweaks and trying to prepend scoping directives to newCONDOP when PL_copline was if or unless. I even got it to handle the newLOGOP optimization, for some definition of handle.) So I've set that aside for now.
So then I moved on to an IO bug I was recently directed to at work. I did a preliminary trace at work, and then delved into bleadperl. I've a pretty good idea of what it's doing, but not a good idea of what it's supposed to be doing. (And although I'm not exactly sure of how to fix either of the two situations, I've a good idea of the gist of what those solutions would entail.) So I wrote up a detailed description as accurately as I can, and says "you're ignored until you contribute." I can't contribute because I'm always being ignored!) So I've set that aside for now.
Now, at work, I've authored 118 different modules. Most of them are junk, or, at best, too specialized for CPAN. The rest I can't export for control reasons. So on CPAN I've a whopping ZERO next to my name. So when a request came in for something I was planning to do anyway, I decided to work on it at home, instead. (Importation is also difficult, but much easier than exportation.) So I'll be working on that this week and the next.
But then last night, I was explaining typeglobs to a friend of mine, and inspiration hit for another module, as well. And in the process of coding it, I thought of something so wonderfully evil. The base module is tentatively named Version.pm, and provides facilities for more fine-tuned version control, similar to what I talked about after last year's TPC. The evil version, however, would allow multiple versions of one module to be included and called from one script. (Yeah, yeah, yeah, I know a lot of things wrong with that idea; fundamentally, it's like multithreading non-threadsafe code.) Version's import sub simply needed to abstract and require the version requested, then play typeglob tricks to repoint the package the version was in:
*{"${pkg}_${version}::"} = \%{"${pkg}::"};
It then tied %{"${pkg}::"}, which mapped the caller tree to the particular version that we just created. Upon access to the package's stash, Version would trace the new caller stack, and compare it with the instantiation caller stack (to guess what version is expected), and then vector the request to the versioned namespace. (The point being, if Foo wants version 1.2 of Baz, and Bar wants version 1.3, they can both be happy.)
Except Perl stashes and namespaces don't work that way, as testing (and traipsing through the source again) showed. It did lead to some interesting behavior, though. Now, if I were to ignore non-subs, I could do that with AUTOLOAD facilities. (And, FYI, this is one use for AUTOGLOB, as proposed by David Cantrell in RFC 324.)
Come to think of it, there's no reason why the package variables couldn't be shared, unless they are being used differently. (And that goes back to the thread-safe analogy...) If you're going to be evil, may as well be extremely evil, so I may do that just for shins and grits.