Perl:“变量将不会保持共享" [英] Perl: "Variable will not stay shared"

查看:99
本文介绍了Perl:“变量将不会保持共享"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我查找了一些有关此警告的答案,但是它们都没有帮助我,也没有使我真正理解Perl在这里所做的一切.这就是我想要做的事情:

I looked up a few answers dealing with this warning, but neither did they help me, nor do I truly understand what Perl is doing here at all. Here's what I WANT it to do:

sub outerSub {
  my $dom = someBigDOM;
  ...
  my $otherVar = innerSub();
  return $otherVar;

  sub innerSub {
    my $resultVar = doStuffWith($dom);
    return $resultVar;
  }
}

所以基本上,我有一个很大的DOM对象存储在$ dom中,如果可能的话,我不想在堆栈上传递.在outerSub中,正在发生需要innerSub的结果的事情. innerSub需要访问$ dom.当我这样做时,我收到警告变量$ dom将不会保持共享".

So basically, I have a big DOM object stored in $dom that I don't want to pass along on the stack if possible. In outerSub, stuff is happening that needs the results from innerSub. innerSub needs access to $dom. When I do this, I get this warning "Variable $dom will not stay shared".

我不明白的地方:

  1. 此警告是否与我有关?我的预期逻辑会在这里工作还是会发生奇怪的事情?

  1. Does this warning concern me here? Will my intended logic work here or will there be strange things happening?

如果它没有按预期工作:可以这样做吗?使局部变量对嵌套子可见?还是仅将其作为参数传递会更好?还是声明一个我们的"变量更好?

If it doesn't work as intended: is it possible to do that? To make a local var visible to a nested sub? Or is it better to just pass it as a parameter? Or is it better to declare an "our" variable?

如果我将其作为参数推送,是否会将具有其所有数据(可能有几个MB)的整个对象推送到堆栈上?还是我可以通过参考之类的内容?还是Perl自己单独处理该参数作为参考?

If I push it as a parameter, will the whole object with all its data (may have several MB) be pushed on the stack? Or can I just pass something like a reference? Or is Perl handling that parameter as a reference all by itself?

中的变量$ foo将不会保持共享状态" Perl中的警告/错误调用子例程时,有人在谈论匿名子例程,这将使之成为可能.我不明白它是如何工作的,从未使用过类似的东西.

In "Variable $foo will not stay shared" Warning/Error in Perl While Calling Subroutine, someone talks about an anonymous sub that will make this possible. I did not understand how that works, never used anything like that.

我根本不理解这种解释(可能是因为英语不是我的第一语言):当调用内部子例程时,它将看到外部子例程的变量值,与之前和期间一样.第一次调用外部子例程;在这种情况下,在第一次调用外部子例程完成之后,内部和外部子例程将不再共享该变量的公共值.:

I do not understand that explanation at all (maybe cause English is not my first language): "When the inner subroutine is called, it will see the value of the outer subroutine's variable as it was before and during the first call to the outer subroutine; in this case, after the first call to the outer subroutine is complete, the inner and outer subroutines will no longer share a common value for the variable.":

对外部子例程的第一次调用已完成?"是什么意思?
我的意思是:首先,我称外部子.外子称为内子.外部子程序当然仍在运行.一旦外部子项完成,内部子项也将完成.那么当内部子程序已经完成时,这仍然如何适用呢?那第一"电话呢?什么时候发生第二次"通话...抱歉,这种解释使我困惑不已.

What does "the first call to the outer subroutine is complete? mean"
I mean: first I call the outer sub. The outer sub calls the inner sub. The outer sub is of course still running. Once the outer sub is complete, the inner sub will be finished as well. Then how does any of this still apply when the inner sub is already finished? And what about the "first" call? When is the "second" call happening... sorry, this explanation confuses me to no end.

很抱歉有很多问题.也许有人至少可以回答其中的一些问题.

Sorry for the many questions. Maybe someone can at least answer some of them.

推荐答案

简而言之,第二次或更晚一次调用externalSub将具有与innerSub使用的变量不同的$ dom变量.您可以通过以下方法解决此问题:

In brief, the second and later times outerSub is called will have a different $dom variable than the one used by innerSub. You can fix this by doing this:

{
    my $dom;
    sub outerSub {
        $dom = ...
        ... innerSub() ...
    }
    sub innerSub {
        ...
    }
}

或执行以下操作:

sub outerSub {
    my $dom = ...
    *innerSub = sub {
        ...
    };
    ... innerSub() ...
}

或者这个:

sub outerSub {
    my $dom = ...
    my $innerSub = sub {
        ...
    };
    ... $innerSub->() ...
}

所有变量最初都是预先分配的,并且innerSub和externalSub共享相同的$ dom.离开范围时,perl将遍历在该范围中声明的词法变量,然后将其重新初始化.因此,在对outerSub的第一次调用完成时,它将获得一个新的$ dom.由于命名子是全局的,因此,innerSub不受此影响,并始终引用旧的$ dom.因此,如果第二次调用externalSub,则其$ dom和innerSub的$ dom实际上是单独的变量.

All the variables are originally preallocated, and innerSub and outerSub share the same $dom. When you leave a scope, perl goes through the lexical variables that were declared in the scope and reinitializes them. So at the point that the first call to outerSub is completed, it gets a new $dom. Because named subs are global things, though, innerSub isn't affected by this, and keeps referring to the old $dom. So if outerSub is called a second time, its $dom and innerSub's $dom are in fact separate variables.

因此,将声明移出externalSub或使用匿名子(在运行时新绑定到词法环境)都可以解决此问题.

So either moving the declaration out of outerSub or using an anonymous sub (which gets freshly bound to the lexical environment at runtime) fixed the problem.

这篇关于Perl:“变量将不会保持共享"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆