DRb and method_missing?

K

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?

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
 
E

Eric Hodel

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)

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top