我的程序创建了一个对象,反过来又创建了另一个对象
MainScript.pm
use module::FirstModule qw ($hFirstModule); $hFirstModule->new(parametres); $hFirstModule->function();
FirstModule.pm
use Exporter (); @EXPORT = qw($hFirstModule); use module::SecondModule qw ($hSecondModule); sub new { my $className = shift; my $self = { key => 'val' }; bless $self,$classname; return $self; } sub function{ $hSecondModule->new(parametres); #some other code here }
我想从MainScript.pm访问$hSecondModule.
解决方法
这是一个非常hacky的方法,考虑到您的更新代码.它使用
Sub::Override来获取对SecondModule东西的构造函数调用的返回值.这通常可以在单元测试中进行,但不能在生产代码中进行.但是,它应该工作.这是一个例子.
Foo.pm
package Foo; use Bar; sub new { return bless {},$_[0]; } sub frobnicate { Bar->new; return; }
Bar.pm
package Bar; sub new { return bless {},$_[0]; } sub drink { return 42; # because. }
script.pl
package main; use Foo; # this will load Bar at compile time use Sub::Override; my $foo = Foo->new; my $bar; # this is lexical to the main script,so we can use it inside my $orig = \&Bar::new; # grab the original function my $sub = Sub::Override->new( "Bar::new" => sub { my $self = shift; # call the constructor of $hSecondModule,grab the RV and assign # it to our var from the main script $bar = $self->$orig(@_); return $bar; } ); $foo->frobnicate; # restore the original sub $sub->restore; # $bar is now assigend print $bar->drink;
同样,我不会在生产代码中这样做.
我们来看看主要功能.它首先创建一个新的Foo对象.然后它抓取对Bar :: new函数的引用.我们需要它作为原始,所以我们可以调用它来创建对象.然后我们使用Sub :: Override将Bar :: new暂时替换为调用原始的sub,但是获取返回值(即对象)并将其分配给我们对主脚本有词汇的变量.然后我们归还它.
现在,当$foo-> frobnicate调用Bar-> new时,将调用此函数.在该调用之后,我们的主脚本中填充了$bar.然后我们恢复Bar :: new,这样我们就不会意外覆盖我们的$bar,以防再次从其他地方调用.
之后,我们可以使用$bar.
请注意,这是先进的.我再说一遍,我不会在生产代码中使用这种黑客攻击.可能有更好的方法来做你想要的.这里可能存在x / y问题,您需要更好地解释为什么需要这样做,以便我们找到一个不那么疯狂的解决方案.