tied at both ends

I’ve been getting into Perl again in a big way. I’d been getting in the mood for code again, and started looking through my old stuff to see if anything tickled my fancy. I found some Perl stuff, which I’ve been chucking in git, and was poking about it, when a question about IO::Prompt came up. Since I’m theoretically responsible for that module, it seemed like a good place to kick off.

I started work again on Test::MockTerm, this time making a pure-Perl version rather than relying on IO::Pty, which had a few issues that made it unsuitable for what I needed. As mentioned in that old post of mine though, without real terminal handles I have no way to test the code paths that expect them.

During my break, Perl 5.10.0 was released, but the hoped for patch that would allow me to override the -t file test operator never made the cut, so I’m still stuck without a solution. The short-term workaround will therefore be to modify IO::Prompt to use POSIX::isatty, which does essentially the same thing. Hopefully it’ll work on Windows when that time comes.

Longer term, there needs to be a way to make -t overridable in some way, so I started poking at the code a bit, and thought about extending tied handles to do the work.

For the uninitiated, Perl has a facility called “tying” where you can essentially tuck an object reference into a variable. When operations are performed on that variable (like storing a value in it), Perl arranges to call methods on the object to do the work. perltie explains the details.

You can tie a filehandle to an object in the same way, so its the ideal way to do what I want. Except that in the BUGS section, we see:

Tied filehandles are still incomplete. sysopen(), truncate(), flock(), fcntl(), stat() and -X can’t currently be trapped.

-X is the general way to refer to the file test operators. Damn.

Tonight I sent off a patch that implements stat() and -X for tied filehandles.

It was quite a challenge to write, but very fulfilling. One of the really interesting things about hacking on Perl is that the culture of writing comprehensive tests and documentation is deeply entrenched, so no matter what you do, you end up with high-quality work at the end of it because its provably correct.

Unfortunately even if it is accepted it seems unlikely to me that the patch will appear anytime soon. I don’t know what the policy is on new features on the current maintenance branch, but I wouldn’t be surprised if it was slated for inclusion in 5.12. It took over three years for 5.10 to appear after 5.8, so I won’t have this code available in a stable Perl for quite a while yet, but at least I have something to point to.

Next is to get Test::MockTerm finished, which I’ll get back into tomorrow.