true_atlantis has asked for the wisdom of the Perl Monks concerning the following question:

Is there a way to create an object where the type is a variable? For example:
use test::object; my $x='test::object'; my $y=($x)->new();

I am using this in a more complicated manner, but this shows the basic idea of whatI am trying to do. I want $y to be of type test::object but using the variable $x to 'cast' it. Thanks.

Replies are listed 'Best First'.
Re: create an object where type is a variable
by ikegami (Patriarch) on Sep 11, 2007 at 15:26 UTC
    Your code works as is. The parens are not needed, by the way.
      "Works", presuming for any value of $x, the corresponding class understands an empty new call to mean "return a reasonable object of type $x". Have to say this since there's absolutely nothing special about calling new: it's just a method call.
        Ahh... my problem was that i was trying to do something like this:
        use test::object; my $x='object'; my $y=test::$x->new();

        That didnt work, and i just realized it was because you have to concat the 'test::' and $x... just in case anyone is running into the same issue, it would look like this:
        use test::object; my $x='object'; my $y=test::.$x->new();

        Thank you everyone.
Re: create an object where type is a variable
by leocharre (Priest) on Sep 11, 2007 at 15:48 UTC
    How weird, I didn't know..
    #!/usr/bin/perl -w use Test::Simple 'no_plan'; use strict; use warnings; use CGI::Session; my $x = 'CGI::Session'; my $z = 'new'; my $y = $x->$z; ok($y,'instanced'); print STDERR $y->header;
    output:
    loot@moonshine dev# perl /tmp/test.pl
    ok 1 - instanced
    Set-Cookie: CGISESSID=71079ce5211b3e460f8924c780ff9c0b; 
    Date: Tue, 11 Sep 2007 15:48:01 GMT
    Content-Type: text/html; charset=ISO-8859-1
    
    1..1
    
Re: create an object where type is a variable
by naikonta (Curate) on Sep 11, 2007 at 15:57 UTC
    Yes, no problem. You can also use a variable in the whole process. For example if you need to load a series of modules,
    my %objects; for my $class (@available_classes) { eval qq(require $class); if ($@) { # you can make it die() here, if you want warn "Failed to load class '$class': $@"; next; } $objects{$class} = $class->new; }
    Because the way require works, you have to eval the require $class statement in double quotes so the $class becomes bareword.

    Or, you may have to pick a correct class by certain criteria. You can use UNIVERSAL::require in place of the eval statement and $@ checking.

    use UNIVERSAL::require; my $class = get_implementor_class(); #defined somewhere $class->use or die $@; my $object = $class->new;

    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!