Schrift
[thread]9038[/thread]

struct als hash value: Ungewollte Ueberspeicherung



<< >> 5 Einträge, 1 Seite
Gast Gast
 2007-05-25 23:57
#76966 #76966
Hallo Leute,

mein Problem ist, dass die "score"-Werte des globalen hash %network ueberspeichert werden.
Was ich will ist, dass in der Subroutine "scoren" eine Kopie von %network mit dem value von %NOA ausgestattet und zurueckgegeben wird. (Siehe nachfolgendes Bsp.)
Am Ende sollte ausgegeben werden P0=0.9

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
my (%network, %NOA); 

use Class::Struct;

struct Node => {
score => '$',
strange => '@',
};

# network hash mit key P0, value=Node
my $key = "P0";
my $first = Node->new();
$first->score(0.9);
$network{$key} = $first;

# der hash mit dem Wert, den nur eine Kopie von %network erhalten soll
$NOA{$key}=0.22;

#Kopie von %network erhält neuen score (von NOA)
our $refnet = scoren(\%NOA, \%network);

sub scoren{
my ($refmap, $refnet) =  @_;
my %q_map = %$refmap; my %network2 = %$refnet;
while (my ($key, $value) = each(%q_map)) {
$network2{$key}->score($value);
}
return(\%network2);
}

foreach (keys %network){
$dia = $network{$_}->score;
print "$_ = $dia \n";
}

AUSGABE: P0=0.22

Kann mir Jemand sagen, wie man diese Ueberspeicherung vermeidet (eine wirkliche Kopie %network erzeugt)?  
MfG, Jaque
PerlProfi
 2007-05-26 00:27
#76967 #76967
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
An sich kopierst du den Hash schon und änderst ihn nicht direkt, dein Problem ist die Node, da das ja eine Referenz ist und ihre Kopie auf die selbe Position im Speicher zeigt wie das Original.

Wie wäre es denn, wenn du in scoren() in der while-Schleife eine neue Node für alle keys aus der q_map erstellst ?

MfG
Jaque
 2007-05-26 14:15
#76968 #76968
User since
2007-05-26
8 Artikel
BenutzerIn
[default_avatar]
Quote
in scoren() in der while-Schleife eine neue Node für alle keys aus der q_map

In Wirklichkeit hab ich neben der score Eigenschaft und dem Array noch einen Hash in Node. Müssten die dann ebenfalls neu erstellt werden? Das wollte ich durch die Kopie vermeiden.\n\n

<!--EDIT|Jaque|1180174612-->
PerlProfi
 2007-05-26 14:42
#76969 #76969
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Ja, es sieht so aus, als müsstest du die Node in der while-Schleife von Hand kopieren.
Du musst ja die Werte nicht neu erstellen, die nimmst du einfach von der alten Node und schreibst sie in eine neue für %network2.

Solange da keine zirkulären Referenzen drin sind, sollte das machbar sein.

MfG
Jaque
 2007-05-26 17:11
#76970 #76970
User since
2007-05-26
8 Artikel
BenutzerIn
[default_avatar]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/perl 
use strict; use warnings;
my (%network, %NOA);

use Class::Struct;

struct Node => {
score => '$',
neighbor => '@',
};

# network hash mit key P0, value=Node
my $key = "P0";
my $first = Node->new();
$first->score(0.9);
$first->neighbor(['P1', 'P2', 'P3']);
$network{$key} = $first;

# der hash mit dem Wert, den nur eine Kopie von %network erhalten soll
$NOA{$key}=0.22;

#Kopie von %network erhält neuen score (von NOA)
our $refnet = scoren(\%NOA, \%network);
our %new_network = %$refnet;

# Gebe P0 zusätlichen Nachbar
push @{$new_network{$key}->neighbor}, 'P4';

sub scoren{
my ($refmap, $refnet) = @_;
my %q_map = %$refmap; my %network = %$refnet;
my %network2;
while (my ($key, $value) = each(%q_map)) {
$network2{$key} = Node->new();
$network2{$key}->score($value);
# Nachbarn kopieren:
my @hold = @{$network{$key}->neighbor};
$network2{$key}->neighbor(\@hold);
}
return(\%network2);
}

# das Ganze ausgeben
foreach (keys %network){
print "Our old network:\n";
my $dia = $network{$_}->score;
print "$_ = $dia neighbors: @{$network{$key}->neighbor}\n\n";

print "The new network:\n";
$dia = $new_network{$_}->score;
print "$_ = $dia neighbors: @{$new_network{$key}->neighbor}\n";
}


Grossartig, deine Hinweise haben mein Problem gelöst! Danke PerlProfi  :blues:
<< >> 5 Einträge, 1 Seite



View all threads created 2007-05-25 23:57.