Perl 子例程可以返回数据但继续处理吗?
有没有办法让子程序在处理的同时发送回数据?例如(此示例仅用于说明)- 子例程读取文件。当它读取文件时,如果满足某些条件,则“返回”该行并继续处理。我知道有些人会回答——你为什么要这么做?为什么你不只是......?,但我真的很想知道这是否可能。
Is there any way to have a subroutine send data back while still processing? For instance (this example used simply to illustrate) - a subroutine reads a file. While it is reading through the file, if some condition is met, then "return" that line and keep processing. I know there are those that will answer - why would you want to do that? and why don't you just ...?, but I really would like to know if this is possible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
实现此类功能的常见方法是使用回调函数:
或者甚至不命名回调:
A common way to implement this type of functionality is with a callback function:
or without even naming the callback:
某些语言使用 “生成器” 或 "协程",但 Perl 没有。上面链接的生成器页面包含 Python、C# 和 Ruby(以及其他语言)的示例。
Some languages offer this sort of feature using "generators" or "coroutines", but Perl does not. The generator page linked above has examples in Python, C#, and Ruby (among others).
Coro 模块看起来对此很有用问题,尽管我不知道它是如何工作的,也不知道它是否按照其广告宣传的那样工作。
The Coro module looks like it would be useful for this problem, though I have no idea how it works and no idea whether it does what it advertises.
在 Perl 中执行此操作的最简单方法可能是使用迭代器类型的解决方案。例如,这里我们有一个子例程,它形成一个 闭包 在文件句柄上:
子程序遍历各行,直到找到与模式
/foo/
匹配的行,然后返回它,否则不返回任何内容。 (标量上下文中的undef
。)因为文件句柄$fh
是在子范围之外定义的,所以它在调用之间仍然驻留在内存中。最重要的是,它的状态,包括文件中当前的查找位置,都会被保留。因此,每次调用子例程都会从上次停止的位置继续读取文件。要使用迭代器:
The easiest way to do this in Perl is probably with an iterator-type solution. For example, here we have a subroutine which forms a closure over a filehandle:
The sub iterates over the lines until it finds one matching the pattern
/foo/
and then returns it, or else returns nothing. (undef
in scalar context.) Because the filehandle$fh
is defined outsite the scope of the sub, it remains resident in memory between calls. Most importantly, its state, including the current seek position in the file, is retained. So each call to the subroutine resumes reading the file where it last left off.To use the iterator:
如果您确实想这样做,可以使用线程。一种选择是分叉一个单独的线程来读取文件,当它找到某一行时,将其放置在线程之间共享的数组中。然后另一个线程可以获取找到的行并处理它们。下面是一个读取文件、在文件行中查找“X”并在找到时执行操作的示例。
尝试将此代码作为 test.txt 文件:
If you really want do this you can by using threading. One option would be to fork a separate thread that reads the file and when it finds a certain line, place it in an array that is shared between threads. Then the other thread could take the lines, as they are found, and process them. Here is an example that reads a file, looks for an 'X' in a file's line, and does an action when it is found.
Try this code as the test.txt file:
如果你的语言支持闭包,你也许可以这样做:
顺便说一句,该函数不会继续处理文件,它会在你调用它时运行,所以它可能不是你需要的。
(这是类似javascript的伪代码)
If your language supports closures, you may be able to do something like this:
By the way, the function would not keep processing the file, it would run just when you call it, so it may be not what you need.
(This is a javascript like pseudo-code)
递归子怎么样?重新
打开
现有文件句柄不会重置输入行号,因此它会从中断处继续。下面是一个示例,其中
process_file
子例程打印出包含 foo 的以空行分隔的"\n\n"
段落。What about a recursive sub? Re-
open
ing existing filehandles do not reset the input line number, so it carries on from where it's left off.Here is an example where the
process_file
subroutine prints out blank-line-separated"\n\n"
paragraphs that contain foo.