我寫了一個簡單的 ruby?? Fiber 程式來看看它們是如何作業的,并得到了意想不到的結果。
#! /usr/bin/env ruby
#encoding: utf-8
#frozen_string_literal: true
sg = Fiber.new do
File.open(begin print "Enter filename: "; gets.chomp end).each{|l| Fiber.yield l}
end
begin
loop do
puts sg.resume
end
rescue => err
puts "Error: #{err.message}"
end
資料檔案
This is the first
This is the second
This is the third
This is the fourth
This is the fifth
以及上述程式的輸出
Enter filename: datafile
This is the first
This is the second
This is the third
This is the fourth
This is the fifth
#<File:0x0000557ce26ce3c8>
Error: attempt to resume a terminated fiber
我不確定為什么它在輸出中顯示#File:0x0000557ce26ce3c8。
注意:ruby 3.0.2p107(2021-07-07 修訂版 0db68f0233)[x86_64-linux-gnu]
uj5u.com熱心網友回復:
從檔案中,
在產生或終止時,
Fiber回傳最后執行的運算式的值
除了Fiber.yield呼叫,一個纖程(就像一個普通函式)回傳纖程中最終運算式的結果。
你的纖維體是這樣的。
File.open(begin print "Enter filename: "; gets.chomp end).each{|l| Fiber.yield l}
在 中.each,您生成檔案的每一行,正如您已經觀察到的那樣,它們會被列印出來。但是,當纖維完成后,它會產生一個最終值,這是 的結果File.open。并File.open回傳File物件本身。所以你sg.resume實際上看到了六個結果,而不是五個。
"This is the first"
"This is the second"
"This is the third"
"This is the fourth"
"This is the fifth"
(the file object itself)
這實際上指出了您程式中的一個小問題:您永遠不會關閉檔案。您可以使用File#close或通過將塊傳遞給File::open. 為了完全安全,您的光纖代碼應該如下所示。
sg = Fiber.new do
print "Enter filename: "
filename = gets.chomp
# By passing File.open a block, the file is closed after the block automatically.
File.open(filename) do |f|
f.each{|l| Fiber.yield l}
end
# Our fiber has to return something at the end, so let's just return nil
nil
end
begin
loop do
# Get the value. If it's nil, then we're done; we can break out of the loop.
# Otherwise, print it
value = sg.resume
break if value.nil?
puts value
end
rescue => err
puts "Error: #{err.message}"
end
現在,除了處理那個討厭的檔案句柄之外,我們還有一種方法可以檢測光纖何時完成并且我們不再收到“嘗試恢復終止的光纖”錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/495319.html
標籤:红宝石
上一篇:如何通過api獲取媒體url
