我正在尝试了解高阶Perl的平面文件数据库。
在包装FlatDB,sub new,第141页,他有声明:
祝福{FH => $ fh,FIELDS => \ @field,FIELDNUM => \%fieldnum, FIELDSEP => $ FIELDSEP} => $类;
其中$ class == FlatDB。
没有符号的这些变量(FH,FIELDNUM等)是什么?如何打印其值,查找其类型或使用它们?
FlatDB似乎是哈希的某种哈希值,但我打印值的所有尝试都会导致错误,例如:
printhash(\%fieldnum,"at37:\\%fieldnum=");
# prints the hash properly, BUT
printhash(FlatDB{FIELDNUM),"at38:FlatDB{FIELDNUM}=");
printhash(FlatDB->FIELDNUM,"at39:FlatDB->FIELDNUM=");
# print the error:
# Can't locate object method "FIELDNUM" via package "FlatDB"
为什么它认为FIELDNUM是一种方法,当它被定义为哈希?
仅供参考:printhash子是:
sub printhash
{ my $href=shift; # a REFERENCE to a hash
my $msg=shift; # a text message
my %h = %{$href};
my $len = keys %h;;
print "\n$msg, length=$len";
foreach my $k ( keys %h )
{ print "\nkey: $k, value: $h{$k}"; }
print "\n";
}
答案 0 :(得分:9)
他们不是变数。
它们是受祝福的哈希引用中的键(即an object)。 “fat comma”(=>
运算符)允许左侧的裸字被解释为字符串,如果它以字母或下划线开头,并且只包含字母数字字符和下划线。 (这与对象无关,但是在初始化散列或散列引用时,或者当有人明确尝试指示关联时,您通常会看到此语法。)
回答你的问题:
为什么它认为FIELDNUM是一种方法,当它被定义为哈希?
因为您将其作为方法调用。语法接近dereference operator,但不完全相同。事实上,documentation甚至说出了这样的结果:
在对象上调用方法写为
$object->method
。方法调用(或箭头)运算符的左侧是 对象(或类名),右侧是方法名称。
my $pod = File->new( 'perlobj.pod', $data ); $pod->save();
取消引用引用时也使用
->
语法。它看起来 像同一个操作员,但这是两个不同的操作。
和
“
->
”是一个中缀解除引用运算符,就像在C和C ++中一样。 如果右侧是[...]
,{...}
或(...)
下标,那么左侧必须是硬的或象征性的 分别引用数组,散列或子例程。 (要么 从技术上讲,一个能够持有硬参考的位置, 如果它是用于赋值的数组或散列引用。)参见 perlreftut和perlref。否则,右侧是方法名称或简单标量变量 包含方法名称或子程序引用,以及 左侧必须是一个对象(一个有福的参考)或一个类 name(即包名)。请参阅perlobj。
但实际上,你可能想要的是一个类的实例,它看起来像这样:
my $obj = FlatDB->new;
然后您可以像这样访问对象成员:
$obj->{FH};
@{$obj->{FIELDS}};
%{$obj->{FIELDNUM}};
$obj->{FIELDSEP};
但你不应该因为封装。不幸的是,解释这个和其他OOP原则超出了这个答案的范围。