Tôi đã thấy nhiều lần trong các File.open
cuộc gọi chưa từng có mã ruby
Bạn có thể đưa ra một ví dụ không? Tôi chỉ thấy rằng trong mã được viết bởi những người mới thiếu "kiến thức phổ biến trong hầu hết các ngôn ngữ lập trình rằng quy trình làm việc với các tệp là mở-sử dụng-đóng".
Các Rubyists có kinh nghiệm hoặc đóng tệp của họ một cách rõ ràng, hoặc nói một cách dễ hiểu hơn, sử dụng biểu mẫu khối File.open
để tự động đóng tệp cho bạn. Việc triển khai của nó về cơ bản trông giống như sau:
def File.open(*args, &block)
return open_with_block(*args, &block) if block_given?
open_without_block(*args)
end
def File.open_without_block(*args)
# do whatever ...
end
def File.open_with_block(*args)
yield f = open_without_block(*args)
ensure
f.close
end
Tập lệnh là một trường hợp đặc biệt. Các tập lệnh thường chạy quá ngắn và sử dụng quá ít bộ mô tả tệp nên việc đóng chúng chỉ đơn giản là không hợp lý, vì hệ điều hành sẽ đóng chúng lại khi tập lệnh thoát.
Chúng ta có cần phải đóng một cách rõ ràng không?
Đúng.
Nếu có thì tại sao GC tự động đóng?
Bởi vì sau khi nó đã thu thập đối tượng, không có cách nào để bạn đóng tệp nữa, và do đó bạn sẽ làm rò rỉ các bộ mô tả tệp.
Lưu ý rằng nó không phải là trình thu gom rác đóng các tệp. Bộ thu gom rác chỉ đơn giản là thực thi bất kỳ trình hoàn thiện nào cho một đối tượng trước khi nó thu thập nó. Nó chỉ xảy ra khi File
lớp xác định một trình hoàn thiện đóng tệp.
Nếu không thì tại sao tùy chọn?
Bởi vì bộ nhớ lãng phí là rẻ, nhưng bộ mô tả tệp lãng phí thì không. Do đó, không có ý nghĩa gì khi buộc thời gian tồn tại của bộ mô tả tệp với thời gian tồn tại của một số đoạn bộ nhớ.
Bạn chỉ đơn giản là không thể dự đoán khi nào trình thu gom rác sẽ chạy. Bạn thậm chí không thể đoán được liệu nó có chạy hết hay không : nếu bạn không bao giờ hết bộ nhớ, trình thu gom rác sẽ không bao giờ chạy, do đó trình hoàn thiện sẽ không bao giờ chạy, do đó tệp sẽ không bao giờ bị đóng.