djerius has asked for the wisdom of the Perl Monks concerning the following question:
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:use File::Temp qw( tempfile ); if ( 0 ) { print STDERR "required\n"; # require FileHandle; } my ($fh, $file) = tempfile( UNLINK => 1 ); $fh->getline;
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.$ perl ttrap.t
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).$ perl ttrap.t Can't locate object method "getline" via package "FileHandle" at ttrap +.t line 12.
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$ perl ttrap.t required
withrequire FileHandle;
doesn't trigger the error, which bolsters the argument.eval 'require FileHandle';
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).
Update:
It seems the compiler is doing a pattern match for require Filehandle, as require FileHandle::WhoCaresAnyway; has the same effect.
Updated Update:
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:
use if $^V ge v5.10.0 && $^V lt v5.11.0, 'FileHandle';
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Compile time action of require in 5.10.1??
by tobyink (Canon) on Feb 06, 2014 at 21:43 UTC | |
by djerius (Beadle) on Feb 06, 2014 at 22:16 UTC |