perl 在 %ENV 中存储散列
perl storing hash in %ENV
我想(滥用)使用全局 %ENV 来存储哈希。这似乎对 %ENV 的工作方式不同于对普通哈希的工作方式。在下面的程序中,$ENV{myhash}
仍然包含 'myhash' => 'HASH(0x7ffad8807380)'
并且 %ahash
仍然存在。是否可以将十六进制地址转换回指向它的位置,而不是只包含字符串?我想我可以序列化和反序列化散列。正确的做法是什么?
#!/usr/bin/perl -w
use common::sense;
use Data::Dumper;
my %QENV = ( nohash => 'noh' );
my %ahash= ( hv1 => 'htext1', hv2 => 'htext2' );
$QENV{'myhash'} = \%ahash;
print "works: ". Dumper(\%QENV)."\n\n\n";
$ENV{'myhash'} = \%ahash;
print "fails: ". Dumper(\%ENV)."\n";
%ENV
是一个神奇的散列。它反映了进程的环境。从它读取从环境中读取,向它写入会改变环境。
如果你能保证引用的变量仍然存在(通过它仍然在范围内或者通过它增加它的 REFCNT
),你确实可以从地址创建对它的引用。
use strict;
use warnings;
use Data::Dumper;
use Inline C => <<'__EOS__';
SV* _newRV(IV iv) {
return newRV((SV*)iv);
}
__EOS__
my %hash = ( a => 1, b => 2 );
my $ref = \%hash;
my $ref_string = "$ref";
my $addr = hex( ( $ref_string =~ /\((.*)\)/ )[0] );
my $ref2 = _newRV($addr);
print(Dumper($ref2));
我不知道你为什么要这样做。它不允许另一个进程访问数据,因为一个进程无法访问另一个进程的内存。
您似乎想要共享数据。这是我经常放在那里的一个例子,它展示了如何将数据存储在 JSON 文件中,然后检索它。 JSON是跨语言的,所以数据可以被多种编程语言使用,而不仅仅是Perl。尽管此示例在单个脚本中,但可以想象它是两个不同的 Perl 应用程序:
use warnings;
use strict;
use JSON;
my $file = 'data.json';
my %h = (
foo => 'bar',
raz => {
ABC => 123,
XYZ => [4, 5, 6],
}
);
my $json = encode_json \%h;
# write the JSON to a file, and close it
open my $fh, '>', $file or die $!;
print $fh $json;
close $fh or die $!;
# open the JSON file, and read it
open my $json_file, '<', $file or die $!;
my $read_json;
{
local $/;
$read_json = <$json_file>;
}
my $perl_hash = decode_json $read_json;
我想(滥用)使用全局 %ENV 来存储哈希。这似乎对 %ENV 的工作方式不同于对普通哈希的工作方式。在下面的程序中,$ENV{myhash}
仍然包含 'myhash' => 'HASH(0x7ffad8807380)'
并且 %ahash
仍然存在。是否可以将十六进制地址转换回指向它的位置,而不是只包含字符串?我想我可以序列化和反序列化散列。正确的做法是什么?
#!/usr/bin/perl -w
use common::sense;
use Data::Dumper;
my %QENV = ( nohash => 'noh' );
my %ahash= ( hv1 => 'htext1', hv2 => 'htext2' );
$QENV{'myhash'} = \%ahash;
print "works: ". Dumper(\%QENV)."\n\n\n";
$ENV{'myhash'} = \%ahash;
print "fails: ". Dumper(\%ENV)."\n";
%ENV
是一个神奇的散列。它反映了进程的环境。从它读取从环境中读取,向它写入会改变环境。
如果你能保证引用的变量仍然存在(通过它仍然在范围内或者通过它增加它的 REFCNT
),你确实可以从地址创建对它的引用。
use strict;
use warnings;
use Data::Dumper;
use Inline C => <<'__EOS__';
SV* _newRV(IV iv) {
return newRV((SV*)iv);
}
__EOS__
my %hash = ( a => 1, b => 2 );
my $ref = \%hash;
my $ref_string = "$ref";
my $addr = hex( ( $ref_string =~ /\((.*)\)/ )[0] );
my $ref2 = _newRV($addr);
print(Dumper($ref2));
我不知道你为什么要这样做。它不允许另一个进程访问数据,因为一个进程无法访问另一个进程的内存。
您似乎想要共享数据。这是我经常放在那里的一个例子,它展示了如何将数据存储在 JSON 文件中,然后检索它。 JSON是跨语言的,所以数据可以被多种编程语言使用,而不仅仅是Perl。尽管此示例在单个脚本中,但可以想象它是两个不同的 Perl 应用程序:
use warnings;
use strict;
use JSON;
my $file = 'data.json';
my %h = (
foo => 'bar',
raz => {
ABC => 123,
XYZ => [4, 5, 6],
}
);
my $json = encode_json \%h;
# write the JSON to a file, and close it
open my $fh, '>', $file or die $!;
print $fh $json;
close $fh or die $!;
# open the JSON file, and read it
open my $json_file, '<', $file or die $!;
my $read_json;
{
local $/;
$read_json = <$json_file>;
}
my $perl_hash = decode_json $read_json;