DRb and unknown_methods

S

Stephan Kämper

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
 
E

Eric Hodel

Hi all,

I just ran into this situation: There's a module which uses DL to =20
provide calls into a dynamic library. Now, I'd like to make these =20
functions of the dyn. lib. available via DRb. (If I remember =20
correctly, I somewhere read that "include ModuleThatUsesDL" is not =20
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 =20
`check_insecure_method': undefined method `a_method' called for =20
#<TheProxy:0x2911e98> (NameError)
from (druby://localhost:42000) c:/ruby/lib/ruby/1.8/drb/drb.rb:=20
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 =3D "#{ 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 }'", =20
caller

You can super here.

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

--=20
Eric Hodel - (e-mail address removed) - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04
 
S

Stephan Kämper

Hi Eric, hi all,

Eric said:
You can super here.

Thanks for the tip, now I do.
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
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top