DRb and unknown_methods

Hi all,

I just ran into this situation: There's a module which uses DL to provide calls into a dynamic library. Now, I'd like to make these functions of the dyn. lib. available via DRb. (If I remember correctly, I somewhere read that "include ModuleThatUsesDL" is not a good idea to do, if that module uses DL in turn.)

With the code below, I get this error message:

···

-------------------------------------------------
(druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1419:in `check_insecure_method': undefined method `a_method' called for #<TheProxy:0x2911e98> (NameError)
  from (druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1461:in `check_insecure_method'
  from (druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1466:in `setup_message'
  from (druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1435:in `perform'
  from (druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1512:in `main_loop'
  from (druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1508:in `loop'
  from (druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1508:in `main_loop'
  from (druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1504:in `start'
  from (druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1504:in `main_loop'
   ... 6 levels...
  from (druby://localhost:42000) F:/tmp/the_proxy.rb:24
  from F:/tmp/the_client.rb:10
  from F:/tmp/the_client.rb:9:in `times'
  from F:/tmp/the_client.rb:9
-------------------------------------------------

So the question is: How can I get this to work?
I would be grateful for information about this.

And here's the boiled down code:

# The Module (uses DL in real life)
# Filename: 'the_module.rb'
module TheModule
   def a_method
     "result"
   end
end
-------------------------------------------------

# The Proxy (provide access to the Module methods)
# Filename: 'the_proxy.rb'
require 'drb'
require 'English'
require 'the_module'

class TheProxy

   # I seem to recall that doing this is bad in case
   # the module uses DL (but where did I read that?)
   # include TheModule

   def method_missing( meth_name, *arguments )
     call_it = "#{ meth_name.to_s }( #{arguments.join( ', ' )} )"
     if TheModule.respond_to? meth_name
       TheModule.instance_eval( call_it )
     else
       raise NoMethodError, "Can't handle method '#{ call_it }'", caller
     end
   end

end

if $PROGRAM_NAME == __FILE__

   proxy = TheProxy.new

   DRb.start_service( "druby://localhost:42000", proxy )
   DRb.thread.join

end
-------------------------------------------------

# The client which uses the Module via the Proxy
# Filename: 'the_client.rb'
require 'drb'

$stdout.sync = true

DRb.start_service

proxy = DRbObject.new( nil, "druby://localhost:42000" )

5.times do
   puts proxy.a_method
   sleep 0.5
end
-------------------------------------------------

Happy rubying

Stephan

Hi all,

I just ran into this situation: There's a module which uses DL to provide calls into a dynamic library. Now, I'd like to make these functions of the dyn. lib. available via DRb. (If I remember correctly, I somewhere read that "include ModuleThatUsesDL" is not a good idea to do, if that module uses DL in turn.)

With the code below, I get this error message:

-------------------------------------------------
(druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1419:in `check_insecure_method': undefined method `a_method' called for #<TheProxy:0x2911e98> (NameError)
    from (druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:1461:in `check_insecure_method'

So the question is: How can I get this to work?
I would be grateful for information about this.

And here's the boiled down code:

# The Module (uses DL in real life)
# Filename: 'the_module.rb'
module TheModule
  def a_method
    "result"
  end
end
-------------------------------------------------

# The Proxy (provide access to the Module methods)
# Filename: 'the_proxy.rb'
require 'drb'
require 'English'
require 'the_module'

class TheProxy

  # I seem to recall that doing this is bad in case
  # the module uses DL (but where did I read that?)
  # include TheModule

  def method_missing( meth_name, *arguments )
    call_it = "#{ meth_name.to_s }( #{arguments.join( ', ' )} )"
    if TheModule.respond_to? meth_name
      TheModule.instance_eval( call_it )
    else
      raise NoMethodError, "Can't handle method '#{ call_it }'", caller

You can super here.

    end
  end

You also need to have a respond_to? method that returns true for proxied methods.

···

On 24 Jul 2005, at 10:15, Stephan Kämper wrote:

end

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

Hi Eric, hi all,

Eric Hodel wrote:

  def method_missing( meth_name, *arguments )
    call_it = "#{ meth_name.to_s }( #{arguments.join( ', ' )} )"
    if TheModule.respond_to? meth_name
      TheModule.instance_eval( call_it )
    else
      raise NoMethodError, "Can't handle method '#{ call_it }'", caller

You can super here.

Thanks for the tip, now I do.

    end
  end

You also need to have a respond_to? method that returns true for proxied methods.

Thanks a lot. That's the solution. Even after some years of Ruby, things are still so natural (and yet sometimes so surprising)...

Thanks again. What a great language.

Happy rubying

Stephan

···

On 24 Jul 2005, at 10:15, Stephan Kämper wrote: