输出复杂结构

Data::DumperData::DumpData::Printer都可以用来输出复杂的数据结构。本文只介绍简单的几个输出形式,以后再需要的地方再详细介绍。

前两者建议传递数据结构的引用给对应的函数、方法,当然直接传递非引用也不会错(标量、数组、哈希或引用都允许)。第三个Printer,则可以自动判断是否是引用。

例如,下面的数据结构,一个是复杂的hash,一个是相对简单的匿名数组引用,分别使用这3个模块来输出。

  1. %Config = (
  2. 'auto_commit' => '0',
  3. 'build_dir' => '/home/fairy/.cpan/build',
  4. 'bzip2' => '/bin/bzip2',
  5. 'urllist' => [
  6. 'http://cpan.metacpan.org/',
  7. \@my_urllist # 将数组my_urllist作为元素
  8. ],
  9. 'wget' => '/usr/bin/wget',
  10. );
  11. @my_urllist=('http://mirrors.aliyun.com/CPAN/',
  12. 'https://mirrors.tuna.tsinghua.edu.cn/CPAN/',
  13. 'https://mirrors.163.com/cpan/',
  14. \@more_urllist # 将数组more_urllist引用作为元素
  15. );
  16. @more_urllist=qw(http://mirrors.shu.edu.cn/CPAN/
  17. http://mirror.lzu.edu.cn/CPAN/
  18. );
  19. $ref_arr=[qw(longshuai wugui fairy xiaofang)];

1.使用Data::Dumper的Dumper函数,期待的是引用

  1. #!/usr/bin/perl
  2. use Data::Dumper;
  3. print Dumper(\%Config,$abc);

输出结果:

  1. $VAR1 = {
  2. 'wget' => '/usr/bin/wget',
  3. 'urllist' => [
  4. 'http://cpan.metacpan.org/',
  5. [
  6. 'http://mirrors.aliyun.com/CPAN/',
  7. 'https://mirrors.tuna.tsinghua.edu.cn/CPAN/',
  8. 'https://mirrors.163.com/cpan/',
  9. [
  10. 'http://mirrors.shu.edu.cn/CPAN/',
  11. 'http://mirror.lzu.edu.cn/CPAN/'
  12. ]
  13. ]
  14. ],
  15. 'bzip2' => '/bin/bzip2',
  16. 'auto_commit' => '0',
  17. 'build_dir' => '/home/fairy/.cpan/build'
  18. };
  19. $VAR2 = [
  20. 'longshuai',
  21. 'wugui',
  22. 'fairy',
  23. 'xiaofang'
  24. ];

注意,Dumper()将第一个引用赋值给$VAR1,第二个引用赋值给$VAR2。例如:

如果想要将默认的$VAR修改为自定义的变量名称,可以使用Data::Dumper->Dump方法。

2.使用Data::Dumper的Dump方法,期待两个数组引用,第二个数组引用用来定义现实的变量名,而不是默认的VAR

  1. #!/usr/bin/perl
  2. use Data::Dumper;
  3. print Data::Dumper->Dump([\%Config,$ref_arr],[qw(myvar myarr)]);

以下是输出结果:

  1. $myvar = {
  2. 'wget' => '/usr/bin/wget',
  3. 'auto_commit' => '0',
  4. 'bzip2' => '/bin/bzip2',
  5. 'build_dir' => '/home/fairy/.cpan/build',
  6. 'urllist' => [
  7. 'http://cpan.metacpan.org/',
  8. [
  9. 'http://mirrors.aliyun.com/CPAN/',
  10. 'https://mirrors.tuna.tsinghua.edu.cn/CPAN/',
  11. 'https://mirrors.163.com/cpan/',
  12. [
  13. 'http://mirrors.shu.edu.cn/CPAN/',
  14. 'http://mirror.lzu.edu.cn/CPAN/'
  15. ]
  16. ]
  17. ]
  18. };
  19. $myarr = [
  20. 'longshuai',
  21. 'wugui',
  22. 'fairy',
  23. 'xiaofang'
  24. ];

注意上面用了两个数组引用,第一个数组引用是待输出的复杂数据结构,第二个数组引用是定义前一个数组引用的变量名称。

例如,下面的Dump方法,myvar定义\%Config的输出变量名称,myarr定义\@name1的输出变量名称,\@name2没有对应的变量名称,所以使用默认的$VAR3来输出。

  1. print Data::Dumper->Dump([\%Config,\@name1,\@name2],[qw(myvar,myarr)]);

3.使用Data::Dump的dump方法,它输出时不会将输出结果赋值给标量变量,而是直接输出数据结构,有什么就输出什么

例如,输出数组引用:

  1. #!/usr/bin/perl
  2. use Data::Dump qw(dump);
  3. print dump($ref_arr);

输出结果:

  1. ["longshuai", "wugui", "fairy", "xiaofang"]

输出hash引用:print dump(\%Config);

  1. {
  2. auto_commit => 0,
  3. build_dir => "/home/fairy/.cpan/build",
  4. bzip2 => "/bin/bzip2",
  5. urllist => [
  6. "http://cpan.metacpan.org/",
  7. [
  8. "http://mirrors.aliyun.com/CPAN/",
  9. "https://mirrors.tuna.tsinghua.edu.cn/CPAN/",
  10. "https://mirrors.163.com/cpan/",
  11. [
  12. "http://mirrors.shu.edu.cn/CPAN/",
  13. "http://mirror.lzu.edu.cn/CPAN/",
  14. ],
  15. ],
  16. ],
  17. wget => "/usr/bin/wget",
  18. }

输出hash引用和匿名数组结果:print dump(\%Config,$ref_arr);

  1. (
  2. {
  3. auto_commit => 0,
  4. build_dir => "/home/fairy/.cpan/build",
  5. bzip2 => "/bin/bzip2",
  6. urllist => [
  7. "http://cpan.metacpan.org/",
  8. [
  9. "http://mirrors.aliyun.com/CPAN/",
  10. "https://mirrors.tuna.tsinghua.edu.cn/CPAN/",
  11. "https://mirrors.163.com/cpan/",
  12. [
  13. "http://mirrors.shu.edu.cn/CPAN/",
  14. "http://mirror.lzu.edu.cn/CPAN/",
  15. ],
  16. ],
  17. ],
  18. wget => "/usr/bin/wget",
  19. },
  20. ["longshuai", "wugui", "fairy", "xiaofang"],
  21. )

4.使用Data::Printerp函数,它会直接输出结果,无需额外的print或say

  • p函数可以直接传递数据对象
  • 如果传递的是引用,则必须是引用变量,而不能是反斜线开头的引用
  • p函数不能同时格式化输出两个对象

例如:

  1. p(%Config) # 正确
  2. p($ref_Config) # 正确
  3. p(\%Config) # 错误
  4. p($ref_arr,$ref_Config) # 错误

首先安装这个模块:

  1. shell> cpan -i Data::Printer

直接传递数据对象:

  1. use Data::Printer;
  2. p(%Config)

以下是输出:

  1. {
  2. auto_commit 0,
  3. build_dir "/home/fairy/.cpan/build",
  4. bzip2 "/bin/bzip2",
  5. urllist [
  6. [0] "http://cpan.metacpan.org/",
  7. [1] [
  8. [0] "http://mirrors.aliyun.com/CPAN/",
  9. [1] "https://mirrors.tuna.tsinghua.edu.cn/CPAN/",
  10. [2] "https://mirrors.163.com/cpan/",
  11. [3] [
  12. [0] "http://mirrors.shu.edu.cn/CPAN/",
  13. [1] "http://mirror.lzu.edu.cn/CPAN/"
  14. ]
  15. ]
  16. ],
  17. wget "/usr/bin/wget"
  18. }

传递引用变量:

  1. p($ref_arr);

以下是结果:

  1. \ [
  2. [0] "longshuai",
  3. [1] "wugui",
  4. [2] "fairy",
  5. [3] "xiaofang"
  6. ]

让Dumper和eval结合

由于Data::Dumper以及Data::Dump的输出中会包含变量,所以如果将dump出的结果持久化保存到文本后,可以在读取时使用eval将其直接构建成新的数据结构。

例如:

  1. print DATA Dumper(\%Config);

它将%Config的内容持久化到文件句柄DATA连接的文件中。当需要时,读取它并解除引用:

  1. open DATA, "<$datafile" or die "$!";
  2. {
  3. local $/;
  4. %new_Config = %{ eval <DATA> };
  5. }

上面的eval使得perl去编译读取到的DATA,因为DATA是由Dumper出去的数据,它们都是变量开头的,所以eval <DATA>编译读取的内容后先进行赋值,然后返回赋值完成的类似$VAR1变量,由于这个标量变量是在解除引用的结构中,所以将新构建一个hash对象。

但是上面的语句还有点问题,因为有时候持久化的文件可能会是空的,这时就会报错eval那里就会报错。为了健壮性,不得不加入更多的逻辑判断。

比如,下面先将DATA的内容当作字符串赋值给变量变量$dumped_hash,然后判断这个变量。

  1. open DATA, "<$datafile" or die "$!";
  2. my $dumped_hash;
  3. {
  4. local $/;
  5. $dumped_hash = <DATA>;
  6. }
  7. my %new_Config = %{ eval $dumped_hash } if $dumped_hash;

但是,以下是我见过最亮瞎狗眼的写法:

  1. %new_Config = %{ +eval { <DATA> } };

用eval进行错误捕获,如果DATA不为空,则返回赋值后的变量$VAR1,前面加一个+得到+$VAR1,这个加号显式提示perl这是一个匿名hash,而不是一次性的语句块结构。然后解除引用。

Perl输出复杂数据结构:Data::Dumper,Data::Dump,Data::Printer的更多相关文章

  1. centos 7安装mysql 执行./scripts/mysql_install_db --user=mysql 报错 FATAL ERROR: please install the following Perl modules before executing ./scripts/mysql_install_db: Data::Dumper

    [root@localhost mysql]# ./scripts/mysql_install_db  --user=mysql FATAL ERROR: please install the fol ...

  2. FATAL ERROR: please install the following Perl modules before executing ./mysql_install_db: Data::Dumper

    今天安装本地数据库,所遇到的错误 FATAL ERROR: please install the following Perl modules before executing ./mysql_ins ...

  3. Linux下安装mysql时报错:FATAL ERROR: please install the following Perl modules before executing ./scripts/mysql_install_db:Data::Dumper

    如题,安装mysql过程中,执行scripts/mysql_install_db --user=mysql命令时报错: FATAL ERROR: please install the followin ...

  4. Linux 安装MySql启动Can't locate Data/Dumper.pm in @INC

    通过RPM包CentOS7 安装MySQL的时候提示“Can't locate Data/Dumper.pm in @INC (@INC contains: /usr/local/lib64/perl ...

  5. Can't locate Data/Dumper.pm in perl5的处理

    Can't locate Data/Dumper.pm in perl5的处理 wget http://www.cpan.org/modules/by-module/Data/Data-Dumper- ...

  6. 安装mysql_cluster报错: Data::Dumper丢失

    步骤 安装包:mysql-cluster-gpl-7.3.5-linux-glibc2.5-x86_64.tar.gz 下载解压到/usr/local/mysql mkdir /usr/local/m ...

  7. 初始化mysql数据库提示缺少Data:dumper模块解决方法

    初始化默认数据库运行此命令:/usr/local/mysql/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ 出现错 ...

  8. 以Excel 作为Data Source,将data导入db

    将Excel作为数据源,将数据导入db,是SSIS的一个简单的应用,下图是示例Excel,数据列是code和name 第一部分,Excel中的数据类型是数值类型 1,使用SSDT创建一个package ...

  9. 17.1.1.6 Creating a Data Snapshot Using Raw Data Files 创建一个数据快照使用 Raw Data Files

    17.1.1.6 Creating a Data Snapshot Using Raw Data Files 创建一个数据快照使用 Raw Data Files 如果数据库是大的, 复制raw 数据文 ...

随机推荐

  1. 如何从本地远程访问虚拟机内的Mysql服务器?

    假设重装了操作系统,则本地的很多软件可能都需要重新安装,比如数据库.但是,假设我们把一些重要的软件安装在虚拟机当中,则在重装操作系统之前,数据库服务器可以和虚拟机一起进行备份.重装操作系统之后,原先的 ...

  2. 基于面向方面和UML的实时系统建模研究

    一.基本信息 标题:基于面向方面和UML的实时系统建模研究 时间:2010 出版源:计算机技术与发展 领域分类:面向方向:实时系统:横切关注点:统一建模语言: 二.研究背景 问题定义:实时系统建模研究 ...

  3. Cookie的几点忠告

    1.不要在COOKIE中保存明文的敏感信息 2.不要在COOKIE中保存永久的敏感信息,即每个COOKIE 都需要有时效性,过期则失效. 参考 XSS跨站攻击相关资料 http://www.cnblo ...

  4. poj3660 cow contest

    这题主要是传递闭包 题意: n头牛,m次测试,假设a牛赢过b牛,那么说明a牛的能力比b牛强,问你根据输入的m次测试结果,最多能确定多少条牛的排名 大题的思路: 对于 k 牛,比他强的有x头牛,比他弱的 ...

  5. java笔试之输出

    1. public class foo { private static void testMethod(){ System.out.println("testMethod"); ...

  6. 51nod OJ P1000 A+B

    P1000 A+B OJ:51Nod 链接:"http://www.51nod.com/Challenge/Problem.html#!#problemId=1000" 题目描述: ...

  7. Java 利用 UUID 生成唯一性 ID 示例代码

    用户ID首先生成,订单ID的生成可依赖用户ID. 下面代码前六位是日期,后八位是随机数,用于生成用户ID. public String getNewUserId() { String ipAddres ...

  8. Spark基础-scala学习(三、Trait)

    面向对象编程之Trait trait基础知识 将trait作为接口使用 在trait中定义具体方法 在trait中定义具体字段 在trait中定义抽象字段 trait高级知识 为实例对象混入trait ...

  9. 页面怎么引用外部css+js代码

    外部css样式:把css样式写到一个文件内,方便使用,减少冗余. 如果使用的是外部css样式,页面怎么引用: 使用 <link rel="stylesheet" type=& ...

  10. java 常见面试题总结(一)

    1.Redis应用场景 答:分布式会话,分布式锁,计数器,缓存,消息队列,排行榜,最新列表. 2.如何访问一个类的私有方法? 答:使用反射进行访问,代码如下: package cn.entity; p ...