# Another Programming Ruby Question

**URL:** <https://www.ruby-forum.com/t/another-programming-ruby-question/85601>\
**Category:** Ruby\
**Created:** [February 14, 2007, 9:40pm UTC](https://www.ruby-forum.com/t/another-programming-ruby-question/85601 "2007-02-14T21:40:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bruparel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e47774/32.png) [@bruparel](https://www.ruby-forum.com/u/bruparel)\
**Post date:** [February 14, 2007, 9:40pm UTC](https://www.ruby-forum.com/t/another-programming-ruby-question/85601/1 "2007-02-14T21:40:28Z")

</div>

This is from Chapter 11 titled “Threads and Processes” of Programming  
Ruby book on page 139.

I am pasting the source code below:

# Sample code from Programing Ruby, page 131

$stderr.sync = $stdout.sync = true  
Thread.abort\_on\_exception = true  
threads = []  
4.times do |number|  
threads \<\< Thread.new(number) do |i|  
raise “Boom!” if i == 2  
print “#{i}\n”  
end  
end  
threads.each {|t| t.join }

Note that the page numbers in the downloaded code with the actual page  
numbers do not match - probably due to two different Editions of the  
book. Has not been a problem thus far.

When I run the code in SCITE, I get the following output:

> ruby ex0318.rb  
> ex0318.rb:7: Boom! (RuntimeError)  
> from ex0318.rb:6:in `initialize' from ex0318.rb:6:in`new’  
> from ex0318.rb:6  
> from ex0318.rb:5:in `times’  
> from ex0318.rb:5  
> Exit code: 1

Now the output shown in the book is different. It shows that a 0  
followed by 1 are going to be output (on separate lines) before the  
program hits the exception condition. I commented out the line which  
says

$stderr.sync = $stdout.sync = true as follows:

# Sample code from Programing Ruby, page 131

# $stderr.sync = $stdout.sync = true

Thread.abort\_on\_exception = true  
threads = []  
4.times do |number|  
threads \<\< Thread.new(number) do |i|  
raise “Boom!” if i == 2  
print “#{i}\n”  
end  
end  
threads.each {|t| t.join }

and re-ran the program.

This time I got the right output as below:

> ruby ex0318.rb  
> 0  
> 1  
> ex0318.rb:7: Boom! (RuntimeError)  
> from ex0318.rb:6:in `initialize' from ex0318.rb:6:in`new’  
> from ex0318.rb:6  
> from ex0318.rb:5:in `times’  
> from ex0318.rb:5  
> Exit code: 1

That set me thinking what does the line:  
$stderr.sync = $stdout.sync = true  
actually do?  
I looked it up into the book and googled for it, but cannot find an  
answer that makes sense. Would someone kindly explain in Ruby/Newby  
terms? When to use it when not to use it etc? I know that this is  
setting both standard error and standard output to the same channel.  
What does the sync method do? What does it mean to set it to true? If  
there are online resources that can be looked up for these kinds of  
questions I will not bother you. But the online Ruby API almost mirrors  
Dave T.'s Programming Ruby book which I am working with anyway.  
Thanks in advance for your time.  
Bharat

---

<div class="post-metadata">

**Author:** ![bruparel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e47774/32.png) [@bruparel](https://www.ruby-forum.com/u/bruparel)\
**Post date:** [February 15, 2007, 11:39am UTC](https://www.ruby-forum.com/t/another-programming-ruby-question/85601/2 "2007-02-15T11:39:48Z")

</div>

Bharat R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> That set me thinking what does the line:  
> $stderr.sync = $stdout.sync = true  
> actually do?

(from the “sync= (IO)” section of [RDoc Documentation](http://www.ruby-doc.org/core/)):

ios.sync = boolean =\> boolean

Sets the ``sync mode’’ to true or false. When sync mode is true, all  
output is immediately flushed to the underlying operating system and  
is not buffered internally. Returns the new state. See also IO#fsync.

f = File.new(“testfile”)  
f.sync = true

(produces no output)

When data is output through an IO handle, it might be buffered. What  
this means is that the data is held until a certain number of bytes are  
received or until certain characters are fed to the stream (such as  
newline), and only then are they sent to the output destination.

The “sync mode” determines whether this buffering takes place … if  
it’s set to true, then there is no such buffering, and the data is  
“synchronized” with the output destination immediately upon being sent  
through the IO handle.

The statement you refer to above makes sure that $stdout and $stderr are  
both synchronized. Therefore, in the thread, data written to these  
handles will be output immediately. Without your statement, there could  
be a delay between the moment that the data is sent to $stdout or  
$stderr and it shows up on the terminal. That’s why you are seeing the  
output in a different sequence, depending on whether or not the sync  
mode is set.

As you can see, this has nothing to do with setting $stdout and $stderr  
to be in sync with each other.

---

<div class="post-metadata">

**Author:** ![bruparel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e47774/32.png) [@bruparel](https://www.ruby-forum.com/u/bruparel)\
**Post date:** [February 16, 2007, 4:04am UTC](https://www.ruby-forum.com/t/another-programming-ruby-question/85601/3 "2007-02-16T04:04:12Z")

</div>

Hello Lloyd,  
I appreciate your time and detailed response.  
It seems to me that I should see the opposite behavior to what I am  
seeing based on the explanation that you provided. That is:  
If setting sync to true causes no buffering then I should actually  
observe the first two values (0 and 1) to be immediately output.  
Instead, I see the exception messages as I show above. Since the  
exception does not get raised until i reaches a value of 2, I should see  
the 0 and 1 printed to the standard output and then I should see  
exception being printed to standard error?  
Bharat

---

<div class="post-metadata">

**Author:** ![bruparel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e47774/32.png) [@bruparel](https://www.ruby-forum.com/u/bruparel)\
**Post date:** [February 16, 2007, 11:53pm UTC](https://www.ruby-forum.com/t/another-programming-ruby-question/85601/4 "2007-02-16T23:53:46Z")

</div>

Thank you Mauricio. This makes perfect sense now.

On a separate note to all Ruby Newby persons: I am finding that  
Programming Ruby or the PickAxe book almost should be your 2nd or 3rd  
Ruby book. I am glad that I bought David Black’s Ruby for Rails book  
and went through it entirely before coming back to Programming Ruby  
book. I have also bought Everyday Scripting based on my bookstore  
browsing and am planning on going through it next. I will continue to  
work through Dave T.'s Programming Ruby book though. My advice to  
everyone based on my experience is that don’t get frustrated and ask  
questions on this forum for clarifications. There are some very kind,  
patient, and knowledgable people who are willing to spare their time and  
facilitate the learning process.

Regards,  
Bharat

---

<div class="post-metadata">

**Author:** ![bruparel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e47774/32.png) [@bruparel](https://www.ruby-forum.com/u/bruparel)\
**Post date:** [February 16, 2007, 10:27am UTC](https://www.ruby-forum.com/t/another-programming-ruby-question/85601/5 "2007-02-16T10:27:09Z")

</div>

On Thu, Feb 15, 2007 at 05:40:30AM +0900, Bharat R. wrote:

> threads.each {|t| t.join }  
> […]  
> When I run the code in SCITE, I get the following output:
> 
> > ruby ex0318.rb  
> > ex0318.rb:7: Boom! (RuntimeError)  
> > from ex0318.rb:6:in `initialize' from ex0318.rb:6:in`new’  
> > from ex0318.rb:6  
> > from ex0318.rb:5:in `times’  
> > from ex0318.rb:5  
> > Exit code: 1

The example assumes that the threads will be executed serially, and  
those with  
i=0,1 will terminate before the third one raises a RuntimeError.

However, when you set $stdout.sync = true each time you printf  
whatever  
Ruby will try to schedule another thread. In the above example, the two  
first  
threads run until print “#{i}\n” and the third thread, which raises an  
exception, is scheduled before the numbers are actually written to  
$stdout.

If you change the example so that the threads are rescheduled before the  
next  
one is created, you’ll get the expected output:

$ ruby  
$stderr.sync = $stdout.sync = true  
Thread.abort\_on\_exception = true  
threads = []  
4.times do |number|  
threads \<\< Thread.new(number) do |i|  
raise “Boom!” if i == 2  
print “#{i}\n”  
end  
sleep 0.01  
end  
threads.each {|t| t.join }  
^D  
0  
1  
-:6: Boom! (RuntimeError)  
from -:5:in `initialize' from -:5:in`new’  
from -:5  
from -:4:in `times’  
from -:4

IO#sync does work the way it should, but the example is confusing.
