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

in/out parameters binding

Expand Messages
  • Pierre DENIS
    Hello, In SOAP::Lite there s an interesting feature that is powerful, but scary: the in/out parameters binding (see code extract below). Tell me if I m wrong,
    Message 1 of 3 , May 9, 2002
    • 0 Attachment
      Hello,

      In SOAP::Lite there's an interesting feature that is powerful, but scary:
      the in/out parameters binding (see code extract below).

      Tell me if I'm wrong, but the purpose is to bind the client parameters with
      what happens on the server side.
      It allows the code to run as if it was ran locally. The data the server
      alter are also altered on the client side, magically.
      This is really nice, however, it can lead to very tricky bugs, because that
      is *not* an expected behavior (at least, not by me).

      Again, I may not understand everything here, so please correct me if I miss
      a point.
      When I use SOAP, I expect the client to be completely shielded from the
      server. Even if the server change the content of the hashref I'm sending,
      the client should keep the hashref as-is.
      But in some occasions, it doesn't. The magic binding propagate the change to
      the client.
      Now, I think it's a specific SOAP::Lite behavior, and that's not a part of
      SOAP specfication (is it?). Moreover, it seems to works only with a client
      AND server using SOAP::Lite.
      So the behavior would be different with a .net client and a SOAP::Lite
      server. I think that leads to problems. And to say the truth, I've spent
      several hours trying to debug something related to that auto-binding.

      I would be glad to have an explanation about the purpose of the binding and
      when it occurs.
      Ideally, it would be nice to switch it on or off, so I don't have too much
      magic happening, but maybe that's already possible.

      Thank you


      ============================================


      # little bit tricky part that binds in/out parameters
      if (UNIVERSAL::isa($result => 'SOAP::SOM') &&
      ($result->paramsout || $result->headers) &&
      $serializer->signature) {
      my $num = 0;
      my %signatures = map {$_ => $num++} @{$serializer->signature};
      for ($result->dataof(SOAP::SOM::paramsout),
      $result->dataof(SOAP::SOM::headers)) {
      my $signature = join $;, $_->name, $_->type || '';
      if (exists $signatures{$signature}) {
      my $param = $signatures{$signature};
      my($value) = $_->value; # take first value
      UNIVERSAL::isa($_[$param] => 'SOAP::Data') ?
      $_[$param]->SOAP::Data::value($value) :
      UNIVERSAL::isa($_[$param] => 'ARRAY') ? (@{$_[$param]} =
      @$value) :
      UNIVERSAL::isa($_[$param] => 'HASH') ? (%{$_[$param]} =
      %$value) :
      UNIVERSAL::isa($_[$param] => 'SCALAR') ? (${$_[$param]} =
      $$value) :
      ($_[$param] = $value)
      }
      }
      }

      Pierre Denis
    • Paul Kulchenko
      Hi, Pierre! ... yes. ... yes. ... it is ;) when you have sub a { $_[0] = b } $a = a ; a($a); print $a; you expect it to print b as far as I understand.
      Message 2 of 3 , May 9, 2002
      • 0 Attachment
        Hi, Pierre!

        --- Pierre DENIS <pdenis@...> wrote:
        > Tell me if I'm wrong, but the purpose is to bind the client
        > parameters with what happens on the server side.
        yes.

        > It allows the code to run as if it was ran locally. The data the
        > server alter are also altered on the client side, magically.
        yes.

        > This is really nice, however, it can lead to very tricky bugs,
        > because that is *not* an expected behavior (at least, not by me).
        it is ;)

        when you have

        sub a { $_[0] = 'b' }

        $a = 'a';
        a($a);
        print $a;

        you expect it to print 'b' as far as I understand. That's exactly
        what's happening here.

        > When I use SOAP, I expect the client to be completely shielded from
        > the server.
        yes.

        > Even if the server change the content of the hashref I'm sending,
        > the client should keep the hashref as-is.
        May or may not be the case. See above. Also when $a is an object:

        $a->foo('bar'); # which is almost the same as foo($a, 'bar')

        may change attributes of $a.

        > But in some occasions, it doesn't. The magic binding propagate the
        > change to the client.
        yes. it's part of contract. if you have a('a'); in early mentioned
        example, you'll get an error.

        > Now, I think it's a specific SOAP::Lite behavior, and that's not a
        > part of SOAP specification (is it?).
        no. It's part of SOAP spec that describes in, out and in/out
        parameters.

        > Moreover, it seems to works only with a
        > client AND server using SOAP::Lite.
        no. it'll work with SOAP::Lite on client AND server side as well as
        with SOAP::Lite on client OR server side. Other implementations use
        information from service description to do the mapping, whereas
        SOAP::Lite uses name/type information to do the same thing.

        > So the behavior would be different with a .net client and a
        > SOAP::Lite server.
        No. At least in theory ;). the ONLY processing that is specific for
        SOAP::Lite is object binding. when you do

        $a->foo('bar')

        and this method gets executed on server side you expect to get
        modified $a back when this object is modified on server side. However
        there is no way to return this object back as return parameter, so
        SOAP::Lite uses header information to do that. If you have
        non-SOAP::Lite server, your object ($a) won't be updated. Everything
        else, including method result, will work just fine.

        > I think that leads to problems. And to say the truth, I've
        > spent
        > several hours trying to debug something related to that
        > auto-binding.
        Any details? I may add tracing for that step.

        > I would be glad to have an explanation about the purpose of the
        > binding and when it occurs.
        It occurs only when incoming and outcoming parameters have the same
        name and type. SOAP::Lite will try to assign new value and will
        generate an error if you have static value or incompatible type
        (array ref on one side and hash ref on another side), which is
        probably what you expect.

        > Ideally, it would be nice to switch it on or off, so I don't have
        > too much magic happening, but maybe that's already possible.
        no, currently there is no way to switch is off. Although you can
        overload signature() method of SOAP::Serializer and return undef. Is
        it really necessary?

        Best wishes, Paul.

        __________________________________________________
        Do You Yahoo!?
        Yahoo! Shopping - Mother's Day is May 12th!
        http://shopping.yahoo.com
      • Pierre DENIS
        Hi Paul, Thank you for the explanation. If object binding only occurs with SOAP::Lite server and client, it can be surprising because the behavior will be
        Message 3 of 3 , May 10, 2002
        • 0 Attachment
          Hi Paul,

          Thank you for the explanation.

          If object binding only occurs with SOAP::Lite server and client, it can be
          surprising because the behavior will be different from one client to
          another.
          Can you tell me which section of SOAP specifies the binding of objects in
          client and server as explained in your example? I've missed that point in
          http://www.w3.org/TR/SOAP/

          I've encountered a problem with object binding, this is a simplified example
          of the problem:

          ========

          $obj1 = bless { foo => 'bar' } => 'MyPackage';
          $obj2 = bless { foo => 'boo' } => 'MyPackage';

          $result = $soap->call( 'mymethod', $obj1, $obj2);

          =======
          After calling the soap service with $soap, the result is:
          $result is a scalar
          $obj1 = bless { foo => 'bar' } => 'MyPackage';
          $obj2 = bless { foo => 'bar' } => 'MyPackage'; ??????????? - $obj2 has
          became $obj1

          I've made many tests, and so far, the problem occurs when I send 2 objects
          of the same type. Then, the second object becomes the first object. The
          memory space of each objects don't change and the 2d object alteration
          occurs in SOAP::Lite, in the in/out binding section.
          On the server side, $obj2 is not altered at all.
          So, if I use the code locally, not through SOAP::Lite, it works fine, but if
          I use it through SOAP::Lite, the 2d object is altered.

          Did I miss something?

          Regards


          -----Original Message-----
          From: Paul Kulchenko [mailto:paulclinger@...]
          Sent: 09 May 2002 16:34
          To: Pierre DENIS; soaplite@yahoogroups.com
          Subject: Re: [soaplite] in/out parameters binding


          Hi, Pierre!

          --- Pierre DENIS <pdenis@...> wrote:
          > Tell me if I'm wrong, but the purpose is to bind the client
          > parameters with what happens on the server side.
          yes.

          > It allows the code to run as if it was ran locally. The data the
          > server alter are also altered on the client side, magically.
          yes.

          > This is really nice, however, it can lead to very tricky bugs,
          > because that is *not* an expected behavior (at least, not by me).
          it is ;)

          when you have

          sub a { $_[0] = 'b' }

          $a = 'a';
          a($a);
          print $a;

          you expect it to print 'b' as far as I understand. That's exactly
          what's happening here.

          > When I use SOAP, I expect the client to be completely shielded from
          > the server.
          yes.

          > Even if the server change the content of the hashref I'm sending,
          > the client should keep the hashref as-is.
          May or may not be the case. See above. Also when $a is an object:

          $a->foo('bar'); # which is almost the same as foo($a, 'bar')

          may change attributes of $a.

          > But in some occasions, it doesn't. The magic binding propagate the
          > change to the client.
          yes. it's part of contract. if you have a('a'); in early mentioned
          example, you'll get an error.

          > Now, I think it's a specific SOAP::Lite behavior, and that's not a
          > part of SOAP specification (is it?).
          no. It's part of SOAP spec that describes in, out and in/out
          parameters.

          > Moreover, it seems to works only with a
          > client AND server using SOAP::Lite.
          no. it'll work with SOAP::Lite on client AND server side as well as
          with SOAP::Lite on client OR server side. Other implementations use
          information from service description to do the mapping, whereas
          SOAP::Lite uses name/type information to do the same thing.

          > So the behavior would be different with a .net client and a
          > SOAP::Lite server.
          No. At least in theory ;). the ONLY processing that is specific for
          SOAP::Lite is object binding. when you do

          $a->foo('bar')

          and this method gets executed on server side you expect to get
          modified $a back when this object is modified on server side. However
          there is no way to return this object back as return parameter, so
          SOAP::Lite uses header information to do that. If you have
          non-SOAP::Lite server, your object ($a) won't be updated. Everything
          else, including method result, will work just fine.

          > I think that leads to problems. And to say the truth, I've
          > spent
          > several hours trying to debug something related to that
          > auto-binding.
          Any details? I may add tracing for that step.

          > I would be glad to have an explanation about the purpose of the
          > binding and when it occurs.
          It occurs only when incoming and outcoming parameters have the same
          name and type. SOAP::Lite will try to assign new value and will
          generate an error if you have static value or incompatible type
          (array ref on one side and hash ref on another side), which is
          probably what you expect.

          > Ideally, it would be nice to switch it on or off, so I don't have
          > too much magic happening, but maybe that's already possible.
          no, currently there is no way to switch is off. Although you can
          overload signature() method of SOAP::Serializer and return undef. Is
          it really necessary?

          Best wishes, Paul.

          __________________________________________________
          Do You Yahoo!?
          Yahoo! Shopping - Mother's Day is May 12th!
          http://shopping.yahoo.com


          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/
        Your message has been successfully submitted and would be delivered to recipients shortly.