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...
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
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
···
On 10/07/2009 05:28 AM, Russell Fulton wrote:
from :0
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/