Loading ...
Sorry, an error occurred while loading the content.
 

object method call problem

Expand Messages
  • joerg.ziefle@gmx.de
    I have a Beam object whose blessed hash contains a Mass object: print $beam- mass in the program gives Mass=HASH(0x481250) Now I want to call methods of the
    Message 1 of 6 , May 19, 2001
      I have a Beam object whose blessed hash contains a Mass object:

      print $beam->mass

      in the program gives

      Mass=HASH(0x481250)

      Now I want to call methods of the Mass object:

      print $beam->mass->in_pounds

      But the in_pounds method of the Mass object is never called (no error
      message).

      Do I have to specify that I now want to use the Mass module? If so,
      is there a way to avoid this and do the remote calls as if they are
      local?

      Below is the (autodispatched code). I would be grateful for a
      solution for both this autodispatched and the OOP interface way.

      Thanks,

      Jörg

      #!/usr/local/bin/perl -w

      use strict;

      # hostname censored
      use SOAP::Lite
      +autodispatch =>
      uri => 'http://XXX/Beam',
      proxy => 'http://XXX/';

      my $beam = Beam->new(
      'length' => 100,
      'type' => 'rectangular',
      'width' => 0.05,
      'height' => 0.05,
      'mass' => 50,
      );

      print $beam->mass->in_pounds;
    • Paul Kulchenko
      Hi, Joerg! It should work EXACTLY as you described. Here is the server code: use SOAP::Transport::HTTP; $SIG{PIPE} = $SIG{INT} = IGNORE; my $daemon =
      Message 2 of 6 , May 20, 2001
        Hi, Joerg!

        It should work EXACTLY as you described. Here is the server code:

        use SOAP::Transport::HTTP;

        $SIG{PIPE} = $SIG{INT} = IGNORE;

        my $daemon = SOAP::Transport::HTTP::Daemon
        -> new (LocalPort => 80)
        -> dispatch_to('A', 'B')
        ;
        print "Contact to SOAP server at ", $daemon->url, "\n";
        $daemon->handle;

        package A;

        sub new { bless {} => ref $_[0] || $_[0] }
        sub getB { B->new }
        sub whoami { ref shift }

        package B;

        sub new { bless {} => ref $_[0] || $_[0] }
        sub whoami { ref shift }

        Here is the AD client:

        use SOAP::Lite +autodispatch =>
        uri => 'http://www.soaplite.com/A',
        proxy => 'http://localhost/',
        ;

        my $a = A->new;
        print $a->whoami, "\n";
        my $b = $a->getB;
        print $b->whoami, "\n";

        print A->new->getB->whoami, "\n";

        > Now I want to call methods of the Mass object:
        >
        > print $beam->mass->in_pounds
        >
        > But the in_pounds method of the Mass object is never called (no
        > error message).
        SOMETHING should come back. Did you try to get a wire dump with
        on_debug(sub{print@_})?

        > Do I have to specify that I now want to use the Mass module? If
        No, autodispatch will guess it from object type.

        > so,
        > is there a way to avoid this and do the remote calls as if they are
        > local?
        autodispatch should do EXACTLY this. Even more, if you have this
        module locally, but still want to do remote call, you can use SOAP::
        prefix (but not abuse it):

        print $b->SOAP::whoami, "\n";

        will go remotely, even if there is local 'B' module ('use B').

        > Below is the (autodispatched code). I would be grateful for a
        > solution for both this autodispatched and the OOP interface way.
        I have a OO code for this case, but it's not so concise:

        use SOAP::Lite;

        my $soap = SOAP::Lite
        -> uri('http://www.soaplite.com/A')
        -> proxy('http://localhost/')
        ;

        my $a = $soap->call('new')->result;
        print $soap->whoami($a)->result, "\n";
        my $b = $soap->getB($a)->result;

        $soap->uri('http://www.soaplite.com/B');
        print $soap->whoami($b)->result, "\n";

        Problem is the line with $soap->uri();

        OO call doesn't have enough information (as AD call does) to guess
        package you want to dispatch your call, so it'll use package you
        specified in URI. To dispatch you call to 'B' instead of 'A' you need
        to specify it (at least for now). I didn't come up with nice solution
        yet. Everything can be done in both AD and OO interfaces, but with
        different number of lines (each of them has pros and cons). In THIS
        case, when you operate with multiple object better use autodispatch
        interface (or autoinheritance, that will be introduced in next
        version). Do you want to be able to inherit from remote class? :)

        Hope it helps. Any ideas how to do it better for OO interface will be
        greatly appreciated.

        Best wishes, Paul.

        --- joerg.ziefle@... wrote:
        > I have a Beam object whose blessed hash contains a Mass object:
        >
        > print $beam->mass
        >
        > in the program gives
        >
        > Mass=HASH(0x481250)
        >
        > Now I want to call methods of the Mass object:
        >
        > print $beam->mass->in_pounds
        >
        > But the in_pounds method of the Mass object is never called (no
        > error
        > message).
        >
        > Do I have to specify that I now want to use the Mass module? If
        > so,
        > is there a way to avoid this and do the remote calls as if they are
        >
        > local?
        >
        > Below is the (autodispatched code). I would be grateful for a
        > solution for both this autodispatched and the OOP interface way.
        >
        > Thanks,
        >
        > J�rg
        >
        > #!/usr/local/bin/perl -w
        >
        > use strict;
        >
        > # hostname censored
        > use SOAP::Lite
        > +autodispatch =>
        > uri => 'http://XXX/Beam',
        > proxy => 'http://XXX/';
        >
        > my $beam = Beam->new(
        > 'length' => 100,
        > 'type' => 'rectangular',
        > 'width' => 0.05,
        > 'height' => 0.05,
        > 'mass' => 50,
        > );
        >
        > print $beam->mass->in_pounds;
        >
        >
        >
        > To unsubscribe from this group, send an email to:
        > soaplite-unsubscribe@yahoogroups.com
        >
        >
        >
        > Your use of Yahoo! Groups is subject to
        > http://docs.yahoo.com/info/terms/
        >
        >


        __________________________________________________
        Do You Yahoo!?
        Yahoo! Auctions - buy the things you want at great prices
        http://auctions.yahoo.com/
      • joerg.ziefle@gmx.de
        Thanks for the extensive answer and examples, Paul! Your code works for me indeed. But what I forgot to mention in my posting was that I don t want to
        Message 3 of 6 , May 21, 2001
          Thanks for the extensive answer and examples, Paul!

          Your code works for me indeed. But what I forgot to mention in my
          posting was that I don't want to hardcode the modules in the dispatch_to
          method (as in your examples). My dispatch_to call just specifies the
          directory in which my modules are placed.

          I have

          -> dispatch_to('/dir/to/perl/modules/')

          instead of

          -> dispatch_to('A', 'B')


          And if I do that, it doesn't work again. :(

          So, is there a way of keeping the flexibility of dynamic autodispatching
          but being able to do the "subobject" method calls?

          It turns out that I get the error:

          Denied access to method (mass) in class (Mass) at
          /u0/gt4556a/perl/SOAP/Lite.pm line 1498.

          on the call

          print $beam->mass->mass;

          where $beam->mass returns a Mass object (this is verified with
          Data::Dumper) and the second mass call is a method of the returned Mass
          object.

          The situation doesn't change if I choose two different names for the
          methods, so a name clash can't be the reason.

          I have put the minimalized code at the following address for further
          inspection:

          Server:

          http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/daemon.plx

          Client:

          http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/abeamclient.plx

          Modules:

          (main object, contains Mass object)
          http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/Beam.pmx

          (contains the mass() method that fails for dynamic autodispatching)
          http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/Mass.pmx

          Thanks,

          Jörg

          P.s.: The first example works for me even if I don't specify the
          package explicitely:

          uri => 'http://www.soaplite.com/',

          instead of

          uri => 'http://www.soaplite.com/A',

          Is that intended?
        • Steve McKay
          If I understand your question correctly, we are getting around specifying each module individually by using the following dispatch_to line in our server:
          Message 4 of 6 , May 21, 2001
            If I understand your question correctly, we are getting around specifying
            each module individually by using the following dispatch_to line in our
            server:

            ->dispatch_to('/opt/soap/lib','[\w:]+');

            All of our perl modules live in /opt/soap/lib. The regex matches any module
            that contain words and allows the server to execute them. This will also
            traverse sub-directories in /opt/soap/lib in looking for modules.

            Hope that helps.

            Steve McKay.





            joerg.ziefle@... wrote:

            > Thanks for the extensive answer and examples, Paul!
            >
            > Your code works for me indeed. But what I forgot to mention in my
            > posting was that I don't want to hardcode the modules in the dispatch_to
            > method (as in your examples). My dispatch_to call just specifies the
            > directory in which my modules are placed.
            >
            > I have
            >
            > -> dispatch_to('/dir/to/perl/modules/')
            >
            > instead of
            >
            > -> dispatch_to('A', 'B')
            >
            > And if I do that, it doesn't work again. :(
            >
            > So, is there a way of keeping the flexibility of dynamic autodispatching
            > but being able to do the "subobject" method calls?
            >
            > It turns out that I get the error:
            >
            > Denied access to method (mass) in class (Mass) at
            > /u0/gt4556a/perl/SOAP/Lite.pm line 1498.
            >
            > on the call
            >
            > print $beam->mass->mass;
            >
            > where $beam->mass returns a Mass object (this is verified with
            > Data::Dumper) and the second mass call is a method of the returned Mass
            > object.
            >
            > The situation doesn't change if I choose two different names for the
            > methods, so a name clash can't be the reason.
            >
            > I have put the minimalized code at the following address for further
            > inspection:
            >
            > Server:
            >
            > http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/daemon.plx
            >
            > Client:
            >
            > http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/abeamclient.plx
            >
            > Modules:
            >
            > (main object, contains Mass object)
            > http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/Beam.pmx
            >
            > (contains the mass() method that fails for dynamic autodispatching)
            > http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/Mass.pmx
            >
            > Thanks,
            >
            > Jörg
            >
            > P.s.: The first example works for me even if I don't specify the
            > package explicitely:
            >
            > uri => 'http://www.soaplite.com/',
            >
            > instead of
            >
            > uri => 'http://www.soaplite.com/A',
            >
            > Is that intended?
            >
            > To unsubscribe from this group, send an email to:
            > soaplite-unsubscribe@yahoogroups.com
            >
            >
            >
            > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
          • Paul Kulchenko
            Hi, Joerg! Steve is absolutely right, it should work, but it might defeat the purspose of specifying modules explicitely in dispatch_to() method. You have only
            Message 5 of 6 , May 21, 2001
              Hi, Joerg!

              Steve is absolutely right, it should work, but it might defeat the
              purspose of specifying modules explicitely in dispatch_to() method.
              You have only two choices:
              1. you load modules yourself, directly (with 'use MODULE' in your
              server code) or indirectly ('use/require' in your module) and ALLOW
              SOAP server to dispatch calls there providing NAMES of those modules
              in dispatch_to() calls, either in full or with regexp.
              2. you do NOT load modules, but specify directory(ies), then ALL
              that SOAP processor will load from those directories will be allowed
              to be accessed, but SOAP processor needs to load them itself.

              You want to load it youself, but do not specify the name. You can
              follow Steve's advice, but in THAT case user will be able to access
              LWP::UserAgent, "system" or any other module on your system. I bet it
              isn't something you want. That's the way you should either list all
              modules you want to give access to, or at least limit those mask to
              something more meaningfull.

              At the same time, dispatch_to() list isn't something static. You can
              manipulate it if you want:

              # server code

              my $server = SOAP::Transport::HTTP::Daemon
              .....
              ;

              package Manipulate::Server;

              sub add {
              shift;
              $server->dispatch_to($server->dispatch_to, @_);
              }

              later in your module code you can do something like:

              sub new {
              ......
              Manipulate::Server->add('MyClass');
              bless {} => 'MyClass';
              }

              Code is incomplete, but you got the idea. I didn't try it, but don't
              see any reason why it shouldn't work.

              > > P.s.: The first example works for me even if I don't specify the
              > > package explicitely:
              > >
              > > uri => 'http://www.soaplite.com/',
              > >
              > > instead of
              > >
              > > uri => 'http://www.soaplite.com/A',
              > >
              > > Is that intended?
              Yes, autodispatch will specify class for (as PATH of URI) you even
              you don't. That's why this piece works with autodispatch and for OO
              you need to specify it manually. Tradeoff between flexibility and
              convenience :)

              Best wishes, Paul.

              --- Steve McKay <smckay@...> wrote:
              > If I understand your question correctly, we are getting around
              > specifying
              > each module individually by using the following dispatch_to line in
              > our
              > server:
              >
              > ->dispatch_to('/opt/soap/lib','[\w:]+');
              >
              > All of our perl modules live in /opt/soap/lib. The regex matches
              > any module
              > that contain words and allows the server to execute them. This
              > will also
              > traverse sub-directories in /opt/soap/lib in looking for modules.
              >
              > Hope that helps.
              >
              > Steve McKay.
              >
              >
              >
              >
              >
              > joerg.ziefle@... wrote:
              >
              > > Thanks for the extensive answer and examples, Paul!
              > >
              > > Your code works for me indeed. But what I forgot to mention in
              > my
              > > posting was that I don't want to hardcode the modules in the
              > dispatch_to
              > > method (as in your examples). My dispatch_to call just specifies
              > the
              > > directory in which my modules are placed.
              > >
              > > I have
              > >
              > > -> dispatch_to('/dir/to/perl/modules/')
              > >
              > > instead of
              > >
              > > -> dispatch_to('A', 'B')
              > >
              > > And if I do that, it doesn't work again. :(
              > >
              > > So, is there a way of keeping the flexibility of dynamic
              > autodispatching
              > > but being able to do the "subobject" method calls?
              > >
              > > It turns out that I get the error:
              > >
              > > Denied access to method (mass) in class (Mass) at
              > > /u0/gt4556a/perl/SOAP/Lite.pm line 1498.
              > >
              > > on the call
              > >
              > > print $beam->mass->mass;
              > >
              > > where $beam->mass returns a Mass object (this is verified with
              > > Data::Dumper) and the second mass call is a method of the
              > returned Mass
              > > object.
              > >
              > > The situation doesn't change if I choose two different names for
              > the
              > > methods, so a name clash can't be the reason.
              > >
              > > I have put the minimalized code at the following address for
              > further
              > > inspection:
              > >
              > > Server:
              > >
              > > http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/daemon.plx
              > >
              > > Client:
              > >
              > >
              >
              http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/abeamclient.plx
              > >
              > > Modules:
              > >
              > > (main object, contains Mass object)
              > > http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/Beam.pmx
              > >
              > > (contains the mass() method that fails for dynamic
              > autodispatching)
              > > http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/Mass.pmx
              > >
              > > Thanks,
              > >
              > > J�rg
              > >
              > > P.s.: The first example works for me even if I don't specify the
              > > package explicitely:
              > >
              > > uri => 'http://www.soaplite.com/',
              > >
              > > instead of
              > >
              > > uri => 'http://www.soaplite.com/A',
              > >
              > > Is that intended?
              > >
              > > To unsubscribe from this group, send an email to:
              > > soaplite-unsubscribe@yahoogroups.com
              > >
              > >
              > >
              > > Your use of Yahoo! Groups is subject to
              > http://docs.yahoo.com/info/terms/
              >
              >
              > To unsubscribe from this group, send an email to:
              > soaplite-unsubscribe@yahoogroups.com
              >
              >
              >
              > Your use of Yahoo! Groups is subject to
              > http://docs.yahoo.com/info/terms/
              >
              >


              __________________________________________________
              Do You Yahoo!?
              Yahoo! Auctions - buy the things you want at great prices
              http://auctions.yahoo.com/
            • Paul Kulchenko
              Hi, Joerg! ... Considering your examples can only recomment to add prefix to your classes (say Materials::CrossSection, Materials::Material) and then do:
              Message 6 of 6 , May 21, 2001
                Hi, Joerg!

                --- joerg.ziefle@... wrote:
                > Your code works for me indeed. But what I forgot to mention in my
                > posting was that I don't want to hardcode the modules in the
                > dispatch_to
                > method (as in your examples). My dispatch_to call just specifies
                > the directory in which my modules are placed.
                Considering your examples can only recomment to add prefix to your
                classes (say Materials::CrossSection, Materials::Material) and then
                do:

                dispatch_to('your/dir', 'Materials::\w+');

                You can definitely come up with better name for prefix, but probably
                that's the best way I can see.

                Best wishes, Paul.

                >
                > I have
                >
                > -> dispatch_to('/dir/to/perl/modules/')
                >
                > instead of
                >
                > -> dispatch_to('A', 'B')
                >
                >
                > And if I do that, it doesn't work again. :(
                >
                > So, is there a way of keeping the flexibility of dynamic
                > autodispatching
                > but being able to do the "subobject" method calls?
                >
                > It turns out that I get the error:
                >
                > Denied access to method (mass) in class (Mass) at
                > /u0/gt4556a/perl/SOAP/Lite.pm line 1498.
                >
                > on the call
                >
                > print $beam->mass->mass;
                >
                > where $beam->mass returns a Mass object (this is verified with
                > Data::Dumper) and the second mass call is a method of the returned
                > Mass
                > object.
                >
                > The situation doesn't change if I choose two different names for
                > the
                > methods, so a name clash can't be the reason.
                >
                > I have put the minimalized code at the following address for
                > further
                > inspection:
                >
                > Server:
                >
                > http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/daemon.plx
                >
                > Client:
                >
                >
                http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/abeamclient.plx
                >
                > Modules:
                >
                > (main object, contains Mass object)
                > http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/Beam.pmx
                >
                > (contains the mass() method that fails for dynamic autodispatching)
                > http://www.normans.isd.uni-stuttgart.de/~ziefle/soap/Mass.pmx
                >
                > Thanks,
                >
                > J�rg
                >
                > P.s.: The first example works for me even if I don't specify the
                > package explicitely:
                >
                > uri => 'http://www.soaplite.com/',
                >
                > instead of
                >
                > uri => 'http://www.soaplite.com/A',
                >
                > Is that intended?
                >
                > To unsubscribe from this group, send an email to:
                > soaplite-unsubscribe@yahoogroups.com
                >
                >
                >
                > Your use of Yahoo! Groups is subject to
                > http://docs.yahoo.com/info/terms/
                >
                >


                __________________________________________________
                Do You Yahoo!?
                Yahoo! Auctions - buy the things you want at great prices
                http://auctions.yahoo.com/
              Your message has been successfully submitted and would be delivered to recipients shortly.