=head1 TITLE UNIVERSAL::require() =head1 VERSION Maintainer: Michael G Schwern Date: 17 Sep 2000 Mailing List: perl6-language@perl.org Number: 253 Version: 1 Status: Developing =head1 ABSTRACT UNIVERSAL::require() allows modules to be loaded from variables with $module->require rather than the current eval "require $module"; =head1 DESCRIPTION Currently, to load a module one uses either require() or use() with a bareword expression. C is reserved for loading and evaling files. It is not obvious how one loads a module from the value of a variable. Currently, its done like this: $module = "Some::Module"; eval "require $module"; This has two problems. First, its unintuitive. Secondly, $@ is often accidentally not checked, so if the module load fails the error will not be noticed. As a solution, a UNIVERSAL:::require() method can be added with the following syntax: $module = "Some::Module"; $module->require; This is neatly analagous with $module->import and causes a run-time error should the module fail to load. =head2 What about use()? UNIVERSAL::use() and thus C<$module->use> would be an obvious analogy, but unfortunately use() is a compile-time beastie. Variables and methods are run-time. It would be confusing for use() to be compile-time and UNIVERSAL::use() to be run-time, so UNIVERSAL::use() should not be. Instead, this code suffices: BEGIN { $module->require; $module->import; } We see here how neatly the UNIVERSAL::require() syntax lines up with Exporter::import(). Of course, if you really want a run-time use() method you can easily write one. =head2 Version checking The lack of a UNIVERSAL::use() leaves out module version checking (ie. C). UNIVERSAL::require() can take on this feature by taking a version as an argument. $module->require(0.23); =head2 UNIVERSAL::require() is only a class method. What should happen if UNIVERSAL::require() is called as an object method? Should it C or should it be an error? Because the situation is very rare when you will have an object from a class which has not yet been required, UNIVERSAL::require() should only work as a class method. C<$obj->require> should be an explicit run-time error. If require() is desired as an object method, it can easily be overridden with: sub require { my $proto = shift; my $class = ref $proto || $proto; return $class->SUPER::require; } Ta da. =head1 IMPLEMENTATION A complete Perl 5 implementation follows: package UNIVERSAL; sub require { my($class, $want_version) = @_; die("UNIVERSAL::require() can only be run as a class method") if ref $class; die("UNIVERSAL::require() takes no or one arguments") if @_ > 2; # Load the module. my $return = eval "CORE::require $class"; # Check for module load failure. if( $@ ) { $@ =~ s/ at .*?\n$//; die sprintf "$@ at %s line %d.\n", (caller)[1,2]; } # Module version check. my $have_version = ${$class.'::VERSION'}; if( @_ == 2 and $have_version < $want_version ) { die sprintf "%s version %s required--this is only version %s ". "at %s line %d\n", $class, $want_version, $have_version, (caller)[1,2]; } return $return; } this could be added to UNIVERSAL.pm and eventually implemented in universal.c. It could even be safely added to Perl 5. =head1 REFERENCES RFC 103 laments that C does not DWIM.