On Fri, Aug 08, 2003 at 12:26:19AM +0900, Steve Tuckner wrote:
>    I am try to implement a simple object database where one process is a
>    DRb server that holds the objects in the database and uses pstore to
>    save/restore the database. In my client program I want to create an
>    object that I then want to put into the database. So for example here
>    is a simple class:

I don't know anything about pstore, but I do use DRb a lot, so I might be
able to help partly.

If you generate an instance of class Foo on the server, then running
     foo.x = 4
on the client (where foo is a DRb object pointing at the remote object)
it will be sent as a method call to the object on the server, which will
update itself.

However if pstore is a remote object store, then I imagine the only methods
it offers will be "fetch" and "put" operations. So if you use DRb directly
as a front to the object store itself, that will be all you can do. In order
to modify an object, the client will have to:

    - get foo (makes a local copy on the client)
    - update it (on the client)
    - put foo (replace the object in the object store)

If you want to have a way to update foo directly on the server, then your
DRb server needs to implement a method to dispatch a call to it:

    /---------- SERVER ------------\        DRB        /--- CLIENT ---\
 
      pstore <----- proxy object <-------------------------- client

The client calls a method on the proxy object, which you have written. It in
turn gets an object from pstore, performs an operation, and puts it back (or
putting it back might not be necessary since it's on the same machine):

    e.g. in pseudo-code

       class MyProxy 
         def initialize
           @store = Pstore.new
           3.times { @store.push(Foo.new) }   # put some objects in
         end
         def setx(index, value)
           @store.fetch(index).x = value
         end
       end

You might think of implementing a generic send-to method:

         def send_to(index, meth, *args)
           @store.fetch(index).send(meth, *args)
         end

         # client can do:
         #     pstore.send_to(2, :y=, 99)

but this is extremely dangerous, because it bypasses the protection of
'private' methods. In particular, you can send any Kernel methods like
system and backtick:

irb(main):003:0> a = ""
irb(main):004:0> a.send(:system,"ls")

So if the client does

         a.send_to(0, :system, "rm -rf /*")

this would probably not be a welcome method call :-)

Regards,

Brian.