Perl输出复杂数据结构:Data::Dumper,Data::Dump,Data::Printer
輸出復(fù)雜結(jié)構(gòu)
Data::Dumper、Data::Dump、Data::Printer都可以用來輸出復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。本文只介紹簡(jiǎn)單的幾個(gè)輸出形式,以后再需要的地方再詳細(xì)介紹。
前兩者建議傳遞數(shù)據(jù)結(jié)構(gòu)的引用給對(duì)應(yīng)的函數(shù)、方法,當(dāng)然直接傳遞非引用也不會(huì)錯(cuò)(標(biāo)量、數(shù)組、哈希或引用都允許)。第三個(gè)Printer,則可以自動(dòng)判斷是否是引用。
例如,下面的數(shù)據(jù)結(jié)構(gòu),一個(gè)是復(fù)雜的hash,一個(gè)是相對(duì)簡(jiǎn)單的匿名數(shù)組引用,分別使用這3個(gè)模塊來輸出。
%Config = ('auto_commit' => '0','build_dir' => '/home/fairy/.cpan/build','bzip2' => '/bin/bzip2','urllist' => ['http://cpan.metacpan.org/',\@my_urllist # 將數(shù)組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 # 將數(shù)組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函數(shù),期待的是引用
#!/usr/bin/perl use Data::Dumper;print Dumper(\%Config,$abc);輸出結(jié)果:
$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()將第一個(gè)引用賦值給$VAR1,第二個(gè)引用賦值給$VAR2。例如:
如果想要將默認(rèn)的$VAR修改為自定義的變量名稱,可以使用Data::Dumper->Dump方法。
2.使用Data::Dumper的Dump方法,期待兩個(gè)數(shù)組引用,第二個(gè)數(shù)組引用用來定義現(xiàn)實(shí)的變量名,而不是默認(rèn)的VAR
#!/usr/bin/perl use Data::Dumper;print Data::Dumper->Dump([\%Config,$ref_arr],[qw(myvar myarr)]);以下是輸出結(jié)果:
$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'];注意上面用了兩個(gè)數(shù)組引用,第一個(gè)數(shù)組引用是待輸出的復(fù)雜數(shù)據(jù)結(jié)構(gòu),第二個(gè)數(shù)組引用是定義前一個(gè)數(shù)組引用的變量名稱。
例如,下面的Dump方法,myvar定義\%Config的輸出變量名稱,myarr定義\@name1的輸出變量名稱,\@name2沒有對(duì)應(yīng)的變量名稱,所以使用默認(rèn)的$VAR3來輸出。
print Data::Dumper->Dump([\%Config,\@name1,\@name2],[qw(myvar,myarr)]);3.使用Data::Dump的dump方法,它輸出時(shí)不會(huì)將輸出結(jié)果賦值給標(biāo)量變量,而是直接輸出數(shù)據(jù)結(jié)構(gòu),有什么就輸出什么
例如,輸出數(shù)組引用:
#!/usr/bin/perl use Data::Dump qw(dump);print dump($ref_arr);輸出結(jié)果:
["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引用和匿名數(shù)組結(jié)果: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函數(shù),它會(huì)直接輸出結(jié)果,無需額外的print或say
- p函數(shù)可以直接傳遞數(shù)據(jù)對(duì)象
- 如果傳遞的是引用,則必須是引用變量,而不能是反斜線開頭的引用
- p函數(shù)不能同時(shí)格式化輸出兩個(gè)對(duì)象
例如:
p(%Config) # 正確 p($ref_Config) # 正確 p(\%Config) # 錯(cuò)誤 p($ref_arr,$ref_Config) # 錯(cuò)誤首先安裝這個(gè)模塊:
shell> cpan -i Data::Printer直接傳遞數(shù)據(jù)對(duì)象:
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);以下是結(jié)果:
\ [[0] "longshuai",[1] "wugui",[2] "fairy",[3] "xiaofang" ]讓Dumper和eval結(jié)合
由于Data::Dumper以及Data::Dump的輸出中會(huì)包含變量,所以如果將dump出的結(jié)果持久化保存到文本后,可以在讀取時(shí)使用eval將其直接構(gòu)建成新的數(shù)據(jù)結(jié)構(gòu)。
例如:
print DATA Dumper(\%Config);它將%Config的內(nèi)容持久化到文件句柄DATA連接的文件中。當(dāng)需要時(shí),讀取它并解除引用:
open DATA, "<$datafile" or die "$!"; {local $/;%new_Config = %{ eval <DATA> }; }上面的eval使得perl去編譯讀取到的DATA,因?yàn)镈ATA是由Dumper出去的數(shù)據(jù),它們都是變量開頭的,所以eval <DATA>編譯讀取的內(nèi)容后先進(jìn)行賦值,然后返回賦值完成的類似$VAR1變量,由于這個(gè)標(biāo)量變量是在解除引用的結(jié)構(gòu)中,所以將新構(gòu)建一個(gè)hash對(duì)象。
但是上面的語句還有點(diǎn)問題,因?yàn)橛袝r(shí)候持久化的文件可能會(huì)是空的,這時(shí)就會(huì)報(bào)錯(cuò)eval那里就會(huì)報(bào)錯(cuò)。為了健壯性,不得不加入更多的邏輯判斷。
比如,下面先將DATA的內(nèi)容當(dāng)作字符串賦值給變量變量$dumped_hash,然后判斷這個(gè)變量。
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進(jìn)行錯(cuò)誤捕獲,如果DATA不為空,則返回賦值后的變量$VAR1,前面加一個(gè)+得到+$VAR1,這個(gè)加號(hào)顯式提示perl這是一個(gè)匿名hash,而不是一次性的語句塊結(jié)構(gòu)。然后解除引用。
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Perl输出复杂数据结构:Data::Dumper,Data::Dump,Data::Printer的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这份程序员的简历刷爆了九月的朋友圈
- 下一篇: 在抛弃 MVP-Clean 后,我自主设