假设我有哈希哈希:
my %hash_of_hashes = (
FOO => {
BAR => "BAZ",
},
ALICE => {
BOB => "CHARLIE",
},
);
现在我想添加一些元数据:即哈希的名称:
%hash_of_hashes = (
FOO => {
BAR => "BAZ",
name => "hash_of_hashes",
},
ALICE => {
BOB => "CHARLIE",
name => "hash_of_hashes",
},
);
我看到了this question,我可以这样做:
use Data::Dumper::Simple;
my ($var) = split /=/, Dumper(%hash_of_hashes);
但我认为该调用应该封装在自己的sub
中(因为这是一个奇怪的操作)。但如果我将其放在sub
中,则$var
不包含'%hash_of_hashes'
:
sub get_hash_name{
my $h_ref = shift;
my ($name) = split /=/, Dumper($href);
return $name;
}
my $name = get_hash_name(\%hash_of_hashes); # $name contains $h_ref!
有没有办法将哈希的名称添加到哈希中? (我意识到it's stupid to use a variable name in a variable,但我递归地解析哈希并需要知道“父”哈希是什么)。
答案 0 :(得分:2)
Data::Dumper::Simple
通过应用源过滤器来工作。它使用Filter::Simple
在编译源代码之前对其进行修改,以便调用Dumper
来传递参数的名称以及值
我建议您错过中间人并直接使用Data::Dumper::Simple
Filter::Simple
的输出。
我会写一些示例代码,但是你没有充分说明你想做什么
这是一些示例代码。我假设你只是想要一个子程序,给定一个哈希,将该哈希的名称放在其中的二级哈希的元素中
模块AddName
包含源过滤器和导出的子例程add_name
。主程序中add_name(%xxx)
或add_name(\%xxx)
的所有调用都转换为add_name(\%xxx, 'xxx')
,因此子例程知道哈希的名称并可以轻松插入
谨防源过滤器:它们是一种非常粗略和准备好的方法,可以让你的代码按照自己的意愿行事,虽然我已经编写了一些可能出现空白的余地,但它并不是一门精确的科学,没有什么比这更简单了完全模拟perl解析器本身
package AddName;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT = qw/ add_name /;
use Filter::Simple sub {
s/ \b add_name \s* \( \s* \\? %(\w+) \s* \) /add_name(\\\%$1, '$1')/gx;
};
sub add_name {
my ($hash, $name) = @_;
$_->{name} = $name for values %$hash;
}
1;
use strict;
use warnings 'all';
use AddName;
use Data::Dump;
my %hash_of_hashes = (
FOO => {
BAR => "BAZ",
},
ALICE => {
BOB => "CHARLIE",
},
);
add_name(\%hash_of_hashes);
dd \%hash_of_hashes;
{
ALICE => { BOB => "CHARLIE", name => "hash_of_hashes" },
FOO => { BAR => "BAZ", name => "hash_of_hashes" },
}
答案 1 :(得分:1)
当您传递对子的引用时,它所获得的全部内容 - 引用。 (如果您要传递一个完整的哈希值,它将获得一个列表。)我们无法直接从子内部的封闭范围中读取一个名称。
然而,有些模块可以完成这项工作。例如,可以使用PadWalker
查看变量名称。请注意他们建议不要直接在生产代码中使用它" "。
有一个功能var_name
完全符合这一特定目的。
use warnings;
use strict;
use PadWalker qw(var_name);
sub get_var_name { return var_name(1, $_[0]) }
my %hash_of_hashes = ( FOO => { BAR => "BAZ" }, ALICE => { BOB => "CHARLIE", } );
my $hash_name = get_var_name(\%hash_of_hashes);
$hash_name
的字符串为%hash_of_hashes
。因为你不想使用sigil
sub get_var_name { return substr var_name(1, $_[0]), 1 };
var_name(1, $_[0])
返回其引用是第二个参数的变量的名称,只要该变量位于调用此函数的sub上方1
级别的范围内(因此调用者&#39} ; S)
这是模块通常提供的特殊情况 - 它在给定级别(相对于调用其函数的位置)读取范围内所有变量的名称和值。参见文档。