Toon posts:

[Perl] Element van een array voor naam hash gebruiken.

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoe kan ik in perl de elementen uit een array gebruiken als namen van hashes?

Met onderstaande voorbeeld werkt het alleen als ik 'use strict;' niet gebruikt. Er is vast een elegantere methode waar deze beginner niet van op de hoogte is.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/perl -w

#use strict;

my @klanten = qw(klant1 klant2 klant3);
my $klantnummer = 1;

foreach my $klant (@klanten) {


        ${$klant}{klantnummer} = $klantnummer;

        $klantnummer++;

        print "$klant $$klant{klantnummer}\n";
}


Met 'use strict;' krijg ik de error:

Can't use string ("klant1") as a HASH ref while "strict refs" in use at ./123 line 11. Ik heb gezocht op soortgelijke foutmeldingen, maar ik kom er niet uit.

Verwijderd

Door de 'use strict' mag je onder meer geen symbolic references gebruiken, je kan dan geen variabelen gebruiken als hashnaam.
In een constructie als $$klant{klantnummer} is $klant niet toegestaan, je mag alleen $klant1{klantnummer} e.d. gebruiken.
Onhandig als je zoals hier een loopje wil gebruiken om dynamisch hashes te creeren.

'use strict' bestaat uit 3 restricties:
- strict 'refs'
- strict 'subs'
- strict 'vars'
Je zou 'use strict' kunnen vervangen door de 2 andere expliciet te noemen:
code:
1
2
use strict 'subs';
use strict 'vars';

of door 'strict refs' achteraf uit te schakelen:
code:
1
2
use strict;
no strict 'refs';


De loop kan korter door bv. de expliciete loopvariabele $klant te vervangen door de impliciete variabele $_
code:
1
2
3
4
5
6
7
8
9
10
use strict;
no strict 'refs';

my @klanten = qw(klant1 klant2 klant3);
my klantnr;

for (@klanten) {
     $$_{klantnr} = ++$klantnr;
     print "$_   $$_{klantnr}\n";    
}


Als je de 'print'-regel niet gebruikt, kan de for-loop ook als one-liner door de 'for' er achter te plakken:
code:
1
$$_{klantnr} = ++$klantnr for @klanten;

Of met een 'map', dat is in feite een impliciete 'for':
code:
1
map { $$_{klantnr} = ++$klantnr } @klanten;

Verwijderd

Topicstarter
Dank voor je antwoord. Ik gebruik nu " no strict 'refs'; " .

Het verbaast me wel een beetje dat de mogelijkheden minder worden als je " use strict; " gebruikt. Ik dacht dat het meer bedoeld was om te zorgen dat je netjes ging coden.

  • oVRoM
  • Registratie: Juli 2000
  • Niet online
De reden dat dit niet mag met 'use strict' is juist dat het niet als 'netjes' gezien wordt :-)
Ik neem aan dat je meer dingen kwijt wil dan alleen het klantnummer :-), en daar zou je dan een hash van hashes voor kunnen gebruiken:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/perl -w

use strict;

my @klanten = qw(klant1 klant2 klant3);
my $klantnummer = 1;
my %klanten_hash;

foreach my $klant (@klanten) {

        $klanten_hash{$klant} = {
                    klantnummer => $klantnummer,
                    klantid => "K". $klantnummer * 2,
                    bladieblaat => "whatever",
                };

        $klantnummer++;

        print "$klant $klanten_hash{$klant}->{'klantnummer'} met ID $klanten_hash{$klant}->{'klantid'} en bladieblaat
$klanten_hash{$klant}->{'bladieblaat'}\n";
}