Perl5和Perl6对比使用Sigils的差别

我们将看到Sigls(变量名称开头处的符号)Perl 5和Perl 6之间的差别。

概述

让我们从Perl 5和Perl 6中的Sigils概述开始:

符号 Perl5 Perl6
@   Array  Positional
%   Hash  Associative
Subroutine  Callable
Scalar  Item
Typeglob N/a

@(Array vs. Positional)

在perl 5中定义数组时,可以创建一个可扩展的标量值列表,并给它一个带有sigil的名称。@:

# Perl 5
my @foo = (1,2,3);
push @foo, 42;
say for @foo; # 1␤2␤3␤42␤

在perl 6中定义数组时,将创建一个新的列阵对象和绑定它以词法垫中的那个名字输入条目。因此:

# Perl 6
my @foo = 1,2,3;
push @foo, 42;
.say for @foo; # 1␤2␤3␤42␤

在功能上与Perl 5中相同。然而,第一行是用于:

# Perl 6
my @foo := Array.new( 1,2,3 );

这将绑定(而不是赋值)一个新的列阵对象指向词汇定义的名称。@foo。这,这个,那,那个@perl 6中的sigil表示一个类型约束:如果您想用该sigil将某个东西绑定到lexpad条目中,则它必执行位置角色。要确定一个类是否使用SmartMatch执行某个角色并不困难:

# Perl 6
say Array ~~ Positional; # True

您可以认为perl 6中的所有数组都是以与绑定阵列在Perl 5中实现。而这也离事实不远。如果不深入细节,一个简单的例子可能会澄清这一点。这,这个,那,那个at-POS方法是实现位置角色。每当需要访问单个元素时,都会调用此方法。所以,当你写:

say @a[42]

你正在执行:

say @a.AT-POS(42)

当然,这不是唯一可以实现的方法;更多.

而不是必须绑定您的类来执行位置角色,有一种特殊的语法使用是特质。所以不必写:

# Perl 6
my @a := YourClass.new( 1,2,3 );

你可以写:

# Perl 6
my @a is YourClass = 1,2,3;

在Perl 5中,绑定数组比“普通”数组慢得多。在Perl 6中,数组在启动时同样缓慢。幸运的是,rakudo perl 6通过内联和“在定时”(Jiting)优化热代码路径。操作码在可能的情况下使用机器代码。(由于优化器的进步,这种情况发生得更快、更频繁、更好)。

%(Hash vs. Associative)

Perl 6中的散列实现类似于数组;您还可以将它们视为绑定散列(使用Perl 5术语)。而不是位置用于实现数组的角色,则结合性角色应用于实现散列。

同样,一个简单的例子可能会有所帮助。关键方法是实现结合性角色。每当需要访问特定键的值时,都会调用此方法。所以,当你写:

say %h<foo>

你正在执行:

say %h.AT-KEY("foo")

当然,有许多其他方法 你可以实现。

&(Subroutine vs. Callable)

在Perl 5中,只有一种可调用的可执行代码,即子程序:

# Perl 5
sub frobnicate { shift ** 2 }

而且,如果要将子例程作为参数传递,则需要获得对它的引用:

# Perl 5
sub do_stuff_with {
 my $lambda = shift;
 &$lambda(shift);
}
say do_stuff_with( \&frobnicate, 42 ); # 1764

在Perl 6中,多种类型的对象可以包含可执行代码。他们的共同点是他们消耗了可赎回角色.

Sgil强制绑定到执行可赎回角色,就像%信号与结合性角色和@信号与位置角色。一个与Perl 5非常接近的例子是:

# Perl 6
my &foo = sub ($a,$b) { $a + $b }
say foo(42,666); # 708

注意,即使变量具有&Sigil,你知道不需要使用它来执行该变量中的代码。实际上,如果您在开始与普通的人相比,没有什么区别分声明:

# Perl 6
BEGIN my &foo = sub ($a,$b) { $a + $b } # same as sub foo()

与Perl 5不同的是,在Perl 6中,开始块可以是没有块的单个语句,因此它与外部共享其词法范围。但我们将在以后的文章中更多地讨论这个问题。

使用&变量是在编译时知道某物可执行文件,即使某物还不知道。

还有其他方法可以设置一段代码以供执行:

# Perl 6
my &boo = -> $a, $b { $a + $b } # same, using a Block with a signature
my &goo = { $^a + $^b }   # same, using auto-generated signature
my &woo = * + *;     # same, using Whatever currying

还可以使用&在签名内签名以表示被调用者希望在那里执行什么东西。这使我们回到本节中的前两个代码示例:

# Perl 5
sub frobnicate { shift ** 2 }
sub do_stuff_with {
 my $lambda = shift;
 &$lambda(shift);
}
say do_stuff_with( \&frobnicate, 42 ); # 1764
# Perl 6
sub frobnicate { $^a ** 2 }
sub do-stuff-with(&lambda, $param) { lambda($param) }
say do-stuff-with( &frobnicate, 42 ); # 1764

注意,在Perl 6中,您不需要接受引用;您可以简单地传递代码对象如&作为参数。

$(Scalar vs. Item)

与@、%和&Sigils相比,$sigil有点平淡。它不强制执行任何类型检查,因此可以将其绑定到任何类型的对象。因此,当你写:

# Perl 6
my $answer = 42;

像这样的事情发生了:

# Perl 6
my $answer := Scalar.new(42);

除了在一个很低的水平。因此,如果您想知道,此代码将无法工作。当你声明标量变量时,就是这样。

在Perl 6中,$还指出,其中的任何内容都应被视为单一的项目。因此,即使标量容器中填充了列阵对象时,在需要迭代的情况下,它将被视为单个项:

# Perl 6
my @foo = 1,2,3;
my $bar = Array.new(1,2,3); # alternately: [1,2,3]
.say for @foo; # 1␤2␤3␤
.say for $bar; # [1 2 3]

请注意,后一种情况只适用于一迭代VS三在前一种情况下。您可以通过前缀适当的sigil来指示是否要迭代某些内容:

# Perl 6
.say for $@foo; # [1 2 3] , consider the array as an item
.say for @$bar; # 1␤2␤3␤ , consider the scalar as a list

但也许这会把我们带到噪音太远的地方。幸运的是,还有更详细的等价物:

# Perl 6
.say for @foo.item; # [1 2 3] , consider the array as an item
.say for $bar.list; # 1␤2␤3␤ , consider the scalar as a list

* (Typeglobs)

正如您可能已经注意到的,Perl 6没有*sigil或type globs的概念。如果你不知道是什么类型的球体,你不必担心这个。您可以很好地度过难关,而不必知道Perl 5中复杂的符号表(也可以跳过下一段)。

  • 在Perl 6中,Sigil是存储在符号表中的名称的一部分,而在Perl 5中,名称是在没有信号的情况下存储的。例如,在Perl 5中,如果在程序中引用$foo,编译器将查找foo(没有sigil),然后获取相关信息(这是一个数组),并查找它所需的$sigil索引。在Perl 6中,如果引用$foo,编译器将查找$foo并直接使用与该键相关的信息。

请不要混淆用于表示Perl 6中的参数与Perl 5中的Type Gulb SIGL的SLurpy,它们彼此没有任何关系。

Sigilless variables

Perl 5不支持无符号变量(除了可能的左值子程序,但这确实非常笨拙)。

Perl 6也不直接支持Sigilless变量,但它支持通过前缀反斜杠(\)定义中的名称:

# Perl 6
my \the-answer = 42;
say the-answer; # 42

由于赋值的右边是常量,这与定义常量基本相同:

# Perl 5
use constant the_answer => 42;
say the_answer; # 42
# Perl 6
my constant the-answer = 42;
say the-answer; # 42

如果定义的右边是别的东西,那就更有趣了。就像一个容器!这允许使用以下语法技巧来获得无符号变量:

# Perl 6
my \foo = $ = 41;    # a sigilless scalar variable
my \bar = @ = 1,2,3,4,5;   # a sigilless array
my \baz = % = a => 42, b => 666; # a sigilless hash

这基本上是创建匿名词法实体(标量、数组和哈希),使用正常语义初始化它们,然后绑定生成的对象(标量集装箱列阵对象,以及散列对象)的名称,您可以将其用作Perl 6中的任何其他普通变量。

# Perl 6
say ++foo;  # 42
say bar[2]; # 3
bar[2] = 42;
say bar[2]; # 42
say baz<a b>; # (42 666)

当然,这样做,您将失去所有的优势,特别是在插值方面。然后,您将始终需要使用{ }在插值中。

# Perl 6
say "The answer is {the-answer}."; # The answer is 42.

在Perl 5的大多数版本中,对应的内容更麻烦:

# Perl 5
say "The answer is @{[the_answer]}."; # The answer is 42.

当使用Perl 5概念考虑这些变量时,Perl 6中的所有变量都可以被视为绑定变量。这使得他们在一开始就有点慢。但是在某些基准测试中,运行时优化和热代码路径的JITting(从一点到机器代码)已经使其速度超过Perl 5变量。

@, %,和&在Perl 6中,不要创建任何特定的对象,而是指示一个类型约束,该约束将应用于名称绑定到的对象。$Sigil在这方面是不同的,因为没有要强制执行的类型约束。

@和$前缀分别表示实值化和项化,尽管使用.清单和.项目方法代替。

通过几个语法技巧,可以不用变量名称中的任何Sigl来编程Perl 6。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • 强大的Perl正则表达式实例详解

    一.介绍 正则表达式各语言都有自己的规范,但是基本都差不多,都是由元字符的组合来进行匹配:由于Nmap内嵌的服务与版本探测是使用的Perl正则规范,因此此篇博客记录一下Perl正则的相关内容,方便后期查阅. 二.Perl正则例子 下面的例子可能有不足之处,有些来源于博客,没有验证: 1. 匹配IP地址:\d+\.\d+\.\d+\.\d+ \d:匹配一个数字字符,\d+:匹配一次或多次数字字符. \.:使用转义字符匹配'.'. 2. 匹配邮箱类似于123456@qq.com: /^[a-zA-Z

  • Perl与JS的对比分析(数组、哈希)

    上一篇列出了Perl中定义数组,对象的方式与JS的异同.这里继续补充数组,哈希的相关操作. 一.数组 可以对数组进行增删,插入.与JS不同的是这些函数都是全局的,JS则是挂在Array.prototype上. 1,对数组尾部的操作pop(删除最后的元素).push(在尾部添加) @goods = qw/pen pencil/; pop(@goods); # @goods 变成 (pen) push(@goods, 'brush'); # @goods 变为 (pen, brush) 在Perl中

  • 将Perl5代码迁移到Perl6上的解决方案

    无论您是一个正在将Perl 5代码转换为Perl 6并遇到一些问题的程序员,还是您只是想了解如果您尝试将Perl 5程序移植到Perl 6可能会发生什么,本文应该回答您的问题. Perl 6文档已经包含了大部分(如果不是全部)你需要的文件要解决将Perl 5代码迁移到Perl 6时所面临的问题,请执行以下操作.但是,正如文件所述,重点是事实上的差异.我将尝试更深入地讨论具体问题,并根据我将相当多的Perl 5代码移植到Perl 6的经验,提供更多的第一手信息. Perl 6怎么样? 很好,谢谢!

  • ASP.NET中HyperLink超链接控件的使用方法

    HyperLink(超链接) 作用:负责页面之间的导航 属性 值 作用 NavigateUrl url 将要跳转的页面地址(url) Font-Underline False 去除超链接下划线 一.HyperLink控件的基础使用 用到最多的无非就是NavigateUrl,既然是超链接,总得有个链接地址,下面看具体用法: 复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeFile=&quo

  • Perl中常见符号与操作

    注释: 1.单行: #print 2.多行:=pod -. =cut 查询perl相关: Perldoc perlvar($a,$$,$"...) Perldoc perfunc(sort-) Perldoc perl 查看perldoc文章列表 Perldoc –q 正则表达式 Perldoc –f 函数名 Perldoc module_name 查看模块 Perldoc –v 变量名 查看变量 Perldoc perlop 查看操作符 查看模块相关函数: 1.Perl –d –e 0 2.U

  • Perl中的符号 ->;、=>; 和 :: 分别表示什么意思?

    What do the ->, => and :: symbols mean? The -> is the "infix dereference operator". In other words it is the means by which one calls a sub with a pass by reference (among other things you can do with ->). As stated above most things

  • Perl学习教程之单行命令详解

    前言 本文主要给大家介绍了关于Perl单行命令的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 与One-Liner相关的perl参数 -a 自动分隔模式,用空格分隔$并保存在@F中,也就是@F=split //, $ -F 指定-a的分隔符 -l 对输入的内容进行自动chomp,对输出的内容自动加换行符 -n 相当于while(<>) -e 执行命令,也就是脚本 -p 自动循环+输出,也就是while(<>){命令(脚本); print;} 记住以上几

  • 详解linux下批量替换文件内容的三种方法(perl,sed,shell)

    在建设本网站的时候,发现新建了很多的网页,突然发现,每个文件都需要进行修改一样的内容,一个一个打开很是麻烦,所以,总结了一下如何快速修改一个目录下多个文件进行内容替换.第三种方法用的不多 方法一 使用perl ,命令如下: 复制代码 代码如下: find -name '要查找的文件名' | xargs perl -pi -e 's|被替换的字符串|替换后的字符串|g' 方法二 使用sed命令如下: 复制代码 代码如下: sed -i "s/原字符串/新字符串/g" `grep 原字符串

  • 使用Perl生成随机密码

    可以通过参数控制生成密码中包括的字符种类 #!/usr/bin/perl use strict; use warnings; use Getopt::Std; sub show_help { print "Useage:\n"; print "newp -aAnsl\n"; print "-a\t\t the password contains lower case letters(a-z)\n"; print "-A\t\t the

  • Perl字符串处理函数大全

    下面请看本文详细介绍. Perl字符串处理函数 1. index 语法: position=index(string,substring,position); 语义: 返回子串substring在字符串string中的位置,如果不存在则返回-1. 参数position是可选项,表示匹配之前跳过的字符数,或者说从该位置开始匹配. 2. rindex 语法: position=rindex(string,substring,position); 语义: 与index类似,区别是从右端匹配. 3. l

  • Perl时间处理函数用法介绍

    一. Perl时间的表示函数 1. 表示日期的方式多种多样: "18Jan1973"; "18/01/1973"; "01/18/1973"; "Jan181973"; "18-01-73"; "18-01-1973"; "01/73". 其中一些格式意思不清(如"01-06-1973",是表示6月1日呢,还是表示1月6日呢?) 如果不规定日期的表

  • Perl6中的垃圾收集

    参考计数 在perl 5中,通过参考计数.当在Perl 5中创建某物时,它的引用计数为1或更多,这使它保持活力.在最简单的情况下,如下所示: # reference count of $a = 1, because lives in lexical pad # lexical pad is gone, reference count to 0 在Perl 5中,如果该值是一个对象,则DESTROY方法将被调用. Foo-> # $a->DESTROY called 如果不涉及外部资源,及时销毁

随机推荐