使用ARGF使用管道的两种方式之间的区别?

时间:2015-04-27 12:06:39

标签: ruby command-line pipeline

使用ARGF我可以创建尊重管道的Ruby程序。假设,我不断阅读新条目:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Subtype: KERN_PROTECTION_FAILURE at 0x090d3330
Triggered by Thread:  13

    Thread 13 name:  Dispatch queue: com.apple.root.default-qos
Thread 13 Crashed:
0   ???                                  0x090d3330 0 + 151860016
1   CoreGraphics                         0x22886b6c 0x22874000 + 76652
2   CoreGraphics                         0x228a036e 0x22874000 + 181102
3   MyApplication                        0x001c8062 0xb6000 + 1122402
4   QuartzCore                           0x256d08fc 0x25695000 + 243964
5   QuartzCore                           0x257a9e86 0x25695000 + 1134214
6   QuartzCore                           0x256fdd14 0x25695000 + 429332
7   libdispatch.dylib                    0x30f99866 0x30f8b000 + 59494
8   libdispatch.dylib                    0x30f9a89e 0x30f8b000 + 63646
9   libsystem_pthread.dylib              0x3110eda6 0x3110e000 + 3494
10  libsystem_pthread.dylib              0x3110eaf8 0x3110e000 + 2808

我可以这样做:

$ tail -f log/test.log | my_prog

另外,我找到了另一种方式:

ARGF.each_line do |line|
 ...
end

看起来,这两种变体都做同样的事情或它们之间有区别吗?如果是这样,它是什么?

提前致谢。

1 个答案:

答案 0 :(得分:1)

正如Stefan所说,你在第二种情况下犯了一点错误。正确使用" ARGF.gets"在您的情况下,方法将如下所示:

while input = ARGF.gets
  # input here represents a line
end

如果你重写上面的第二个例子,你的行为就没有区别了。

ARGF#getsARGF#each_line之间您可能会注意到的实际差异在于语义:each_line接受阻止或返回枚举数,gets返回下一行(如果可用)。< / p>

另一种选择是使用Kernel#gets。请注意,在某些情况下,它的行为可能与ARGF#gets不同,尤其是在您更改分隔符时:

  

nil的分隔符读取整个内容,零长度分隔符一次读取输入的一个段落,其中段落除以两个连续的换行符。

但是为了从stdin不断阅读(然后打印)你可以按如下方式使用它:

print while gets