Vì mục đích học tập, tôi đang đùa giỡn với ý tưởng xây dựng các chương trình hướng sự kiện trong Perl và nhận thấy rằng có thể tốt hơn nếu một chương trình con đã được đăng ký như một trình xử lý sự kiện có thể bị thất bại, chỉ cần lên lịch một cuộc gọi khác cho chính nó sau này. Cho đến nay, tôi có đưa ra một cái gì đó như thế này:Trong Perl, làm thế nào một chương trình con có thể nhận được một coderef trỏ đến chính nó?
my $cb;
my $try = 3;
$cb = sub {
my $rc = do_stuff();
if (!$rc && --$try) {
schedule_event($cb, 10); # schedule $cb to be called in 10 seconds
} else {
do_other_stuff;
}
};
schedule_event($cb, 0); # schedule initial call to $cb to be performed ASAP
Có cách nào mà mã bên trong tiểu có thể truy cập vào coderef đó phụ vì vậy tôi có thể làm mà không sử dụng một biến thêm? Tôi muốn lập lịch cuộc gọi ban đầu như thế này.
schedule_event(sub { ... }, 0);
tôi suy nghĩ đầu tiên của việc sử dụng caller(0)[3]
, nhưng điều này chỉ mang lại cho tôi một tên chức năng, (nếu không có tên), không phải là một tài liệu tham khảo đang mà có một pad gắn liền với nó.
Câu hỏi thực sự thú vị. –
Nếu bạn làm điều này rất nhiều trong cùng một chương trình, bạn sẽ bị rò rỉ bộ nhớ do tham chiếu vòng tròn. Bạn có thể sử dụng Scalar :: Util :: weaken() để tránh điều này, hoặc sử dụng Sub :: Current hoặc Y-combinator như gợi ý bên dưới. Xem http://use.perl.org/~Aristotle/journal/30896 để thảo luận. Nếu mã này không ở trong môi trường liên tục, mã của bạn ở trên có thể là tốt. – runrig
runrig: Cảm ơn bạn đã liên kết. Đầu của tôi đang quay. :-) Có lẽ tôi thực sự sẽ học một cái gì đó ... – hillu