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

Re: [soaplite] off-by-one on array input

Expand Messages
  • Sam Tregar
    ... SOAP calls are class method calls. The first parameter is the name of the class where foo is defined. Add: my $pkg = shift; above the line where you load
    Message 1 of 4 , Feb 26, 2002
      On Tue, 26 Feb 2002, v_pareto wrote:

      > sub foo {
      >
      > my @a = @_;
      > return($a[1]);
      >
      > }
      >
      > prints 0, not 1. Of course, I can shift my way around this problem,
      > but I would still consider this a bug. Arrays in perl start at 0.
      > What's going on here?

      SOAP calls are class method calls. The first parameter is the name of the
      class where foo is defined. Add:

      my $pkg = shift;

      above the line where you load @a and you should get the behavior you're
      looking for. If OO in Perl is new to you, may I suggest you read Damian
      Conway's excelent book "Object-Oriented Perl"?

      -sam
    • Duncan Cameron
      ... Not sure what you are looking at. This code: my @array1 = ( z , x , c , v ); my $r = $s- test1(@array1); generates XML like this:
      Message 2 of 4 , Feb 26, 2002
        On 2002-02-26 David Wright wrote:
        >> BTW, I don't think tht you are actually sending an array, rather a
        >> series of individual elements which the server decides to treat as
        >> an array. It's not the same as sending a SOAP array, which you
        >> asked about on this list a week ago.
        >
        >What I asked about a week ago was how to send an arrary from the server;
        >this question involved sending an array from the client. The undesirable
        >behaviour is that SOAP::Lite handles these situations asymmetrically.
        >
        >If you look with a packet sniffer, you will see that what goes out over
        >the wire when you
        > $soap->foo(@a)->result;
        >from the client is indeed a SOAP array. In fact, is has the exact same
        >XML structure as what goes out from the server when you
        > return [@a];

        Not sure what you are looking at. This code:

        my @array1 = ('z','x', 'c', 'v');
        my $r = $s->test1(@array1);

        generates XML like this:

        <namesp1:test1 xmlns:namesp1="urn:Demo">
        <c-gensym3 xsi:type="xsd:string">z</c-gensym3>
        <c-gensym5 xsi:type="xsd:string">x</c-gensym5>
        <c-gensym7 xsi:type="xsd:string">c</c-gensym7>
        <c-gensym9 xsi:type="xsd:string">v</c-gensym9>
        </namesp1:test1>

        This is not a SOAP array. Whereas return[@a] generates xml like:

        <namesp1:test1Response xmlns:namesp1="urn:Demo">
        <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[3]" xsi:type="SOAP-ENC:Array">
        <item xsi:type="xsd:string">a</item>
        <item xsi:type="xsd:string">b</item>
        <item xsi:type="xsd:string">c</item>
        </SOAP-ENC:Array>
        </namesp1:test1Response>

        >This is one reason this behaviour is undesirable. In one direction
        >(server passes array to client),
        > $a[0] (on client) = $a[0] (on server)
        >but in the other direction (client passes array to server)
        > $a[0] (on client) = $a[1] (on server)
        The 'off by one' is due to the class/object reference, and applies
        regardless of whether you're sending an array, a hash or a scalar.

        >The other reason this behaviour is undesirable is that it prevents you
        >from taking a perfectly good perl package you have written and turning
        >it into a SOAP service by just slapping on a SOAP::Transport:HTTP
        >wrapper. Array handling will be broken until you insert a shift
        >operation at the beginning of every subroutine that takes an array.
        The way to approach this is to wrap the existing function in a layer
        which discards the class and calls the function:

        package Package1;

        sub doit {
        my @array = @_;
        # do something;
        return 134;
        }

        package WrapPackage1;
        sub doit {
        my $class = shift;
        Package1::doit(@_);
        }

        >
        >Perl is not an OO language. We should stop breaking it by trying to make
        >it one.

        That's another topic!

        Regards,
        Duncan Cameron
      Your message has been successfully submitted and would be delivered to recipients shortly.