# Errors with monitor

**URL:** <https://www.ruby-forum.com/t/errors-with-monitor/176857>\
**Category:** Ruby\
**Created:** [October 7, 2009, 5:28am UTC](https://www.ruby-forum.com/t/errors-with-monitor/176857 "2009-10-07T05:28:34Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [October 7, 2009, 5:28am UTC](https://www.ruby-forum.com/t/errors-with-monitor/176857/1 "2009-10-07T05:28:34Z")

</div>

getting this error in a synchronize call:

/usr/lib/ruby/1.8/monitor.rb:212:in `mon_enter': undefined method`+’  
for nil:NilClass (NoMethodError)  
from /usr/lib/ruby/1.8/monitor.rb:236:in `synchronize’

class definition is here:

class SyncPipe \< IO  
include MonitorMixin

def initialize( p )  
@file = IO.popen( p )  
end

def puts( output)  
synchronize do  
@file.puts(output)  
end  
end

def close  
@file.close  
end  
end

The idea is to have a pipe that threads can write their output too  
without interfering with each other…

Any idea what is going wrong. I had this working at one stage, sigh…

Russell

---

<div class="post-metadata">

**Author:** ![russellf](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@russellf](https://www.ruby-forum.com/u/russellf)\
**Post date:** [October 7, 2009, 10:25pm UTC](https://www.ruby-forum.com/t/errors-with-monitor/176857/2 "2009-10-07T22:25:50Z")

</div>

On 10/07/2009 05:28 AM, Russell F. wrote:

> include MonitorMixin
> 
> def close  
> @file.close  
> end  
> end
> 
> The idea is to have a pipe that threads can write their output too  
> without interfering with each other…
> 
> Any idea what is going wrong. I had this working at one stage, sigh…

I believe there are some issues with your code. The one which stroke me  
first is that you do not guard #close which can likely result in issues.

Then you inherit IO and leave most methods untouched which also means  
they are not guarded. Btw, I don’t believe that you actually need to  
inherit class IO.

IIRC IO.popen with just a command name will open only one pipe for  
reading stdout so your writing might not succeed anyway.

That’s all not necessarily related to your issue. The show stopper is  
that you do not invoke super() in #initialize and thus prevent  
initialization of the mixin:

irb(main):021:0\> robert@fussel:~$ irb1.8 -r monitor  
irb(main):001:0\> class X  
irb(main):002:1\> include MonitorMixin  
irb(main):003:1\> def foo  
irb(main):004:2\> synchronize { puts “yy” }  
irb(main):005:2\> end  
irb(main):006:1\> end  
=\> nil  
irb(main):007:0\> X.new.foo  
yy  
=\> nil  
irb(main):008:0\> class X  
irb(main):009:1\> def initialize; end # no call to super  
irb(main):010:1\> end  
=\> nil  
irb(main):011:0\> X.new.foo  
NoMethodError: undefined method `+' for nil:NilClass from /usr/lib/ruby/1.8/monitor.rb:215:in`mon\_enter’  
from /usr/lib/ruby/1.8/monitor.rb:240:in `synchronize' from (irb):4:in`foo’  
from (irb):11  
from :0  
irb(main):012:0\>

Here’s a slightly different approach that takes all these points into  
account:

class SyncPipe  
include MonitorMixin

def initialize(\*a)  
super()  
@io = IO.popen(\*a)  
end

def method\_missing(\*a, &b)  
synchronize do  
@io.send(\*a, &b)  
end  
end  
end

or even more general

class SyncIO  
include MonitorMixin

def initialize(io)  
super()  
@io = io  
end

def method\_missing(\*a, &b)  
synchronize do  
@io.send(\*a, &b)  
end  
end  
end

Kind regards

robert
