Как запустить кусок кода непосредственно перед выходом из Perl script

В моем script мне нужно загрузить некоторую информацию из файла диска, а во время запуска script информация может быть изменена. Чтобы сохранить консистенцию файла на диске и копировать его в память, мне нужно записывайте информацию на диск всякий раз, когда информация изменяется в памяти или периодически записывает их обратно на диск или просто записать их во время выхода script, который является предпочтительным, поскольку он сэкономит много времени ввода-вывода и сделает script отзывчивым.

Итак, как и название, мой вопрос в том, что perl имеет какой-то механизм, который будет отвечать моим потребностям?

Ответ 1

Есть два разных способа сделать это, в зависимости от того, что вы ищете.

  • Блок END выполняется, когда интерпретатор выключен. Дополнительную информацию см. В предыдущем ответе:)
  • Блок /sub DESTROY, который выполняется, когда ваш объект выходит из области видимости. То есть, если вы хотите встроить свою логику в модуль или класс, вы можете использовать DESTROY.

Взгляните на следующий пример (это рабочий пример, но некоторые детали, такие как проверка ошибок и т.д.) опущены):

#!/usr/bin/env perl

package File::Persistent;

use strict;
use warnings;
use File::Slurp;

sub new {
    my ($class, $opt) = @_;

    $opt ||= {};

    my $filename = $opt->{filename} || "./tmpfile";
    my $self = {
        _filename => $filename,
        _content => "",
    };

    # Read in existing content
    if (-s $filename) {
        $self->{_content} = File::Slurp::read_file($filename);
    }

    bless $self, $class;
}

sub filename {
    my ($self) = @_;
    return $self->{_filename};
}

sub write {
    my ($self, @lines) = @_;
    $self->{_content} .= join("\n", @lines);
    return;
}

sub DESTROY {
    my ($self) = @_;
    open my $file_handle, '>', $self->filename
        or die "Couldn't save persistent storage: $!";
    print $file_handle $self->{_content};
    close $file_handle;
}

# Your script starts here...
package main;

my $file = File::Persistent->new();

$file->write("Some content\n");

# Time passes...
$file->write("Something else\n");

# Time passes...
$file->write("I should be done now\n");

# File will be written to only here..

Ответ 2

Я думаю, что вы ищете END block:

END {
    # cleanup
}

Кодовый блок END выполняется как можно дольше, то есть после того, как perl завершил запуск программы и незадолго до выхода интерпретатора, даже если он выходит из функции die(). (Но нет, если он превращается в другую программу через exec или выдувается из воды сигналом - вы должны заманивать это самостоятельно (если можете).) У вас может быть несколько блоков END в файле - они будут выполнить в обратном порядке определения; то есть: последний, первый (LIFO). Блоки END не выполняются при запуске perl с ключом -c или сбой компиляции.