2009-07-31 5 views
5

ich tun möchte, in Perl, das Äquivalent der folgenden Ruby-Code:Wie kann ich einen verschachtelten Hash als Konstante in Perl erstellen?

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' ] 

Das heißt, ich möchte nur für eine konstante, verschachtelte Hash-Struktur deklarieren sowohl in der Klasse als auch außerhalb. Wie man?

+0

Ich habe bereits meine Perl-Klasse eingerichtet (mit segnen usw.), also muss ich nicht gezeigt werden, wie das geht. – Pistos

Antwort

8

Sie können das Modul Hash::Util verwenden, um einen Hash zu sperren und zu entsperren (Schlüssel, Werte oder beides).

package Foo; 
use Hash::Util; 

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

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

dann in einer anderen Datei:

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

Danke, Michael, genau das brauche ich. Ich habe versucht, lock_hashref zu verwenden, aber es scheint nicht für mich definiert zu sein, aber das ist in Ordnung, ich kann mit lock_hash auskommen. – Pistos

+0

Ich bemerke, dass ich erreichen kann, was ich einfach mit "unserem" brauche, ich brauche Hash :: Util nicht. Mir geht es nicht darum, dass andere Leute nach der Tat mit dem Hash-Vorgang herumhantieren, ich musste einfach wissen, wie man in Perl eine zugängliche Konstante definiert. Dein Beispielcode hat es mir gezeigt. – Pistos

+2

Sie brauchen also keine Konstante? Das Hash :: Util-Zeug ist die Magie, die die Leute davon abhält, den Hash zu ändern. –

1

Hier ist eine Anleitung zu Hashes in Perl. Hash of Hashes

+0

Danke, obwohl ich genestete Hashes im Allgemeinen in Perl gebaut habe. Mein spezifischer Bedarf hat damit zu tun, es innerhalb und außerhalb eines Pakets/einer Klasse zu verwenden. – Pistos

4

Siehe 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; 

Ausgang:

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

Readonly ist nicht auf dem System installiert, das ich benutze, und ich bin nicht frei, neue Module frei zu installieren. Aber danke für deinen Vorschlag. Das habe ich beim googlen gesehen. – Pistos

+4

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

+0

@Sinan: Danke, aber das hilft mir nicht Fall. Sie können meine Umstände für diejenigen eines Benutzers auf Shared Hosting oder etwas verwechseln. Die Barrieren sind nicht technisch, sie sind sozial/politisch/leitend. :) – Pistos

11

Sie können dies auch mit builtins völlig tun:

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

Danke, Ether. Ich werde mit dieser Syntax gehen, da ich überall Referenzen verwenden kann. Ich würde deine als die akzeptierte Antwort markieren, aber es kam ein bisschen zu spät. :) – Pistos

+0

Hash :: Util :: lock_hash_recurse ist eine feine Lösung, aber ich mag die eingebaute Lösung. –

Verwandte Themen