我無法理解如何retrieve()在 Perl (v5.30.0) 中反序列化哈希:
#!/usr/bin/perl
use warnings;
use strict;
use Storable;
package main;
my %origHash = (key1 => 'data1',
key2 => 'data2',
key3 => 'data3',
key4 => 'data4');
# Retrieve, modify, and retrieve again in %origHash:
printf "Retrieved: %s\n", $origHash{'key2'};
$origHash{'key2'} = 'data22'; # Modify value
$origHash{'key5'} = 'data5'; # Add new value
printf "Retrieved: %s %s\n", $origHash{'key2'}, $origHash{'key5'};
# Serialize origHash, store in file 'file':
store \%origHash, 'file';
# Deserialize the hash, now store data in ref 'hashref':
my %hashref = retrieve('file'); # Line 24
# Retrieve, modify, and retrieve again in 'hashref':
printf "Retrieved: %s\n", $hashref{'key2'}; # Line 27
$hashref{'key2'} = 'data222'; # Modify value
$hashref{'key6'} = 'data6'; # Add new value
printf "Retrieved: %s %s\n", $hashref{'key2'}, $hashref{'key6'};
輸出是:
me@ubuntu01$ ./SerHash.perl
Retrieved: data2
Retrieved: data22 data5
Reference found where even-sized list expected at ./SerHash.perl line 24.
Use of uninitialized value in printf at ./SerHash.perl line 27.
Retrieved:
Retrieved: data222 data6
me@ubuntu01$
所以腳本的前半部分是 Perl/Hash 101,演示了在哈希中創建、檢索和修改值的簡單語法。然后我成功序列化哈希并使用以下行存盤在檔案file中:store \%origHash, 'file';.
我不確定這是否有效......?這是我在執行file上述store命令后查看時看到的內容:
me@ubuntu01$ more file
pst0
12345678
data4
data1
data3
data5
data22
me@ubuntu01$
嗯。所以我的價值觀在那里,但關鍵在哪里?
回到測驗腳本:序列化哈希后,我嘗試從file以下行中反序列化哈希: my %hashref = retrieve('file'); ...盡管我不完全確定該語法。請注意,如果我嘗試使用此命令從反序列化哈希中檢索資料...
printf "Retrieved: %s\n", $hashref{'key2'}; # Line 27
...目標值似乎未初始化?這是該命令的輸出:
Use of uninitialized value in printf at ./SerHash.perl line 27.
Retrieved:
呃,所以這不是很好。我注意到我可以將新值添加到反序列化的散列中,但如果原始散列中的資料不可用,那就有點離題了。
此測驗代碼是使用本教程構建的,這讓我對retrieve()函式的理解有些模糊。根據檔案:
要檢索存盤到磁盤的資料,請使用帶有檔案名的檢索。存盤在該檔案中的物件會為您重新創建到記憶體中,并回傳對根物件的參考。如果讀取時發生 I/O 錯誤,則回傳 undef。
所以retrieve()回報a reference to the root object[.]?嗯......所以代碼不應該是:
# Deserialize the hash, now store data in ref 'hashref':
# (***NOTE*** that we define hashref with a '$', not '%' now!)
my $hashref = retrieve('file'); # Line 24
# Retrieve, modify, and retrieve again in 'hashref':
printf "Retrieved: %s\n", $hashref{'key2'}; # Line 27
$hashref{'key2'} = 'data222'; # Modify value # Line 28
$hashref{'key6'} = 'data6'; # Add new value # Line 29
printf "Retrieved: %s %s\n", $hashref{'key2'}, $hashref{'key6'}; # Line 30
現在輸出是:
me@ubuntu01$ ./SerHash.perl
Global symbol "%hashref" requires explicit package name (did you forget to declare "my %hashref"?) at ./SerHash.perl line 27.
Global symbol "%hashref" requires explicit package name (did you forget to declare "my %hashref"?) at ./SerHash.perl line 28.
Global symbol "%hashref" requires explicit package name (did you forget to declare "my %hashref"?) at ./SerHash.perl line 29.
Global symbol "%hashref" requires explicit package name (did you forget to declare "my %hashref"?) at ./SerHash.perl line 30.
Global symbol "%hashref" requires explicit package name (did you forget to declare "my %hashref"?) at ./SerHash.perl line 30.
me@ubuntu01$
呸!這看起來更糟。我不明白回傳的是什么,也不明白retrieve()如何在語法上處理它。任何人都可以幫忙嗎?
uj5u.com熱心網友回復:
由于retrieve回傳一個參考,因此您確實希望使用標量( $hashref),就像您的第二次嘗試一樣。問題是您正試圖$hashref用作哈希。您需要使用解參考語法$hashref->{key2}::
my $hashref = retrieve('file'); # Line 24
# Retrieve, modify, and retrieve again in 'hashref':
printf "Retrieved: %s\n", $hashref->{'key2'}; # Line 27
$hashref->{'key2'} = 'data222'; # Modify value
$hashref->{'key6'} = 'data6'; # Add new value
printf "Retrieved: %s %s\n", $hashref->{'key2'}, $hashref->{'key6'};
uj5u.com熱心網友回復:
我想說這會retrieve回傳您輸入的內容。并store獲得了哈希參考,因此retrieve將該參考回傳給您。
但是,Perl 有一個實驗性declared_refs功能,您可以將其分配給您正在參考的命名散列。前面\的就是my這樣做的。即使您從檢索中獲得參考,它也會以%hashref:
use v5.26;
use experimental qw(declared_refs);
\my %hashref = retrieve('file');
當我瀏覽 hashrefs 串列但不希望到處取消參考箭頭時,我發現這很方便:
foreach \my %h ( @array_of_hashrefs ) {
say "No arrow for $h{name}"
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/533313.html
