2009-07-31 15 views
5

tôi muốn làm, trong Perl, tương đương với mã Ruby sau:Làm cách nào để tạo một băm lồng nhau dưới dạng hằng số trong 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' ] 

Đó là, tôi chỉ muốn khai báo một cấu trúc băm lồng nhau liên tục cho sử dụng cả trong lớp và ngoài. Làm thế nào để?

+0

Tôi đã có lớp Perl tôi thiết lập (với ban phước , vv), vì vậy tôi không cần phải trình bày cách thực hiện điều đó. – Pistos

Trả lời

8

Bạn có thể sử dụng mô-đun Hash::Util để khóa và mở khóa băm (khóa, giá trị hoặc cả hai).

package Foo; 
use Hash::Util; 

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

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

Sau đó, trong một số tập tin khác:

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

Cảm ơn, Michael, đây chính xác là những gì tôi cần. Tôi đã cố gắng sử dụng lock_hashref, nhưng nó dường như không được xác định cho tôi, nhưng đó là okay, tôi có thể làm gì với lock_hash. – Pistos

+0

Tôi nhận thấy tôi có thể thực hiện những gì tôi cần đơn giản với "của chúng tôi", tôi không cần Hash :: Util. Tôi không quan tâm đến những người khác rối tung với băm sau khi thực tế, tôi chỉ cần biết làm thế nào để xác định một hằng số có thể truy cập trong Perl. Mã ví dụ của bạn cho tôi thấy. – Pistos

+2

Vì vậy, bạn không thực sự cần một hằng số? Công cụ Hash :: Util là phép thuật giúp mọi người thay đổi giá trị băm. –

1

Đây là một hướng dẫn để băm trong perl. Hash of Hashes

+0

Cảm ơn, mặc dù tôi đã xây dựng băm lồng nhau nói chung trong Perl. Nhu cầu cụ thể của tôi đã làm với việc sử dụng nó cả trong và ngoài một gói/lớp. – Pistos

4

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

Output:

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

Chỉ đọc không được cài đặt trên hệ thống tôi đang sử dụng và tôi không có quyền tự do cài đặt các mô-đun mới. Nhưng cảm ơn đề nghị của bạn. Tôi đã đi qua đó khi googling. – Pistos

+4

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

+0

@Sinan: Cảm ơn, nhưng điều đó không giúp ích gì cho tôi trường hợp. Bạn có thể đang nhầm lẫn hoàn cảnh của tôi với những người dùng của một người dùng trên lưu trữ được chia sẻ hoặc một thứ gì đó. Các rào cản không phải là kỹ thuật, chúng là xã hội/chính trị/quản lý. :) – Pistos

11

Bạn cũng có thể làm được điều này hoàn toàn với 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

Cảm ơn, Ether. Tôi sẽ đi với cú pháp này, vì nó cho phép tôi liên tục sử dụng tài liệu tham khảo ở khắp mọi nơi. Tôi sẽ đánh dấu của bạn là câu trả lời được chấp nhận, nhưng nó đã đến một chút quá muộn. :) – Pistos

+0

Hash :: Util :: lock_hash_recurse là một giải pháp tốt, nhưng tôi thích giải pháp tích hợp sẵn. –