I'm working in a module that enables a way to use all the Perl Objects and types remotely, but transparently. Soo, I can have a SCALAR in my local code, that actually is a reference to a scalar in other machine, but this scalar will work as a normal scalar, and apply changes remotely. Here's an example of code:
use RPO ; ## Remote Perl Objects ## Set the value of a SCALAR remotely: RPO::CLIENT->eval('$scalar = 123'); ## Get the reference to this SCALAR: my $remote_ref = RPO::CLIENT->eval('\$scalar') ; ## Use the SCALAR reference normally, but making changes remotely: $$remote_ref = 'xyz' ; ## Define $local_scalar as an alias to the remote scalar: my $local_scalar ; RPO::ALIAS(\$local_scalar , $remote_ref) ; ## Append some data to the previous scalar value ('xyz'): $local_scalar .= 'abc' ; ## The remote value now should be 'xyzabc': print RPO::CLIENT->eval('return $scalar') ;
The reference to the remote SCALAR, $remote_ref, can be used as a normal reference, but all the changes made to it will be applied remotely too. And the alias, $local_scalar, make all the use easier, since all the changes done to this scalar, that seems to be a normal scalar, will be applied to the remote SCALAR returned by eval(). Note that the internal value of the remote SCALAR will never exists in the local interpreter, soo for each acces or change to a variable, a communication will exits between the RPO Server and the RPO Client.

Who make all the magic is the method RPO::CLIENT->eval(), where any reference that it returns, is transformed to a bridge between the RPO Server and the RPO Client. Soo, you don't need to care of how to create all this remote objects, you just return a reference, that also can be an object, and you have it working remotely.

For now I only have SCALAR, ARRAY and HASH working remotely. I still need to implement the GLOB and IO types, to after this can implement Objects and packages. I'm still thinking in the best way to do that, since the hard work starts now, soo I will appreciate suggestions about the architecture.

The main purpose of this module is to use Perl modules without need to install them, since with this resource you can use a remote object without actually have the class of this object locally. Also will be possible to make function calls that are holded remotely, actually will be possible to have a package that actually runs in other interpreter, since the main idea is to have everything transparent.

You can download the development code at:
http://www.inf.ufsc.br/~gmpassos/RPO-0.01-beta.tar.gz

Enjoy and send your comments. ;-P

UPDATE

Here's some complex usage with HASH and what happens in the backstages.

## Set the value of a HASH remotely: RPO::CLIENT->eval('%hash = ( a=>1 , b=>2 , c=>{ d=>3.1 , e=>3.2 } )' +); ## Get the reference to this HASH: my $ref = RPO::CLIENT->eval('\%hash') ; ## Define the alias: my %hash ; RPO::ALIAS(\%hash , $ref) ; ## store '11': $hash{a} = 11 ; ## fetch 'a': print "$hash{a}\n" ; ## fetch 'c', what returns a new remote HASH ## reference, and fetch 'd': print "$hash{c}{d}\n" ; my $scalar_ref = RPO::CLIENT->eval('\$scalar') ; RPO::ALIAS(\$scalar , $scalar_ref) ; ## fetch 'c', what returns a new remote HASH ## fetch $scalar and ## store into 'e' in the returned HASH in 'c'. $hash{c}{e} = $scalar ;

Graciliano M. P.
"Creativity is the expression of the liberty".

Edited by BazB shorted title slightly from "Using Objects and basic types (SCALAR, ARRAY, HASH...) from other Perl interpreters transparently (as a normal Perl variable and reference)"

Replies are listed 'Best First'.
Re: Using objects and basic types from other Perl interpreters transparently.
by liz (Monsignor) on Apr 12, 2004 at 10:43 UTC
    I was thinking of adding this type of functionality to forks. Most of the code needed to do this, is already in there. The only thing that is needed extra is hooking up a local tied variable to a remote variable's index.

    This would give the added simplicity of providing an existing interface (namely threads and threads::shared) to this functionality.

    Maybe something like:

    my $thread = threads->remote( "host:port" );
    ?

    Liz

      Well, after have the resource 100% implemented we can use it in any way! ;-P

      Actually you already can make some tests with SCALAR, ARRAY and HASH, since generally this are the types shareds between 2 threads.

      Other thing that I can implement is a different IPC system, since I'm using sockets between the RPO Server and the RPO Client, and for a thread or fork system we can use something that doesn't use external things, like shared memory, but need to be a portable resource. Any idea?

      Graciliano M. P.
      "Creativity is the expression of the liberty".

      About adding the resource, what you mean with
      my $thread = threads->remote( "host:port" );
      this is a thread that exists in other interpreter?

      Well, to do that I think that I need to make a bidiretional communication between the RPO Server and the client. For now only the server wait's for inputs, and always send a response to the client, what make the execution of both sides synchronized. Or for now this can be done making the main thread/process as the server, and all the threads made from it, or any remote thread, will work as a client, since the real location of a shared variable is in the server side.

      A bidiretional IPC will also enable a way to create a remote reference in the server side, let's say, a scalar in the server that points to a real scalar in the client. For now is only possible to make the oposite. And this will create something even more crazy, like have 2 clients, where the server points to a scalar in client 1, and the client 2 can get a reference to the remote scalar in the server, and when the client 2 access this reference it's actually accessing the client 1. So, is possible to create a network of remote objects without really know that!

      But you already have some bidiretional socket system for forks, not? Maybe I can use it.

      Graciliano M. P.
      "Creativity is the expression of the liberty".

        About adding the resource, what you mean with
        my $thread = threads->remote( "host:port" );
        this is a thread that exists in other interpreter?

        Well, it would look like a thread to the local program. It's just that the thread runs somewhere else.

        Actually, you would need it to tell what sub to run on the other side as well, so I guess the syntax would be:

        my $thread = threads->remote( 'host:port:namespace::subname' );
        and consequently, forks should have a seperately installable server functionality as well (which now only happens in a fork).

        Currently, when you register a shared variable, it is the server who assigns ordinal numbers to know which variable is associated with what remote variable. Currently the numbers are the same on either side, so some type of mapping would be needed. And other things would prop up as well. But if we could get this together, then not only could you offload threads to other systems, you would have create a very transparent Perl RPC mechanism as well.

        But you already have some bidiretional socket system for forks, not? Maybe I can use it.

        forks uses the blocking behaviour of sockets to handle all the locking and cond_wait/signal/broadcast issues. So all of your locking issues should be handle by that already. So yes, I think you can definitely use the code, or even better: integrate it into forks.pm.

        I'm willing to work with you on that!

        Liz

Re: Using objects and basic types from other Perl interpreters transparently
by adrianh (Chancellor) on Apr 12, 2004 at 10:52 UTC
    The main purpose of this module is to use Perl modules without need to install them, since with this resource you can use a remote object without actually have the class of this object locally. Also will be possible to make function calls that are holded remotely, actually will be possible to have a package that actually runs in other interpreter, since the main idea is to have everything transparent.

    I'd just use SOAP::Lite myself.

      I didn't know SOAP::, but seems that we need to create an interface, or a service, to access that remotely.

      The idea with RPO is to write a normal code, or get an existing code, and make some part of it to work remotely.

      I know that I'm not inventing the idea, or I'm not the 1st to implement something for remote control. But, at least, I'm the 1st to implement in this architecture and with transparency use in the code.

      I will take more look in SOAP... ;-P

      Graciliano M. P.
      "Creativity is the expression of the liberty".

        I'm the 1st to implement in this architecture and with transparency use in the code.

        Once you've set everything up and worked around its somewhat pathologic way of doing things, SOAP::Lite is fairly transparent. This is probably dangerous, as many programmers don't think of the security implications of directly executing remote methods. Many programmers have a hard enough time with the more limited CGI environment.

        ----
        : () { :|:& };:

        Note: All code is untested, unless otherwise stated

Re: Using objects and basic types from other Perl interpreters transparently.
by hardburn (Abbot) on Apr 12, 2004 at 13:17 UTC

    As another poster mentioned, SOAP::Lite does a lot of the same things, though it's more specific to methods rather than all Perl datatypes. Even so, I've personally never felt the need for anything more (though I could stand to have something less).

    On another subject, I'd like to point something out to you. PM tends to not get bogged down in useless debates over grammer and spelling, and I tend to avoid them even in other forums (because it should be obvious to everyone that my own spelling is far from perfect). However, I've seen you use 'soo' in many nodes, and it's been bugging me. There is only one 'o' in 'so'.

    Also, you seem to use 'so' as a "crutch word", i.e. a word which tends to be overused by a writer when they can't think of something better to get down. Most (perhaps all) writers pick up a crutch word from time to time (I think I use words like 'although', 'though', and 'just' as crutches), so don't feel like you're singled out here.

    ----
    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

Re: Using objects and basic types from other Perl interpreters transparently.
by stvn (Monsignor) on Apr 12, 2004 at 15:50 UTC

    For what you are trying to do, making remote things seem local transparently, I would recommend looking into Erlang. Not to write it in, but to see how it can be done really well. Erlangs basic model is that of communicating processes, usually on the sames machine and interpreter instance. But with virtually no code change at all, one Erlang process on one machine, can communicate with another process on another machine half the world away. Of course this is all built into the Erlang interpreter, but I would still recommend looking at it to see how others are accomplishing similar goals.

    -stvn
Re: Using objects and basic types from other Perl interpreters transparently.
by jdporter (Paladin) on Apr 12, 2004 at 18:16 UTC
    If you are interested in this subject, you should probably be familiar with the Obliq system (prototyped in Oberon). For quite some time, I've been thinking it would be cool to have variables with Obliq semantics in Perl. I think you've got the right idea, but your approach has way too much syntactic overhead, IMHO.

    jdporter
    The 6th Rule of Perl Club is -- There is no Rule #6.

      ..which, looking at this scanned page of an Obliq (but easy to understand) paper is really cool! (actually the whole paper is interesting though I only saw a few pages, click here for top page with pdf and other formats)
Re: Using objects and basic types from other Perl interpreters transparently.
by Fletch (Bishop) on Apr 12, 2004 at 14:52 UTC

    Not a direct Perl solution, but take a look at how things like Objective-C and CORBA use local proxies for their distributed object schemes.