is IO::Handle
此类自 2017.06 版起在 Rakudo 中提供。
IO::CatHandle
类提供了一种创建 IO::Handle
的方法,该方法无缝地从多个 IO::Handle
和 IO::Pipe
源收集输入。
所有 IO::Handle
的方法都已实现,虽然尝试使用写入方法(目前)会引发异常;但可以在任何可以使用只读 IO::Handle
的地方使用 IO::CatHandle
。
方法§
method new§
method new(*, :, : = True,: = ["\n", "\r\n"], Str :, Bool :)
创建一个新的 IO::CatHandle
对象。
@handles
位置参数指示 IO::CatHandle
读取的句柄源,并且可以处理 Cool
、IO::Path
和 IO::Handle
(包括 IO::Pipe
)对象的混合集合。由于 IO::CatHandle
的输入正在处理(因此操作不会在 .new
调用期间发生,而仅在需要 @handles
的数据时发生),它将遍历 @handles
列表,按如下方式处理每个参数
未打开的
IO::Handle
对象将以与IO::Path
对象相同的方式打开;并且已经打开的
IO::Handle
对象的所有属性都将设置为调用者IO::CatHandle
的属性。
简而言之,所有 @handles
最终都作为 IO::Handle
对象结束,这些对象以与调用者 IO::CatHandle
相同的模式和属性打开。
有关 :&on-switch
命名参数的详细信息,请参阅 .on-switch
方法,默认情况下未设置。
命名参数 :$encoding
指定句柄的编码,并接受与 IO::Handle.encoding
相同的值。如果希望句柄处于二进制模式,请将命名参数 :$bin
设置为 True
。尝试同时指定已定义的 :$encoding
和 True
的 :$bin
是一个致命错误,会导致抛出 X::IO::BinaryAndEncoding
异常。如果既未设置 :$encoding
,也未将 :$bin
设置为真值,则句柄将默认为 utf8
编码。
参数 :$chomp
和 :$nl-in
与 IO::Handle
中的含义相同,并采用相同的值作为默认值。
方法 chomp§
method chomp(IO::CatHandle:) is rw
将调用者的 $.chomp
属性设置为分配的值。所有源句柄(包括活动句柄)都将使用提供的 $.chomp
值。
(my = 'foo'.IO).spurt: "A\nB\nC\n";(my = 'bar'.IO).spurt: "D\nE\n";with IO::CatHandle.new: ,
方法 nl-in§
method nl-in(IO::CatHandle:) is rw
将调用者的 $.nl-in
属性设置为分配的值,该值可以是 Str
或 List
的 Str
,其中每个 Str
对象都表示行尾字符串。所有源句柄(包括活动句柄)都将使用提供的 $.nl-in
值。请注意,源句柄边界始终被视为一个新的换行符。
(my = 'foo'.IO).spurt: "A\nB\nC";(my = 'bar'.IO).spurt: "DxEx";with IO::CatHandle.new: ,
方法 close§
method close(IO::CatHandle: --> True)
关闭当前活动的源句柄以及任何已打开的源句柄,并清空源句柄队列。与常规 IO::Handle
不同,在 IO::CatHandle
上通常不需要显式调用 .close
,因为仅仅耗尽所有输入就会关闭所有需要关闭的句柄。
with IO::CatHandle.new:
方法 comb§
method comb(IO::CatHandle: |args --> Seq)
读取句柄并处理其内容的方式与 Str.comb
相同,采用相同参数。在调用此方法时,实现可能会完全读取所有源句柄的内容。
(my = 'foo'.IO).spurt: 'foo';(my = 'bar'.IO).spurt: 'bar';IO::CatHandle.new(, ).comb(2).raku.say;# OUTPUT: «("fo", "ob", "ar").Seq»
方法 DESTROY§
method DESTROY(IO::CatHandle:)
调用 .close
。此方法不能直接使用,但会在垃圾回收期间调用。
方法 encoding§
multi method encoding(IO::CatHandle:)multi method encoding(IO::CatHandle: )
将调用者的 $.encoding
属性设置为提供的值。有效值与 IO::Handle.encoding
接受的值相同(使用值 Nil
切换到二进制模式)。所有源句柄(包括活动句柄)都将使用提供的 $.encoding
值。
(my = 'foo'.IO).spurt: 'I ♥ Raku';(my = 'bar'.IO).spurt: 'meow';with IO::CatHandle.new: ,
方法 eof§
method eof(IO::CatHandle: --> Bool)
如果读取操作已耗尽源句柄队列(包括最后一个句柄的内容),则返回 True
。注意:在检查源句柄队列时,调用此方法可能会导致一个或多个 .on-switch
调用,并且 源句柄队列可能会耗尽。
(my = 'foo'.IO).spurt: 'foo';(my = 'bar'.IO).spurt: 'bar';with IO::CatHandle.new: :on-switch, ,
此处应用于 IO::Handle.eof 的不可寻址句柄和空文件的相同注意事项。
方法 get§
method get(IO::CatHandle: --> Bool)
从句柄返回一行输入,新行字符串由 $.nl-in
属性 的值定义,如果 $.chomp
属性 设置为 True
,则该值将从行中移除。当没有更多输入时,返回 Nil
。当句柄 处于二进制模式 时,调用此方法会出错,从而导致抛出 X::IO::BinaryMode
异常。
(my = 'foo'.IO).spurt: "a\nb\nc";(my = 'bar'.IO).spurt: "d\ne";my = IO::CatHandle.new: , ;.say while = .get; # OUTPUT: «abcde»
方法 getc§
method getc(IO::CatHandle: --> Bool)
从句柄返回一个输入字符。在 IO::Handle.getc
中描述的所有注意事项都适用。当没有更多输入时,返回 Nil
。当句柄 处于二进制模式 时,调用此方法会出错,从而导致抛出 X::IO::BinaryMode
异常。
(my = 'foo'.IO).spurt: 'I ♥ Raku';(my = 'bar'.IO).spurt: 'meow';my = IO::CatHandle.new: , ;.say while = .getc; # OUTPUT: «I ♥ Rakumeow»
方法 handles§
定义为
method handles(IO::CatHandle: --> Seq)
返回一个 Seq
,其中包含当前活动的句柄以及通过调用 next-handle 产生的所有剩余源句柄。如果调用者已被完全消耗,则返回一个空的 Seq
。
在处理 IO::ArgFiles
时,此方法特别方便,因为您希望分别处理每个文件句柄
# print at most the first 2 lines of each file in $*ARGFILES:.say for flat .handles.map: *.lines: 2
多次调用此方法是可以接受的;.handles.head
是获取当前活动句柄的有效习语。如果在返回的 Seq
的元素的 具体化 之间,句柄通过其他方式进行切换,则 Seq
产生的下一个元素将是调用者的下一个句柄,而不是如果没有发生切换,则会产生的句柄
(my := 'file1'.IO).spurt: "1a\n1b\n1c";(my := 'file2'.IO).spurt: "2a\n2b\n2c";(my := 'file3'.IO).spurt: "3a\n3b\n3c";my := IO::CatHandle.new: , , ;for .handles# OUTPUT: «(1a 1b)(3a 3b)»
同样,具体化返回的 Seq
会消耗调用者的源句柄,并且一旦完全具体化,调用者就会被完全消耗。
方法 IO§
method IO(IO::CatHandle:)
.path
的别名
方法 lines§
method lines(IO::CatHandle: = Inf, : --> Seq)
与 IO::Handle.lines
相同。请注意,源句柄之间的边界被认为是换行符。
(my = 'foo'.IO).spurt: "foo\nbar";(my = 'bar'.IO).spurt: 'meow';IO::CatHandle.new(, ).lines.raku.say;# OUTPUT: «("foo", "bar", "meow").Seq»
注意:如果 :$close
为 False
,则完全消耗的句柄仍然会被关闭。
方法 lock§
method lock(IO::CatHandle: Bool : = False, Bool : = False --> True)
与 IO::Handle.lock
相同。如果 源句柄队列已用尽,则返回 Nil
。
仅锁定当前活动的源句柄。 .on-switch
Callable
可用于在 CatHandle 处理句柄时方便地锁定/解锁句柄。
方法 native-descriptor§
method native-descriptor(IO::CatHandle: --> Int)
返回当前活动的源句柄的 native-descriptor,如果 源句柄队列已用尽,则返回 Nil
。
由于 CatHandle
在完成后会关闭源句柄,因此如果源句柄作为 Cool
或 IO::Path
对象传递给 .new,则连续的源句柄可能具有相同的本机描述符。
(my = 'foo'.IO).spurt: 'foo';(my = 'bar'.IO).spurt: 'bar';with IO::CatHandle.new: , ,
方法 next-handle§
method next-handle(IO::CatHandle: --> IO::Handle)
将活动源句柄切换到源句柄队列中的下一个句柄,该句柄是 .new
中 @handles
属性中给出的源。
将 Cool
源“句柄”强制转换为 IO::Path
;使用调用者的 $.nl-in
、$.chomp
和 $.encoding
属性打开 IO::Path
和未打开的 IO::Handle
源句柄以进行读取;已打开的 IO::Handle
对象的相同属性将更改为调用者属性的值。
每当 CatHandle 的方法需要切换到下一个源句柄时,都会自动调用此方法,触发 .on-switch
Callable
被调用,并在 .new 调用期间调用一次。即使源句柄队列已用尽,每次调用此方法时,.on-switch
仍将继续触发。请注意,通常达到当前活动源句柄的 EOF 不会触发 .next-handle
调用,而是需要更多数据的进一步读取操作。
(my = 'foo'.IO).spurt: "a\nb";(my = 'bar'.IO).spurt: "c\nd";with IO::CatHandle.new: :on-switch, ,
方法 on-switch§
has is rw
可以在 .new
调用期间设置并稍后通过赋值更改的属性之一。默认情况下未指定。采用 .count
为 0
、1
、2
或 Inf
的 Callable
。每次 .next-handle
时都会调用,这在 .new
调用期间发生一次,然后每次将源句柄切换到队列中的下一个句柄时,或手动调用 .next-handle
方法时都会发生。
如果 &.on-switch
的 .count
为 0
,则它不接收任何参数;如果为 1
,则它接收当前活动句柄;如果为 2
或 Inf
,则它接收当前活动句柄和最后一个活动句柄作为位置参数(按此顺序)。在第一次 &.on-switch
执行时,“最后一个活动句柄”参数为 Nil
。在源句柄队列耗尽时,“当前活动句柄”参数为 Nil
,并且之后进行的所有执行都将两个参数作为 Nil
。
(my = 'foo'.IO).spurt: "A\nB\nC";(my = 'bar'.IO).spurt: "D\nE";my ;my = IO::CatHandle.new: :on-switch, , ;say ": $_" for .lines;# OUTPUT:# foo:1 A# foo:2 B# foo:3 C# bar:1 D# bar:2 E
my ;sub on-switch (, )(my = 'foo'.IO).spurt: "A\nB\nC";(my = 'bar'.IO).spurt: "D\nE";my = IO::CatHandle.new: :, , ;.lines.raku.say; # OUTPUT: «("", "B", "C", "", "E").Seq».raku.say; # OUTPUT: «["A\nB\nC", "D\nE"]»
方法 open§
method open(IO::CatHandle: --> IO::CatHandle)
返回调用者。此方法的目的是仅使 CatHandle 可用于使用 IO::Handle
打开内容。您永远不必有意调用此方法。
方法 opened§
method opened(IO::CatHandle: --> Bool)
如果调用者有任何源句柄,则返回 True
,否则返回 False
。
say IO::CatHandle.new .opened; # OUTPUT: «False»say IO::CatHandle.new().opened; # OUTPUT: «True»(my = 'foo'.IO).spurt: "A\nB\nC";with IO::CatHandle.new:
方法 path§
method path(IO::CatHandle:)
返回当前活动源句柄的 .path
属性的值,或者如果 IO/CatHandle#method_next-handle
源句柄队列已耗尽,则返回 Nil
。基本上,如果您的 CatHandle 基于文件,这是获取 CatHandle 当前正在从中读取的文件路径的方法。
(my = 'foo'.IO).spurt: "A\nB\nC";(my = 'bar'.IO).spurt: "D\nE";my ;my = IO::CatHandle.new: :on-switch, , ;say ": $_" for .lines;# OUTPUT:# foo:1 A# foo:2 B# foo:3 C# bar:1 D# bar:2 E
方法 read§
method read(IO::CatHandle: Int(Cool) = 65536 --> Buf)
从句柄中读取最多 $bytes
字节,并在 Buf
中返回它们。$bytes
默认为实现特定的值(在 Rakudo 中,$*DEFAULT-READ-ELEMS
的值,默认设置为 65536
)。允许对非二进制模式的句柄调用此方法。
(my = 'foo'.IO).spurt: 'meow';(my = 'bar'.IO).spurt: Blob.new: 4, 5, 6;with IO::CatHandle.new: :bin, ,# Non-binary mode is OK too:with IO::CatHandle.new: ,
方法 readchars§
method readchars(IO::CatHandle: Int(Cool) = 65536 --> Str)
返回从句柄中读取的最多 $chars
个字符的 Str
。$chars
默认为实现特定的值(在 Rakudo 中,$*DEFAULT-READ-ELEMS
的值,默认设置为 65536
)。不允许对以二进制模式打开的句柄调用此方法,这样做会导致抛出 X::IO::BinaryMode
异常。
(my = 'foo'.IO).spurt: 'Raku loves to';(my = 'bar'.IO).spurt: ' meow';with IO::CatHandle.new: ,
方法 seek§
method seek(IO::CatHandle: |c)
在当前活动源句柄上调用 .seek
,将所有参数转发给它,并返回结果。如果 IO/CatHandle#method_next-handle
源句柄队列已耗尽,则返回 Nil
。注意:此方法不会执行任何源句柄切换,因此在当前源句柄的末尾之后进行搜索不会搜索队列中的下一个源句柄,并且在当前源句柄的开头之后进行搜索是致命错误。另请参阅 .next-handle
,以了解有关何时切换源句柄的详细信息。
(my = 'foo'.IO).spurt: 'foo';(my = 'bar'.IO).spurt: 'bar';with IO::CatHandle.new: ,
方法 tell§
method tell(IO::CatHandle: --> Int)
在当前活动源句柄上调用 .tell
并返回结果。如果 源句柄队列已耗尽,则返回 Nil
。
(my = 'foo'.IO).spurt: 'foo';(my = 'bar'.IO).spurt: 'bar';with IO::CatHandle.new: ,
方法 slurp§
method slurp(IO::CatHandle:)
读取所有源句柄的所有可用输入,如果句柄处于 二进制模式,则以 Buf
形式返回,否则以 Str
形式返回。如果 源句柄队列已耗尽,则返回 Nil
。
(my = 'foo'.IO).spurt: 'foo';(my = 'bar'.IO).spurt: 'bar';IO::CatHandle.new( , ).slurp.say; # OUTPUT: «foobar»IO::CatHandle.new(:bin, , ).slurp.say; # OUTPUT: «Buf[uint8]:0x<66 6f 6f 62 61 72>»IO::CatHandle.new .slurp.say; # OUTPUT: «Nil»
方法 split§
method split(IO::CatHandle: |args --> Seq)
读取句柄并处理其内容,处理方式与 Str.split
相同,采用相同的参数。实现可能会在调用此方法时完全吸收所有源句柄的内容。
(my = 'foo'.IO).spurt: 'foo';(my = 'bar'.IO).spurt: 'bar';IO::CatHandle.new(, ).split(/o+/).raku.say;# OUTPUT: «("f", "bar").Seq»
方法 Str§
method Str(IO::CatHandle: --> Str)
在当前活动源句柄上调用 .Str
并返回结果。如果 源句柄队列已耗尽,则返回一个实现定义的字符串(在 Rakudo 中为 '<closed IO::CatHandle>'
)。
方法 Supply§
method Supply(IO::CatHandle: : = 65536 --> Supply)
返回一个 Supply
,该 Supply
由 .read
(如果句柄处于 二进制模式)或 .readchars
(如果句柄不处于二进制模式)提供支持,读取 :$size
字节或字符。:$size
默认为实现特定的值(在 Rakudo 中,为 $*DEFAULT-READ-ELEMS
的值,默认设置为 65536
)。
(my = 'foo'.IO).spurt: 'foo';(my = 'bar'.IO).spurt: 'bar';react whenever IO::CatHandle.new(, ).Supply: :2size# OUTPUT: «foobar»react whenever IO::CatHandle.new(:bin, , ).Supply: :2size# OUTPUT: «Buf[uint8]:0x<66 6f>Buf[uint8]:0x<6f 62>Buf[uint8]:0x<61 72>»
方法 t§
method t(IO::CatHandle: --> Bool)
在当前活动源句柄上调用 .t
,该方法会告知句柄是否是 TTY,并返回结果。如果 源句柄队列已耗尽,则返回 False
。
(my = 'foo'.IO).spurt: 'foo';with IO::CatHandle.new: ,
方法 unlock§
method unlock(IO::CatHandle:)
与 IO::Handle.unlock
相同。如果 源句柄队列已耗尽,则返回 Nil
。
仅解锁当前活动的源句柄。可以使用 .on-switch
Callable
在 CatHandle 处理句柄时方便地锁定/解锁句柄。
方法 words§
method words(IO::CatHandle: = Inf, : --> Seq)
与 IO::Handle.words
相同(包括有关读取比生成一定数量的单词所需更多数据的警告)。请注意,源句柄之间的边界被视为单词边界。
(my = 'foo'.IO).spurt: 'foo bar';(my = 'bar'.IO).spurt: 'meow';IO::CatHandle.new(, ).words.raku.say;# OUTPUT: «("foo", "bar", "meow").Seq»
注意:如果 :$close
为 False
,则完全消耗的句柄仍然会被关闭。