"AUTOLOAD" for variables?

C

cyl

When an AUTOLOAD function is implemented, I can do something such as
delegating a nonexistent method to another package. I'm wondering if
there is a similar way to do this for variables exported by a module?
Here is my demonstration sample code

#### main.pl ####
use TestA;
use TestB;

TestB::FuncA();
print $TestB::VarA;



#### TestA.pm ####
package TestA;

@ISA = qw(Exporter);
@EXPORT = qw($VarA);

our $VarA = "VarA";

sub FuncA
{
print "TestA\n";
}

#### TestB.pm ####
package TestB;

#our $VarA = $TestA::VarA;
1;

sub AUTOLOAD
{
$AUTOLOAD =~ s/TestB/TestA/;
&$AUTOLOAD;
}

__END__

Running the script will get TestA::FuncA invoked but $TestB::VarA
undefined unless I remove the comment in TestB.pm. I want to know a
method that can do the transparent relay for a nonexistent variable in
TestB to TestA. Thanks.
 
B

Ben Morrow

Quoth cyl said:
When an AUTOLOAD function is implemented, I can do something such as
delegating a nonexistent method to another package. I'm wondering if
there is a similar way to do this for variables exported by a module?

No, there isn't. Why do you want to do this? This implies you have a
variable name that isn't known until runtime, which in turn implies you
should be storing these variables in an ordinary hash instead of in the
symbol table.

Ben
 
C

cyl

No, there isn't. Why do you want to do this? This implies you have a
variable name that isn't known until runtime, which in turn implies you
should be storing these variables in an ordinary hash instead of in the
symbol table.

Ben

In my case, TestA is fixed so I cannot modify it. TestB is a wrapper
of TestA and its job is to relay the actions to TestA. There are also
TestC or TestD that plays the same role as TestB. I don't want to
access TestA directly. Instead I want to use the wrapper. The current
problem is I need to define the constants exported by TestA in TestB,
TestC and TestD which does not make sense to me. Maybe there is a
better design. If so I'm glad to know that. Thanks.
 
B

Ben Morrow

Quoth cyl said:
[re: AUTOLOADing variables]

No, there isn't. Why do you want to do this? This implies you have a
variable name that isn't known until runtime, which in turn implies you
should be storing these variables in an ordinary hash instead of in the
symbol table.

In my case, TestA is fixed so I cannot modify it. TestB is a wrapper
of TestA and its job is to relay the actions to TestA. There are also
TestC or TestD that plays the same role as TestB. I don't want to
access TestA directly. Instead I want to use the wrapper. The current
problem is I need to define the constants exported by TestA in TestB,
TestC and TestD which does not make sense to me. Maybe there is a
better design. If so I'm glad to know that. Thanks.

When you say 'exported', do you mean with Exporter? In which case they
are listed in @TestA::EXPORT_OK.

In any case, you can do something like

package TestB;

use TestA;

for (keys %TestA::) {
no strict 'refs';
*$_ = \*{"TestA::$_"};
}

to alias everything from TestA to TestB.

Ben
 
C

cyl

In any case, you can do something like

package TestB;

use TestA;

for (keys %TestA::) {
no strict 'refs';
*$_ = \*{"TestA::$_"};
}

to alias everything from TestA to TestB.

This way is so cool. It does work. Thanks very much. May I ask an
additional question? When there is a package in TestA, say
TestA::SubPackageA, I can see a key "SubPackageA::" in %TestA but I
can not use "new TestB::SubPackageA;" to do the same alias mapping. Is
there a way to work this out? Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top