2009-07-31 27 views
5

Ben Perl, aşağıdaki Yakut kod eşdeğer, yapmak istiyorum:Perl'de nasıl iç içe geçmiş bir karma oluşturabilirim?

olduğunu
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' ] 

, sadece kullanım sınıfında ve dış her ikisi için sürekli, iç içe karma yapıyı ilan etmek istiyorum. Nasıl?

+0

(korusun ile vs.), nasıl yapılacağını göstermem gerekmiyor. – Pistos

cevap

8

Bir hash'ı (tuşlar, değerler veya her ikisi) kilitlemek ve kilidini açmak için Hash::Util modülünü kullanabilirsiniz.

package Foo; 
use Hash::Util; 

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

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

Sonra diğer bazı dosyasında:

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

Teşekkürler Michael, tam olarak ihtiyacım olan şey bu. Lock_hashref'i kullanmayı denedim, ancak benim için tanımlanmış gibi görünmüyor, ama bu tamam, lock_hash ile yapabilirim. – Pistos

+0

Sadece "bizim" ile ihtiyacım olan şeyi başarabildiğimi fark ettim, Hash :: Util'e ihtiyacım yok. Aslında insanı karmaşadan kurtaran insanlarla ilgilenmiyorum, Perl'de erişilebilir bir sabiti nasıl tanımlayacağımı bilmem gerekiyordu. Örnek kodun bana gösterdi. – Pistos

+2

Yani gerçekten bir sabite ihtiyacınız yok mu? Hash :: Util şeyler, insanları karma değişimini engelleyen bir sihirdir. –

1

perl'de sağlamalarının bir rehberdir. Hash of Hashes

+0

Teşekkürler, yine de Perl'de yuvalanmış karmalar inşa ettim. Benim özel ihtiyacım, bir paket/sınıfın içinde ve dışında kullanmakla ilgilidir. – Pistos

4

Readonly bakınız:

#!/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; 

Çıktı:

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

Readonly, kullandığım sisteme yüklü değil ve yeni modülleri serbestçe yüklemek için özgürlüğüm yok. Ancak öneriniz için teşekkürler. Ben googling yaparken rastladım. – Pistos

+4

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

+0

@Sinan: Teşekkürler, ama bu benim için vaka. Koşullarımın bir kullanıcı için paylaşılan barındırma veya bir şeyle ilgili olduğunu düşünüyor olabilirsiniz. Engeller teknik değil, sosyal/politik/yönetsel. :) – Pistos

11

Ayrıca yerleşikleri ile tamamen bunu yapabilirsiniz:

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}; 
Zaten Perl sınıfı kurdunuz
+1

Teşekkürler, Ether. Bu sözdizimi ile gideceğim, çünkü her yerde referansları sürekli kullanmamı sağlıyor. Seninkini kabul edilen cevap olarak işaretlerdim, ama biraz geç oldu. :) – Pistos

+0

Hash :: Util :: lock_hash_recurse iyi bir çözüm, ancak yerleşik çözümü seviyorum. –

İlgili konular