Data::Dumper - 將 Perl 資料結構轉換為字串,適用於列印和 eval
use Data::Dumper;
# simple procedural interface
print Dumper($foo, $bar);
# extended usage with names
print Data::Dumper->Dump([$foo, $bar], [qw(foo *ary)]);
# configuration variables
{
local $Data::Dumper::Purity = 1;
eval Data::Dumper->Dump([$foo, $bar], [qw(foo *ary)]);
}
# OO usage
my $d = Data::Dumper->new([$foo, $bar], [qw(foo *ary)]);
...
print $d->Dump;
...
$d->Purity(1)->Terse(1)->Deepcopy(1);
eval $d->Dump;
給定一個標量或引用變數的清單,將其內容以 Perl 語法輸出。這些引用也可以是物件。每個變數的內容將在單個 Perl 陳述中輸出。正確處理自我參照結構。
返回值可以進行 eval
,以獲得原始參考結構的相同副本。 (請考慮從不受信任的來源 eval 代碼的安全性影響!)
任何與傳遞的參數之一相同的引用將被命名為 $VAR
n(其中 n 是數字後綴),其他對 $VAR
n 內子結構的重複引用將使用箭頭符號適當地標記。如果使用 Dump()
方法,則可以為要轉儲的個別值指定名稱,或者您可以將默認的 $VAR
前綴更改為其他內容。請參閱下面的 "設定變數或方法" 中的 $Data::Dumper::Varname
和 $Data::Dumper::Terse
。
自我參照結構的默認輸出可以進行 eval
,但對於 $VAR
n 的嵌套引用將是未定義的,因為不能使用一個 Perl 陳述構造遞歸結
在擴展的使用形式中,要轉儲的引用可以給定使用者指定的名稱。如果一個名稱以*
開頭,則輸出將描述提供的引用的解引用類型,用於哈希和數組以及代碼引用。如果設置了Terse
標誌,將盡可能避免輸出名稱。
在許多情況下,用於設置對象內部狀態的方法將返回對象本身,因此方法調用可以方便地連鎖在一起。
可以使用幾種不同的輸出風格,所有這些都由設置Indent
標誌來控制。詳細信息請參閱下面的“配置變量或方法”。
返回一個新創建的Data::Dumper
對象。第一個參數是要轉儲的匿名數組的值。可選的第二個參數是值的匿名數組的名稱。名稱不需要以$
符號開頭,必須由字母數字字符組成。您可以以*
開頭來指定必須轉儲解引用類型而不是引用本身,用於數組和哈希引用。
如果值的名稱未定義,則將使用$Data::Dumper::Varname
指定的前綴以數字後綴。
在轉儲值時,Data::Dumper將對所有遇到的引用進行目錄化。交叉引用(以perl語法中的子結構名稱的形式)將插入到所有可能的點上,保留原始值集中的任何結構相互依賴。結構遍歷是深度優先的,並按照從第一個提供的值到最後的順序進行。
返回对象中存储值的字符串形式(保留它们被提供给 new
的顺序),受下面配置选项的影响。在列表上下文中,它返回与提供的值对应的字符串列表。
为方便起见,第二种形式在立即转储对象之前简单地在其参数上调用 new
方法。
查询或添加到已经遇到的引用的内部表中。如果需要,您必须使用 Reset
明确清除表格。这样的引用不会被转储;相反,它们的名称将被插入到随后遇到它们的地方。这对于正确地转储子例程引用特别有用。
期望一个匿名散列的名称 => 值对。与 new
中的名称相同的规则适用。如果未提供参数,则将以列表上下文返回名称 => 值对的“已看到”列表。否则,返回对象本身。
查询或替换将要转储的值的内部数组。当不带参数调用时,将值作为列表返回。当用替换值数组的引用调用时,返回对象本身。当用其他类型的参数调用时,将会报错。
查询或替换将要转储的值的用户提供名称的内部数组。当不带参数调用时,返回名称。当用替换名称数组调用时,返回对象本身。如果替换名称的数量超过要命名的值的数量,则不会使用多余的名称。如果替换名称的数量少于要命名的值的数量,则替换名称列表将耗尽,剩余的值将不会重命名。当用其他类型的参数调用时,将会报错。
清除“已看到”引用的内部表并返回对象本身。
返回列表中值的字符串形式,受下面配置选项的影响。输出中的值将以 $VAR
n 的形式命名,其中 n 是数字后缀。在列表上下文中返回字符串列表。
在使用过程化接口时可以使用几个配置变量来控制生成的输出类型。通常,这些变量在一个块中被 local
化,以便代码的其他部分不受更改的影响。
这些变量确定通过调用 new
方法创建的对象的默认状态,但不能用于改变之后对象的状态。应使用等效的方法名称来查询或设置对象的内部状态。
当使用参数调用方法形式时,将返回对象本身,以便它们可以很好地链接在一起。
$Data::Dumper::Indent 或 $OBJ->Indent([NEWVAL])
控制縮排的風格。可以設置為 0、1、2 或 3。風格 0 會將輸出呈現為沒有任何換行、縮排或列表項目之間的空格的最緊湊格式,但仍然是有效的 Perl 代碼。風格 1 輸出可讀性較高的形式,但沒有花式縮排(結構中的每個層級僅通過一定數量的空格進行縮排)。風格 2(默認值)輸出非常可讀的形式,並將哈希鍵對齊。風格 3 與風格 2 類似,但也將陣列的元素與其索引進行標註(但評論位於自己的行上,因此陣列輸出佔用的行數是原來的兩倍)。風格 2 是默認值。
$Data::Dumper::Trailingcomma 或 $OBJ->Trailingcomma([NEWVAL])
控制是否在陣列或哈希的最後一個元素後添加逗號。即使為 true,當最後一個元素與關閉括號出現在同一行時,也不會在陣列或哈希的最後一個元素與關閉括號之間添加逗號。默認值為 false。
$Data::Dumper::Purity 或 $OBJ->Purity([NEWVAL])
控制輸出可以被 eval
重建所需的程度。將其設置為 1 將輸出額外的 Perl 語句,這些語句將正確地重建嵌套引用。默認值為 0。
$Data::Dumper::Pad 或 $OBJ->Pad([NEWVAL])
指定將添加到輸出的每一行的字符串。默認為空字符串。
$Data::Dumper::Varname 或 $OBJ->Varname([NEWVAL])
包含在輸出中標記變量名的前綴。默認值為 "VAR"。
$Data::Dumper::Useqq 或 $OBJ->Useqq([NEWVAL])
當設置時,允許使用雙引號表示字符串值。除空格外的空白將被表示為 [\n\t\r]
,"不安全" 字符將被反斜杠,並且無法打印的字符將以引號括起的八進制整數輸出。默認值為 0。
$Data::Dumper::Terse 或 $OBJ->Terse([NEWVAL])
當設置時,Data::Dumper 將作為原子/項目發出單個、非自我引用的值,而不是語句。這意味著在可能的情況下將避免使用 $VAR
n 名稱,但請注意,這樣的輸出可能並不總是可解析的 eval
。
$Data::Dumper::Freezer 或 $OBJ->Freezer([NEWVAL])
可以設置為方法名,或設置為空字符串以禁用該功能。Data::Dumper 將在嘗試將對象串行化之前通過對象調用該方法。該方法可以更改對象的內容(如果,例如,它包含從 C 中分配的數據),甚至可以在不同的包中重新 bless 它。客戶端負責確保指定的方法可以通過對象調用,並且在調用該方法後,對象最終只包含 Perl 數據類型。默認為空字符串。
如果對象不支持指定的方法(使用 UNIVERSAL::can() 確定),則該調用將被跳過。如果方法產生錯誤,則將生成警告。
$Data::Dumper::Toaster 或 $OBJ->Toaster([NEWVAL])
可以設定為方法名稱,或設為空字串以停用此功能。當使用語法 bless(DATA, CLASS)->METHOD()
對要轉儲的物件進行轉儲時,Data::Dumper 會發出一個方法呼叫。請注意,這意味著指定的方法將必須對物件進行任何所需的修改(例如在其中創建新的狀態,和/或在不同套件中重新 bless 它),然後返回它。客戶端負責確保可以通過物件呼叫該方法,並且它返回一個有效的物件。預設為空字串。
$Data::Dumper::Deepcopy 或 $OBJ->Deepcopy([NEWVAL])
可以設定為布林值以啟用結構的深度拷貝。當絕對必要時(例如,為了中斷參照循環),則只會進行交叉參照。默認值為 0。
$Data::Dumper::Quotekeys 或 $OBJ->Quotekeys([NEWVAL])
可以設定為布林值以控制是否引用哈希鍵。定義為 false 的值將在看起來像簡單字符串時避免引用哈希鍵。默認值為 1,它將始終將哈希鍵封裝在引號中。
$Data::Dumper::Bless 或 $OBJ->Bless([NEWVAL])
可以設定為一個字符串,該字符串指定用於創建物件的 bless
內置運算符的替代方法。應該存在一個具有指定名稱的函數,並且應該接受與內置函數相同的參數。默認為 bless
。
$Data::Dumper::Pair 或 $OBJ->Pair([NEWVAL])
可以設定為一個字符串,該字符串指定哈希鍵和值之間的分隔符。要將嵌套的哈希、數組和標量值轉儲為 JavaScript,請使用:$Data::Dumper::Pair = ' : ';
。在 JavaScript 中實現 bless
是讀者的練習。存在一個具有指定名稱的函數,並接受與內置函數相同的參數。
默認值為: =>
。
$Data::Dumper::Maxdepth 或 $OBJ->Maxdepth([NEWVAL])
可以設定為正整數,指定我們不深入結構的深度。當設置了 Data::Dumper::Purity
時,不起作用。 (在調試器中很有用,當我們通常不希望看到更多內容時)。默認為 0,表示沒有最大深度。
$Data::Dumper::Maxrecurse 或 $OBJ->Maxrecurse([NEWVAL])
可以設定為正整數,指定遞歸進入結構的深度,超過該深度將引發異常。這旨在作為一種安全措施,以防止 perl 在轉儲過深的結構時耗盡堆棧空間。可以將其設置為 0 以移除限制。默認為 1000。
$Data::Dumper::Useperl 或 $OBJ->Useperl([NEWVAL])
可以設定為布林值,控制是否使用純 Perl 實現的 Data::Dumper
。 Data::Dumper
模塊是一個雙重實現,幾乎所有功能都是用純 Perl 和 XS('C')兩種方式寫的。由於 XS 版本速度更快,如果可能,將始終使用它。此選項允許您覆蓋默認行為,通常僅用於測試目的。默認為 0,這意味著如果可能,將使用 XS 實現。
$Data::Dumper::Sortkeys 或 $OBJ->Sortkeys([NEWVAL])
可以設置為布林值,以控制是否對哈希鍵進行排序。設置為真值將導致所有哈希的鍵按照 Perl 的默認排序順序進行輸出。也可以設置為子例程引用,將在對每個哈希進行輸出時調用。在這種情況下,Data::Dumper
將為每個哈希調用一次該子例程,並將哈希的引用作為參數傳遞給它。該子例程的目的是返回一個哈希鍵的引用陣列,按照應該輸出的順序進行排列。使用此功能,您可以控制鍵的順序以及實際使用的鍵。換句話說,該子例程充當了一個過濾器,可以排除某些鍵不被輸出。默認值為 0,表示哈希鍵不進行排序。
$Data::Dumper::Deparse 或 $OBJ->Deparse([NEWVAL])
可以設置為布林值,以控制是否將代碼引用轉換為 Perl 源代碼。如果設置為真值,將使用B::Deparse
來獲取代碼引用的源代碼。在舊版本中,使用此選項在除代碼引用外的部分數據結構進行輸出時會帶來顯著的性能損耗,但現在不再如此。
注意:只有在您知道您的代碼引用將被B::Deparse
正確重建時,才使用此選項。
$Data::Dumper::Sparseseen 或 $OBJ->Sparseseen([NEWVAL])
默認情況下,Data::Dumper會構建序列化期間遇到的“seen”純量的散列。這非常昂貴。這個“seen”散列是必要的,以支持甚至只是檢測循環引用。通過Seen()
調用,用戶可以對其進行讀寫操作。
如果您作為用戶不需要對“seen”散列進行顯式訪問,那麼您可以設置Sparseseen
選項,以允許Data::Dumper省略為已知不擁有多於一個引用的純量構建“seen”散列。如果您使用XS實現,這將大大加快序列化速度。
注意:如果您啟用了Sparseseen
,則不要依賴“seen”散列的內容,因為其內容將是一個實現細節!
運行這些代碼片段以快速了解此模塊的行為。在完成這些示例後,您可能希望添加或更改上面描述的各種配置變量,以查看它們的行為。(請參見Data::Dumper發行版中的測試套件以獲取更多示例。)
use Data::Dumper;
package Foo;
sub new {bless {'a' => 1, 'b' => sub { return "foo" }}, $_[0]};
package Fuz; # a weird REF-REF-SCALAR object
sub new {bless \($_ = \ 'fu\'z'), $_[0]};
package main;
$foo = Foo->new;
$fuz = Fuz->new;
$boo = [ 1, [], "abcd", \*foo,
{1 => 'a', 023 => 'b', 0x45 => 'c'},
\\"p\q\'r", $foo, $fuz];
########
# simple usage
########
$bar = eval(Dumper($boo));
print($@) if $@;
print Dumper($boo), Dumper($bar); # pretty print (no array indices)
$Data::Dumper::Terse = 1; # don't output names where feasible
$Data::Dumper::Indent = 0; # turn off all pretty print
print Dumper($boo), "\n";
$Data::Dumper::Indent = 1; # mild pretty print
print Dumper($boo);
$Data::Dumper::Indent = 3; # pretty print with array indices
print Dumper($boo);
$Data::Dumper::Useqq = 1; # print strings in double quotes
print Dumper($boo);
$Data::Dumper::Pair = " : "; # specify hash key/value separator
print Dumper($boo);
########
# recursive structures
########
@c = ('c');
$c = \@c;
$b = {};
$a = [1, $b, $c];
$b->{a} = $a;
$b->{b} = $a->[1];
$b->{c} = $a->[2];
print Data::Dumper->Dump([$a,$b,$c], [qw(a b c)]);
$Data::Dumper::Purity = 1; # fill in the holes for eval
print Data::Dumper->Dump([$a, $b], [qw(*a b)]); # print as @a
print Data::Dumper->Dump([$b, $a], [qw(*b a)]); # print as %b
$Data::Dumper::Deepcopy = 1; # avoid cross-refs
print Data::Dumper->Dump([$b, $a], [qw(*b a)]);
$Data::Dumper::Purity = 0; # avoid cross-refs
print Data::Dumper->Dump([$b, $a], [qw(*b a)]);
########
# deep structures
########
$a = "pearl";
$b = [ $a ];
$c = { 'b' => $b };
$d = [ $c ];
$e = { 'd' => $d };
$f = { 'e' => $e };
print Data::Dumper->Dump([$f], [qw(f)]);
$Data::Dumper::Maxdepth = 3; # no deeper than 3 refs down
print Data::Dumper->Dump([$f], [qw(f)]);
########
# object-oriented usage
########
$d = Data::Dumper->new([$a,$b], [qw(a b)]);
$d->Seen({'*c' => $c}); # stash a ref without printing it
$d->Indent(3);
print $d->Dump;
$d->Reset->Purity(0); # empty the seen cache
print join "----\n", $d->Dump;
########
# persistence
########
package Foo;
sub new { bless { state => 'awake' }, shift }
sub Freeze {
my $s = shift;
print STDERR "preparing to sleep\n";
$s->{state} = 'asleep';
return bless $s, 'Foo::ZZZ';
}
package Foo::ZZZ;
sub Thaw {
my $s = shift;
print STDERR "waking up\n";
$s->{state} = 'awake';
return bless $s, 'Foo';
}
package main;
use Data::Dumper;
$a = Foo->new;
$b = Data::Dumper->new([$a], ['c']);
$b->Freezer('Freeze');
$b->Toaster('Thaw');
$c = $b->Dump;
print $c;
$d = eval $c;
print Data::Dumper->Dump([$d], ['d']);
########
# symbol substitution (useful for recreating CODE refs)
########
sub foo { print "foo speaking\n" }
*other = \&foo;
$bar = [ \&other ];
$d = Data::Dumper->new([\&other,$bar],['*other','bar']);
$d->Seen({ '*foo' => \&foo });
print $d->Dump;
########
# sorting and filtering hash keys
########
$Data::Dumper::Sortkeys = \&my_filter;
my $foo = { map { (ord, "$_$_$_") } 'I'..'Q' };
my $bar = { %$foo };
my $baz = { reverse %$foo };
print Dumper [ $foo, $bar, $baz ];
sub my_filter {
my ($hash) = @_;
# return an array ref containing the hash keys to dump
# in the order that you want them to be dumped
return [
# Sort the keys of %$foo in reverse numeric order
$hash eq $foo ? (sort {$b <=> $a} keys %$hash) :
# Only dump the odd number keys of %$bar
$hash eq $bar ? (grep {$_ % 2} keys %$hash) :
# Sort keys in default order for all other hashes
(sort keys %$hash)
];
}
由於Perl子例程調用語義的限制,您不能傳遞陣列或哈希。請在其前面加上\
以傳遞其引用。這將在某個時候得到補救,現在Perl具有子例程原型。目前,您需要使用擴展使用形式,並在名稱前加上*
以將其輸出為哈希或陣列。
Data::Dumper
透過 CODE 參考來欺騙。如果在處理的結構中遇到代碼參考(且您尚未設置 Deparse
標誌),則將插入一個包含字符串 '"DUMMY"' 的匿名子例程作為其位置,如果設置了 Purity
,則會打印警告。您可以 eval
結果,但請注意,所創建的匿名子例程只是一個佔位符。即使使用 Deparse
標誌,在某些情況下,將結果傳遞給 eval
後會產生行為不同的結果;請參閱 B::Deparse 的文檔。
SCALAR 物件具有最奇怪的 bless
解決方法。
不同的 Perl 執行將具有不同的哈希鍵排序。此更改是出於更大的安全性考慮,參見 perlsec 中的「Algorithmic Complexity Attacks」。這意味著如果數據包含哈希,不同的 Perl 執行將具有不同的 Data::Dumper 輸出。如果需要從不同的 Perl 執行獲得相同的 Data::Dumper 輸出,請使用環境變數 PERL_HASH_SEED,參見 perlrun 中的「PERL_HASH_SEED」。使用這個方法可以恢復舊的(特定於平台的)排序:更好的解決方法可能是使用 Data::Dumper 的 Sortkeys
過濾器。
Gurusamy Sarathy gsar@activestate.com
版權所有(c)1996-2019 Gurusamy Sarathy。保留所有權利。本程序是自由軟件;您可以按照 Perl 本身的相同條款重新發布或修改它。
版本 2.188
perl(1)