DRb and method_missing?

You have a class that defines method_missing. Some set of the functionality
of your object comes from calling method_missing and invoking methods through
it. You want to use one of these things through DRb. Can you?

A little code:

require 'drb'
class Thing
include DRbUndumped
        attr_accessor :receiver

        def method_missing(method,*args)
                @receiver.__send__(method,args)
        end

        def join(arg)
                @receiver.__send__(:join,arg)
        end
end

a = [1,2,3,4,5]
o = Thing.new
o.receiver = a

DRb.start_service('drbunix://tmp/drb.sock',o)
DRb.thread.join

If one drops into irb:

irb(main):001:0> require 'drb'
=> true
irb(main):002:0> DRb.start_service('drbunix://tmp/drb2.sock')
=> #<DRb::DRbServer:0xb756cb6c @uri="drbunix://tmp/drb2.sock",
@grp=#<ThreadGroup:0xb756cae0>, @protocol=#<DRb::DRbUNIXSocket:0xb75c7034 @u>
irb(main):003:0> o = DRbObject.new_with_uri('drbunix://tmp/drb.sock')
=> #<DRb::DRbObject:0xb7329f30 @uri="drbunix://tmp/drb.sock", @ref=nil>
irb(main):004:0> o.join(',')
=> "1,2,3,4,5"

Okay, that proves that we're properly interacting with the object.

If one calls another method, such as o.length, though, it blows up with a:

NameError: undefined method 'length'

Which is true. If you have a real instance of Thing, method_missing would get
called, but it isn't with DRb. Is there a way to make DRb invoke
method_missing? BTW, this works identically whether or not I use
DRbUndumped.

Thanks,

Kirk Haines

You have a class that defines method_missing. Some set of the functionality
of your object comes from calling method_missing and invoking methods through
it. You want to use one of these things through DRb. Can you?

This has come up a couple of times in the past month and a half...

A little code:

require 'drb'
class Thing
include DRbUndumped
        attr_accessor :receiver

        def method_missing(method,*args)
                @receiver.__send__(method,args)

                 @receiver.__send__(method, *args)

        end

   def respond_to?(method)
     @receiver.respond_to? method
   end

        def join(arg)
                @receiver.__send__(:join,arg)
        end
end

a = [1,2,3,4,5]
o = Thing.new
o.receiver = a

DRb.start_service('drbunix://tmp/drb.sock',o)
DRb.thread.join

The backtrace is your clue:

irb(main):005:0> o.length
NameError: undefined method `length' called for #<Thing:0x3533b8>
         from (drbunix://tmp/drb.sock) /usr/local/lib/ruby/1.8/drb/drb.rb:1475:in `check_insecure_method'
         from (drbunix://tmp/drb.sock) /usr/local/lib/ruby/1.8/drb/drb.rb:1536:in `check_insecure_method'
...

PS: In 1.9, you no longer need to define #respond_to? for #method_missing to work.

···

On 03 Aug 2005, at 05:51, Kirk Haines wrote:

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04