[25666] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 7907 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Mar 23 03:05:39 2005

Date: Wed, 23 Mar 2005 00:05:13 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Wed, 23 Mar 2005     Volume: 10 Number: 7907

Today's topics:
        How do i send email as HTML format using Net::SMTP_auth <urgearun@gmail.com>
    Re: How do i send email as HTML format using Net::SMTP_ <noreply@gunnar.cc>
        LWP Doesn't Seem To Save Cookies: <hal@thresholddigital.com>
    Re: LWP Doesn't Seem To Save Cookies: <toddrw69@excite.com>
    Re: memory leak in 5.8.2??? <sisyphus1@optusnet.com.au>
    Re: Need help getting start with a test cgi script. <chariya@verizon.not>
        newbie question <usr@nomail.mail>
    Re: newbie question <postmaster@castleamber.com>
    Re: newbie question <tadmc@augustmail.com>
        perl thread question cji_work@yahoo.com
    Re: perl thread question <pilkowsk@informatik.uni-marburg.de>
        Regex: changing longer patterns to shorter ones <stevo@berkeley.edu>
    Re: Regex: changing longer patterns to shorter ones <noreply@gunnar.cc>
    Re: Regex: changing longer patterns to shorter ones <tadmc@augustmail.com>
        Seeking Recommendations For Perl Shopping Cart System <john_tilly@hotmail.com>
    Re: Seeking Recommendations For Perl Shopping Cart Syst <sbryce@scottbryce.com>
    Re: simple help <tadmc@augustmail.com>
    Re: The error "Use of uninitialized value " <tadmc@augustmail.com>
    Re: Two-dim array: Strange "can't use string as ARRAY r <spamtrap@dot-app.org>
    Re: Two-dim array: Strange "can't use string as ARRAY r <noreply@gunnar.cc>
    Re: Two-dim array: Strange "can't use string as ARRAY r <tadmc@augustmail.com>
    Re: Two-dim array: Strange "can't use string as ARRAY r <noreply@gunnar.cc>
    Re: Two-dim array: Strange "can't use string as ARRAY r <eric-amick@comcast.net>
    Re: Two-dim array: Strange "can't use string as ARRAY r <nobull@mail.com>
    Re: Will XML::Simple work with keys, strings, integers, <jgibson@mail.arc.nasa.gov>
    Re: Will XML::Simple work with keys, strings, integers, <postmaster@castleamber.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: 22 Mar 2005 19:34:14 -0800
From: "arun" <urgearun@gmail.com>
Subject: How do i send email as HTML format using Net::SMTP_auth
Message-Id: <1111548854.406035.57360@z14g2000cwz.googlegroups.com>

Hi
How do i send HTML Mail using Perl Module Net::SMTP_auth. Right now i
can able to send the mail but the receipents are able to view all the
HTML tags. How to resolve this.

With Regards
Arun



------------------------------

Date: Wed, 23 Mar 2005 04:43:38 +0100
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: How do i send email as HTML format using Net::SMTP_auth
Message-Id: <3ac75mF69r5a1U1@individual.net>

arun wrote:
> How do i send HTML Mail using Perl Module Net::SMTP_auth. Right now i
> can able to send the mail but the receipents are able to view all the
> HTML tags. How to resolve this.

Probably by specifying the correct content-type.

See Mail::Sender for a mail sending module that handles authentication 
and whose docs includes HTML examples.

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl


------------------------------

Date: Wed, 23 Mar 2005 01:14:15 -0500
From: Hal Vaughan <hal@thresholddigital.com>
Subject: LWP Doesn't Seem To Save Cookies:
Message-Id: <2Y-dnU1DnpqllNzfRVn-jA@comcast.com>

I'm trying to write a scraper for a website that uses cookies.  The short of
it is that I keep getting their "You have to set your browser to allow
cookies" message.  The code for the full scraper is a bit much, so here are
the relevant sections:

 use File::Spec::Functions;
 use File::Basename;
 use File::Copy;
 use LWP::UserAgent;
 use HTTP::Cookies;
 use URI::WithBase;
 use DBI;
 use strict;

Here's where I set up the variables (not all "my" and "our" statements are
included):

 print "Cookie file: $cfile\n";
 $ua = LWP::UserAgent->new;
 $ua->timeout(5);
 $ua->agent("Netscape/7.1");
 $cjar = HTTP::Cookies->new(file =>$cfile, autosave => 1, ignore_discard =>
1);
 $ua->cookie_jar($cjar);

Here's where I get the login page (which I always retrieve to make sure the
fields or info hasn't changed):


  $page = $ua->get($url);
  $page = $page->as_string;

And after that, I go through the page, make sure the form input fields
haven't changed (which are "login" and "key" for the username and
password).  Then I post the data for the next page, including the form
data:


 $parm = "";
 foreach (keys %form) {
 print "\tAdding parm.  Key: $_, Value: $form{$_}\n";
  $parm = "$parm$_=$form{$_}&";
 }
 $parm =~ s/&$//;
 $req = HTTP::Request->new(POST => $url);
 $req->content_type("application/x-www-form-urlencoded");
 $req->header('Accept' => 'text/html');
 $req->content_type("form-data");
 $req->content($parm);
 $page = $ua->request($req);

When I'm building up $parm, I'm taking the values from %form.  I TRIED to
use the hash to post the values, using "$page = $ua->post($url, \%form);",
but even though it worked on a test web server on my LAN, it wouldn't work
on the system I'm scraping (don't know why -- if you can help here as well,
feel free to chip in).

The problem comes up when I use the code above to post the form data and get
the next page.  The next page is a frameset with two frames.  I get the
frame urls from the page and load them:

 $req = HTTP::Request->new(GET => $url);
 $req->content_type("application/x-www-form-urlencoded");
 $req = $ua->request($req);
 $page = $req->as_string;

And this is when I always get the "You don't have cookies" message.

I thought that LWP automatically took the cookies out of the page (I also
thought cookies were in the header, the one here is set with
document.cookie="doc cookie" within the document), and stored them in the
cookie jar automatically.  That doesn't seem to be happening.  I've been
reading the perldocs, but I can't see anything in the response object that
allows me to check the page for cookies, so I can do it myself.

So why aren't the cookies being kept and why can't the pages I retrieve
AFTER the cookie is set?  Is part of the problem because they are in
frames?

Any help on this is appreciated.

Thanks!

Hal


------------------------------

Date: Wed, 23 Mar 2005 07:16:20 GMT
From: "Todd W" <toddrw69@excite.com>
Subject: Re: LWP Doesn't Seem To Save Cookies:
Message-Id: <8J80e.23587$hU7.3620@newssvr33.news.prodigy.com>


"Hal Vaughan" <hal@thresholddigital.com> wrote in message
news:2Y-dnU1DnpqllNzfRVn-jA@comcast.com...
> I'm trying to write a scraper for a website that uses cookies.  The short
of
> it is that I keep getting their "You have to set your browser to allow
> cookies" message.  The code for the full scraper is a bit much, so here
are
> the relevant sections:
>
<snip />

I've had a lot of sucess using LWP to scrape web pages, for instance I have
a neat program that shows me all my bank account balances on my web enabled
cell phone, but Ive had some trouble getting LWP to scrape some pages that
required cookies also.

Heres my code:

[trwww[at]waveright temp]$ perl -MWWW::Mechanize::Shell -e 'shell'
>get https://www.setsivr.odjfs.state.oh.us/welcome.asp
Retrieving https://www.setsivr.odjfs.state.oh.us/welcome.asp(200)
https://www.setsivr.odjfs.state.oh.us/cookieerror.htm>

If the client and the server were doing everything according to
specification, this would work.

I get the same problem with lynx, and another poster on perl.libwww verified
my issue, and also got the same error using a python http library.

Heres the archive of my thread:

http://groups-beta.google.com/group/perl.libwww/browse_thread/thread/38d09ffd6ff2f4fd

I guess that since it dosent work with lynx I can say that the server is
doing something that isnt standard, but it sucks beause it works fine on any
of the major graphical browsers I've tried.

I suppose that someone who knew http well enough could say why it dosent
work, but I know it pretty well and I cant figure it out, and I've tried
pretty hard.

Todd W




------------------------------

Date: Wed, 23 Mar 2005 18:31:44 +1100
From: "Sisyphus" <sisyphus1@optusnet.com.au>
Subject: Re: memory leak in 5.8.2???
Message-Id: <42411c09$0$3069$afc38c87@news.optusnet.com.au>


<joe.cipale@radisys.com> wrote in message
news:1111527148.542438.231190@g14g2000cwa.googlegroups.com...
> I have an application written in Perl/tk that will write a small file
> (~128 bytes) to disk. At random intervals, the application is unable to
> write ti the disk. No error message is given, the write file is
> executed but the trap 'or die...' is not. The OS is RedHat 7.2.
>

I assume you mean that you can successfully open() the filehandle to the
file for witing.
Are you checking that the close() of the filehandle is also successful ?

Cheers,
Rob




------------------------------

Date: Wed, 23 Mar 2005 01:34:28 GMT
From: "packat" <chariya@verizon.not>
Subject: Re: Need help getting start with a test cgi script.
Message-Id: <EI30e.14391$GI6.4610@trnddc05>

Trey Waters wrote:
> On Tue, 22 Mar 2005, packat wrote:
>
>> I am trying to get my first cgi script running.  First I 
>> put
>> a simple try.cgi in the directory
>> C:\Program Files\Apache Group\Apache2\cgi-bin\try.cgi
>
>> The config file has the line ScriptAlias cgi-bin
>> "C:/perl/eg/cgi-bin/"
>>
>> Can anyone help me find what was wrong?
>
> This question appears to be related to misconfiguring 
> Apache, and
> should probably be directed to a group dealing with 
> Apache.
>
> As for your problem:
>
> The above discrepency sticks out for me....I haven't used 
> Apache on
> Win, but on Unix the ScriptAlias declaration usually 
> denotes where
> you put your CGI scripts; and you stated that you put your 
> CGI script
> in a different location than you configured.
> \


I did try both SCRIPTALIAS configuration.  Also restart 
Apache each time.
Well, I also believe hte root cause is probably Apache 
config.
Thanks for your comment,
pac




>
> +-----------------------------------------------------------------------+
> Trey Waters
> news5@sidestreet.gotdns.org                  Experience is 
> the worst
> teacher.     It always gives the test first and the 
> instruction
> afterward.
> +-----------------------------------------------------------------------+ 




------------------------------

Date: Thu, 24 Mar 2005 16:47:52 +1200
From: usr <usr@nomail.mail>
Subject: newbie question
Message-Id: <pan.2005.03.24.04.47.51.887362@nomail.mail>

hi
I feel embarrassed to ask this question but I'm pretty new to this and
can't seem to get it.
Right here it is, How do I get the program 'Hello, World!' to run.
I'm using linux and this is my code
/usr/bin/perl
print "Hello, World!\n";
I then
chmod a+x program_name
then
 ./program_name
then the terminal screen just sits until I stop it.
Thanks,
please enter giggles and restraind laughter were you see fit.


------------------------------

Date: 23 Mar 2005 05:07:45 GMT
From: John Bokma <postmaster@castleamber.com>
Subject: Re: newbie question
Message-Id: <Xns9621EB48B208Fcastleamber@130.133.1.4>

usr wrote:

> hi
> I feel embarrassed to ask this question

Reduce this feeling by reading:
<http://www.catb.org/~esr/faqs/smart-questions.html>

Quite some questions here are newbie questions, no need to state this 
(it's often clear from the rest of the message).

> I'm using linux and this is my code
> /usr/bin/perl
> print "Hello, World!\n";
> I then
> chmod a+x program_name
> then
> ./program_name
> then the terminal screen just sits until I stop it.

Change the first line to:

#!/usr/bin/perl

> Thanks,
> please enter giggles and restraind laughter were you see fit.

No giggles, but a sound advice: read a good book on Perl (Learning 
Perl), read it front to back, and then start at the beginning again. The 
first time: *don't* sit behind a computer. The second time, yes. And 
make sure you make notes the second time you read it :-D.

A little extra: make sure you put the following two lines under the
first line:

use strict;
use warnings;

The latter "replaces" the -w one can see now and then after the /perl in 
the first line.

-- 
John                   Small Perl scripts: http://johnbokma.com/perl/
               Perl programmer available:     http://castleamber.com/
            Happy Customers: http://castleamber.com/testimonials.html
                        


------------------------------

Date: Tue, 22 Mar 2005 23:47:24 -0600
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: newbie question
Message-Id: <slrnd420nc.1in.tadmc@magna.augustmail.com>

usr <usr@nomail.mail> wrote:

> I'm using linux and this is my code
> /usr/bin/perl
> print "Hello, World!\n";


   #!/usr/bin/perl
   print "Hello, World!\n";


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


------------------------------

Date: 22 Mar 2005 18:01:57 -0800
From: cji_work@yahoo.com
Subject: perl thread question
Message-Id: <1111543317.461528.63620@g14g2000cwa.googlegroups.com>

Hi all,
I am a beginner to the Perl Thread, and I need some help for the
following code. What I was trying to do is to crate two threads, one is
to write some data to the stack while the other one is to read from the
same stack ? This is just a test for me, but it does not work.  Any
comments ?

Following are the code,
"
use Thread;
use Thread::Queue;

my $stream = new Thread::Queue;
my $first_thr = new Thread(\&read_number, $stream, \@stack);
my $second_thr = new Thread(\&write_number, $stream, \@stack);

$stream->enqueue(undef);
$first_thr->join();
$second_thr->join();

sub write_number {
    my $ref_stack = shift;
    for my $i ( 1 .. 3 ) {
        for my $j ( 1 ..3) {
            push(@{$ref_stack}, $i*$j);
            sleep 1;
            print "write::In the stack: @{$ref_stack}\n";
        }
        sleep 1;
    }
}


sub read_number {
    my $ref_stack = shift;
    while(1) {
        print "read::In the stack: @{$ref_stack}\n";
        sleep 1;
    }
}

"



------------------------------

Date: Wed, 23 Mar 2005 04:43:01 +0100
From: Fabian Pilkowski <pilkowsk@informatik.uni-marburg.de>
Subject: Re: perl thread question
Message-Id: <3ac6qtF668ggjU1@individual.net>

* cji_work@yahoo.com schrieb:
> 
> I am a beginner to the Perl Thread, and I need some help for the
> following code. What I was trying to do is to crate two threads, one is
> to write some data to the stack while the other one is to read from the
> same stack ? This is just a test for me, but it does not work.  Any
> comments ?
> 
> Following are the code,
> 
> use Thread;
> use Thread::Queue;
> 
> my $stream = new Thread::Queue;
> my $first_thr = new Thread(\&read_number, $stream, \@stack);
> my $second_thr = new Thread(\&write_number, $stream, \@stack);
> 
> $stream->enqueue(undef);
> $first_thr->join();
> $second_thr->join();

You don't declare the array @stack anywhere -- and don't use it anywhere
else. Remember: $stream is the first param given to read_number(), your
reference to @stack is the second one. Your sub read_number() is using
only its first param -- just as write_number().

Btw, on my Windows XP machine (Perl 5.8.6) your script works fine when
turning on autoflush mode for STDOUT, e.g. by beginning your script with

    #!/usr/bin/perl -w
    use strict;
    $|++; # autoflush on

Read `perldoc perlvar` to learn more about the special var »$|«.

regards,
fabian


------------------------------

Date: Tue, 22 Mar 2005 19:09:23 -0800
From: "Steventangle" <stevo@berkeley.edu>
Subject: Regex: changing longer patterns to shorter ones
Message-Id: <d1qmmn$k0n$1@geode.berkeley.edu>

ITEM 0

How does one go about changing a longer pattern to a shorter one?  For 
instance, I try

    $string =~ tr/longer/short/;

but it doesn't change "This is a longer pattern." to "This is a short 
pattern."  Rather, it does a one-for-one replacement yielding "This is a 
shortr pattrro."

ITEM 1

How do you use variables in regexes?  For instance, if I wanted to replace 
the variable $var with $string, what's the tr or s syntax for it?

Thanks for the help,
Steve 




------------------------------

Date: Wed, 23 Mar 2005 04:22:59 +0100
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: Regex: changing longer patterns to shorter ones
Message-Id: <3ac5uiF69t2koU1@individual.net>

Steventangle wrote:
> How does one go about changing a longer pattern to a shorter one?  For 
> instance, I try
> 
>     $string =~ tr/longer/short/;
> 
> but it doesn't change "This is a longer pattern." to "This is a short 
> pattern."

Not surprising, since you are using the tr/// operator, which doesn't 
include any pattern or regular expression.

> Rather, it does a one-for-one replacement yielding "This is a 
> shortr pattrro."

Yep, that's what the tr/// operator does.

Try the s/// operator instead.

     perldoc perlop

> How do you use variables in regexes?  For instance, if I wanted to replace 
> the variable $var with $string, what's the tr or s syntax for it?

     s/$var/$string/

     perldoc perlop

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl


------------------------------

Date: Tue, 22 Mar 2005 23:44:53 -0600
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: Regex: changing longer patterns to shorter ones
Message-Id: <slrnd420il.1in.tadmc@magna.augustmail.com>

Steventangle <stevo@berkeley.edu> wrote:

> How do you use variables in regexes?  


The same way that you use them in double quoted strings.


> For instance, if I wanted to replace 
> the variable $var with $string, what's the tr or s syntax for it?


Show us what you have tried and we will help you fix it.


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


------------------------------

Date: Wed, 23 Mar 2005 05:57:22 GMT
From: John <john_tilly@hotmail.com>
Subject: Seeking Recommendations For Perl Shopping Cart System
Message-Id: <pan.2005.03.23.05.58.10.372368@hotmail.com>

All:

I am looking to get some feedback and recommendations on Shopping Cart and
E-Commerce systems that are written in Perl and have Open Source licenses.

The requirements will include being able to take and process a credit card
order on a secure page.  I typically use MySQL for database and Apache for
HTTP server.

If you feel like sharing your experiences with me, I would certainly
appreciate it and perhaps others can learn from it as well.

Thanks!

John


------------------------------

Date: Tue, 22 Mar 2005 23:59:38 -0700
From: Scott Bryce <sbryce@scottbryce.com>
Subject: Re: Seeking Recommendations For Perl Shopping Cart System
Message-Id: <ZKOdnW8BPrJJjtzfRVn-gQ@comcast.com>

John wrote:

> All:
> 
> I am looking to get some feedback and recommendations on Shopping Cart and
> E-Commerce systems that are written in Perl and have Open Source licenses.

This newsgroup is for discussing Perl programing. Your question is off 
topic here.

You might try this question at alt.www.webmaster or alt.ecommerce.


------------------------------

Date: Tue, 22 Mar 2005 17:32:26 -0600
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: simple help
Message-Id: <slrnd41aoa.8na.tadmc@magna.augustmail.com>

jaw56856@yahoo.com <jaw56856@yahoo.com> wrote:

> Subject: simple help


Please put the subject of your article in the Subject of your article.

That is what it is there for.


> I am parsing an error file greping for a cretin conditions,
                                           ^^^^^^
                                           ^^^^^^

Excluding all of the smart conditions?  :-)


> have working fine
> While(<error_file>)


I don't believe you, as that is not Perl code. Case matters.


> 	print output $_

> That is working fine.


It will stop working fine when you upgrade perl and it introduces
a new function named output().

You should use UPPER CASE for filehandles.



> so what is wrong with the if(($last_runtime eq $comp_string) )
> statement???
> It never matches??


I dunno, did you print out the two values?

   print "\$last_runtime is '$last_runtime'\n";
   print "\$comp_string is '$comp_string'\n";


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


------------------------------

Date: Tue, 22 Mar 2005 17:39:03 -0600
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: The error "Use of uninitialized value "
Message-Id: <slrnd41b4n.8na.tadmc@magna.augustmail.com>

Sherm Pendley <spamtrap@dot-app.org> wrote:
> Tad McClellan wrote:
> 
>> Sherm Pendley <spamtrap@dot-app.org> wrote:
>>> A. Sinan Unur wrote:
>>> 
>>>> which error?
>>> 
>>> Don't be ridiculous. The error is in the subject.
>> 
>>> Complaining because he
>>> didn't repeat it in the message body is petty.
>> 
>> 
>> Complaining because he called a warning an error is not petty,
> 
> A cryptic two-word question like the one above leaves the OP with a vague
> impression that he's done something wrong, 


Like posting horridly formatted code?

Like posting the same question 3 times a few minutes apart?


> but does nothing to tell him
> what that was, or help him learn to do better next time.


He might consider being more respectful of other people's time.


> A. Sinan *could* have chosen to be helpful and point out that the text in
> the subject was a warning. He chose not to. Instead, he chose to post a
> snide two-word comment.


You reap what you sow.

(though I must agree that A. Sinan does too-often go overboard
 on the harshness.
)


> The comment wasn't intended to be
> helpful or constructive, it was intended to make the OP look foolish,


You're right, there was no need to point that out, the OP did
a fine job of making that rather obvious.


> I call that petty.


OK.


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


------------------------------

Date: Tue, 22 Mar 2005 18:07:55 -0500
From: Sherm Pendley <spamtrap@dot-app.org>
Subject: Re: Two-dim array: Strange "can't use string as ARRAY ref"
Message-Id: <W72dnYXZr7fQON3fRVn-iQ@adelphia.com>

Eric Schwartz wrote:

> You can't use an array as a hash key.

It's not impossible to use array refs as keys, but it does require some
additional steps that aren't needed when you use strings as keys. Have a
look at Tie::RefHash. (It's a core module in my copy of 5.8.1 - I don't
know about earlier.)

sherm--

-- 
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org


------------------------------

Date: Wed, 23 Mar 2005 00:09:12 +0100
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: Two-dim array: Strange "can't use string as ARRAY ref"
Message-Id: <3abmtsF67g4ikU1@individual.net>

Markus Dehmann wrote:
> I am using a two-dim hash with a string as first key, and an array as 2nd
> key.

No you are not. A hash key cannot be an array.

But it doesn't work! Can anyone tell me what's wrong?
> 
> #!/usr/bin/perl -w
> $hash{"test"}{["one", "two"]} = 42;
> $hash{"test"}{["three", "four"]} = 23;

Try this:

     use Data::Dumper;
     print Dumper \%hash;

> my $key = "test";
> foreach(keys %{$hash{$key}}){
>   print "Value for $_ is $hash{$key}{$_}\n"; # ARRAY(0x804c958)
>   # print "@$_\n"; # Can't use string ("ARRAY(0x804c958)") as an ARRAY ref 
> }
> 
> The output is:
> Value for ARRAY(0x804c958) is 23
> 
> Why does it print only *one* value?

Because there is only one value.

> Why can't I dereference the array ref $_?

See Eric's answer about that.

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl


------------------------------

Date: Tue, 22 Mar 2005 17:17:26 -0600
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: Two-dim array: Strange "can't use string as ARRAY ref"
Message-Id: <slrnd419s6.8na.tadmc@magna.augustmail.com>

Markus Dehmann <markus.dehmann@gmail.com> wrote:

> I am using a two-dim hash with a string as first key, and an array as 2nd
> key. 


You cannot have arrays as keys in Perl hashes.


> But it doesn't work! 


What were you hoping that it would do?


> Can anyone tell me what's wrong?


You are trying to create an impossible data structure.

If you had told us what you really want, then we would have a
chance of showing you how to refactor your data structure.


> #!/usr/bin/perl -w
> $hash{"test"}{["one", "two"]} = 42;


Hash keys are forced to be strings.

If you give it an array ref as a hash key, you will get a stringified
representation of the reference, which can no longer be used to
access the array.


> $hash{"test"}{["three", "four"]} = 23;


Do you want the 2nd level hash to have 4 key/value pairs in it?

   $hash{test}{one}   = 42;
   $hash{test}{two}   = 42;
   $hash{test}{three} = 23;
   $hash{test}{four}  = 23;

or, by using a "hash slice":

   @hash{ qw/ one two three four / } = (42, 42, 23, 23);


If you wanted something else, try telling us what that something else is.


> my $key = "test";
> foreach(keys %{$hash{$key}}){
>   print "Value for $_ is $hash{$key}{$_}\n"; # ARRAY(0x804c958)
>   # print "@$_\n"; # Can't use string ("ARRAY(0x804c958)") as an ARRAY ref 
> }
> 
> The output is:
> Value for ARRAY(0x804c958) is 23
> 
> Why does it print only *one* value? 


Because there is only one key ("test") in the hash, your 2nd
assignment stomped over the value of the 1st assignment.


> Why can't I dereference 
> the array ref $_?


Because it is NOT an array ref, it is a string.


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


------------------------------

Date: Wed, 23 Mar 2005 00:44:15 +0100
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: Two-dim array: Strange "can't use string as ARRAY ref"
Message-Id: <3abp07F6avmghU1@individual.net>

Sherm Pendley wrote:
> Eric Schwartz wrote:
>> You can't use an array as a hash key.
> 
> It's not impossible to use array refs as keys, but it does require some
> additional steps that aren't needed when you use strings as keys. Have a
> look at Tie::RefHash.

While giving Eric right, "perldoc perlref" mentions that Tie::RefHash 
provides a *workaround*. The distinction seems to be important to 
understand this limitation with Perl hashes.

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl


------------------------------

Date: Tue, 22 Mar 2005 19:36:44 -0500
From: Eric Amick <eric-amick@comcast.net>
Subject: Re: Two-dim array: Strange "can't use string as ARRAY ref"
Message-Id: <13e141puomfh70hrmdvn56tcfo1si81to1@4ax.com>

On Tue, 22 Mar 2005 17:31:39 -0500, Markus Dehmann
<markus.dehmann@gmail.com> wrote:

>I am using a two-dim hash with a string as first key, and an array as 2nd
>key. But it doesn't work! Can anyone tell me what's wrong?

>
>#!/usr/bin/perl -w
>$hash{"test"}{["one", "two"]} = 42;
>$hash{"test"}{["three", "four"]} = 23;

Hash keys are strings, so the array reference is converted to a string.
You need to look at the Tie::RefHash module, which I believe is a core
module, to do what you're after.

-- 
Eric Amick
Columbia, MD


------------------------------

Date: Wed, 23 Mar 2005 07:44:58 +0000
From: Brian McCauley <nobull@mail.com>
Subject: Re: Two-dim array: Strange "can't use string as ARRAY ref"
Message-Id: <d1r6es$kbu$1@sun3.bham.ac.uk>



Eric Amick wrote:
> On Tue, 22 Mar 2005 17:31:39 -0500, Markus Dehmann
> <markus.dehmann@gmail.com> wrote:
> 
> 
>>I am using a two-dim hash with a string as first key, and an array as 2nd
>>key. But it doesn't work! Can anyone tell me what's wrong?
> 
> 
>>#!/usr/bin/perl -w
>>$hash{"test"}{["one", "two"]} = 42;
>>$hash{"test"}{["three", "four"]} = 23;
> 
> 
> Hash keys are strings, so the array reference is converted to a string.
> You need to look at the Tie::RefHash module, which I believe is a core
> module, to do what you're after.

But if using Tie::RefHash you can't look up an element using 
$hash{"test"}{["three", "four"]} because the ["three", "four"] creates a 
  new array.  It may have the same content as the array that's used as a 
key but it is not the same array.



------------------------------

Date: Tue, 22 Mar 2005 18:13:45 -0800
From: Jim Gibson <jgibson@mail.arc.nasa.gov>
Subject: Re: Will XML::Simple work with keys, strings, integers, and dates?
Message-Id: <220320051813450399%jgibson@mail.arc.nasa.gov>

In article <th6%d.4321$C7.2935@news-server.bigpond.net.au>, Wes Barris
<noway@nohow.com> wrote:

> Hi,

I haven't seen anybody else post a response, so I will give it a shot.
I have only done a little XML processing in Perl (and some in Java),
but I am not an expert.

> 
> I am trying to use XML::Simple to parse an xml file.  However, the xml file
> that I am trying to parse is not in the same format as any of the XML::Simple
> examples that I have seen.  In all of the examples I have seen, the xml tags
> are specific to their contents.  In my xml file, the tag names are generic.
> Here is a short sample of the xml that I am trying to parse:
> 
>  <dict>
>     <key>35</key>
>     <dict>
>        <key>Track ID</key><integer>35</integer>
>        <key>Name</key><string>Earache My Eye (Full Version)</string>
>        <key>Artist</key><string>Alice Bowie</string>

[XML lines snipped]

Is that really your XML? You have nested tags with the same name:
<dict>. You also have <key> tags at different levels. That is going to
make parsing more difficult.

>     </dict>
>     <key>36</key>
>     <dict>
>        <key>Track ID</key><integer>36</integer>
>        <key>Name</key><string>Earache My Eye</string>
>        <key>Artist</key><string>Cheech &#38; Chong</string>

[more lines snipped]

>     </dict>
> 
> I would like to be able to extract things like the "Name", "Artist", and
> "Location" but I don't understand how to associate one of the elements of
> the key array with one of the elements of the resulting string array.

You have some very poorly designed XML there. It would be better if it
were something like

   <attribute name="Track ID" value="35"> ...

If you cannot change the XML definition, then you are probably better
off using a SAX parser. XML::SAX::PurePerl works, but it is slow. For
big files, try XML::Parser and the expat library. I found it about 75
times faster in my one use. 

In a SAX parser, you define a handler package with callbacks that are
called for each element in the XML. Then, you will be able to associate
the <key> value with the subsequent value attribute because you will
get the callbacks sequentially.

Something like this might get you started:

#!/usr/local/bin/perl
use strict;
use warnings;
use XML::SAX::PurePerl;

my $xmlstring;
{
  local $/;
  $xmlstring = <DATA>;
}

my $handler = My::XML::Handler->new();
my $parser = XML::SAX::PurePerl->new(Handler => $handler);
$parser->parse_string($xmlstring);

package My::XML::Handler;
sub new
{
  my $class = shift;
  my $self = {
    'key' => '',
    'data' => ''
  };
  bless $self, $class;
}

sub start_document{ print "start_document\n"; }

sub start_element
{
  my( $self, $element ) = @_;
  my $name = $element->{LocalName};
}

sub end_element
{
  my( $self, $element ) = @_;
  my $name = $element->{Name};
  if( $name eq 'key' ) {
    $self->{key} = $self->{data};
  }elsif( $self->{data} ) {
    print "<$self->{key}> is '$self->{data}' of type $name\n";
  }
  $self->{data} = '';
}

sub characters
{
  my( $self, $element ) = @_;
  my $chars = $element->{Data};
  $self->{data} .= $chars if( $chars =~ /\S/ );
}
sub end_document{ print "end_document\n"; }
sub warning{ print "warning\n"; }
sub error{ print "error\n"; }

1;

package main;

__DATA__
<doc>
<key>35</key>
<dict>
<key>Track ID</key><integer>35</integer>
<key>Name</key><string>Earache My Eye (Full Version)</string>
<key>Artist</key><string>Alice Bowie</string>
</dict>
<key>36</key>
<dict>
<key>Track ID</key><integer>36</integer>
<key>Name</key><string>Earache My Eye</string>
<key>Artist</key><string>Cheech &#38; Chong</string>
</dict>
</doc>


Which produces:

start_document
<Track ID> is '35' of type integer
<Name> is 'Earache My Eye (Full Version)' of type string
<Artist> is 'Alice Bowie' of type string
<Track ID> is '36' of type integer
<Name> is 'Earache My Eye' of type string
<Artist> is 'Cheech & Chong' of type string
end_document

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----


------------------------------

Date: 23 Mar 2005 02:26:29 GMT
From: John Bokma <postmaster@castleamber.com>
Subject: Re: Will XML::Simple work with keys, strings, integers, and dates?
Message-Id: <Xns9621CFF10EA26castleamber@130.133.1.4>

Jim Gibson wrote:

> In article <th6%d.4321$C7.2935@news-server.bigpond.net.au>, Wes Barris
> <noway@nohow.com> wrote:

>>  <dict>
>>     <key>35</key>
>>     <dict>
>>        <key>Track ID</key><integer>35</integer>
>>        <key>Name</key><string>Earache My Eye (Full Version)</string>
>>        <key>Artist</key><string>Alice Bowie</string>
> 
> [XML lines snipped]
> 
> Is that really your XML? You have nested tags with the same name:
> <dict>. You also have <key> tags at different levels. That is going to
> make parsing more difficult.

Nop, for an XML parser that really doesn't matter.

>>     </dict>
>>     <key>36</key>
>>     <dict>
>>        <key>Track ID</key><integer>36</integer>
>>        <key>Name</key><string>Earache My Eye</string>
>>        <key>Artist</key><string>Cheech &#38; Chong</string>
> 
> [more lines snipped]
> 
>>     </dict>
>> 
>> I would like to be able to extract things like the "Name", "Artist",
>> and "Location" but I don't understand how to associate one of the
>> elements of the key array with one of the elements of the resulting
>> string array. 
> 
> You have some very poorly designed XML there. It would be better if it
> were something like
> 
>    <attribute name="Track ID" value="35"> ...

In some cases that will be considered poor design too. Some people 
recommend not to use attributes but elements unless it's meta info on 
the element itself.

Better: <track>36</track>
    	  <name>.......</name>
    	  <artist>.....</artist>

> If you cannot change the XML definition, then you are probably better
> off using a SAX parser. XML::SAX::PurePerl works, but it is slow. For
> big files, try XML::Parser and the expat library. I found it about 75
> times faster in my one use. 
> 
> In a SAX parser, you define a handler package with callbacks that are
> called for each element in the XML. Then, you will be able to
> associate the <key> value with the subsequent value attribute because
> you will get the callbacks sequentially.

Extremely cumbersome, since, as you already noted the use of elements at 
different levels.

I would probably use XML::Twig for this.

-- 
John                   Small Perl scripts: http://johnbokma.com/perl/
               Perl programmer available:     http://castleamber.com/
            Happy Customers: http://castleamber.com/testimonials.html
                        


------------------------------

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 V10 Issue 7907
***************************************


home help back first fref pref prev next nref lref last post