http://qs321.pair.com?node_id=664910


in reply to 'require/use' scoping

[ Whenever someone asks you the difference between require and use, point them to the use entry in perlfunc. Not only will they get the right answer, but they'll learn how to use the docs. In this case, the OP wants to know about what require does and how it does it. Again, perlfunc has the answer. :)]

Packages or namespaces are not scopes! This week I've seen a few people mention that, but it's not true and I don't know where people ever see that. Scopes are either blocks of code or the file, which has an implicit scope around all of its contents. The package pragma is scoped, but any symbol table work it does is not.

These two are equivalent and there's nothing else special going on. It's not just a run-/compile-time thing. The use also implies an import.

use Foo; BEGIN { require Foo; Foo->import; }

Curiously, the answer in perlfaq8 on "What's the difference between use and require" is crap, so now I must go fix it. And so it has come to pass:

What's the difference between require and use?

Perl runs require statement at run-time. Once Perl loads, compiles, and runs the file, it doesn't do anything else. The use statement is the same as a require run at compile-time, but Perl also calls the import method for the loaded package. These two are the same:

use MODULE qw(import list); BEGIN { require MODULE; MODULE->import(import list); }

However, you can suppress the import by using an explicit, empty import list. Both of these still happen at compile-time:

use MODULE (); BEGIN { require MODULE; }

Since use will also call the import method, the actual value for MODULE must be a bareword. That is, use cannot load files by name, although require can:

require "lib/Foo.pm"; # no @INC searching!

See the entry for use in perlfunc for more details.

Now, the other part of the OP's question is what require is actually doing. Again, it's right in perlfunc. This code is directly from the entry on require and shows exactly what you would have to do on your own to recreate its behaviour:

sub require { my ($filename) = @_; if (exists $INC{$filename}) { return 1 if $INC{$filename}; die "Compilation failed in require"; } my ($realfilename,$result); ITER: { foreach $prefix (@INC) { $realfilename = "$prefix/$filename"; if (-f $realfilename) { $INC{$filename} = $realfilename; $result = do $realfilename; last ITER; } } die "Can't find $filename in \@INC"; } if ($@) { $INC{$filename} = undef; die $@; } elsif (!$result) { delete $INC{$filename}; die "$filename did not return true value"; } else { return $result; } }

That little snippet is already assuming that a bareword has been turned into a filename, and doesn't do portable path construction, but it's the mechanics that count. Notice the do to actually run the code.

--
brian d foy <brian@stonehenge.com>
Subscribe to The Perl Review