2014-01-24 4 views
5
내가 명령 줄에서이 일을 인쇄하는 루비에 의해 사용되는 출력 스트림 알고 싶어

:

irb(main):001:0> a="test" 
=> "test" 
irb(main):002:0> puts a 
test 
=> nil 
irb(main):003:0> a 
=> "test" 

$stdoutirb(main):002:0>irb(main):003:0>에 사용됩니다? 그리고이 두 호출 사이에 $stdout의 값이 변경 되었습니까?

또한 루비 소스를 통해 이러한 것들이 인쇄되고 쓰여지는 지점을 알려줄 수 있습니까?

+3

'=> nil'은 혼란 스럽습니까? 'nil'이 반환되는 것은 STDOUT 또는 STDERR과 아무 관련이 없습니다. 'puts'가 nil을 반환하기 때문입니다. IRB가 의무적으로보고합니다. –

답변

8

예. 테스트/증명하기가 쉽습니다. 커맨드 라인에서 시도 :

ruby -e 'puts "foo"' > test.out 
cat test.out 

출력 될 것이다

foo 

루비 콘솔 출력 표준 출력 채널을 이용한다. 그런 다음 OS는 STDOUT을 "test.out"으로 리디렉션합니다.

는 그것을 시도 :

ruby -e 'STDOUT.puts "foo"' > test.out 

와 동일한 결과를 얻을 수 있습니다.

우리가 할 경우

ruby -e 'STDERR.puts "foo"' > test.out 
foo 
cat test.out 

당신은 파일에 아무것도하지만, "foo는"볼 것은 STDERR 채널에서 콘솔에 기록 된 것입니다.

루비는 변경할 수있는 글로벌 주소로 $stdout을 정의하고, 변경해서는 안되는 상수로 STDOUT을 정의합니다. 마찬가지로 $stderrSTDERR도 사용할 수 있습니다.

자, 여기가 재미있게되고, 당신의 질문을 증명합니다.

ruby -e '$stdout = STDERR; puts "foo"' > test.out 

puts에서 출력 스트림을 선택 $stdout의 값을 사용했는데, 때문에 당신은 STDERR에 때 출력과 같은 결과를 얻을 것이고, STDERR에 쓴이보십시오. 이러한 스트림 값은 인터프리터가 시작될 때 운영 체제에서 Ruby에 의해 선택되며 스크립트 실행 중 기억됩니다. 필요한 경우 을 변경하고과 루비는 인터프리터가 종료 될 때 해당 설정을 잊어 버리고 다음 번에 정상 상태로 재설정됩니다.

실제로 코드를 혼동시키기 때문에 $stdout을 변경하는 묵시적/비가 시적 동작에 의존해서는 안됩니다. 대신 STDERR에 쓸 때마다 STDERR.puts을 명시 적으로 사용하고 STDOUT에 일반 출력의 경우에는 puts을 사용하는 것이 좋습니다. 둘 다에 출력을 혼합한다면, STDOUT.putsSTDERR.puts을 사용하는 것이 더 명확 할 것입니다. 그러나 그것은 여러분의 부름입니다.

irb(main):001:0> $stdout 
#<IO:<STDOUT>> 
irb(main):002:0> $stderr 
#<IO:<STDERR>> 

그리고 :

irb(main):003:0> $stdout.puts 'foo' 
foo 
nil 
irb(main):004:0> $stderr.puts 'foo' 
foo 
nil 
인터프리터에서 실행해서이 같은까지 너무 $stdout를 사용하여 $stdout에 IRB 출력을 쓰기로한다 작품으로

이제 IRB는 동일합니다

그리고 마지막으로 :

irb(main):007:0> $stdout.isatty 
true 
irb(main):008:0> $stdout.isatty 
true 

우리는 정말 말할 수 없습니다 우리가 조금 더 낮아질 때까지 y 차이; 표준 STDOUT 및 STDERR 채널 번호를 가진 두 TTY 채널입니다.

irb(main):009:0> $stdout.fileno 
1 
irb(main):010:0> $stderr.fileno 
2 

잘하면 'splain it'.


난 그냥 puts의 반환 값의 IRB의보고 당신이 STDOUT가 변화하고 있다고 생각하는 원인을 혼동 될 수 있음을 깨달았다. nil이 반환되면 STDOUT 또는 STDERR과 아무 관련이 없습니다. 이는 puts이 nil을 반환하기 때문입니다. 이는 IRB에서 충실히보고합니다.

+0

좋은 답변입니다! 나는 그것이 매우 도움이되는 것을 알았다. –

1

이유는 IRB가 각 작업 후에 개체를 검사하기 때문입니다.

참조 개체 # 전체 내용은 검사 :

~ $ irb 
>> class Foo 
>> def inspect 
>> 'hi' 
>> end 
>> end 
=> nil 
>> foo = Foo.new 
=> hi 

$ 표준 출력을 때리고 귀하의 경우 유일한 방법은 다음과 같습니다

http://ruby-doc.org/core-2.1.0/Object.html#method-i-inspect

우리는과 같이 검사 재정 의하여이 증명할 수 puts 명령의 결과.

희망이 도움이됩니다.