Perl輸出複雜數據結構:Data::Dumper,Data::Dump,Data::Printer

輸出複雜結構

Data::DumperData::DumpData::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::Printerp函數,它會直接輸出結果,無需額外的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,而不是一次性的語句塊結構。而後解除引用。

相關文章
相關標籤/搜索