|laziness, impatience, and hubris|
Compile time action of require in 5.10.1??by djerius (Beadle)
|on Feb 06, 2014 at 19:31 UTC||Need Help??|
djerius has asked for the
wisdom of the Perl Monks concerning the following question:
Yes 5.10.1 is ancient. Still, I have in the past attempted to make sure code runs on it, if only because it's the standard Perl shipped with CentOS 6, which is one of the platforms I support.
Perhaps no more.
I have always believed that require acts only during the execution phase of a program, not during compilation.
Not under 5.10.1...
Here's the test code. Note that the require FileHandle line is in a block which is never run and commented out
Here's what I get if I run it:
Now, uncomment that require FileHandle line, so that it's visible to the compiler. It's still in a block which will never be run.
Huh? The require FileHandle is never executed, so why should it make a difference if the compiler sees the code? (And it's not actually loading FileHandle.pm; I've checked for that).
Now, change that if ( 0 ) to if ( 1 ) so that the block is executed, and rerun:
Here it actually is loading FileHandle.pm (I checked). So, it looks like the compiler does something special if it detects there's a possibility that FileHandle is being required, but that messes things up if it isn't actually required. Replacing
doesn't trigger the error, which bolsters the argument.
This makes me wonder if there are any other "optimizations" like this lurking in the mists.
(I've tried this code with earlier and later versions of Perl, and this discordant behavior is absent. I checked perldelta's and didn't see any relevant comment. Perhaps I missed it; that happens).
It seems the compiler is doing a pattern match for require Filehandle, as require FileHandle::WhoCaresAnyway; has the same effect.
Ignore the conspiracy theories above. See tobyink's comment below.
tldr; If you're running on 5.10.1 and you conditionally require a module which is in the FileHandle hierarchy (e.g. FileHandle, FileHandle::Fmode), or you use something in that heirarchy below FileHandle (such as FileHandle::Fmode) you may run into problems using methods on file handles. To that end, I've put the following in code with those characteristics: