Skip Menu |

This queue is for tickets about the EasyTCP CPAN distribution.

Report information
The Basics
Id: 31479
Status: new
Priority: 0/
Queue: EasyTCP

People
Owner: Nobody in particular
Requestors: TONVOON [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.26
Fixed in: (no value)



Subject: Does not process data if a negotiating command comes before data bucket
Was not getting callback to the data sub as expected. Using the perl debugger, I found that the serverclient hybrid object had a databucket of this: '_databucket' => ARRAY(0x870bbc8) 0 HASH(0x87179a0) 'data' => 'EN' 'realdata' => 0 1 HASH(0x8717a48) 'data' => HASH(0x842813c) So the first item in the array was a command and the second was a complex hash. However, the 2nd item was not being processed. I think this is due to the databucket array ref being changed during the foreach loop. This is the patch that fixes it: --- EasyTCP.pm.original 2007-12-13 12:28:43.287165224 +0000 +++ EasyTCP.pm 2007-12-13 12:55:05.450675792 +0000 @@ -842,7 +842,9 @@ # # Process all this client's data buckets # - foreach (@{ $serverclient->{_databucket} }) { + # Save a copy of the data into @_ because it could be + # amended if an internal negotiating command comes in before normal data + foreach (@_ = @{ $serverclient->{_databucket} }) { if ($_->{realdata}) { # I found that you need to save off the databucket before you can iterate through it. As the first item is a command which calls _serverclient_negotiate, this attempts to read some data via $client->data(). This method does a shift on {_databucket}. However, this then causes the next iteration of the foreach to bypass the 2nd item. I've attached a small perl program to demonstrate what is happening. You would expect output of "this\nold\nman", but due to the shift, this misses out the 2nd item, which is effectively what is happening within EasyTCP. I thought a @{ $array_ref } copied the data temporarily, but I guess it just dereferences it. Ton
Subject: changing_array.pl
#!/usr/bin/perl use warnings; use strict; my $a; $a = [qw(this old man)]; print "Without copying\n"; foreach my $i (@{$a}) { print $i,$/; shift @$a; } $a = [qw(this old man)]; print "Copied away first\n"; foreach my $i (@_ = @{$a}) { print $i,$/; shift @$a; }