This and other RFCs are available on the web at
http://dev.perl.org/rfc/
=head1 TITLE
UNIVERSAL::require()
=head1 VERSION
Maintainer: Michael G Schwern <[EMAIL PROTECTED]>
Date: 17 Sep 2000
Mailing List: [EMAIL PROTECTED]
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<require $variable> 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<use
Some::Module 0.23>). 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<eval "require ".ref $obj> 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<require $class> does not DWIM.