2009-07-31 8 views
5

chcę robić w Perl, odpowiednik następującego kodu Ruby:Jak mogę utworzyć zagnieżdżony skrót jako stałą w Perlu?

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

Oznacza to, że po prostu chcę zadeklarować stałą strukturę, zagnieżdżone hash do użycia zarówno w klasie i poza nią. Jak?

+0

Mam już moja klasa Perl skonfigurować (z błogosławić itp.), więc nie trzeba pokazywać, jak to zrobić. – Pistos

Odpowiedz

8

Możesz użyć modułu Hash::Util do zablokowania i odblokowania skrótu (klawiszy, wartości lub obu).

package Foo; 
use Hash::Util; 

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

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

Potem w jakiś inny plik:

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

Dzięki, Michael, właśnie tego potrzebuję. Próbowałem użyć lock_hashref, ale wydaje mi się, że nie jest to dla mnie zdefiniowane, ale w porządku, mogę zrobić z lock_hash. – Pistos

+0

Zauważam, że mogę osiągnąć to, czego potrzebuję po prostu z "naszym", nie potrzebuję Hash :: Util. Nie interesują mnie inne osoby mieszające się z hashem po tym, po prostu musiałem wiedzieć, jak zdefiniować stałą dostępną w Perlu. Twój przykładowy kod pokazał mi. – Pistos

+2

Więc naprawdę nie potrzebujesz stałej? The Hash :: Util to magia, która powstrzymuje ludzi przed zmianą hasza. –

1

Oto przewodnik do mieszań w Perl. Hash of Hashes

+0

Dzięki, zbudowałem zagnieżdżone skróty ogólnie w Perlu. Moja szczególna potrzeba dotyczy korzystania z niego zarówno w ramach pakietu, jak i poza nim. – Pistos

4

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

wyjściowa:

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

Readonly nie jest instalowany w używanym przeze mnie systemie i nie mogę swobodnie instalować nowych modułów. Ale dzięki za twoją sugestię. Znalazłem to podczas googlowania. – Pistos

+4

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

+0

@Sinan: Dzięki, ale to nie pomaga w moim walizka. Być może pomylisz moje okoliczności z sytuacjami użytkownika współdzielonego hostingu lub czegoś podobnego. Bariery nie są techniczne, mają charakter społeczno-polityczny/menedżerski. :) – Pistos

11

Można też to zrobić w całości z 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

Dzięki, Ether. Mam zamiar stosować tę składnię, ponieważ pozwala mi stale używać referencji wszędzie. Zaznaczę twoją jako zaakceptowaną odpowiedź, ale przyszło trochę za późno. :) – Pistos

+0

Hash :: Util :: lock_hash_recurse to dobre rozwiązanie, ale podoba mi się wbudowane rozwiązanie. –

Powiązane problemy