【问题标题】:How is the glob iterator stored between function calls?glob 迭代器如何在函数调用之间存储?
【发布时间】:2014-10-27 17:24:47
【问题描述】:

我对我的earlier question about glob 的回答发表了以下评论:

glob() 或 die 在不在函数调用中时可以正常工作。它可以重复调用并按预期工作。所以上面的两个文件是存在的。在函数失败中第四次调用 glob 三次 (main, function, main = success)。函数内的行为不同于函数内的行为。

ysth回复:

函数没有区别,但源代码中的每个 glob 运算符都是一个单独的迭代器,因此除非以某种方式循环返回,否则您不会看到问题

在以下代码中,为什么/在哪里/如何在调用之间保存来自 glob 运算符的迭代器?为什么它没有超出范围?我知道它在做什么,但看不到它在内存中的表现。

sub in_function {
    my $file = shift;

    glob($file) or die ("$file file was not found\n"); #this fails second time called
}

【问题讨论】:

  • 这个问题试图继续一个不存在的“线程”。 Stack Overflow 上的每个帖子都应该是独一无二的
  • 始终在可重用代码的列表上下文中使用 glob,除非您确定在尝试开始新迭代之前会耗尽迭代器
  • glob 没有链接到glob(3)?如果是这样,这取决于您对 glob 的实现。
  • @PatrickJ.S.:不,是上面的 perl 层显示了他遇到问题的迭代器
  • @Borodin 我同意,如果没有 OP 上一篇文章中的 cmets,这个问题可能会更好。简单地说“为什么/在哪里/如何在函数调用之间保存来自 glob 运算符的迭代器?”似乎是一个更好的问题。

标签: perl iterator


【解决方案1】:

它存储在由操作码地址(MY_CXT.x_GLOB_ENTRIES in ext/File-Glob/Glob.xsglob.xs)键入的每个解释器哈希中。

它由操作码的地址作为关键字,这意味着源中操作码的两个实例将具有不同的迭代器。

$ perl -E'say "".glob("{a,b}") for 1..2;'
a
b

$ perl -E'say "".glob("{a,b}"); say "".glob("{a,b}");'
a
a

它是每个解释器的事实意味着每个线程对于给定的操作码实例都有自己的迭代器。

$ perl -Mthreads -E'
   sub f { say "".glob("{a,b}"); }
   f() for 1..2;
'
a
b

$ perl -Mthreads -E'
   sub f { say "".glob("{a,b}"); }
   async { f() }->join for 1..2;
'
a
a

【讨论】:

  • 我知道多次调用 glob 正在被“保存”,但不确定调用之间的位置/方式。隐含堆栈指针指向哈希内存中的全局函数?看不到,烦死我了。
  • 它不在堆栈上。那是行不通的。必须在堆中。 C 的堆,在这种情况下。
  • 第二次调用函数如何知道在堆上的哪个位置引用先前创建的对象,在它停止的地方?在函数之外使用时,它可以工作。那么它在内存上有什么不同呢?好吧...我知道了,哇...说真的,一个人怎么会从文档中知道
  • 每个 op 实例的哈希中都有一个条目,以 op 实例的地址为键。没有两个操作实例具有相同的地址,并且操作的地址永远不会改变。
  • perl -E'sub in_function{ say "".glob("{a,b}"); } in_function(); in_function();' => a b 另一个插图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多