Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Dynamic Class Loading, Compilation, & Speed

by zerohero (Monk)
on Mar 06, 2010 at 22:12 UTC ( #827168=perlquestion: print w/ replies, xml ) Need Help??
zerohero has asked for the wisdom of the Perl Monks concerning the following question:

I'm wondering if there is a better (safer, faster, etc.) way of dynamically loading a class by it's name, and then invoking the constructor (using the class name). The key is we don't want to have to say "use BAREWORD_CLASS", but want to get some of the same benefits. Here's what I'm doing now:

sub creator_func { my ($class, $arg1, $arg2) = @_; eval "require $class"; if ($@) { print "Load error for class='$class': $@\n"; return; } my $new_obj = $class->new ($arg1, $arg2); return $new_obj; }

Is this inefficient? Will it compile the perl class every time it hits the require statement?

Comment on Dynamic Class Loading, Compilation, & Speed
Download Code
Re: Dynamic Class Loading, Compilation, & Speed
by zwon (Monsignor) on Mar 06, 2010 at 22:56 UTC

    You can use Module::Load for loading module. It actually doing the same(not exactly the same) eval you do, but just looks nice. As for creating new object, I don't think it may be better.

    use Module::Load; sub creator { my $class = shift; load $class; $class->new(@_); }
Re: Dynamic Class Loading, Compilation, & Speed
by cdarke (Prior) on Mar 06, 2010 at 23:04 UTC
    Rather than using eval with a string, it is probably better to use a block. For example:
    y $class = 'gash'; eval { require "$class.plm" }; die "Oops: $@" if $@; my $obj = $class->new();
    It will not recompile the class each time, perl maintains %INC to record modules loaded.
      require "$class.plm"

      Note, that won't work if $class='My::Class', you have to replace '::' with '/'. Module::Load takes care about this.

Re: Dynamic Class Loading, Compilation, & Speed
by Anonymous Monk on Mar 06, 2010 at 23:21 UTC
Re: Dynamic Class Loading, Compilation, & Speed
by jdrago999 (Pilgrim) on Mar 07, 2010 at 02:21 UTC

    Try this:

    #!/usr/bin/perl -w use strict; use warnings 'all'; # ...later... load_class("Some::Class"); sub load_class { my ($class) = @_; (my $file = "$class.pm") =~ s/::/\//g; unless( $INC{$file} ) { require $file; $class->import; }# end unless(); }# end load_class()

    Just as use <ClassName> operates in compile-time, require operates in runtime without a string eval.

    To finish the job, call import on the newly-loaded package and you're done.

      Nitpick... to handle the equivalent of use Module qw(foo => 'bar'); -

      # ...later... load_class("Some::Class", @load_args); sub load_class { my $class = shift; (my $file = "$class.pm") =~ s|::|/|g; unless( $INC{$file} ) { require $file; }# end unless(); $class->import(@_); }# end load_class()

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://827168]
Approved by ww
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2014-08-31 08:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (294 votes), past polls