Tôi chắc chắn rằng điều này được đề cập trong tài liệu ở đâu đó nhưng tôi không thể tìm thấy nó ... Tôi đang tìm đường cú pháp mà sẽ làm cho nó có thể gọi một phương thức trên một lớp có tên được lưu trữ trong một băm (như trái ngược với một vô hướng đơn giản):Làm cách nào để gọi tên hàm được lưu trữ trong băm trong Perl?
use strict; use warnings;
package Foo;
sub foo { print "in foo()\n" }
package main;
my %hash = (func => 'foo');
Foo->$hash{func};
Nếu tôi sao chép $hash{func}
vào một biến vô hướng đầu tiên, sau đó tôi có thể gọi Foo->$func
tốt ... nhưng những gì là mất tích để cho phép Foo->$hash{func}
để làm việc?
(EDIT: Tôi không có ý định làm bất cứ điều gì đặc biệt bằng cách gọi một phương thức trên lớp Foo
- điều này có thể dễ dàng là một đối tượng may mắn (và trong mã thực tế của tôi); lập một ví dụ độc lập bằng cách sử dụng phương thức lớp.)
CHỈNH SỬA 2: Chỉ cần điền đầy đủ các nhận xét bên dưới, đây là những gì tôi thực sự đang làm (thư viện đường thuộc tính Moose, được tạo với Moose::Exporter) :
# adds an accessor to a sibling module
sub foreignTable
{
my ($meta, $table, %args) = @_;
my $class = 'MyApp::Dir1::Dir2::' . $table;
my $dbAccessor = lcfirst $table;
eval "require $class" or do { die "Can't load $class: [email protected]" };
$meta->add_attribute(
$table,
is => 'ro',
isa => $class,
init_arg => undef, # don't allow in constructor
lazy => 1,
predicate => 'has_' . $table,
default => sub {
my $this = shift;
$this->debug("in builder for $class");
### here's the line that uses a hash value as the method name
my @args = ($args{primaryKey} => $this->${\$args{primaryKey}});
push @args, (_dbObject => $this->_dbObject->$dbAccessor)
if $args{fkRelationshipExists};
$this->debug("passing these values to $class -> new: @args");
$class->new(@args);
},
);
}
Tôi đã thay thế dòng được đánh dấu ở trên bằng điều này:
my $pk_accessor = $this->meta->find_attribute_by_name($args{primaryKey})->get_read_method_ref;
my @args = ($args{primaryKey} => $this->$pk_accessor);
PS. Tôi đã chỉ nhận thấy rằng kỹ thuật tương tự này (sử dụng lớp meta Moose để tra cứu coderef thay vì giả định quy ước đặt tên) không thể cũng được sử dụng cho các vị từ, vì Class::MOP::Attribute không có truy cập get_predicate_method_ref
tương tự. :(
Tôi không nghĩ rằng có thể do để phân tích cú pháp của Perl. Tại sao bạn không muốn sao chép $ hash {func} vào một vô hướng đầu tiên? –
Không có lý do cụ thể ngoại trừ nó có vẻ không cần thiết, và đây là một câu đố thú vị mà stumped tôi. Tôi không tin rằng đơn giản chỉ vì tôi không biết câu trả lời là không có câu trả lời. :) (tl; dr phiên bản: bởi vì tôi tò mò!) – Ether
Er, có vẻ như với tôi rằng nếu bạn đang sử dụng Moose, sau đó bạn vẫn đang đi về nó một cách sai lầm. Một trong những tính năng của Moose là mô hình đối tượng meta được xây dựng trên ... Tôi có cảm giác rằng có một phương pháp bạn có thể gọi để tìm kiếm thực tế theo tên chuỗi, sau đó bạn có thể gọi, thay vì sử dụng các chuỗi trống . Tôi không biết nó ra khỏi đầu của tôi, mặc dù ... –