Sự khác biệt giữa $ stdout và STDOUT trong Ruby


88

Trong Ruby, sự khác biệt giữa $stdout(đứng trước ký hiệu đô la) và STDOUT(viết hoa toàn bộ) là gì? Khi thực hiện chuyển hướng đầu ra, cái nào nên được sử dụng và tại sao? Tương tự đối với $stderrSTDERR.

Chỉnh sửa: Vừa tìm thấy một câu hỏi liên quan .


Có thể có bản sao của STDIN và $ stdin trong Ruby là gì?
Tín Man

@theTinMan Phần nào đó là một bản sao. Tuy nhiên, cần lưu ý rằng trong khi sự khác biệt giữa $stdoutSTDOUTvs $stdinSTDINlà đối xứng, thì sự khác biệt giữa $stdout$>vs $stdin$<không.
skalee

Câu trả lời:


105

$stdoutlà một biến toàn cục đại diện cho đầu ra tiêu chuẩn hiện tại. STDOUTlà một hằng số đại diện cho đầu ra tiêu chuẩn và thường là giá trị mặc định của $stdout.

Với STDOUTviệc là một hằng số, bạn không nên xác định lại nó, tuy nhiên, bạn có thể xác định lại $stdoutmà không có lỗi / cảnh báo (định nghĩa lại STDOUTsẽ đưa ra cảnh báo). ví dụ, bạn có thể làm:

$stdout = STDERR

Tương tự đối với $stderrSTDERR


Vì vậy, để trả lời phần khác của câu hỏi của bạn, hãy sử dụng các biến toàn cục để chuyển hướng đầu ra, không phải hằng số. Chỉ cần cẩn thận thay đổi nó trở lại trong mã của bạn, việc xác định lại các biến toàn cục có thể ảnh hưởng đến các phần khác của ứng dụng của bạn.


3
Trên thực tế, nếu bạn muốn chuyển hướng đầu ra, bạn có thể nên sử dụng $>, luồng đầu ra mặc định, không $stdout.
Jörg W Mittag

9
Vừa tìm thấy một nhận xét về một câu hỏi khác có nội dung $stdout$>là bí danh, vì vậy việc chỉ định lại một câu hỏi sẽ ảnh hưởng đến câu hỏi kia.
jrdioko

9
@jrdioko: Bạn nói đúng. Rõ ràng, tôi không chỉ học hỏi những điều mới mẻ mỗi ngày, tôi cũng quên một cái gì đó mỗi ngày :-)
Jörg W Mittag

2
Và đọc thêm, có vẻ như tốt hơn là sử dụng IO # reopen thay vì gán đơn giản.
jrdioko

@jrdioko Tại sao bạn nghĩ nó tốt hơn để sử dụng IO#reopentrong trường hợp $stdout? Tôi hoàn toàn không đồng ý với ý kiến ​​này. Các $stdout.reopenphương pháp đột biến thu của nó và đó cũng sẽ ảnh hưởng STDOUTnếu bạn chưa bố trí $stdouttrước đó. Chúng không có nghĩa là từ đồng nghĩa, không có gì xấu khi chúng giữ các giá trị khác nhau do được phân công và bằng cách mở lại STDOUTmục đích mà bạn đang vi phạm.
skalee

5
  • STDOUT là một hằng số toàn cục, vì vậy không nên thay đổi nó.
  • $stdout là một biến được xác định trước, vì vậy nó có thể được thay đổi.

Nếu bạn đang sử dụng shell để chuyển hướng:

$ ruby test.rb > test.log

thì không quan trọng cái nào bạn sử dụng làm trình mô tả tệp cho tập lệnh của bạn đang được xác định trước khi tập lệnh của bạn được thực thi.

Tuy nhiên, nếu bạn đang cố gắng thay đổi bộ mô tả tệp cho STDOUT của hệ điều hành từ bên trong tập lệnh Ruby của mình, chẳng hạn như để gửi đầu ra tới một tập hợp các tệp nhật ký luân phiên dựa trên ngày hiện tại trong tuần, thì bạn sẽ muốn đảm bảo bạn sử dụng $stdout.


5
"STDOUT là một hằng số toàn cục, vì vậy nó sẽ không thay đổi". Nó là một hằng số, CÓ THỂ thay đổi, nhưng một cảnh báo sẽ được đưa ra. STDOUT = $stderr (irb):1: warning: al#=> #<IO:<STDERR>>constant STDOUT >> STDOUT #=> #<IO:<STDERR>>
the Tin Man

Ahh vâng, vì vậy nên nói "vì vậy nó không nên được thay đổi". Cảm ơn!
shakerlxxv

5

Cả hai $stdoutSTDOUTcó ý nghĩa khác nhau. Tài liệu của Ruby khá rõ ràng về chủ đề này:

  • $stdout - Đầu ra tiêu chuẩn hiện tại.
  • STDOUT- Đầu ra tiêu chuẩn. Giá trị mặc định cho $ stdout.

Khi bạn muốn ghi vào đầu ra tiêu chuẩn, thì bạn thực sự có nghĩa là đầu ra tiêu chuẩn hiện tại , do đó bạn nên ghi vào $stdout.

STDOUTcũng không phải là vô dụng. Nó lưu trữ giá trị mặc định cho $stdout. Nếu bạn đã từng gán lại $stdout, thì bạn có thể khôi phục nó về giá trị trước đó với $stdout = STDOUT.

Hơn nữa, có một biến được xác định trước nữa:

  • $>- Đầu ra mặc định cho print, printf, $stdouttheo mặc định.

Tuy nhiên, có vẻ như trong Ruby 2.3, nó chỉ hoạt động như một bí danh cho $stdout. Việc gán lại $stdoutthay đổi giá trị của $>và ngược lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.