dynamic object instantiation using eval 
Author Message
 dynamic object instantiation using eval

# This works:
package Foo;
use MyPackage::MyClass;
my $obj = MyPackage::MyClass->new($myargs);

# This dies with "Can't find method new":
package Foo;
my $class = "MyPackage::MyClass";
my $obj = eval $class . '->new($myargs)';

# this dies with can't find MyPackage::MyClass;
package Foo;
my $class = "MyPackage::MyClass";
require $class;

What am I doing wrong?  I must have screwed with this for two hours today!
I've done this type of thing before without problems but it does not seem to
be working this time...  Grr.

Paul



Tue, 18 Feb 2003 09:07:48 GMT  
 dynamic object instantiation using eval

Quote:

># This works:
>package Foo;
>use MyPackage::MyClass;
>my $obj = MyPackage::MyClass->new($myargs);

># This dies with "Can't find method new":
>package Foo;
>my $class = "MyPackage::MyClass";
>my $obj = eval $class . '->new($myargs)';

Has the interpreter had a chance to reaf the MyPackage::MyClass module
anywhere before this?  Just invoking a method won't cause perl to go and
load the class.  MyPackage::MyClass::new must have been presented to perl
for that call to succeed (unless you're into advanced trickery to fake up
the sub on demand).  In the de{*filter*}:

  DB<1> $class = 'CGI'

  DB<2> print "worked" if $o = eval $class . '->new({})';

  DB<3> use CGI

  DB<4> print "worked" if $o = eval $class . '->new({})';
worked

At step 2 nothing had caused perl to read the CGI module, once read the
statement worked.

You are aware that $myargs will not interpolate inside single quotes,
so you may have a problem there.  You can say


  DB<5> print "worked" if $o = $class->new({});          
worked
  DB<6> print $o
CGI=HASH(0x832dd54)

Quote:
># this dies with can't find MyPackage::MyClass;
>package Foo;
>my $class = "MyPackage::MyClass";
>require $class;

>What am I doing wrong?  I must have screwed with this for two hours today!
>I've done this type of thing before without problems but it does not seem to
>be working this time...  Grr.

Did you spend some time reading the manual, which should be installed with
a perl installation?  On my system

  perldoc -tf require

includes this:

    require VERSION
    require EXPR

    [...]

            If EXPR is a bareword, the require assumes a ".pm" extension and
            replaces "::" with "/" in the filename for you, to make it easy
            to load standard modules. This form of loading of modules does
            not risk altering your namespace.

            In other words, if you try this:

                    require Foo::Bar;    # a splendid bareword

            The require function will actually look for the "Foo/Bar.pm"

            But if you try this:

                    $class = 'Foo::Bar';
                    require $class;      # $class is not a bareword
                #or
                    require "Foo::Bar";  # not a bareword because of the ""

            The require function will look for the "Foo::Bar" file in the

            In this case you can do:

                    eval "require $class";

            For a yet-more-powerful import facility, see the use entry
            elsewhere in this document and the perlmod manpage.

It's worth spending some time reading the docs, and getting a feel for
what's happening.  Using the de{*filter*} and examining things like %INC, and
understanding the difference between perl's compile and run phases will
pay off handsomely.

Hope this helps,

Mike

--

http://www.*-*-*.com/ ~mike/       |
GPG PGP Key 1024D/059913DA         | Fingerprint      0570 71CD 6790 7C28 3D60



Tue, 18 Feb 2003 11:23:49 GMT  
 dynamic object instantiation using eval

Quote:

># This works:
>...
># This dies with "Can't find method new":
>package Foo;
>my $class = "MyPackage::MyClass";
>my $obj = eval $class . '->new($myargs)';

You're missing a C<require> to pull in MyPackage::MyClass.
And you don't need an eval to invoke the constructor:

   eval "require $class";

   $class->new($myargs);

Quote:
># this dies with can't find MyPackage::MyClass;
>package Foo;
>my $class = "MyPackage::MyClass";
>require $class;

That'd only work with a bareword, e.g.,

  require MyPackage::MyClass;

again in this case you'll need:

  eval "require $class";

perldoc -f require for details.

--
Charles DeRykus



Tue, 18 Feb 2003 12:47:17 GMT  
 dynamic object instantiation using eval

Paul> # This dies with "Can't find method new":
Paul> package Foo;
Paul> my $class = "MyPackage::MyClass";
Paul> my $obj = eval $class . '->new($myargs)';

That's too much work.  What's wrong with just:

        $class->new($myargs)

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095

Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!



Tue, 18 Feb 2003 21:22:13 GMT  
 dynamic object instantiation using eval

Quote:

>>my $obj = eval $class . '->new($myargs)';

[...]

Quote:
>You are aware that $myargs will not interpolate inside single quotes,
>so you may have a problem there.

Mike, you blithering idiot.  The eval will see the $myargs and do the
interpolation.  

This may be the effect the poster wanted ... but the s at the end of
$myargs triggered a reaction.  In the de{*filter*}:


  DB<2> $myargs = "foo, bar"

  DB<3> eval "func($myargs)"
Arg count: 2

  DB<4> eval 'func($myargs)'
Arg count: 1

Mike

--

http://www.*-*-*.com/ ~mike/       |
GPG PGP Key 1024D/059913DA         | Fingerprint      0570 71CD 6790 7C28 3D60



Tue, 18 Feb 2003 21:52:33 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Perl5 object instantiation

2. Using "dynamic" object constructors

3. Test for eval() without using eval() ??

4. eval chokes on indirect object syntax within a module

5. (Un)marshalling objects without eval-ing ?

6. OS-specific class instantiation

7. s// using lexicals and refs in an eval'ed string

8. Using eval() for subroutine unwind

9. using here document with eval fails

10. Using eval to iterate over a set of Perl variables

11. Using eval

12. Using Eval Statement To Trap Module Not Present Fatal Error

 

 
Powered by phpBB® Forum Software