[26192] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 8381 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Sep 1 21:05:15 2005

Date: Thu, 1 Sep 2005 18:05:04 -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           Thu, 1 Sep 2005     Volume: 10 Number: 8381

Today's topics:
    Re: Combining multiple hash references into one hash re <nomail@sorry.com>
        Unexpected array behaviour <cNaOlSePbA@MvPeLtEsAtSaEr.com>
    Re: values of hash of hash xhoster@gmail.com
    Re: where to get Active perl modules <1usa@llenroc.ude.invalid>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Thu, 01 Sep 2005 15:42:06 -0700
From: Arvin Portlock <nomail@sorry.com>
Subject: Re: Combining multiple hash references into one hash reference
Message-Id: <df8041$23co$1@agate.berkeley.edu>

xhoster@gmail.com wrote:

> Arvin Portlock  wrote:
>
> >my %newhash = (%$hash1, %$hash2);
> >
> ># The following do not work:
> ># my $newhash = { $hash1, $hash2 };
> ># my $newhash = [ $hash1, $hash2 ];
> ># my %newhash = ( $hash1, $hash2 );
>
> Maybe this is more to your liking:
> my $newhash = { %$hash1, %$hash2 };

That dereferencing % there makes me nervous. It looks
to me like a new hash is being created and then a reference
to it is being assigned to $newhash. So for each of the
thousands of instances of $newhash, each will have (a ref-
erence to) its very own copy of %hash1 and %hash2.

$hash1 and $hash2 do not go out of scope. Also they are not
the only hashes. There are typically 20 or 30 of them
throughout the life of the program. Each XML element contains
some combination from among those 20 or 30. E.g.,

$newhash1 = { %$hash40, %$hash31, %$hash12 };
$newhash10012 = { %$hash1, %$hash21, %$hash26 };

In my XML document (METS for the curious), There are some
30 or forty elements at the top of the document, then further
down there are some thousands that reference some of those
elements with attributes of type IDREFS.

<element id="id1"> ... </element>
<element id="id2"> ... </element>
 ...
<element id="id30"> ... </element>

<refelement ids="id1 id6 id21"/>
<refelement ids="id22 id11 id21"/>
 ... etc. for thousands of <refelements>

Each of the thousands of elements are stored in an array.
At the end of the program I will loop through each of the
thousands of elements and extract certain values from each
one. I want to be able to extract those values by a key
name (which is why an array won't quite work as I can't
access the elements efficiently by key name).

BTW, the above was only an attempt to simplify the problem.
In reality of course I won't be naming my hashes %hash1,
%hash2, etc. Nor will I name the reference elements
$newhash12, $newhash643, etc. The <elements> will live
in a small hash keyed by the id. The <refelement>s will
live in a large array. And I want to be able to write
things like this:

foreach my $refelement (@bigarray) {
    print $refelement->{size}, "\n";
    print $refelement->{type}, "\n";
}

Where "size" and "type" are typical keys from
among the original 20 or 30 elements (assuming
<refelement ids="id1 id6 id21"/>, "size" may be
a key from the element referenced by "id1", "type"
may come from "id21", and so on.

I'm trying to simplify the problem without posting the
entire huge program, but this may be a bit closer to
what I want (except it doesn't quite work):

my $hashelements = {
    '1' => {
       'key1' => 'Value 1',
       'key2' => 'Value 2',
       'key3' => 'Value 3'
     },

    '6' => {
       'key4' => 'Value 4',
       'key5' => 'Value 5',
       'key6' => 'Value 6'
     },

    '21' => {
       'key7' => 'Value 7',
       'key8' => 'Value 8',
       'key9' => 'Value 9'
     },
};

my $newhash = {};
foreach my $id (1, 6, 21) {
    foreach my $key (keys %{$hashelements->{$id}}) {
       $newhash->{$key} = \{$hashelements->{$id}->{$key}};
    }
}

foreach my $key (keys %$newhash) {
    print "$key: ", $newhash->{$key}, "\n";
}

That $newhash->{$key} = \{$hashelements->{$id}->{$key}} part
is an attempt to make sure I only create a reference to
the value rather than make a copy of the value itself.

Perhaps using "each" somehow is the answer. Can't quite get
that to work either though.

Arvin

>
>
>
> >foreach my $key (keys %newhash) {
> >    print "$key: $newhash{$key}\n";
> >}
>
>
> Presumably, that isn't all you are doing, because if it were you would
> just use two loops, one for hash1 and one for hash2, and never make the
> combined hash in the first place.  And not making the combined hash in the
> first place is, of course, the best solution if you can get away with it.
> If you need more generalized than just those two hashes, then use an AoH
> with nested loop for printing.
>
>
> >But I'm concerned I'm creating copies of each of
> >these elements for all of the thousands of instances
> >of %newhash I will be creating.
>
>
> Will $hash1 and $hash2 go out of scope or get redefined shortly after
> %newhash (or $newhash) is created from them?  If so, you most likely
> needn't worry on the memory front.  And will all these thousands of
> instances of %newhash also be properly scoped?
>
>
> >Is there a faster and
> >memory efficient way to do this?
>
>
> Is this micro-optimization week or something?
>
> Would it be acceptable to add %$hash2 into %$hash1 rather than making
> a brand new %newhash?  If so,
> @{$hash1}{keys %$hash2}=values %$hash2;
> is somewhat more memory efficient.
>
> If not, then:
> my %newhash=%$hash1;
> undef $hash1;
> @newhash{keys %$hash2}=values %$hash2;
>
>
> Xho
>



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

Date: Thu, 01 Sep 2005 16:14:27 -0600
From: Spin <cNaOlSePbA@MvPeLtEsAtSaEr.com>
Subject: Unexpected array behaviour
Message-Id: <11hev9uio63g38d@corp.supernews.com>

I am using XML::Simple's XMLin to parse an XML document which has three 
'Accession' sections.

use Data::Dumper;
use XML::Simple;

my $data = new XML::Simple;
my $xml = $data->XMLin($ARGV[0]);
if (ref($xml->{'Accession'}) eq "HASH") {
	my @accessions = [$xml->{'Accession'}];
} elsif (ref($xml->{'Accession'}) eq "ARRAY") {
	my @accessions = $xml->{'Accession'};
}

In this particular case, the second if is true (ie. $xml->{'Accession'} 
is an array).

The following line gets me the second element in the $xml->{'Accession'} 
array:
print Dumper($xml->{'Accession'}[1]);


What I am baffled by is that this returns $VAR1 = undef :
print Dumper($accessions[1]);

But if do this, I get the entire contents of $xml->{'Accession'}:
print Dumper($accessions[0]);

What I want is for $accessions[n] to hold the same info as 
$xml->{'Accession'}[n].

Also I have tried:
print $#xml->{Accession};

but that gives me the "Global symbol @xml requires explicit ..." error. 
Could I have some pointers on how to handle this data better so that I 
have an array of 3 elements in @accessions?

TIA
Caleb


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

Date: 01 Sep 2005 22:20:53 GMT
From: xhoster@gmail.com
Subject: Re: values of hash of hash
Message-Id: <20050901182053.739$g5@newsreader.com>

ngoc <ngoc@yahoo.com> wrote:
>
> Reading from many computer science books, a good programming style is
> not many nested for loop.

While many nested map statements *is* good style?

> Looking back to my app. I use 3 for loop, in many places in my app. So I
> have to change it, IF I WANT  TO KEEP my job :-). So I posted to forum
> in hope some smart guys out there can help me to be better programmer.
> (And they can also learn new cases too).

You do not become a good programmer by blindly following style guides.

If you wish to do something with each item individually, use nested foreach
loops (upon values rather than keys).  If you want to do soemthing with the
items as a collection, use the nested maps.  If you want pretty code, write
subroutines.


Xho

-- 
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service                        $9.95/Month 30GB


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

Date: Thu, 01 Sep 2005 23:03:35 GMT
From: "A. Sinan Unur" <1usa@llenroc.ude.invalid>
Subject: Re: where to get Active perl modules
Message-Id: <Xns96C4C1E2E3AB6asu1cornelledu@127.0.0.1>

News KF <newskf@numericable.fr> wrote in
news:43177605$0$167$a3f2974a@nnrp1.numericable.fr: 

> I wanted do download a precompiled version of the module Rec::Descent,

use ppm, Perl Package Manager, that comes with the ActiveState Perl 
distribution.

Install the AS Perl MSI on your hard drive for the easiest operation, then 
copy all needed modules etc to the USB stick.

Sinan

-- 
A. Sinan Unur <1usa@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.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 8381
***************************************


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