0

0

Perl6 的 YAML::Dumper 模块使用详解

php中文网

php中文网

发布时间:2016-06-02 09:14:05

|

1754人浏览过

|

来源于php中文网

原创

这两天决定试一把 perl6,因为扶凯兄已经把还没有正式发行 rakudo star 包的 moarvm 编译打包好了,所以可以跳过这步直接进入模块安装。当然,源码编译本身也没有太大难度,只不过从 github 下源码本身耗时间比较久而已。

既然木有 Star 包,那么安装好 MoarVM 上的 Rakudo 后我们就有必要先自己把 panda 之类的工具编译出来。这一步需要注意一下你的 @*INC 路径和实际的 $PERL6LIB 路径,已经编译之后的 panda 存在的 $PATH 是不是都正确,如果不对的修改一下 ~/.bashrc 就好了。

我的尝试迁移对象是一个很简单的 Puppet 的 ENC 脚本,只涉及 SQLite 的读取,以及 YAML 格式的输出。通过 panda install DBIish 命令即可安装好 DBIish 模块。

脚本本身修改起来难度不大,结果如下:

#!/usr/bin/env perl6 
use v6; 
use DBIish; 
use YAML; 
my $base_dir = "/etc/puppet/webui"; 
# 函数在 Perl6 中依然使用 sub 关键字定义,不过有个超酷的特性是 multi sub 
# 脚本中没有用到,但是在 YAML::Dumper 中遍地都是,这里也提一句。 
# MAIN 函数在 Perl6 里可以直接用 :$opt 命令参数起 getopt 的作用 
# 不过 ENC 脚本就是直接传一个主机名,用不上这个超酷的特性 
sub MAIN($node) { 
# connect 方法接收参数选项是 |%opts,所以可以把哈希直接平铺写 
# 这个 | 的用法一个月前在《Using Perl6》里看到过 
	my $dbh = DBIish.connect( 'SQLite', database => "{$base_dir}/node_info.db" ); 
	my $sth = $dbh.prepare("select * from node_info where node_fqdn = ?"); 
	$sth.execute("$node"); 
	my $ret = $sth.fetchrow_hashref; 
	my $res; 
	if ( !$ret ) { 
		$res = { 
# Perl5 的 qw() 在 Perl6 里直接写成 <> 。也不用再通过 [] 来指明是引用 
			classes     => <puppetd repos>, 
			environment => 'testing', 
		}; 
	} 
	else { 
		$res = { 
			environment => $ret{'environment'}, 
			parameters  => { role => $ret{'role'} }, 
			classes     => {}, 
		}; 
# 这个 for 的用法,在 Perl5 的 Text::Xslate 模板里就用过 
		for split(',', $ret{'classes'}) -> $class { 
			if ( $class eq 'nginx' ) { 
# 这个 <== 符号指明数据流方向,完全可以把数组倒过来,然后用 ==> 写这行 
# 如果不习惯这种流向操作符的,可以用,号,反正不能跟 Perl5 那样啥都不写 
# 这里比较怪的一点是我试图把这么长的一句分成多行写,包括每行后面加,我看到 YAML 代码里就用分行了,但是我这就会报错 
# Perl6 的正则变化较大,这里 /^#/ 要写成 /^'#'/ 或者 /^x23/ 
# 正则 // 前面不加 m// 不会立刻开始匹配 
# 原先的 s///g 可以写作 s:g///,也可以写作对象式的 .subst(m//, '', :g),. 前面为空就是默认的 $_ 
# 捕获的数据存在 @() 数组里,也可以用 $/[i] 的形式获取 
# 字符串内插时,不再写作 ${*},而是 {$*} 的形式 
# 命名捕获这里没用上,写个示例: 
#     $str ~~ /^(w+?)$<laststr>=(w ** 4)w$/; 
#     $/<laststr>.chomp.say; 
# 注意里面的 w{4} 变成了 w ** 4 
				my @needs <== map { .subst(m/^(.+):(d+)$/, "{$/[0]} max_fails=30 weight={$/[1]}", :g) } <== grep { !m/^x23/ } <== split(',', $ret{'extstr'}); 
				$res{'classes'}{'nginx'}{'iplist'} = @needs; 
			} 
			else { 
# Perl5 的 undef 不再使用,可以使用 Nil 或者 Any 对象 
				$res{'classes'}{$class} = Nil; 
			} 
		} 
	}; 
	$dbh.disconnect(); 
# 这个 dump 就是 YAML 模块导出的函数 
# Perl6 的模块要导出函数不再需要 Exporter 那样,直接用 our sub dump($obj) {} 就可以了 
	say dump($res); 
};

但是麻烦的是 YAML 模块本身,这个模块是 ingydotnet 在好几年前草就,后来就没管了,实际现在压根跑不起来,花了半天时间,一边学习一边修改,总算修改正常了,主要涉及了 Attribute 对象,Nil 对象,twigls 前缀符,:exists 定义几个概念,以及 YAML 格式本身的处理逻辑.

YAML模块修改对比如下:

diff --git a/lib/YAML/Dumper.pm b/lib/YAML/Dumper.pm 
index d7a7981..ec47341 100644 
--- a/lib/YAML/Dumper.pm 
+++ b/lib/YAML/Dumper.pm 
@@ -2,16 +2,16 @@ use v6; 
 class YAML::Dumper; 
 has $.out = []; 
-has $.seen is rw = {}; 
+has $.seen = {}; 
 has $.tags = {}; 
 has $.anchors = {}; 
 has $.level is rw = 0; 
-has $.id is rw = 1; 
+has $.id = 1; 
 has $.info = []; 
 method dump($object) { 
	 $.prewalk($object); 
-    $.seen = {}; 
+    $!seen = {}; 
	 $.dump_document($object); 
	 return $.out.join(''); 
 } 
@@ -45,11 +45,11 @@ method dump_collection($node, $kind, $function) { 
 method check_special($node) { 
	 my $first = 1; 
-    if $.anchors.exists($node.WHICH) { 
-    if $.anchors.exists($node.WHICH) { 
+    if $.anchors{$node.WHICH}:exists { 
		 push $.out, ' ', '&' ~ $.anchors{$node.WHICH}; 
		 $first = 0; 
	 } 
-    if $.tags.exists($node.WHICH) { 
+    if $.tags{$node.WHICH}:exists { 
		 push $.out, ' ', '!' ~ $.tags{$node.WHICH}; 
		 $first = 0; 
	 } 
@@ -64,7 +64,7 @@ method indent($first) { 
			 return; 
		 } 
		 if $.info[*-1]<kind> eq 'seq' && $.info[*-2]<kind> eq 'map' { 
-            $seq_in_map = 1; 
+            $seq_in_map = 0; 
		 } 
	 } 
	 push $.out, "n"; 
@@ -155,7 +155,8 @@ method dump_object($node, $type) { 
	 $.tags{$repr.WHICH} = $type; 
	 for $node.^attributes -> $a { 
		 my $name = $a.name.substr(2); 
-        my $value = pir::getattribute__PPs($node, $a.name);     #RAKUDO 
+        #my $value = pir::getattribute__PPs($node, $a.name);     #RAKUDO 
+        my $value = $a.get_value($node);                         #for non-parrot 
		 $repr{$name} = $value; 
	 } 
	 $.dump_node($repr);

这里的 $.seen 和 $!seen 是不是晕掉了?其实 $.seen 就相当于先声明了 $!seen 后再自动创建一个 method seen() { return $!seen }。

另一处是 pir::getattribute__PPs() 函数,pir 是 parrot 上的语言,而 MoarVM 和 JVM 上都是先实现了一个 nqp 再用 nqp 写 Perl6,不巧的是这个 pir 里的 getattribute__PPs() 刚好至今还没有对应的 nqp 方法。(在 pir2nqp.todo 文件里可见)

所以只能用高级的 Perl6 语言来做了。

《PHP程序设计》第二版
《PHP程序设计》第二版

本书图文并茂,详细讲解了使用LAMP(PHP)脚本语言开发动态Web程序的方法,如架设WAMP平台,安装与配置开源Moodle平台,PHP程序设计技术,开发用户注册与验证模块,架设LAMP平台。 本书适合计算机及其相关专业本、专科学生作为学习LAMP(PHP)程序设计或动态Web编程的教材使用,也适合对动态Web编程感兴趣的读者自觉使用,对LAMP(PHP)程序设计人员也具有一定的参考价值。

下载

总的来说,这个 yaml-pm6 代码里很多地方都是试来试去,同样的效果不同的写法,又比如 .WHICH 和 .WHAT.perl 也是混用。 而且我随手测试了一下,即使在 parrot 上,用 pir::getattribute__PPs 的速度也比 Attribute.get_value 还差点点。

最后提一句,目前 ENC 脚本在 perl5、perl6-m、perl6-p、perl6-j 上的运行时间大概分别是 0.13、1.5、2.8、12s。MoarVM 还差 Perl5 十倍,领先 parrot 一倍。不过 JVM 本身启动时间很长,这里不好因为一个短时间脚本说它太慢。

另外还试了一下如果把我修改过的 YAML::Dumper 类直接写在脚本里运行,也就是不编译成 moarvm 模块,时间大概是 2.5s,比 parrot 模块还快点点。

不过如何把 perl6 脚本本身编译成 moarvm 的 bytecode 格式运行还没有研究出来,直接 perl6-m --target=mbc --output=name.moarvm name.pl6 得到的文件运行 moar name.moarvm 的结果运行会内存报错。

本文地址:

转载随意,但请附上文章地址:-)

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

616

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

194

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

91

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

54

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

598

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

56

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.4万人学习

【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2.1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号