Can storage be stored in a DATA file descriptor?

I was curious to use Storable store_fd, and fd_retrieve will allow me to store the data structure in my own DATA file descriptor. I understand that this is not the best practice, I am just wondering if it works, my quick attempts to try, it seems, do not work.

+3
source share
4 answers

I'm not sure why you want to do this, but you can fake it. However, you should avoid this.

Just for a giggle, you can open the file descriptor, read the lines from $0and print them until you get to it __DATA__, and then add a new section __DATA__. The trick is to rename your new file to become $0, perhaps, with help execif your system locks the file while the program is running:

#!perl

my $mode = (stat($0))[2] & 07777;

open my($fh), '<', $0 or die "I can't open me! $!\n";
open my($new), '>', "$0.new" or die "I can't open you! $!\n";
eval { chmod( $mode, $new ) } or warn "Couldn't set permissions: $@\n";

while( <$fh> )
    {
    last if /^__DATA__$/;
    print { $new } $_;
    }

print "I am $$\n";
print { $new } "__DATA__\n", join '|', $$, time, (stat($0))[1];

rename( "$0.new", $0 )

__DATA__
64574|1265415126|8843292
+2
source

DATAis a descriptor for reading data stored in a script. Conway Inline :: Files is the only module I know that talks about rewritable virtual files. And since script files are usually ASCII, I don’t know what happens if you get binary 26-byte code on MSDOS or binary 4 on UNIX in Storable output.

, , , , script, .

, YAML JSON . , YAML DATA.

+1

:

$ cat write-data
#! /usr/bin/perl

use warnings;
print DATA "bar!\n";

$ ./write-data
Name "main::DATA" used only once: possible typo at ./write-data line 6.
print() on unopened filehandle DATA at ./write-data line 6.

:

#! /usr/bin/perl

use warnings;
use strict;

use Data::Dumper;
use File::Temp qw/ tempfile /;
use Storable qw/ store_fd fd_retrieve /;

sub store_in_DATA {
  my($data) = @_;

  my($fh,$path) = tempfile;
  unlink $path           or warn "$0: unlink: $!";

  *DATA = $fh;
  store_fd $data, \*DATA or warn "$0: print: $!";

  seek DATA, 0, 0        or warn "$0: seek: $!";
}

store_in_DATA { foo => "There is no spoon.\n" };

undef $/;
my $ref = fd_retrieve \*DATA;
print Dumper $ref;

Windows unlink - . , END Win32:: SharedFileOpen.

+1

... , ; unit test script -. , , , , ( ).

__DATA__, Data::Dumper. :

use Data::Dumper;
$Data::Dumper::Terse = 1; # to Eval whole thing as a hash
$Data::Dumper::Indent = 1; # Looks better, just a preference
$Data::Dumper::Sortkeys = 1; # To keep changes minimal in source control
print $fh Dumper(\%HASH);

script DATA mtime (mtime , script).

use vars qw(%HASH $FILEPOS $MTIME);

{
    $FILEPOS = tell(DATA);
    $MTIME = (stat(DATA))[9];
    local $/;
    my $data = <DATA>;
    %HASH = %{eval $data};
}

, __DATA__, __FILE__ $FILEPOS, . .

open(my $fh, '>>', __FILE__) or die $!;
seek($fh, $FILEPOS, 0) or die $!;
die "File changed" if ((stat($fh))[9] != $MTIME);
truncate($fh, $FILEPOS) or die $!;

# Assumes Dumper is already loaded and configured as in first code snippet
print $fh Dumper(\%HASH);

, !

, Storable; . , , , diff , , Dumper.

0

Source: https://habr.com/ru/post/1731606/


All Articles