输出复杂结构

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,而不是一次性的语句块结构。然后解除引用。

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. <c:forEach>循环列表,获取勾选的checkbox中某个<td>的值

    <table> <!--列表表头 开始 --> <tr> <th><input type="checkbox" name=&q ...

  2. 学习笔记day1-计算机介绍

    1.1 “计算机”基本介绍 一.为什么需要计算机 对于现在的我们来说,每天要处理的信息量是巨大的,所以如果还是人工的来对这些数据进行处理,那么效率是很低的.此时计算机的出现就可以帮助我么来提高处理数据 ...

  3. SpringCloud服务注册与发现

    1.介绍对于微服务的治理而言,其核心就是服务的注册和发现.在SpringCloud 中提供了多种服务注册与发现组件:Eureka,Consul,Zookeeper.官方推荐使用Eureka. 说明:E ...

  4. 深入浅出Git教程【转载】转载

    深入浅出Git教程(转载)   目录 一.版本控制概要 1.1.什么是版本控制 1.2.常用术语 1.3.常见的版本控制器 1.4.版本控制分类 1.4.1.本地版本控制 1.4.2.集中版本控制 1 ...

  5. CentOS 6下升级Python版本

    CentOS6.8默认的python版本是2.6,而现在好多python组件开始只支持2.7以上的版本,比如说我今天遇到的pip install pysqlite,升级python版本是一个痛苦但又常 ...

  6. 反编译看java for-each循环

    java 1.5发行版引入的for-each循环.(引自<Effective Java>中文版第二版 第46条) 如以下对数组列表的for-each循环示例: public class F ...

  7. TensorFlow学习笔记1

    1.daocloud 拉取 docker镜像 docker pull daocloud.io/daocloud/tensorflow:latest 镜像位置: /Users/{YourUserName ...

  8. flask-钩子函数&g对象

    常用钩子函数 在Flask中钩子函数是使用特定的装饰器装饰的函数.钩子函数可以在正常执行的代码中,插入一段自己想要执行的代码.那么这种函数就叫做钩子函数.(hook) before_first_req ...

  9. 解读IEEE 7417的软件体系架构描述的概念模型

    本文将解读标准IEEE Std 1471-2000(密集型软件的体系结构描述推荐实施规程)的概念模型图部分,从中一窥作为软件架构师的进行架构设计的思考角度与策略.如果我们把世界当做一场游戏,现在要玩的 ...

  10. Reids学习1 -- 初识Redis

    1. Reids和其他类型数据库对比 名称 类型 数据库存储选项 查询类型 附加功能 Redis 使用内存存储的非关系数据库 字符串,列表,集和,散列表,有序集合 每个类型有自己的专属命令,还有批量操 ...