Errors with monitor

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

···

--
Posted via http://www.ruby-forum.com/.

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/