2008-11-12 27 views
11

Trong PHP, tôi có thể viết:Perl có biến động như PHP không?

$vname = 'phone'; 
$$vname = '555-1234'; 
print $phone; 

... Và kịch bản sẽ ra "555-1234".

Có tương đương nào trong Perl không?

Có cách nào để hạn chế $phone đến phạm vi của khối cục bộ, như thể tôi đã viết my $phone? Sử dụng my $$vname mang lại cho tôi "Không thể khai báo các tham số vô hướng trong các lỗi ... của tôi".

+0

tôi đặt này trong câu trả lời của CMS vì tôi không thấy chỉnh sửa này, nhưng nó phải là "$$ vname = '555 -1234 '", loại bỏ" của tôi ". – gpojd

+2

Đây là mã không dùng nữa ngay cả trong PHP. Khi những người khác đã đăng, hãy sử dụng một băm. – staticsan

+2

Tính năng đó được sao chép từ Perl, khi PHP được viết bằng Perl. –

Trả lời

56

Những gì bạn đang cố gắng thực hiện được gọi là "tham chiếu tượng trưng". Trong khi bạn có thể làm điều này trong Perl you shouldn't. Các tham chiếu tượng trưng chỉ hoạt động với các biến toàn cầu - không phải các biến số từ vựng (my). Không có cách nào để hạn chế phạm vi của họ. Các tham chiếu tượng trưng rất nguy hiểm. Vì lý do đó, chúng không hoạt động theo pragma strict.

Nói chung, bất cứ khi nào bạn nghĩ rằng bạn cần tài liệu tham khảo mang tính biểu tượng, bạn nên sử dụng một băm thay vì:

my %hash; 
$hash{phone} = '555-1234'; 
print $hash{phone}; 

Có một vài trường hợp symrefs là hữu ích và thậm chí cần thiết. Ví dụ, cơ chế xuất khẩu của Perl sử dụng chúng. Đây là những chủ đề nâng cao. Đến lúc bạn sẵn sàng cho họ, bạn sẽ không cần phải hỏi làm thế nào. ;-)

8

Bạn có thể làm điều đó một cách rất giống nhau:

Nhưng mà bạn có thể không có nghĩa là bạn nên. Cách tốt nhất để quản lý việc này là, as Michael Carman says, SỬ DỤNG TIỀN MẶT!

+1

Tại sao tôi không bao giờ biết bạn có thể làm điều đó trong Perl? –

+0

Ta. Có cách nào để hạn chế điện thoại $ đến phạm vi của khối cục bộ, như thể tôi đã viết "điện thoại $ của tôi"? Sử dụng "my $$ vname" cung cấp cho tôi "Không thể khai báo darference vô hướng trong của tôi tại ..." lỗi. –

+0

Điều này cho tôi lỗi sau: "Biểu tượng toàn cầu" $ phone "yêu cầu tên gói rõ ràng ở temp.pl dòng 6." – Svante

6

Bạn không thể thực hiện việc này với chế độ pragma nghiêm ngặt được bật và pragma nghiêm ngặt thường luôn được bật. Bạn có thể làm điều đó với pragma tắt tuy nhiên, hãy nhìn vào này một liner:

perl -le 'my $vname = "phone"; ${ $vname } = "555-1234"; print $phone' 

Điều đó sẽ làm việc, nhưng điều này sẽ không:

perl -Mstrict -le 'my $vname = "phone"; ${ $vname } = "555-1234"; print $phone' 

"-Mstrict" cho nó để "sử dụng nghiêm khắc".

Tốt nhất nên sử dụng hàm băm cho một thứ như thế này, giống như một mảng kết hợp trong PHP.

13

Đọc các bài viết của Mark-Jason Dominus về việc này trong Why it's stupid to `use a variable as a variable name'.

Bạn sẽ giới hạn phạm vi thay đổi của bạn đến $ điện thoại bằng cách bắt đầu khối với

local $phone; 

hoặc thậm chí

local $$vname; 

(Mặc dù một trong hai thay đổi $ điện thoại cho bất kỳ tàu ngầm gọi từ khối của bạn quá , vì vậy nó không giống như phạm vi từ vựng của một tuyên bố my().)

+3

Tôi chưa bao giờ dự tính sử dụng C để giới hạn phạm vi của symref. Đó là cả hai thú vị và hư hỏng. Nó giống như nói rằng bạn sẵn sàng để bắn mình vào chân nhưng chỉ với một khẩu súng BB. –

0

Bạn nhận ra rằng PHP thừa hưởng nhiều tính năng của nó từ Perl, phải không?

Không chỉ Perl có thể làm tất cả các biểu tượng tài liệu tham khảo thứ PHP có thể,

use strict; 
use warnings; 
use 5.010; 

our $test=1; 

# Access $test through the special hash %:: 
say ${$::{test}}++; 

# This is essentially what the previous line did. 
say ${\$test}++ 

# Same as $test 
say ${test}++; 

{ 
    # PHP's simple symbolic ref 
    my $ref = "test"; 
    no strict 'refs'; 
    say $$ref++; 
    say ${"test"}++; 
} 
{ 
    package d; 
    say ${$main::{test}}++; 

    my $ref = $main::{"test"}; 
    say $$ref++; 

    $ref = \$main::test; 
    say $$ref++; 
} 
Các vấn đề liên quan