CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Instantiating a class when name is in variable?

 



DrewJones
Novice

Jan 11, 2005, 8:15 PM

Post #1 of 13 (1274 views)
Instantiating a class when name is in variable? Can't Post

How would I go about instantiating this...

require 'path/to/' . $name . '.pm';

$obj = new ???;


davorg
Thaumaturge / Moderator

Jan 13, 2005, 5:15 AM

Post #2 of 13 (1256 views)
Re: [DrewJones] Instantiating a class when name is in variable? [In reply to] Can't Post

For example:

In Foo.pm


Code
package Foo; 

sub new {
bless {}, shift;
}

sub check {
print "This is a Foo\n";
}

1;


In test.pl


Code
#!/usr/bin/perl 

use strict;
use warnings;

my $class = 'Foo';

require "./$class.pm";

my $foo = $class->new;

$foo->check;


And running test.pl


Code
$ ./test.pl 
This is a Foo
$


You can use "$foo = new $class" instead, but it's not advised for all the usual reasons for avoiding indirect object notation.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


DrewJones
Novice

Jan 13, 2005, 7:34 AM

Post #3 of 13 (1255 views)
Re: [davorg] Instantiating a class when name is in variable? [In reply to] Can't Post

Interesting...the following fails on my box. In addition, the 'use lib' array won't take entries with variables either.

require "./$class.pm";

use lib ('./modules', './modules/' . $special_dir, './');

Grr...


davorg
Thaumaturge / Moderator

Jan 13, 2005, 7:40 AM

Post #4 of 13 (1253 views)
Re: [DrewJones] Instantiating a class when name is in variable? [In reply to] Can't Post

Can we see more of the code - specifically the bits that set $class and $special_dir. And which directory are your modules in?

Remember that the "use lib" line is executed at compile time, so $special_dir won't have a value at that point unless it's been set in a BEGIN block.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


DrewJones
Novice

Jan 13, 2005, 8:47 AM

Post #5 of 13 (1251 views)
Re: [davorg] Instantiating a class when name is in variable? [In reply to] Can't Post

Well, in it's simplest form ...

modules/conf.pm [
package conf;
%app::conf = (
host => 'localhost',
port => '3306',
...others...
theme => 'custom'
);
]

index.cgi [
#!/usr/bin/perl -w

package app;
use strict;
use warnings;
use modules::conf;
$themedir = './themes/' . $app::conf->{theme}; # has value if printed
use lib (
'./modules',
$themedir, # does not work
'./'
);
...more code...
]

structure of themes is
/themes/default/global.pm | index.pm | user.pm | admin.pm ...
/themes/custom/global.pm | index.pm | user.pm | admin.pm ...
/themes/other/global.pm | index.pm | user.pm | admin.pm ...


davorg
Thaumaturge / Moderator

Jan 13, 2005, 9:00 AM

Post #6 of 13 (1250 views)
Re: [DrewJones] Instantiating a class when name is in variable? [In reply to] Can't Post


In Reply To
index.cgi

Code
#!/usr/bin/perl -w 

package app;
use strict;
use warnings;
use modules::conf;
$themedir = './themes/' . $app::conf->{theme}; # has value if printed
use lib (
'./modules',
$themedir, # does not work
'./'
);



As I hinted at in my last email, the problem is that the "use lib" line is executed at compile time, but $themedir isn't given a value until runtime (which is later).

Try putting the code which sets $themedir into a BEGIN block. I mean, replace the line:


Code
$themedir = './themes/' . $app::conf->{theme};


with


Code
BEGIN { 
$themedir = './themes/' . $app::conf->{theme};
}


--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


DrewJones
Novice

Jan 13, 2005, 9:05 AM

Post #7 of 13 (1249 views)
Re: [davorg] Instantiating a class when name is in variable? [In reply to] Can't Post

I will do that and reply in a while with resolution state.


DrewJones
Novice

Jan 13, 2005, 9:40 AM

Post #8 of 13 (1245 views)
Re: [DrewJones] Instantiating a class when name is in variable? [In reply to] Can't Post

One more question for now. I am trying to avoid namespace conflicts between two modules with the same name. Would the following also work?

$mod = 'themes::theme::global';
BEGIN { use $mod; }
$skin = $mod->new;

$mod = 'themes::lang::global';
BEGIN { use $mod; }
$lang = $mod->new;


MrPJ
User

Jan 15, 2005, 4:23 PM

Post #9 of 13 (1232 views)
Re: [davorg] Instantiating a class when name is in variable? [In reply to] Can't Post

As a side note, you can also do...


Code
lib->import($themedir);



davorg
Thaumaturge / Moderator

Jan 16, 2005, 12:44 AM

Post #10 of 13 (1220 views)
Re: [DrewJones] Instantiating a class when name is in variable? [In reply to] Can't Post


In Reply To
One more question for now. I am trying to avoid namespace conflicts between two modules with the same name. Would the following also work?

Code
$mod = 'themes::theme::global'; 
BEGIN { use $mod; }
$skin = $mod->new;

$mod = 'themes::lang::global';
BEGIN { use $mod; }
$lang = $mod->new;



Er.. no. That won't work for exactly the same reason that I've been trying to explain to you for the last few days :)

The "use" statements will be excuted at compile time and the statements setting $mod are't excuted until runtime. You need to give values to $mod inside a BEGIN block.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


DrewJones
Novice

Jan 16, 2005, 8:55 AM

Post #11 of 13 (1217 views)
Re: [davorg] Instantiating a class when name is in variable? [In reply to] Can't Post

My bad...assuming BEGIN blocks are compile time and the variable I need to set isn't known until runtime, there's simply no way to do it this way period right? For example, the $global var must be set at runtime because it comes from a database and might be any number of values. The following will still not work. If I am correct, I think I get it now. Correct me if I'm wrong.

BEGIN {

$mod = 'themes::lang::$global';
use $mod;


}
$lang = $mod->new;



davorg
Thaumaturge / Moderator

Jan 16, 2005, 10:48 AM

Post #12 of 13 (1216 views)
Re: [DrewJones] Instantiating a class when name is in variable? [In reply to] Can't Post

Well, I'm always loathe to say that some something _can't_ be done in Perl.

What's to stop you setting $global in a BEGI block too?

Or it's that's no possible, then can you "require" your module instead of "use"ing it? "require" happens at runtime.

--
Dave Cross, Perl Hacker, Trainer and Writer
http://www.dave.org.uk/
Get more help at Perl Monks


DrewJones
Novice

Jan 16, 2005, 10:53 AM

Post #13 of 13 (1215 views)
Re: [davorg] Instantiating a class when name is in variable? [In reply to] Can't Post

I got that. I just wanted to make sure I got the concept of compile time vs runtime.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives