2009-07-31 7 views
5

je veux faire, en Perl, l'équivalent du code Ruby suivant:Comment créer un hachage imbriqué en tant que constante dans Perl?

class Foo 
    MY_CONST = { 
    'foo' => 'bar', 
    'baz' => { 
     'innerbar' => 'bleh' 
    }, 
    } 

    def some_method 
    a = MY_CONST[ 'foo' ] 
    end 

end 

# In some other file which uses Foo... 

b = Foo::MY_CONST[ 'baz' ][ 'innerbar' ] 

C'est, je veux juste de déclarer une structure de hachage constante, imbriquée pour utilisation à la fois dans la classe et à l'extérieur. Comment?

+0

Je l'ai déjà ma classe Perl mis en place (avec bénédiction , etc.), donc je n'ai pas besoin d'être montré comment faire cela. – Pistos

Répondre

8

Vous pouvez utiliser le module Hash::Util pour verrouiller et déverrouiller un hachage (clés, valeurs ou les deux).

package Foo; 
use Hash::Util; 

our %MY_CONST = (
    foo => 'bar', 
    baz => { 
     innerbar => 'bleh', 
    } 
); 

Hash::Util::lock_hash_recurse(%MY_CONST); 

Puis, dans un autre fichier:

use Foo; 
my $b = $Foo::MY_CONST{baz}{innerbar}; 
+0

Merci, Michael, c'est exactement ce dont j'ai besoin. J'ai essayé d'utiliser lock_hashref, mais ça ne semble pas être défini pour moi, mais ça va, je peux me débrouiller avec lock_hash. – Pistos

+0

Je remarque que je peux accomplir ce dont j'ai besoin simplement avec "notre", je n'ai pas besoin de Hash :: Util. Je ne suis pas préoccupé par les autres personnes à jouer avec le hachage après le fait, j'ai simplement besoin de savoir comment définir une constante accessible en Perl. Votre exemple de code m'a montré. – Pistos

+2

Donc, vous n'avez pas vraiment besoin d'une constante? Le Hash :: Util est la magie qui empêche les gens de changer le hash. –

1

Voici un guide pour hash en Perl. Hash of Hashes

+0

Merci, bien que j'ai construit des hachages imbriqués en général à Perl. Mon besoin spécifique a à voir avec l'utilisation à l'intérieur et à l'extérieur d'un paquet/classe. – Pistos

4

Voir Readonly:

#!/usr/bin/perl 

package Foo; 

use strict; 
use warnings; 

use Readonly; 

Readonly::Hash our %h => (
    a => { b => 1 } 
); 

package main; 

use strict; 
use warnings; 

print $Foo::h{a}->{b}, "\n"; 

$h{a}->{b} = 2; 

Sortie:

 
C:\Temp> t 
1 
Modification of a read-only value attempted at C:\Temp\t.pl line 21 
+0

Readonly n'est pas installé sur le système que j'utilise, et je ne suis pas libre d'installer librement de nouveaux modules. Mais merci pour votre suggestion. Je suis tombé sur ça en faisant des recherches sur Google. – Pistos

+4

@Pistos http://perldoc.perl.org/perlfaq8.html#How-do-I-keep-my-own-module/library-directory%3F –

+0

@Sinan: Merci, mais cela n'aide pas dans mon Cas. Vous pourriez confondre mes circonstances avec celles d'un utilisateur sur un hébergement partagé ou quelque chose comme ça. Les barrières ne sont pas techniques, elles sont sociales/politiques/managériales. :) – Pistos

11

Vous pouvez aussi le faire entièrement builtins:

package Foo; 
use constant MY_CONST => 
{ 
    'foo' => 'bar', 
    'baz' => { 
     'innerbar' => 'bleh', 
    }, 
}; 

sub some_method 
{ 
    # presumably $a is defined somewhere else... 
    # or perhaps you mean to dereference a parameter passed in? 
    # in that case, use ${$_[0]} = MY_CONST->{foo} and call some_method(\$var); 
    $a = MY_CONST->{foo}; 
} 

package Main; # or any other namespace that isn't Foo... 
# ... 
my $b = Foo->MY_CONST->{baz}{innerbar}; 
+1

Merci, Ether. Je vais aller avec cette syntaxe, car elle me permet d'utiliser systématiquement des références partout. Je voudrais marquer le vôtre comme la réponse acceptée, mais c'est arrivé un peu trop tard. :) – Pistos

+0

Hash :: Util :: lock_hash_recurse est une bonne solution, mais j'aime la solution intégrée. –

Questions connexes