Perl sẽ yêu cầu trợ giúp một chút để thực hiện việc này. Bởi vì nó không xem xét các tham chiếu mã được lưu trữ trong băm như "các phương thức". Các phương thức được thực hiện như các mục nhập vào một bảng biểu tượng gói.Perl là nhiều hơn theo định hướng lớp học so với JavaScript, tự hào tuyên bố rằng nó là nhiều hơn hướng đối tượng (trên từng đối tượng đối tượng).
Để thực hiện chức năng đó, bạn sẽ phải tạo một lớp đã ánh xạ các tham chiếu theo cách này. Cách lấy các phương thức trong bảng biểu tượng là phương thức AUTOLOAD
. Nếu một gói chứa một chương trình con AUTOLOAD
, khi một cuộc gọi được thực hiện đến một đối tượng may mắn mà Perl không thể tìm thấy trong chuỗi kế thừa, nó sẽ gọi AUTOLOAD
và đặt biến có phạm vi gói (our
) $AUTOLOAD
sẽ chứa tên đầy đủ của chức năng.
Chúng tôi lấy tên của phương thức được gọi, bằng cách nhận nút cuối cùng (sau 'cuối cùng' :: ') của tên phụ đủ điều kiện. Chúng tôi tìm xem liệu có một coderef tại vị trí đó không và nếu có, chúng tôi có thể trả lại.
package AutoObject;
use strict;
use warnings;
use Carp;
use Params::Util qw<_CODE>;
our $AUTOLOAD;
sub AUTOLOAD {
my $method_name = substr($AUTOLOAD, index($AUTOLOAD, '::') + 2);
my ($self) = @_;
my $meth = _CODE($self->{$method_name});
unless ($meth) {
Carp::croak("object does not support method='$method_name'!");
}
goto &$meth;
}
1;
Sau đó, bạn sẽ chúc phúc cho các đối tượng vào lớp rằng:
package main;
my $obj
= bless { foo => 1
, hello => sub { return 'world' }
}, 'AutoObject';
print $obj->hello();
Thông thường, trong một AUTOLOAD
phụ tôi "xi măng" hành vi. Tức là, tôi tạo các mục nhập vào bảng biểu tượng gói để tránh AUTOLOAD
vào lần tiếp theo. Nhưng đó thường là cho một hành vi lớp học được xác định hợp lý.
Tôi cũng thiết kế một gói QuickClass
để tạo gói cho từng đối tượng được khai báo, nhưng có chứa rất nhiều biểu tượng bàn cãi rằng giờ đây có thể thực hiện tốt hơn với Class::MOP
.
Đưa ra đề xuất của Eric Strom, bạn có thể thêm mã sau đây vào gói AutoObject. Phụ đề import
sẽ được gọi bất cứ lúc nào ai đó use
-d AutoObject
(với thông số 'object'
).
# Definition:
sub object ($) { return bless $_[0], __PACKAGE__; };
sub import { # gets called when Perl reads 'use AutoObject;'
shift; # my name
return unless $_[0] eq 'object'; # object is it's only export
use Symbol;
*{ Symbol::qualify_to_reference('object', scalar caller()) }
= \&object
;
}
Và sau đó, khi bạn muốn tạo ra một "đối tượng theo nghĩa đen", bạn có thể chỉ cần làm:
use AutoObject qw<object>;
Và biểu thức sẽ là:
object { foo => 1, hello => sub { return 'world' } };
Bạn thậm chí có thể làm :
object { name => 'World'
, hello => sub { return "Hello, $_[0]->{name}"; }
}->hello()
;
Và bạn có một "đối tượng chữ "biểu hiện". Có lẽ mô-đun sẽ tốt hơn được gọi là Object::Literal
.
phương pháp Perl không phải là lĩnh vực trong một hash - đây không phải là Java. – Ether
JavaScript cũng không phải là Java. – cjm