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