Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to run piece of code just before the exit of perl script

Tags:

perl

In my script, I need to load some info from disk file and during the run of script the info might be changed.To keep the consistence of the file in disk and it's in memory copy I need to write back the info to disk whenever the info is changed in memory or periodically write them back to disk or just write them back at the time of the script exit, which is the preferred one, because it will save lots of IO time and make the script responsive.

So just as the title, my question is does perl has some mechanism that will meet my needs?

like image 342
Haiyuan Zhang Avatar asked Jun 20 '10 07:06

Haiyuan Zhang


People also ask

How do I set an exit code in perl?

The exit code If you have used the Unix/Linux shell, then you might know each program when exits provides an exit code that can be found in the $? variable. You can provide this exit value from a perl script as well by passing a number to the exit() call.

What is $? In perl script?

$? The status returned by the last pipe close, backtick (\`\`) command or system operator. Note that this is the status word returned by the wait() system call, so the exit value of the subprocess is actually ($? >> 8). $? & 255 gives which signal, if any, the process died from, and whether there was a core dump.

How do I run an exec in perl?

exec - Perldoc Browser. The exec function executes a system command and never returns; use system instead of exec if you want it to return. It fails and returns false only if the command does not exist and it is executed directly instead of via your system's command shell (see below).


2 Answers

I think you're looking for END block:

END {
    # cleanup
}

An END code block is executed as late as possible, that is, after perl has finished running the program and just before the interpreter is being exited, even if it is exiting as a result of a die() function. (But not if it's morphing into another program via exec, or being blown out of the water by a signal--you have to trap that yourself (if you can).) You may have multiple END blocks within a file--they will execute in reverse order of definition; that is: last in, first out (LIFO). END blocks are not executed when you run perl with the -c switch, or if compilation fails.

like image 181
Amadan Avatar answered Oct 19 '22 23:10

Amadan


There's two different ways to do this, depending on what you're looking for.

  • The END block is executed when the interpreter is shut down. See the previous answer for more details :)
  • The DESTROY block/sub, that is executed when your object goes out of scope. That is, if you want to embed your logic into a module or class, then you can use DESTROY.

Take a look at the following example (it's a working example, but some details like error checking, etc.. are omitted):

#!/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..
like image 26
Cosimo Avatar answered Oct 20 '22 00:10

Cosimo