免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5564 | 回复: 10
打印 上一主题 下一主题

Using Perl6 第一二十章(更新第十章内置操作符,类型) [复制链接]

论坛徽章:
1
处女座
日期:2014-03-28 10:11:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-03-23 20:39 |只看该作者 |倒序浏览
本帖最后由 rongchaogao 于 2014-05-12 19:04 编辑

                            2: The Basics
                            =============

Author: GRC(扬眉剑)
Date: 2014-05-12 19:01:38 中国标准时间


Table of Contents
=================
1 github地址
2 第二章:基础


1 github地址
=============
[https://github.com/gaorongchao/Perl6/tree/master/Using_perl6]

所有后续更新都在github上进行,其他地方不做同步。
发现任何错误,或者不当的地方,请先到github查看是否改正。
如果没有请留言。或者邮件交流:rongchaogao@gmail.com

2 第二章:基础
===============
Perl起源于一个致力于从文本文件中收集整理信息的编程语言。
现在Perl在文本处理方面仍然强大,Perl 5 是一个一般意义上的强力编程语言。
但是Perl 6更为杰出。

假设你举办了一个乒乓球联赛。
裁判告诉你比赛结果的格式:选手1 选手2 | 3:2,这意味着,选手1赢了3局,选手2赢了2局。
你需要一个脚本来,来统计选手赢了几场比赛,赢了多少局,并以此决定最终冠军的归属。

输入文件格式如下(储存在一个名为“scores”的文件中):


  Beth Ana Charlie Dave
  Ana Dave            |  3:0
  Charlie Beth        |  3:1
  Ana Beth            |  2:3
  Dave Charlie        |  3:0
  Ana Charlie         |  3:1
  Beth Dave           |  0:3


第一行是所有选手的名字,后面跟着的是每场比赛的结果。
这里有一个解决此问题的Perl 6 脚本:perl-1-1:


   1:  use v6;
   2:  
   3:   my $file = open 'scores';
   4:   my @names = $file.get.words;
   5:  
   6:   my %matches;
   7:   my %sets;
   8:  
   9:   for $file.lines -> $line {
  10:   my ($pairing, $result) = $line.split(' | ');
  11:   my ($p1, $p2) = $pairing.words;
  12:   my ($r1, $r2) = $result.split(':');
  13:  
  14:   %sets{$p1} += $r1;
  15:   %sets{$p2} += $r2;
  16:  
  17:   if $r1 > $r2 {
  18:   %matches{$p1}++;
  19:   } else {
  20:   %matches{$p2}++;
  21:   }
  22:   }
  23:  
  24:   my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse;
  25:  
  26:   for @sorted -> $n {
  27:   say "$n has won %matches{$n} matches and %sets{$n} sets";
  28:   }

输出文件:


  Ana has won 2 matches and 8 sets
  Dave has won 2 matches and 6 sets
  Charlie has won 1 matches and 4 sets
  Beth has won 1 matches and 4 sets

每一个Perl6程序都需要以 “use v6”; 开始。这一行告诉编译器Perl代码的版本。
如果,你不小心用Perl5来运行这个程序,你将得到错误信息。

一个Perl6程序包含0行或者更多的语句。每一个语句以分号结尾,或者以大括号结尾:


  1:  my $file = open 'scores';

"my"声明一个词法变量。词法变量只在当前代码块可用,从声明开始到代码块的结束。
如果一个代码块始终没有闭合,那么该变量可以在剩下的所有地方使用。代码块的定义是:
一段在花括号\{\}之间的代码。

一个变量名称以“魔符”开始,魔符是指那些非字母,非数字的符号,比如:$,@,% 或者&-
或者有时出现的双冒号“::”也是。
魔符指明了变量的结构类型,比如:它应该被当作一个值,还是多个值,还是一个子程序,等等。
跟在“魔符”后面的是“标识符”,标识符可以包含字母,数字和下划线。在字母与字母之间,
你可以用短横线“-”或者撇号“'”。所以“isn't”和“double-click”都是合法的变量标识符。

魔符“$”表明变量是一个数值变量,指明这个变量只存储了一个值。

内建函数“open”打开了一个名为“scores”的文件,然后返回一个文件句柄,
文件句柄是一个代表该文件的对象。
赋值符号“=”,把文件句柄赋值给左边的变量,这也就是意味着变量$file现在存储着文件句柄。

“scores”是字符串文本(string literal)。字符串(string)是一段纯文本。
字符串文本(string literal)是直接出现在程序中的字符串。
在这一行中,它是提供给open函数的参数。



  1:  my @names = $file.get.words;

上面语句的右侧调用了一种“方法”(一个命名的一系列行为的集合体)获取存储在$file变量中的句柄。
被命名为get的这一方法从文件中读取并返回一行,去掉末尾的换行符。word同样是一个方法,调用从
get中返回的一行文本。word这一方法,分解它的invocant(它要操作的字符串)成一系列的单词。
这里单词的意思是不包含空格的字符串。它把字符串“Beth Ana Charlie Dave”分解成多个字符串
“Beth”,“Ana”,“Charlie”,“Dave”。

最后,这一字符串列表存储到数组@names中。魔符@表明所声明的变量是一个数组。数组存储的是有序列表。



  1:  my %matches;
  2:  my %sets;

这两行代码声明了两个哈希。魔符“%”把变量标记为哈希。哈希又称为散列:是无序的键-值对的集合。
在其他语言中又称为“哈希表”,“字典”或者“(map)图”
你可以通过“键 $key”利用“%hash{$key}”来查询在哈希表中的值。

在上述计分程序中,%matches记录了每一位运动员赢的次数。%sets记录了每一位运动员赢的局数。

魔符指出了默认访问变量的方法。数组变量@是通过位置来访问,
哈希变量%是通过“键”来访问。
数值变量$表示一个大箩筐,这里可以盛任何东西,也可以用任何方式来访问。
一个数值变量可以包含一个复杂对象(compound object),比如:数组或者哈希;
魔符$表明它应该被当作一个单独的值,尽管有可能它包含众多的值(像一个数组或者哈希)。


  1:  for $file.lines ->$line{
  2:  ...
  3:  }

“for”产生了一个由花括号界定运行范围的循环,循环会遍历列表中的每一个值。
$file.lines 从scores文件中读取了很多行,除掉前面$file.get读取的那一行以外,到最后一行。
循环依次将每一行的值赋予$line变量。

第一次迭代$line将包含字符串 “Ana Dave | 3:0”;第二次迭代$line将包含字符串“Charlie Beth | 3:1”,等等。



  1:  my ($pairing,$result) = $line.split('|');

“my”可以同时声明多个变量。在赋值符号(=)的右侧调用了一个名为“split”的方法,它把“|”当作参数。

split把他作用的内容以|为分割点,分割成一系列的字符串。所以如果你用“|”作为粘合符号,把这些字符串粘合。
那么你将得到原始字符串。

$pairing 得到返回列表的第一个元素,$result 得到第二个。

当处理完第一行以后,$pairing 包含“Ana Dave”这个字符串,$result包含“3:0”。

下面两行是同样的模式:


  1:  my ($p1,$p2) = $pairing.words;
  2:  my ($r1,$r2) = $result.split(':');

第一行代码提取并保存两位运动员的姓名到$p1和$p2这两个变量中。

第二行提取每一位运动员的比赛结果,并且分别保存到$r1和$r2中。

上面程序运行以后,下面列出每一个变量包含的值:


Table2.1:Contents of Variables


  1:  Variable  Contents               
  2:  $line     'Ana Dave    | 3:0'
  3:  $pairing  'Ana Dave'              
  4:  $result   '3:0'                  
  5:  $p1       'Ana'                  
  6:  $p2       'Dave'                  
  7:  $r1       '3'                     
  8:  $r2       '0'


程序接下来统计了每一位运动员赢的局数:


  1:  %sets{$p1} += $r1;
  2:  %sets{$p2} += $r2;

这是下面的简写:


  1:  %sets{$p1} = %sets{$p1}+$r1;
  2:  %sets{$p2} = %sets{$p2}+$r2;

+= $r1 的含义是:把左侧的变量加上$r1.
在第一次迭代的时候%sets{$p1}还没有设置类型,
所以默认为一个称为“Any”的特殊值。
加法和递增操作符作为一个数字操作符,把Any当作一个值为0的数字。
所以这个字符串自动转换为数字。

在这两行代码执行以前,%sets 是空的。
在hash中添加一个完全不存在的元素,将会使这个元素立马在哈希中存在。
并且赋予初始值为0.(这被称为autovivification)。
当这两行第一次运行以后,%sets包含“ 'Ana'=> 3,'Dave'=>0”。
(胖箭头=>把键值对分开)



  1:  if $r1>$r2{
  2:      %matches{$p1}++;
  3:  } else {
  4:      %matches{$p2}++;
  5:  }

如果$r1 的值大于$r2的值,那么%matches{$p1}增加1。
如果$r1 的值小于$r2的值,那么%matches{$p2}增加1。
和前面的+=的例子一样,如果哈希中没有存在这个值,
那么这个哈希值将会因为自增符号而自动生成。

$thing++ 是$thing +=1的缩写。
需要注意的一点是,$thing++这个表达式返回的$thing的值是没有增加前的值。
而不是增加以后的。在其他很多的编程语言中你可以把++前置。这样得到的增加
以后的返回值。my $x=1; say ++$x 输出2。



  1:  my @sorted = @names.sort({ %sets{$_} }).sort({ %matches{$_} }).reverse;


这一行代码包含三个独立的过程。首先调用数组的sort方法。
但是默认的排序方法是按照内容排序的。为了按照赢得多少的顺序输出运动员的姓名,
我们的程序必须按照运动员的成绩来排序,而不是用他们的名字。
sort方法的参数一个代码块,用来把数组元素(运动员的名字)转化为用来排序的数据。
数组元素是通过“$\_”变量来传递的。

你在前面已经看到过代码块:不论是“for loop-> {...}”还是在代码块中的if语句。
代码块是:一个独立的带有 signature(the ->$line 的部分)Perl6代码。
更多内容请参照sec::signatures。

按照运动员成绩排序的最简单的方法是@names.sort({ %matches{$\_} }),
这是按照运动员赢的次数决定的。但是问题是,Ana 和Dave都赢了2次。
最简单的排序方式并没有考虑到每个人赢的局数,而这个正是决定谁赢的循环赛的第二个评判标准。

如果两个数组元素拥有相同的值, sort按照发现他们的先后顺序放置他们。
计算机科学家们称之为:稳定排序。
这个程序充分利用了Perl6排序的相关特性来利用两次排序来实现目标:
第一次按照赢取局数的多少排序(也就是次要的冠军评判标准),然后按照赢取的次数来排序。

在第一次排序以后,运动员的名字顺序是这样的:Beth Charlie Dave Ana。
在第二次排序以后,顺序依然一样。因为没有人赢了更少的次数,但是赢了更多的局数。
这种情况是很正常的,特别是在大型的循环赛中。

sort是按照升序来排序,也就是从小到大排序。
但这与我们的期望是相反的。所以,我们的程序在第二次排序以后,又调用了.reverse方法。
最后把结果存入到@sorted数组中。



  1:  for @sorted -> $n {
  2:      say "$n has won %matches{$n} matches and %sets{$n} sets";
  3:  }


为了输出运动员的名字和他们的成绩,我们对@sorted数组进行循环。
依次将运动员名字赋值给$n。我们可以这样来读代码“对数组sorted中的每一个元素,
赋值给$n,然后执行下面的代码块”。
然后用say 进行标准输出(也就是输出到屏幕)。
然后后面自动加上换行符。
如果你不想在最后加上换行符,那就用print函数。

当你运行本程序的时候,你会发现,say并不会逐字的输出所有内容。
在$n的位置上,它将会打印变量$n的内容:也就是存储在$n中的运动员的名字。
这种自动替换被称为“interpolation(变量内插)”
这种变量内插只会发生在双引号内,而不会发生在单引号内。


  1:  my $names = 'things';
  2:  say 'Do not call me $name'; # Do not call me $names
  3:  say "Do not call me $name"; # Do not call me things

在Perl6中,双引号不仅能够内插魔符$的变量,同时也可以内插在花括号内的代码块。
因为任意的Perl代码都可以通过花括号出现,所以可以通过把数组和哈希放在花括号内
实现内插的效果。

数组放在花括号内插以后,两个元素之间会插入一个空格。
哈希放在花括号内插以后,以多行的形式显示,每一行包括一个键,然后跟着一个制表符。
然后紧跟这键对应的值,最后加上换行符。


  1:  say "Math: {1+2}";                  # Match: 3
  2:  my @people = <Luke Mattew Mark>;
  3:  say "The synoptics are: {@people}"; # The synoptics are :Luck Matthew Mark
  4:  say "{%sets}";                      # 接前面网球循环赛
  5:  # Charlie 4
  6:  # Dave    6
  7:  # Ana     8
  8:  # Beth    4

当数组和哈希变量直接出现在双引号之间的时候(并没有在花括号之间),那么只有在它们的名字
后面紧跟方括号的时候才会变量内插。当然你也可以在变量名和postcircumfix之间调用一种
方法来实现变量内插。


   1:  my @flavours = <vanilla peach>;
   2:  say "we have @flavours";          # we have @flavours
   3:  say "we have @flavours[0]"        # we have vanilla
   4:  # so-called "Zen slice"
   5:  say "we have @flavours[]";        # we have Vanilla peach
   6:  
   7:  # method calls ending in postcircumfix
   8:  say "we have @flavours.sort()";   # we have peach  vanilla
   9:  
  10:  # chained method calls:
  11:  say "we have @flavours.sort.join(',')"; # we have peach ,vanilla

1_The_Basics.pdf

104.87 KB, 下载次数: 5

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
2 [报告]
发表于 2014-03-24 03:09 |只看该作者
非常感谢。{:3_188:}

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
3 [报告]
发表于 2014-03-24 03:09 |只看该作者
本帖最后由 rubyish 于 2014-03-24 00:26 编辑

代码 => 代码块 is god
3Q~ {:3_188:}

论坛徽章:
1
处女座
日期:2014-03-28 10:11:00
4 [报告]
发表于 2014-03-24 08:51 |只看该作者
回复 3# rubyish


   

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
5 [报告]
发表于 2014-03-24 19:39 |只看该作者

写的太好了, 很赞阿
好东西哈. mark 一个.

扬眉剑 我心中的大神阿

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
6 [报告]
发表于 2014-03-25 01:22 |只看该作者
回复 4# rongchaogao
god => good

example:

1:  my %matches;
2:  my %sets;
复制代码
  1. my %matches;
  2. my %sets;
复制代码
3Q~ {:3_203:}

   

论坛徽章:
1
处女座
日期:2014-03-28 10:11:00
7 [报告]
发表于 2014-03-25 17:32 |只看该作者
回复 6# rubyish


    嗯,是个问题,不过不想搞了,要复制代码的话,直接移步github!要看的话,我觉得PDF版本更赞!

论坛徽章:
1
处女座
日期:2014-03-28 10:11:00
8 [报告]
发表于 2014-03-25 17:33 |只看该作者
回复 5# pitonas


    您老过奖了!

论坛徽章:
1
处女座
日期:2014-03-28 10:11:00
9 [报告]
发表于 2014-05-11 09:29 |只看该作者
本帖最后由 rongchaogao 于 2014-05-12 19:08 编辑

                              1: Preface
                              ==========

Author: GRC(扬眉剑)
Date: 2014-05-12 19:05:02 中国标准时间


Table of Contents
=================
1 github地址
2 第一章:前言
    2.1 Audience 读者人群
    2.2 本书的结构
    2.3 Perl6和Perl5的关系
    2.4 Perl 6 的实现
    2.5 安装Rakudo
    2.6 执行程序
    2.7 参与进来


1 github地址
=============
[https://github.com/gaorongchao/Perl6/tree/master/Using_perl6]

所有后续更新都在github上进行,其他地方不做同步。
发现任何错误,或者不当的地方,请先到github查看是否改正。
如果没有请留言。或者邮件交流:rongchaogao@gmail.com

2 第一章:前言
===============
Perl6是这样一门编程语言,在整个程序的完整周期中,在各个不同的
阶段有着不同的编译器和解释器。
这些东西的实现又反过来影响了这门语言的设计,
帮助发现那些性能不足、矛盾或者难以实现且得不偿失的特性。
(by highlighting misfeatures,contradictions,or features
of difficult implementation and little benefit)
这门语言通过反复的改进,成为一个衔接顺畅且统一的规范语言。
(翻译待改善)。

Perl6是一门通用,直观灵活的语言。它融合了如程序化(procedural),
面向对象,和函数式编程等众多范式;同时也为文本解析提供了强大的工具。

这本书正在书写中。已经发布的版本中依然包许多TODO的注释,这些是我们在
正式刊印本书前要做的。我们保留TODO是因为他们可以为读者和我们提供一个有用
的提示,让我们知道那些地方需要改善和完成。
尽管如此,我们仍然要祈求读者的宽容和理解。

2.1 Audience 读者人群
----------------------
这本书主要是为那些想学习Perl6的人准备的。
它只是一系列的学习指南,而不是综合的参考手册。
尽快不要求对Perl有一定的认识,但是我们依然希望读者能够有一些使用其他编程语言的
经验。

2.2 本书的结构
---------------
每一章以一个合理而完整的例子来阐述本章的主题。
我们希望通过解释每一章中真实的程序,能够通过这些例子来展现如何使用这些特色,技巧和惯用语。
我们的目标是把Perl6的特点在程序中表现出来,这样读者就可以自己写出地道的Perl6程序,
而不是写出像其它语言的程序。

2.3 Perl6和Perl5的关系
-----------------------
Perl6是Perl大家族中新的一员。从5到6的进化中,Perl6在语法和语义的兼容性
上有了很大的代沟。但是这并不意味着Perl5会消逝。实际上,恰恰相反,Perl5和
Perl6都有活跃的开发团队,正是他们铸造了这门语言。
Perl5的开发人员,都在保持兼容老版本Perl的基础上,用不同的方式来进行扩展。
而Perl6的开发人员,通过添加新的语法和语义上功能来让Perl这门语言更加的强大和
有更强的表现能力,而不用严格的考虑兼容Perl5以及以前的版本。

也许有些人会问,“既然是一门不同的语言为何还称之为Perl?”Perl不仅仅是一种语法。
而是一种理念(比如:做事情的方法不只有一种;让容易的事情更容易,不容易的事情可以实现)
;还是一种风俗(comprehensive testing,idioms);还是一座大厦(CPAN);还是一个社群
(perl5-porters,perl6-language)。不论Perl5还是Perl6都在不同程度上烙有这些基因。
同样,Perl也是包容的。如同Perl从其它语言借鉴好的想法一样,Perl5和Perl6也共享着一些特性。

2.4 Perl 6 的实现
------------------
Perl 6是一种规范。任何一种能完整通过官方测试的实现方式都可以把自己称之为Perl6。
现在已经存在几种不同的实现形式,他们的完备性各不相同。本书的所有例子都是在
Rakudo Perl 6 编译器上运行,但是这并不是说他们只能在Rakudo上才能运行,任何一个
成熟的Perl 6的实现都可以运行这些例子。最后祝您好运,如同Perl 6 团队经常说的-玩的开心。

2.5 安装Rakudo
---------------
对于Rakudo的下载和安装的详细说明,请看:[http://www.rakudo.org/how-to-get-rakudo].
源代码的版本:[http://github.com/rakudo/rakudo/downloads] 。
一个windows可用的二进制版本可以从这里下载:[http://sourceforge.net/projects/parrotwin32/files/] 。

Rakudo star 从这里下载:[http://rakudo.org/downloads/star/]

2.6 执行程序
-------------
要用Rakudo来运行Perl 6程序,你需要在你的系统路径中添加安装Rakudo的路径。
并在命令行中执行这样的命令:


  $ perl6 hello.pl

如果你调用Perl6编译器的时候没有指定明确的脚本,那么它将进入一个交互式模式,
允许你在命令行中执行Perl6的语句。

2.7 参与进来
-------------
如果你受到本书内容的启发,并且萌发了对Perl6社区做一些贡献的欲望,那么这里
有一些有用的资源提供给你:
+ World Wide Web 万维网
Perl 6 的主页:[http://perl6.org/] 这里链接了很多有用的资源。
+ IRC
irc.freenode.net 中的#perl6频道讨论Perl6的各个方面。
+ 邮件列表
如果你需要在Perl6编程方面得到帮助,请发送邮件到 perl6-users@perl.org

对Perl6语言规范的问题,请发送邮件到 perl6-language@perl.org

对Perl6编译器的问题,请发送邮件到perl6-compiler@perl.org

Using_perl6_0_Preface.pdf

87.09 KB, 下载次数: 0

论坛徽章:
1
处女座
日期:2014-03-28 10:11:00
10 [报告]
发表于 2014-05-11 09:33 |只看该作者
看到扶凯兄,在更新Perl5 to Perl6,我也要速度一些了!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP