7

Tôi có một chương trình Perl tạo các quy tắc phân tích cú pháp dưới dạng subs từ một tệp đầu vào. Các subs được định nghĩa một cách nặc danh khi đưa vào một băm. Bây giờ, tôi muốn xuất băm đó, với tất cả các đăng ký và sau đó tải chúng lại sau để sử dụng với một chương trình khác.Viết một phụ nặc danh trong Perl vào một tập tin để sử dụng sau này

Tôi làm cách nào để thực hiện việc này? Có cách nào để trích xuất mã của mỗi tiểu, hoặc tôi có thể sao chép khối bộ nhớ mà băm tồn tại và sau đó đúc nó như một băm khi tôi tải nó lại sau?

Xin cảm ơn trước.

+0

Thay vì tiết kiệm các tàu ngầm biên soạn thực tế, bạn có thể tiết kiệm * * văn bản của tàu ngầm, và sau đó tái eval chúng vào coderefs trong quá trình mới. – Ether

+0

Vâng, tôi đã nghĩ về điều đó. Nhưng tôi muốn có thể tiết kiệm được những người đăng ký đã biên soạn vì lý do thẩm mỹ. :-p –

+0

Tất cả các kỹ thuật tôi biết sử dụng B :: Deparse để dịch tham chiếu mã trở lại mã nguồn Perl. Quá trình này có thể không cung cấp cho bạn mã nguồn giống như bạn đã bắt đầu. Tôi không nghĩ rằng điều này sẽ mua cho bạn nhiều hơn chỉ đơn giản là tiết kiệm văn bản gốc thực tế. –

Trả lời

2

Từ phần "Code References" của tài liệu storable (với sự nhấn mạnh thêm):

Kể từ storable phiên bản 2.05, tài liệu tham khảo MÃ thể được tuần tự với sự giúp đỡ của B::Deparse. Để bật tính năng này, hãy đặt $Storable::Deparse thành giá trị thực. Để bật tính năng deserialization, $Storable::Eval phải được đặt thành giá trị thực. Lưu ý rằng quá trình deserialization được thực hiện thông qua eval, điều này rất nguy hiểm nếu tệp Storable chứa dữ liệu độc hại.

Trong bản trình bày bên dưới, quy trình con tạo băm của người đăng ký ẩn danh. Sau đó, phụ huynh — trong một không gian địa chỉ và quy trình hoàn toàn riêng biệt, do đó, nó không thể nhìn thấy %dispatch —đọc sản lượng từ freeze giống như cách bạn có thể từ một tệp trên đĩa.

#! /usr/bin/perl 

use warnings; 
use strict; 

use Storable qw/ freeze thaw /; 

my $pid = open my $fh, "-|"; 
die "$0: fork: $!" unless defined $pid; 

if ($pid == 0) { 
    # child process 
    my %dispatch = (
    foo => sub { print "Yo!\n" }, 
    bar => sub { print "Hi!\n" }, 
    baz => sub { print "Holla!\n" }, 
); 

    local $Storable::Deparse = 1 || $Storable::Deparse; 
    binmode STDOUT, ":bytes"; 
    print freeze \%dispatch; 
    exit 0; 
} 
else { 
    # parent process 
    local $/; 
    binmode $fh, ":bytes"; 
    my $frozen = <$fh>; 

    local $Storable::Eval = 1 || $Storable::Eval; 
    my $d = thaw $frozen; 
    $d->{$_}() for keys %$d; 
} 

Output:

Hi! 
Holla! 
Yo!
+0

và tôi có thể chỉ cần viết '$ frozen' vào một tệp văn bản? và đừng lo lắng, tôi sẽ khử trùng đầu vào của mình. Tôi đã học được điều này từ XKCD: D –

+0

@Mechko Có, trong mã của bạn, bạn sẽ viết đầu ra vào một tập tin trên đĩa và sau đó đọc nó sau này. Tôi đã thay đổi bản trình diễn để giống với cả hai mặt của đường ống của bạn. –

4

KiokuDB có thể xử lý các tham chiếu mã lưu trữ ngoài các loại Perl khác. Vì vậy, có thể các mô-đun YAML khác nhau, Data::Dump::Streamer và thậm chí cả Dữ liệu :: Dumper.