[31075] in Perl-Users-Digest
Perl-Users Digest, Issue: 2320 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sun Apr 5 16:19:49 2009
Date: Sun, 5 Apr 2009 13:19:42 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Sun, 5 Apr 2009 Volume: 11 Number: 2320
Today's topics:
uint32_t 0x80000000 unpacked as 0x7FFFFFFF <Alexander.Farber@gmail.com>
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF <someone@example.com>
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF (Jens Thoms Toerring)
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF <Alexander.Farber@gmail.com>
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF <Alexander.Farber@gmail.com>
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF (Jens Thoms Toerring)
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF (Jens Thoms Toerring)
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF <Alexander.Farber@gmail.com>
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF (Jens Thoms Toerring)
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF <someone@example.com>
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF <tadmc@seesig.invalid>
Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF (Jens Thoms Toerring)
Re: URI queries with varied amounts of named values <devrick88@gmail.com>
Re: URI queries with varied amounts of named values <devrick88@gmail.com>
Re: URI queries with varied amounts of named values <hjp-usenet2@hjp.at>
Re: URI queries with varied amounts of named values <devrick88@gmail.com>
Re: URI queries with varied amounts of named values <tadmc@seesig.invalid>
Re: URI queries with varied amounts of named values <devrick88@gmail.com>
What's the point of xsubpp's -csuffix option? <spamtrap@dot-app.org>
Re: What's the point of xsubpp's -csuffix option? <ben@morrow.me.uk>
Re: XRC vs Perl (GUI) generated code <aboudouvas@panafonet.gr>
Re: XRC vs Perl (GUI) generated code <cartercc@gmail.com>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Sat, 4 Apr 2009 01:54:21 -0700 (PDT)
From: "A. Farber" <Alexander.Farber@gmail.com>
Subject: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <e2fce741-3205-4788-937a-532263c560fe@j8g2000yql.googlegroups.com>
Hello,
I'm using perl 5.8.8 and gcc 3.3.5 of OpenBSD 4.3/i386
to unpack a C-structure received over a unix pipe
(where event_type is enum and SID_LEN is 32):
typedef struct request_header {
char sid[SID_LEN + 1];
event_type event;
time_t modified;
uint32_t arg;
} request_header;
I try to unpack it this way:
($self->{SID}, $self->{EVENT},
$self->{MOD}, $self->{ARG}) =
unpack 'A32x4L3', $self->{REQUEST};
It mostly works well, but for the ARG 0x80000000
I wrongly get 0x7FFFFFFF (which is same but negated?)
Could someone please advise me?
This signed/unsigned binary stuff is so confusing :-(
I tried to read perlpacktut several times, never got it 100%.
Thank you
Alex
------------------------------
Date: Sat, 04 Apr 2009 03:28:40 -0700
From: "John W. Krahn" <someone@example.com>
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <vDGBl.1027$FR3.1014@newsfe04.iad>
A. Farber wrote:
>
> I'm using perl 5.8.8 and gcc 3.3.5 of OpenBSD 4.3/i386
> to unpack a C-structure received over a unix pipe
> (where event_type is enum and SID_LEN is 32):
>
> typedef struct request_header {
> char sid[SID_LEN + 1];
> event_type event;
> time_t modified;
> uint32_t arg;
> } request_header;
char is a built-in C type that is defined by the standard but
event_type, time_t and uint32_t may be a macro or typedef somewhere in
your program and you have to determine what C type they represent in
order to unpack them.
> I try to unpack it this way:
>
> ($self->{SID}, $self->{EVENT},
> $self->{MOD}, $self->{ARG}) =
> unpack 'A32x4L3', $self->{REQUEST};
char sid[SID_LEN + 1]; implies, but does not guarantee, a C "string" so
you probably need 'Z33' to unpack it. Also, why are you skipping 4
bytes between $self->{SID} and $self->{EVENT}?
> It mostly works well, but for the ARG 0x80000000
> I wrongly get 0x7FFFFFFF (which is same but negated?)
They are two different numbers:
$ perl -le 'print for 0x80000000, 0x7FFFFFFF'
2147483648
2147483647
> Could someone please advise me?
>
> This signed/unsigned binary stuff is so confusing :-(
I think that char depends on the compiler? Some define it as signed and
some as unsigned? I have no idea whether event_type is signed or
unsigned or what size it is. time_t, I believe, is usually a signed
type but the size depends on how it is defined. And the 'u' at the
front of uint32_t implies that it is an unsigned type that is 32 bits wide.
> I tried to read perlpacktut several times, never got it 100%.
John
--
Those people who think they know everything are a great
annoyance to those of us who do. -- Isaac Asimov
------------------------------
Date: 4 Apr 2009 11:20:51 GMT
From: jt@toerring.de (Jens Thoms Toerring)
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <73ou4jF1000kaU1@mid.uni-berlin.de>
A. Farber <Alexander.Farber@gmail.com> wrote:
> I'm using perl 5.8.8 and gcc 3.3.5 of OpenBSD 4.3/i386
> to unpack a C-structure received over a unix pipe
> (where event_type is enum and SID_LEN is 32):
> typedef struct request_header {
> char sid[SID_LEN + 1];
> event_type event;
> time_t modified;
> uint32_t arg;
> } request_header;
> I try to unpack it this way:
> ($self->{SID}, $self->{EVENT},
> $self->{MOD}, $self->{ARG}) =
> unpack 'A32x4L3', $self->{REQUEST};
> It mostly works well, but for the ARG 0x80000000
> I wrongly get 0x7FFFFFFF (which is same but negated?)
I hope you realize that this is extremely system dependend.
The sizes of at least 'event_type' and 'time_t' depend on
the system you're using as well as the number of padding
bytes that may exist between the members of the structure
(that may even be depend on the C compiler you're using!).
And 0x80000000 and 0x7FFFFFFF are different uint32_t numbers,
the latter being 1 less than the former.
As John Kramer already pointed out, for the 33 byte long
string you need "Z33" to unpack it. Due to padding bytes
between the 'sid' and 'event' member the "x3" is needed
(as long as there are three bytes of padding).
Things ain't getting simpler from here. If I am not
mistaken, an enum value must be an int. So to unpack
it using "i" seems to be the best choice since it
should pick the right size automatically.
Next you've got to check if there are padding bytes following
the 'event_type' member and, if necessary skip them with enough
"x" - on my machine there are none.
'time_t' is even worse since al the C standard says about that
type is that it's "arithmetic type capable of representing times".
So it could be a signed or unsigned int or long but as well a
floating point type. All you can do is try to determine from
your header files what it is on your system. On mine (which
is x64) it seems to be a signed 64-bit integer value. Thus
on my machine I have to use "q" for unpack() - but that may
be different on a 32-bit system!
Now again padding bytes may follow... None so on my machine.
The final 'uint32_t' is simple since here only "L" is to be
considered.
Taking it all together I need on my machine
unpack "Z33x3iqL", $self->{ REQUEST };
to pick the data apart. It may need something else on yours.
That's why it is normally not a good idea to send structures
in binary form around since it's layout and the endian-ness
and sizes of the members might differ from machine to machine
(and even compiler to compiler).
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
------------------------------
Date: Sat, 4 Apr 2009 04:35:46 -0700 (PDT)
From: "A. Farber" <Alexander.Farber@gmail.com>
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <f15011f5-ac6d-4c06-adf1-8a487edc0893@j39g2000yqn.googlegroups.com>
Hello,
I've prepared a simple test case and
found the real reason for my problem -
the argument for atol() was out of range.
I'll probably switch to strtol()
in the C part of my C+Perl program.
Yes, I was using A32x4 because the terminating
null takes 4 bytes (because of padding).
$ cat test-case.c
#include <stdio.h>
#include <unistd.h>
#define SID "01234567890123456789012345678901"
#define SID_LEN 32
typedef enum event_type {
ALIVE = 1 << 0,
CHAT = 1 << 1,
JOIN = 1 << 2,
LOBBY = 1 << 3,
INDEX = 1 << 4,
END = 1 << 5,
EXIT = 1 << 6
} event_type;
typedef struct request_header {
char sid[SID_LEN + 1];
event_type event;
time_t modified;
uint32_t arg;
} request_header;
int main() {
request_header req;
strcpy(req.sid, SID);
req.event = INDEX;
req.modified = 0;
/* req.arg = 0x80000000; */
req.arg = atol("2147483648");
return sizeof(req) != write(STDOUT_FILENO, &req, sizeof(req));
}
$ cat test-case.pl
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my ($req, $href);
$req = qx(./test-case);
($href->{SID}, $href->{EVENT}, $href->{MOD}, $href->{ARG}) =
unpack 'A32x4L3', $req;
print Dumper($href);
printf "%x\n", $href->{ARG};
$ ./test-case.pl
$VAR1 = {
'SID' => '01234567890123456789012345678901',
'MOD' => 0,
'EVENT' => 16,
'ARG' => 2147483647
};
7fffffff
$ perl -v
This is perl, v5.8.8 built for i386-openbsd
$ gcc -v
gcc version 3.3.5 (propolice)
Thanks for comments
Alex
------------------------------
Date: Sat, 4 Apr 2009 04:38:04 -0700 (PDT)
From: "A. Farber" <Alexander.Farber@gmail.com>
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <edf5543b-e328-4a33-b9b7-3aeb22ce1039@f19g2000yqh.googlegroups.com>
On 4 Apr., 13:20, j...@toerring.de (Jens Thoms Toerring) wrote:
> I hope you realize that this is extremely system dependend.
This isn't too bad in my case, because it is
an Apache-module in C talking over a Unix-pipe to
a daemon in Perl, i.e. both run at the same machine...
Regards
Alex
------------------------------
Date: 4 Apr 2009 12:01:55 GMT
From: jt@toerring.de (Jens Thoms Toerring)
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <73p0hjF107ea6U2@mid.uni-berlin.de>
A. Farber <Alexander.Farber@gmail.com> wrote:
> On 4 Apr., 13:20, j...@toerring.de (Jens Thoms Toerring) wrote:
> > I hope you realize that this is extremely system dependend.
> This isn't too bad in my case, because it is
> an Apache-module in C talking over a Unix-pipe to
> a daemon in Perl, i.e. both run at the same machine...
Ok. It's just that the same program wouldn't work on my 64-bit
machine. And another point: for the enumerated type you should
not unpack() for an unsigned value, they're definitely signed.
So better use either "l" or "i" instead of "L" for that one.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
------------------------------
Date: 4 Apr 2009 12:48:07 GMT
From: jt@toerring.de (Jens Thoms Toerring)
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <73p387FvvkbuU1@mid.uni-berlin.de>
A. Farber <Alexander.Farber@gmail.com> wrote:
> Hello,
> I've prepared a simple test case and
> found the real reason for my problem -
> the argument for atol() was out of range.
> I'll probably switch to strtol()
> in the C part of my C+Perl program.
> Yes, I was using A32x4 because the terminating
> null takes 4 bytes (because of padding).
> $ cat test-case.c
> #include <stdio.h>
> #include <unistd.h>
> #define SID "01234567890123456789012345678901"
> #define SID_LEN 32
> typedef enum event_type {
> ALIVE = 1 << 0,
> CHAT = 1 << 1,
> JOIN = 1 << 2,
> LOBBY = 1 << 3,
> INDEX = 1 << 4,
> END = 1 << 5,
> EXIT = 1 << 6
> } event_type;
> typedef struct request_header {
> char sid[SID_LEN + 1];
> event_type event;
> time_t modified;
> uint32_t arg;
> } request_header;
> int main() {
> request_header req;
> strcpy(req.sid, SID);
> req.event = INDEX;
> req.modified = 0;
> /* req.arg = 0x80000000; */
> req.arg = atol("2147483648");
Here you try to convert to a signed long (that's what the
return type of atol() is). But that number (2^31 or, in
hex, 0x80000000) doesn't fit into a 32-bit long (which
seems to be what you have on your machine), and thus
atol() returns LONG_MAX, which is 2147483647 (0x7FFFFFFFF)
on your machine.
Using strtol() wouldn't change that since it also will
return LONG_MAX on too large a number. You better use
the strtoul() function instead (uint32_t and unsigned
long being obviously the same on your machine).
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
------------------------------
Date: Sat, 4 Apr 2009 08:49:33 -0700 (PDT)
From: "A. Farber" <Alexander.Farber@gmail.com>
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <4a84b636-dd4f-45ce-a5ad-42a38c339771@f19g2000yqo.googlegroups.com>
On 4 Apr., 14:48, j...@toerring.de (Jens Thoms Toerring) wrote:
> Using strtol() wouldn't change that since it also will
> return LONG_MAX on too large a number. You better use
> the strtoul() function instead (uint32_t and unsigned
> long being obviously the same on your machine).
gcc says:
module/mod_pref.c:74: warning: implicit declaration of function
`strtoul_is_not_a_portable_function_use_strtol_instead'
Regards
Alex
------------------------------
Date: 4 Apr 2009 17:31:49 GMT
From: jt@toerring.de (Jens Thoms Toerring)
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <73pjs5F100f6iU1@mid.uni-berlin.de>
A. Farber <Alexander.Farber@gmail.com> wrote:
> On 4 Apr., 14:48, j...@toerring.de (Jens Thoms Toerring) wrote:
> > Using strtol() wouldn't change that since it also will
> > return LONG_MAX on too large a number. You better use
> > the strtoul() function instead (uint32_t and unsigned
> > long being obviously the same on your machine).
> gcc says:
> module/mod_pref.c:74: warning: implicit declaration of function
> `strtoul_is_not_a_portable_function_use_strtol_instead'
That's rather surprising since strtoul() is required by
the C standard to exist, and that since 20 years now.
Did you include <stdlib.h>, where it's declared? And
then my version of gcc (4.3.2) doesn't utter any com-
plaints about the use of strtoul() even when invoked
with
gcc -std=c89 -W -Wall -ansi -pedantic
A web search for the warning seems to indicate that
some Apache header file may result in this nonsense
getting spit out if strtoul() isn't declared (i.e.
if you forgot to include <stdlib.h>). I am at a loss
to understand what that is supposed to be good for
(except that it's, of course, a bad idea to try to
use the function without a declaration in scope).
Regards, Jebs
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
------------------------------
Date: Sat, 04 Apr 2009 10:37:09 -0700
From: "John W. Krahn" <someone@example.com>
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <9VMBl.126$qO1.59@newsfe13.iad>
Jens Thoms Toerring wrote:
>
> As John Kramer already pointed out,
John Kramer?
John
--
Those people who think they know everything are a great
annoyance to those of us who do. -- Isaac Asimov
------------------------------
Date: Sat, 4 Apr 2009 12:56:42 -0500
From: Tad J McClellan <tadmc@seesig.invalid>
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <slrngtf7qq.uh.tadmc@tadmc30.sbcglobal.net>
John W. Krahn <someone@example.com> wrote:
> Jens Thoms Toerring wrote:
>>
>> As John Kramer already pointed out,
>
> John Kramer?
Maybe he meant Cosmo Kramer?
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
------------------------------
Date: 4 Apr 2009 19:07:26 GMT
From: jt@toerring.de (Jens Thoms Toerring)
Subject: Re: uint32_t 0x80000000 unpacked as 0x7FFFFFFF
Message-Id: <73ppfeFvs9j9U1@mid.uni-berlin.de>
John W. Krahn <someone@example.com> wrote:
> Jens Thoms Toerring wrote:
> >
> > As John Kramer already pointed out,
> John Kramer?
Sorry, I meant you, of course. I guess I have to
get my glasses checked...
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
------------------------------
Date: Sat, 4 Apr 2009 14:01:55 -0700 (PDT)
From: rick <devrick88@gmail.com>
Subject: Re: URI queries with varied amounts of named values
Message-Id: <c3e3acad-37d4-48c7-807b-1302c5e96373@l1g2000yqk.googlegroups.com>
On Apr 3, 1:00=A0pm, Jim Gibson <jimsgib...@gmail.com> wrote:
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> my @keys =3D qw( l format country zip category ua id );
> my @data;
> while( my $line =3D <DATA> ) {
> =A0 chomp($line);
> =A0 my @fields =3D split(/&/,$line);
> =A0 my %record =3D map { $_, ''} @keys;
> =A0 for my $field ( @fields ) {
> =A0 =A0 my( $key, $val ) =3D split(/=3D/,$field);
> =A0 =A0 $key =3D 'country' if $key eq 'alt-country';
> =A0 =A0 $record{$key} =3D $val;
> =A0 }
> =A0 push( @data, \%record );
>
> }
>
> for my $record ( @data ) {
> =A0 print join(',',@{$record}{@keys}), "\n";
>
> }
>
> __DATA__
> l=3Den&format=3Dxhtml
> format=3Dxml&country=3DUS&ua=3DMozilla
> l=3Dsp&zip=3D00000&category=3Dbooks
> l=3Den&format=3Dxml&id=3Dxyz
> l=3Dfr&country=3DUS&alt-country=3DCA
> __END__
>
> which produces:
>
> en,xhtml,,,,,
> ,xml,US,,,Mozilla,
> sp,,,00000,books,,
> en,xml,,,,,xyz
> fr,,CA,,,,
I'm a bit confused as to how hash's work with arrays. I created this
dummy_file.txt file. The first script I run produces the output it
should, as Jim documented. However, I need to perform this work
against an array and all atempts to work with the array have failed.
The biggest problem is the same line outputs itself repeatedly for the
number of items in the hash. I print both $key and $val and they show
the proper items but when I print the key/val pair I get the same line
repeating over and over. Could someone shed some light on this for
me?
# dummy_file.txt
l=3Den&format=3Dxhtml
format=3Dxml&country=3DUS&ua=3DMozilla
l=3Dsp&zip=3D00000&category=3Dbooks
l=3Den&format=3Dxml&id=3Dxyz
l=3Dfr&country=3DUS&alt-country=3DCA
working_version.pl
#!/usr/bin/perl
use strict;
use warnings;
my @keys =3D qw( l format country zip category ua id );
my @data;
open(FILE, 'dummy_file.txt') or die "Can't open file: $!";
while( my $line =3D <FILE> ) {
chomp($line);
my @fields =3D split(/&/,$line);
my %record =3D map { $_, ''} @keys;
for my $field ( @fields ) {
#print "$field\n";
my( $key, $val ) =3D split(/=3D/,$field);
$key =3D 'country' if $key eq 'alt-country';
$record{$key} =3D $val;
}
push( @data, \%record );
}
#print "@data\n";
for my $record ( @data ) {
print join(',',@{$record}{@keys}), "\n";
}
##################################################
failing_version.pl
#!/usr/bin/perl
use strict;
use warnings;
my @keys =3D qw( l format country zip category ua id );
my @data;
my @array;
# the file is in a pre-existing array so I need to mimic that behavior
here
open(FILE, 'dummy_file.txt') or die "Can't open file: $!";
while (<FILE>){
push (@array, $_);
}
my @fields =3D split(/&/,"@array");
my %record =3D map { $_, ''} @keys;
for my $field ( @fields ) {
chomp ($field);
my( $key, $val ) =3D split(/=3D/,$field);
$key =3D 'country' if $key eq 'alt-country';
$record{$key} =3D $val;
push( @data, \%record );
}
for my $record ( @data ) {
print join(',',@{$record}{@keys}), "\n";
}
------------------------------
Date: Sat, 4 Apr 2009 15:02:35 -0700 (PDT)
From: rick <devrick88@gmail.com>
Subject: Re: URI queries with varied amounts of named values
Message-Id: <d7839013-f1fa-4e0c-bc2b-0ae2345aa3fd@y13g2000yqn.googlegroups.com>
On Apr 4, 5:33=A0pm, "Peter J. Holzer" <hjp-usen...@hjp.at> wrote:
>
> Now @array contains the contents of 'dummy_file.txt', one line per
> element. So if want to do the same thing as before you just need to loop
> over the elements instead of the lines. So you just have to replace the
> single line
>
> =A0 =A0 while( my $line =3D <FILE> ) {
>
> from your working script with
>
> =A0 =A0 for my $line (@array) {
>
> > my @fields =3D split(/&/,"@array");
>
> Instead you concatenate all the lines (with spaces between them) and then=
split
> the result into fields.
>
> > my %record =3D map { $_, ''} @keys;
>
> Then construct a single record.
>
> > for my $field ( @fields ) {
> > =A0 =A0 chomp ($field);
> > =A0 =A0 my( $key, $val ) =3D split(/=3D/,$field);
> > =A0 =A0 $key =3D 'country' if $key eq 'alt-country';
> > =A0 =A0 $record{$key} =3D $val;
> > =A0 =A0 push( @data, \%record );
>
> And add that same record to the array for each field you find.
>
> > }
>
> If you don't understand what your program does it is often a good idea
> to step through it in the debugger:
>
> % perl -d failing_version.pl
>
> Loading DB routines from perl5db.pl version 1.3
> Editor support available.
>
> Enter h or `h h' for help, or `man perldebug' for more help.
>
> main::(rick2:6): =A0 =A0 =A0 =A0my @keys =3D qw( l format country zip cat=
egory ua
> id );
> =A0 DB<1> n
> main::(rick2:7): =A0 =A0 =A0 =A0my @data;
> [...]
> main::(rick2:16): =A0 =A0 =A0 my @fields =3D split(/&/,"@array");
> =A0 DB<1>
> main::(rick2:17): =A0 =A0 =A0 my %record =3D map { $_, ''} @keys;
> =A0 DB<1> x @fields
> 0 =A0'l=3Den'
> 1 =A0'format=3Dxhtml
> =A0format=3Dxml'
> 2 =A0'country=3DUS'
> 3 =A0'ua=3DMozilla
> =A0l=3Dsp'
> 4 =A0'zip=3D00000'
> 5 =A0'category=3Dbooks
> =A0l=3Den'
> 6 =A0'format=3Dxml'
> 7 =A0'id=3Dxyz
> =A0l=3Dfr'
> 8 =A0'country=3DUS'
> 9 =A0'alt-country=3DCA
> '
>
> So now you have 10 fields. Note that some of them probably don't look
> like you expected: $fields[1] is "format=3Dxhtml\n format=3Dxml", that is=
is
> contains an embedded newline and space. You probably wanted that to be
> two fields: "format=3Dxhtml" and "format=3Dxml".
>
> [...]
>
> At the beginning of the second run through the loop, @data looks fine:
>
> main::(rick2:19): =A0 =A0 =A0 =A0 =A0 chomp ($field);
> =A0 DB<6> x @data
> 0 =A0HASH(0x8cdb148)
> =A0 =A0'category' =3D> ''
> =A0 =A0'country' =3D> ''
> =A0 =A0'format' =3D> ''
> =A0 =A0'id' =3D> ''
> =A0 =A0'l' =3D> 'en'
> =A0 =A0'ua' =3D> ''
> =A0 =A0'zip' =3D> ''
>
> but at the second run it looks weird:
>
> main::(rick2:19): =A0 =A0 =A0 =A0 =A0 chomp ($field);
> =A0 DB<7> x @data
> 0 =A0HASH(0x8cdb148)
> =A0 =A0'category' =3D> ''
> =A0 =A0'country' =3D> ''
> =A0 =A0'format' =3D> 'xhtml
> =A0format'
> =A0 =A0'id' =3D> ''
> =A0 =A0'l' =3D> 'en'
> =A0 =A0'ua' =3D> ''
> =A0 =A0'zip' =3D> ''
> 1 =A0HASH(0x8cdb148)
> =A0 =A0-> REUSED_ADDRESS
> =A0 DB<8>
>
> You have just pushed a second reference to %record to @data. So now both
> elements point to the same data and both will be modified when you
> modify %record.
>
> =A0 =A0 =A0 =A0 hp
Explained perfectly, thank you for the help. I know how to fix this
problem and I understand how it works so I won't into this same issue
again.
------------------------------
Date: Sun, 5 Apr 2009 00:03:20 +0200
From: "Peter J. Holzer" <hjp-usenet2@hjp.at>
Subject: Re: URI queries with varied amounts of named values
Message-Id: <slrngtfm99.cjc.hjp-usenet2@hrunkner.hjp.at>
[superceded because of excessive quoting in the original]
On 2009-04-04 21:01, rick <devrick88@gmail.com> wrote:
> I'm a bit confused as to how hash's work with arrays. I created this
> dummy_file.txt file. The first script I run produces the output it
> should, as Jim documented. However, I need to perform this work
> against an array and all atempts to work with the array have failed.
> The biggest problem is the same line outputs itself repeatedly for the
> number of items in the hash. I print both $key and $val and they show
> the proper items but when I print the key/val pair I get the same line
> repeating over and over. Could someone shed some light on this for
> me?
>
> # dummy_file.txt
> l=en&format=xhtml
> format=xml&country=US&ua=Mozilla
> l=sp&zip=00000&category=books
> l=en&format=xml&id=xyz
> l=fr&country=US&alt-country=CA
>
>
> working_version.pl
> #!/usr/bin/perl
[...]
> open(FILE, 'dummy_file.txt') or die "Can't open file: $!";
> while( my $line = <FILE> ) {
> chomp($line);
> my @fields = split(/&/,$line);
> my %record = map { $_, ''} @keys;
> for my $field ( @fields ) {
[...]
> }
> push( @data, \%record );
> }
>
>
> #print "@data\n";
> for my $record ( @data ) {
> print join(',',@{$record}{@keys}), "\n";
> }
>
> ##################################################
> failing_version.pl
> #!/usr/bin/perl
[...]
> my @array;
>
> # the file is in a pre-existing array so I need to mimic that behavior
> here
> open(FILE, 'dummy_file.txt') or die "Can't open file: $!";
> while (<FILE>){
> push (@array, $_);
> }
Now @array contains the contents of 'dummy_file.txt', one line per
element. So if want to do the same thing as before you just need to loop
over the elements instead of the lines. So you just have to replace the
single line
while( my $line = <FILE> ) {
from your working script with
for my $line (@array) {
> my @fields = split(/&/,"@array");
Instead you concatenate all the lines (with spaces between them) and then split
the result into fields.
> my %record = map { $_, ''} @keys;
Then construct a single record.
> for my $field ( @fields ) {
> chomp ($field);
> my( $key, $val ) = split(/=/,$field);
> $key = 'country' if $key eq 'alt-country';
> $record{$key} = $val;
> push( @data, \%record );
And add that same record to the array for each field you find.
> }
If you don't understand what your program does it is often a good idea
to step through it in the debugger:
% perl -d failing_version.pl
Loading DB routines from perl5db.pl version 1.3
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(rick2:6): my @keys = qw( l format country zip category ua
id );
DB<1> n
main::(rick2:7): my @data;
[...]
main::(rick2:16): my @fields = split(/&/,"@array");
DB<1>
main::(rick2:17): my %record = map { $_, ''} @keys;
DB<1> x @fields
0 'l=en'
1 'format=xhtml
format=xml'
2 'country=US'
3 'ua=Mozilla
l=sp'
4 'zip=00000'
5 'category=books
l=en'
6 'format=xml'
7 'id=xyz
l=fr'
8 'country=US'
9 'alt-country=CA
'
So now you have 10 fields. Note that some of them probably don't look
like you expected: $fields[1] is "format=xhtml\n format=xml", that is is
contains an embedded newline and space. You probably wanted that to be
two fields: "format=xhtml" and "format=xml".
[...]
At the beginning of the second run through the loop, @data looks fine:
main::(rick2:19): chomp ($field);
DB<6> x @data
0 HASH(0x8cdb148)
'category' => ''
'country' => ''
'format' => ''
'id' => ''
'l' => 'en'
'ua' => ''
'zip' => ''
but at the second run it looks weird:
main::(rick2:19): chomp ($field);
DB<7> x @data
0 HASH(0x8cdb148)
'category' => ''
'country' => ''
'format' => 'xhtml
format'
'id' => ''
'l' => 'en'
'ua' => ''
'zip' => ''
1 HASH(0x8cdb148)
-> REUSED_ADDRESS
DB<8>
You have just pushed a second reference to %record to @data. So now both
elements point to the same data and both will be modified when you
modify %record.
hp
------------------------------
Date: Sun, 5 Apr 2009 07:41:28 -0700 (PDT)
From: rick <devrick88@gmail.com>
Subject: Re: URI queries with varied amounts of named values
Message-Id: <fee9821d-3dd6-4fd1-a6ee-def739c3cfc1@f19g2000yqh.googlegroups.com>
On Apr 3, 1:00=A0pm, Jim Gibson <jimsgib...@gmail.com> wrote:
> my @keys =3D qw( l format country zip category ua id );
> my @data;
> while( my $line =3D <DATA> ) {
> =A0 chomp($line);
> =A0 my @fields =3D split(/&/,$line);
> =A0 my %record =3D map { $_, ''} @keys;
> =A0 for my $field ( @fields ) {
> =A0 =A0 my( $key, $val ) =3D split(/=3D/,$field);
> =A0 =A0 $key =3D 'country' if $key eq 'alt-country';
> =A0 =A0 $record{$key} =3D $val;
> =A0 }
Is there a way to turn the 'country' / 'alt-country' check override
into a variable? For example, let's say I have 'zip' and 'alt-zip'
and a number of others. Basically, anytime there is an "alt-" it
should overwrite the original. I thought I could take care of easily
overriding this but it's not as straight forward as I thought. I have
printed out the various "alt-" attempts below to see if the output is
what I expect and it is when done in a straight 'print "alt-$key"' so
my guess is it has something to do with the value type, scalar vs.
what the hash actually has for values.
#!/usr/bin/perl
use strict;
use warnings;
my @keys =3D qw( l format country zip category ua id );
my @data;
while( my $line =3D <DATA> ) {
chomp($line);
my @fields =3D split(/&/,$line);
my %record =3D map { $_, ''} @keys;
for my $field ( @fields ) {
my( $key, $val ) =3D split(/=3D/,$field);
# works for this simple example but there are too many other
fields in the real logs to make this viable
#$key =3D 'country' if $key eq 'alt-country';
#$key =3D 'zip' if $key eq 'alt-zip';
# only the original values shown, not the "alt-" overrides
#$key =3D $key if $key eq "alt-$key";
#$key =3D "$key" if $key eq "alt-$key";
# fail with scalar errors
#$key =3D $key if $key eq "alt-"$key;
#$key =3D $key if $key eq 'alt-'$key;
$record{$key} =3D $val;
}
push( @data, \%record );
}
for my $record ( @data ) {
print join(',',@{$record}{@keys}), "\n";
}
__DATA__
l=3Den&format=3Dxhtml
format=3Dxml&country=3DUS&ua=3DMozilla
l=3Dsp&zip=3D00000&category=3Dbooks&alt-zip=3D00000-1234
l=3Den&format=3Dxml&id=3Dxyz
l=3Dfr&country=3DUS&alt-country=3DCA
__END__
------------------------------
Date: Sun, 5 Apr 2009 11:25:04 -0500
From: Tad J McClellan <tadmc@seesig.invalid>
Subject: Re: URI queries with varied amounts of named values
Message-Id: <slrngthmr0.c3h.tadmc@tadmc30.sbcglobal.net>
rick <devrick88@gmail.com> wrote:
> Is there a way to turn the 'country' / 'alt-country' check override
"override" has a precise technical meaning.
There is no overriding anywhere in this code.
There is "overwriting" in this code though...
> into a variable? For example, let's say I have 'zip' and 'alt-zip'
> and a number of others. Basically, anytime there is an "alt-" it
> should overwrite the original. I thought I could take care of easily
> overriding this but it's not as straight forward as I thought.
I expect that it is not as *complicated* as you thought!
> my guess is it has something to do with the value type, scalar vs.
> what the hash actually has for values.
That makes no sense.
*all* hash values are scalars.
It is not possible for a hash value to be anything other than a scalar.
> #!/usr/bin/perl
> use strict;
> use warnings;
>
> my @keys = qw( l format country zip category ua id );
> my @data;
> while( my $line = <DATA> ) {
> chomp($line);
> my @fields = split(/&/,$line);
> my %record = map { $_, ''} @keys;
> for my $field ( @fields ) {
> my( $key, $val ) = split(/=/,$field);
>
$key =~ s/^alt-//; # convert "alt-anything" to "anything"
> # fail with scalar errors
> #$key = $key if $key eq "alt-"$key;
What the heck is a "scalar error"?
I've never heard of such a thing.
You really need to take more care in your terminology if you
hope to become a programmer.
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
------------------------------
Date: Sun, 5 Apr 2009 10:47:42 -0700 (PDT)
From: rick <devrick88@gmail.com>
Subject: Re: URI queries with varied amounts of named values
Message-Id: <8be67399-fb11-46ea-8706-7a66d8cee83a@q16g2000yqg.googlegroups.com>
On Apr 5, 12:25=A0pm, Tad J McClellan <ta...@seesig.invalid> wrote:
> =A0 =A0 =A0 $key =3D~ s/^alt-//; =A0# convert "alt-anything" to "anything=
"
Thanks Tad, that was what I was hoping to get accomplished. Trust me,
I know better than anyone that I need to learn the lingo better. I am
sure this problem has been solved many times over and the problem is
that I don't know the language well enough to know what search term to
use when looking through perldocs or searching previous posts in the
newsgroup. I have a few Perl books and searching through them and on
the newsgroup for hash didn't get me where I needed to be.
As a sysadmin I have to focus on just getting things working so I know
just enough of several languages to fix problems without having
mastered any. I have made it my mission this year to pick a language
and really focus on it. Knowing Bash and a few others really well
already, and wanting to expand a bit I have thought about Perl, Python
or Ruby. For the work that I do focusing on Perl makes the most sense
for me.
Thanks again
------------------------------
Date: Sat, 04 Apr 2009 11:29:11 -0400
From: Sherm Pendley <spamtrap@dot-app.org>
Subject: What's the point of xsubpp's -csuffix option?
Message-Id: <m1eiw8h1yw.fsf@dot-app.org>
Why does xsubpp have a -csuffix option, when it can only (as far as I can
see from its perldoc) send its output to stdout, not to a file?
sherm--
--
My blog: http://shermspace.blogspot.com
Cocoa programming in Perl: http://camelbones.sourceforge.net
------------------------------
Date: Sat, 4 Apr 2009 16:40:47 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: What's the point of xsubpp's -csuffix option?
Message-Id: <vkbka6-543.ln1@osiris.mauzo.dyndns.org>
Quoth Sherm Pendley <spamtrap@dot-app.org>:
> Why does xsubpp have a -csuffix option, when it can only (as far as I can
> see from its perldoc) send its output to stdout, not to a file?
-output will direct the output to a file. -csuffix appears to only be
useful when using ExtUtils::ParseXS directly, as there doesn't seem to
be any way of invoking its functionality from xsubpp.
Ben
------------------------------
Date: Sat, 4 Apr 2009 14:37:49 -0700 (PDT)
From: king kikapu <aboudouvas@panafonet.gr>
Subject: Re: XRC vs Perl (GUI) generated code
Message-Id: <f040f34b-9548-48c3-be83-0a0ac98ccdde@p11g2000yqe.googlegroups.com>
> Do you want to know whether a hammer is good at installing screws, or
> bolts? Or if a screwdriver is good at installing nails or bolts? Perl
> (IMO) is a rifle, good at a small slice of tasks ... witness its name,
> the Practical Extraction & Reporting Language. If you want to do data
> extraction, manipulation, reformatting, and reporting, Perl is a good
> choice. It might be a poor choice for other kinds of jobs.
I think Perl has become a general programming language and that
"extraction and reporting" section was only meant when Perl started,
now Perl is way beyond that.
I have also used Python and saw that it can be used for virtually
everything
and so i do think for Perl.
The fact that you can do something more easily in java (GUI) doesn't
mean
that it is impossible or poor choice in Perl.
wxWidgets is a very nice option in this matter and form designers
already
exists!
> You didn't ask this, but FWIW, my feeling is that GUI apps in general
> are a dying breed. Where I work, a large state university, all the
> apps we've gotten in the last four years have been web apps, with the
> sole exception of the database applications we use. I work in IT, and
> pushing apps to clients, several thousand in our case, is for the
> birds or the insane. Much easier to put an app on a server and let the
> client connect to it with a browser. It's not up to me to judge your
> intention in building a GUI app, and if you have a killer app that
> will make you millions, I sincerely wish you all the best. But my take
> as one who likes to stay in touch with what is going on in various
> communities (Perl included) is that using Perl for building GUI apps
> doesn't constitute a big sector of Perl programming and is becoming a
> smaller sector of other programming technologies.
I agree with you for the web trend and in fact, is is on my mind to
spend
more time to learn to program web apps with Perl.
But web apps simply cannot do many of the things that desktop apps do,
desktop has myriad of options that the web does not have right now...
------------------------------
Date: Sun, 5 Apr 2009 13:03:25 -0700 (PDT)
From: ccc31807 <cartercc@gmail.com>
Subject: Re: XRC vs Perl (GUI) generated code
Message-Id: <94c469c3-6e41-42f6-bef2-8cc0c13645ed@w9g2000yqa.googlegroups.com>
On Apr 4, 5:37=A0pm, king kikapu <aboudou...@panafonet.gr> wrote:
> I think Perl has become a general programming language and that
> "extraction and reporting" section was only meant when Perl started,
> now Perl is way beyond that.
We disagree. That's not to say that your are wrong, you may very well
be right and I may be wrong, but nevertheless I think that Perl isn't
well suited for general programming.
> I have also used Python and saw that it can be used for virtually
> everything
> and so i do think for Perl.
I've used Python as well, but form my job, Perl allows me to write
little scripts easier and quicker than I can do with Python.
> The fact that you can do something more easily in java (GUI) doesn't
> mean
> that it is impossible or poor choice in Perl.
If you can do it easier in Java, I would argue that Java is a 'better'
choice.
> I agree with you for the web trend and in fact, is is on my mind to
> spend
> more time to learn to program web apps with Perl.
I've also written web apps with JSP and Servlets, and I can tell you
from experience that Perl is a better choice. I'm working now on an
app that was originally written in Java that took a year, cost $30,000
and still didn't work. I'm rewritting it in Perl, have billed the
client $1,050 so far, and in three weeks have almost almost programmed
all the functionality that was in the Java version. (Not because I'm
using Perl, the requirements changed rather dramatically and Perl was
just a good fit for the changed requirements.)
> But web apps simply cannot do many of the things that desktop apps do,
> desktop has myriad of options that the web does not have right now...
True, but the administrative headaches are bigger. It's a tradeoff,
but I'd bet that for most of the usual stuff, a web app can to all it
needs to, and the surplus provided by stand alone apps isn't cost
efficient.
Don't get me wrong -- Perl is a genuine pearl for certain kinds of
things. IMO general purpose programs aren't one of those kinds of
things.
CC
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
#The Perl-Users Digest is a retransmission of the USENET newsgroup
#comp.lang.perl.misc. For subscription or unsubscription requests, send
#the single line:
#
# subscribe perl-users
#or:
# unsubscribe perl-users
#
#to almanac@ruby.oce.orst.edu.
NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
#To request back copies (available for a week or so), send your request
#to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
#where x is the volume number and y is the issue number.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 2320
***************************************