Data::Dumper
、Data::Dump
、Data::Printer
均可以用來輸出複雜的數據結構。本文只介紹簡單的幾個輸出形式,之後再須要的地方再詳細介紹。shell
前二者建議傳遞數據結構的引用給對應的函數、方法,固然直接傳遞非引用也不會錯(標量、數組、哈希或引用都容許)。第三個Printer,則能夠自動判斷是不是引用。數組
例如,下面的數據結構,一個是複雜的hash,一個是相對簡單的匿名數組引用,分別使用這3個模塊來輸出。數據結構
%Config = ( 'auto_commit' => '0', 'build_dir' => '/home/fairy/.cpan/build', 'bzip2' => '/bin/bzip2', 'urllist' => [ 'http://cpan.metacpan.org/', \@my_urllist # 將數組my_urllist做爲元素 ], 'wget' => '/usr/bin/wget', ); @my_urllist=('http://mirrors.aliyun.com/CPAN/', 'https://mirrors.tuna.tsinghua.edu.cn/CPAN/', 'https://mirrors.163.com/cpan/', \@more_urllist # 將數組more_urllist引用做爲元素 ); @more_urllist=qw(http://mirrors.shu.edu.cn/CPAN/ http://mirror.lzu.edu.cn/CPAN/ ); $ref_arr=[qw(longshuai wugui fairy xiaofang)];
1.使用Data::Dumper
的Dumper函數,期待的是引用函數
#!/usr/bin/perl use Data::Dumper; print Dumper(\%Config,$abc);
輸出結果:ui
$VAR1 = { 'wget' => '/usr/bin/wget', 'urllist' => [ 'http://cpan.metacpan.org/', [ 'http://mirrors.aliyun.com/CPAN/', 'https://mirrors.tuna.tsinghua.edu.cn/CPAN/', 'https://mirrors.163.com/cpan/', [ 'http://mirrors.shu.edu.cn/CPAN/', 'http://mirror.lzu.edu.cn/CPAN/' ] ] ], 'bzip2' => '/bin/bzip2', 'auto_commit' => '0', 'build_dir' => '/home/fairy/.cpan/build' }; $VAR2 = [ 'longshuai', 'wugui', 'fairy', 'xiaofang' ];
注意,Dumper()將第一個引用賦值給$VAR1
,第二個引用賦值給$VAR2
。例如:url
若是想要將默認的$VAR
修改成自定義的變量名稱,可使用Data::Dumper->Dump
方法。code
2.使用Data::Dumper
的Dump方法,期待兩個數組引用,第二個數組引用用來定義現實的變量名,而不是默認的VAR對象
#!/usr/bin/perl use Data::Dumper; print Data::Dumper->Dump([\%Config,$ref_arr],[qw(myvar myarr)]);
如下是輸出結果:ip
$myvar = { 'wget' => '/usr/bin/wget', 'auto_commit' => '0', 'bzip2' => '/bin/bzip2', 'build_dir' => '/home/fairy/.cpan/build', 'urllist' => [ 'http://cpan.metacpan.org/', [ 'http://mirrors.aliyun.com/CPAN/', 'https://mirrors.tuna.tsinghua.edu.cn/CPAN/', 'https://mirrors.163.com/cpan/', [ 'http://mirrors.shu.edu.cn/CPAN/', 'http://mirror.lzu.edu.cn/CPAN/' ] ] ] }; $myarr = [ 'longshuai', 'wugui', 'fairy', 'xiaofang' ];
注意上面用了兩個數組引用,第一個數組引用是待輸出的複雜數據結構,第二個數組引用是定義前一個數組引用的變量名稱。字符串
例如,下面的Dump方法,myvar定義\%Config
的輸出變量名稱,myarr定義\@name1
的輸出變量名稱,\@name2
沒有對應的變量名稱,因此使用默認的$VAR3
來輸出。
print Data::Dumper->Dump([\%Config,\@name1,\@name2],[qw(myvar,myarr)]);
3.使用Data::Dump
的dump方法,它輸出時不會將輸出結果賦值給標量變量,而是直接輸出數據結構,有什麼就輸出什麼
例如,輸出數組引用:
#!/usr/bin/perl use Data::Dump qw(dump); print dump($ref_arr);
輸出結果:
["longshuai", "wugui", "fairy", "xiaofang"]
輸出hash引用:print dump(\%Config);
{ auto_commit => 0, build_dir => "/home/fairy/.cpan/build", bzip2 => "/bin/bzip2", urllist => [ "http://cpan.metacpan.org/", [ "http://mirrors.aliyun.com/CPAN/", "https://mirrors.tuna.tsinghua.edu.cn/CPAN/", "https://mirrors.163.com/cpan/", [ "http://mirrors.shu.edu.cn/CPAN/", "http://mirror.lzu.edu.cn/CPAN/", ], ], ], wget => "/usr/bin/wget", }
輸出hash引用和匿名數組結果:print dump(\%Config,$ref_arr);
( { auto_commit => 0, build_dir => "/home/fairy/.cpan/build", bzip2 => "/bin/bzip2", urllist => [ "http://cpan.metacpan.org/", [ "http://mirrors.aliyun.com/CPAN/", "https://mirrors.tuna.tsinghua.edu.cn/CPAN/", "https://mirrors.163.com/cpan/", [ "http://mirrors.shu.edu.cn/CPAN/", "http://mirror.lzu.edu.cn/CPAN/", ], ], ], wget => "/usr/bin/wget", }, ["longshuai", "wugui", "fairy", "xiaofang"], )
4.使用Data::Printer
的p
函數,它會直接輸出結果,無需額外的print或say
例如:
p(%Config) # 正確 p($ref_Config) # 正確 p(\%Config) # 錯誤 p($ref_arr,$ref_Config) # 錯誤
首先安裝這個模塊:
shell> cpan -i Data::Printer
直接傳遞數據對象:
use Data::Printer; p(%Config)
如下是輸出:
{ auto_commit 0, build_dir "/home/fairy/.cpan/build", bzip2 "/bin/bzip2", urllist [ [0] "http://cpan.metacpan.org/", [1] [ [0] "http://mirrors.aliyun.com/CPAN/", [1] "https://mirrors.tuna.tsinghua.edu.cn/CPAN/", [2] "https://mirrors.163.com/cpan/", [3] [ [0] "http://mirrors.shu.edu.cn/CPAN/", [1] "http://mirror.lzu.edu.cn/CPAN/" ] ] ], wget "/usr/bin/wget" }
傳遞引用變量:
p($ref_arr);
如下是結果:
\ [ [0] "longshuai", [1] "wugui", [2] "fairy", [3] "xiaofang" ]
因爲Data::Dumper
以及Data::Dump
的輸出中會包含變量,因此若是將dump出的結果持久化保存到文本後,能夠在讀取時使用eval將其直接構建成新的數據結構。
例如:
print DATA Dumper(\%Config);
它將%Config
的內容持久化到文件句柄DATA鏈接的文件中。當須要時,讀取它並解除引用:
open DATA, "<$datafile" or die "$!"; { local $/; %new_Config = %{ eval <DATA> }; }
上面的eval使得perl去編譯讀取到的DATA,由於DATA是由Dumper出去的數據,它們都是變量開頭的,因此eval <DATA>
編譯讀取的內容後先進行賦值,而後返回賦值完成的相似$VAR1
變量,因爲這個標量變量是在解除引用的結構中,因此將新構建一個hash對象。
可是上面的語句還有點問題,由於有時候持久化的文件可能會是空的,這時就會報錯eval那裏就會報錯。爲了健壯性,不得不加入更多的邏輯判斷。
好比,下面先將DATA的內容看成字符串賦值給變量變量$dumped_hash
,而後判斷這個變量。
open DATA, "<$datafile" or die "$!"; my $dumped_hash; { local $/; $dumped_hash = <DATA>; } my %new_Config = %{ eval $dumped_hash } if $dumped_hash;
可是,如下是我見過最亮瞎狗眼的寫法:
%new_Config = %{ +eval { <DATA> } };
用eval進行錯誤捕獲,若是DATA不爲空,則返回賦值後的變量$VAR1
,前面加一個+
獲得+$VAR1
,這個加號顯式提示perl這是一個匿名hash,而不是一次性的語句塊結構。而後解除引用。