Perl输出复杂数据结构:Data::Dumper,Data::Dump,Data::Printer
輸出復雜結構
Data::Dumper、Data::Dump、Data::Printer都可以用來輸出復雜的數據結構。本文只介紹簡單的幾個輸出形式,以后再需要的地方再詳細介紹。
前兩者建議傳遞數據結構的引用給對應的函數、方法,當然直接傳遞非引用也不會錯(標量、數組、哈希或引用都允許)。第三個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);輸出結果:
$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。例如:
如果想要將默認的$VAR修改為自定義的變量名稱,可以使用Data::Dumper->Dump方法。
2.使用Data::Dumper的Dump方法,期待兩個數組引用,第二個數組引用用來定義現實的變量名,而不是默認的VAR
#!/usr/bin/perl use Data::Dumper;print Data::Dumper->Dump([\%Config,$ref_arr],[qw(myvar myarr)]);以下是輸出結果:
$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函數可以直接傳遞數據對象
- 如果傳遞的是引用,則必須是引用變量,而不能是反斜線開頭的引用
- p函數不能同時格式化輸出兩個對象
例如:
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" ]讓Dumper和eval結合
由于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,而不是一次性的語句塊結構。然后解除引用。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Perl输出复杂数据结构:Data::Dumper,Data::Dump,Data::Printer的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这份程序员的简历刷爆了九月的朋友圈
- 下一篇: 在抛弃 MVP-Clean 后,我自主设