[Chicago-talk] calling functions in a package by its name

Steven Lembark lembark at wrkhors.com
Mon Jan 21 13:01:59 PST 2008


>>>      my $prog = "use $classname;";
>>>      eval $prog; die("eval '$prog' failed with " . $@ ) if ($@);
>> You do have to use string eval to load the class.  require is better
>> than use here, though.  (Do you want $class->import to be called?  Not
>> for classes, usually.)
>
> OK, I'll give eval "require.." a try.  It definitely should not import things into the caller's
> namespace - this thing is basically just an object factory.

Actually, the "import" sub might be used to
initialize some portion of the module itself
at runtime,  e.g.,

    use Benchmark qw( :hireswallclock );

turns on the high-res wallclock feature in
Benchmark. If you only use require then it
may help to add something like:

    if( $package->can( 'import' ) )
    {
        log_a_warning "Ignoring import in: $package";
    }

or

    if( $package->can( 'import' ) )
    {
        $package->import;
    }

>> How about:
>>
>>   my $class = 'Foo';
>>   eval "require $class";
>>   $class->can('new')->(); # Foo->new()
>
> I'll give that a try.

Note: foo->can(x)->() breaks if the package
doesn't have a new coderef in their namespace
(you'll be dispatching an undef). With minimal
boilerplate this becomes a lot easeir to debug:

    if( my $sub = $class->can( 'new' ) )
    {
        # "$class->$sub" gets you to the same place,
        # this avoids the indirect-object form and
        # makes it a bit more obvious that you exect
        # $sub to be a coderef.

        $sub->( $class );
    }
    else
    {
        confess "Package missing 'new': $class"
    }

It's also trivial to have the class return its
value of $constructor, which allows for a more
general:

    my $constructor = $classdata->{ constructor } || 'new';

    if( my $sub = $class->can( $constructor ) )
    {
        ...
    }
    else
    {
        confess "Bogus class: $class cannot $constructor"
    }

> few stringy evals from the production code today.

Always a good thing :-)

-- 
Steven Lembark                                          +1 888 359 3508
Workhorse Computing                                       85-09 90th St
lembark at wrkhors.com                                 Woodhaven, NY 11421


More information about the Chicago-talk mailing list