“一等实体”这句话的定义是什么,它与“二等实体”有何不同?
当有人说“当使用 qr// 运算符创建正则表达式是现代 perl 中的一流实体”时,这是什么意思(摘自 Modern Perl: the book)。
“一等实体”这句话的定义是什么,它与“二等实体”有何不同?
当有人说“当使用 qr// 运算符创建正则表达式是现代 perl 中的一流实体”时,这是什么意思(摘自 Modern Perl: the book)。
正如 MeNoMore 正确所说,一等实体是您可以自由分配给变量等的语言的数据类型。在 Perl 中,这些包括:
这些可以驻留在符号表中。此外,标量槽还可以被各种其他类型占用:
其中一些实体在 tha 语言中具有内置构造函数:用于标量的数字和字符串字面量、用于数组和哈希的列表表示法、[]
用于{}
匿名数组和哈希引用、sub
代码的关键字、open
IO 对象的函数、format
格式的内置、引用的引用运算符和正则qr{}
表达式的运算符。
Perl 中有一些语言结构不是一等实体,不能分配给标量或其他一等实体。例如,包裹。此代码不起作用:
my $anonymous_package = package { ... }; # XXX
Shell 命令有自己的内置命令,但不是数据对象,所以这不起作用:
# don't execute `yes`, but store a handle to it in reference
my $shell_command = \qx{yes};
相反,此语句不应终止(并且可能会破坏您的记忆)。
Perl 中的列表是语言结构,但没有数据类型:
my $listref = \($x, $y, $z); # assigns reference to $z instead
Perl 中的内置类型可以有强制规则:
1/8
,或 (c) 为数字上下文中的键数。qr(ab?c) eq "(?-xism:ab?c)"
,具体取决于 perl 的版本。可以通过重载重载对象以显示类似的强制规则。
在正则表达式引用的情况下,包含此类引用的标量可以与正则表达式文字互换使用,例如在模式中
$string =~ /ab?c/
正则表达式可以替换为$regex
if$regex
就像上面一样:
my $regex = qr/ab?c/;
$string =~ $regex ### no dereferencing syntax!
# $string =~ /$regex/ will work too, but may invoke string overloading first (?)
例如,coderefs 需要更多的 biolerplate 代码:
sub foo {...}
foo();
相对
my $foo = sub {...};
$foo->(); # two possibilities
&$foo();
Perl 5.12的发行说明包括以下内容:
正则表达式现在是一流的
在内部,Perl 现在将编译的正则表达式(例如使用 qr// 创建的那些)视为第一类实体。序列化、反序列化或以其他方式与 Perl 的内部数据结构有深度交互的 Perl 模块需要针对这种变化进行更新。在撰写本文时,大多数受影响的 CPAN 模块已经更新。
在 5.12 之前,只有 regex 引擎知道编译的 regex。当您将已编译的正则表达式存储在标量中时,您存储(引用)一个包含指向已编译正则表达式模式的指针的包装器。
# 5.10.1
> perl -MDevel::Peek -e"Dump qr/abc/"
SV = RV(0x3be060) at 0x3be050
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x3be0b0
SV = PVMG(0x2bbfd8) at 0x3be0b0 <--- Uses a generic magic scalar
REFCNT = 1
FLAGS = (OBJECT,SMG)
IV = 0
NV = 0
PV = 0
MAGIC = 0x262aa8
MG_VIRTUAL = 0x28199d00
MG_TYPE = PERL_MAGIC_qr(r)
MG_OBJ = 0x2bdd68 <---- Regex is actually stored
PAT = "(?-xism:abc)" outside the scalar.
REFCNT = 2
STASH = 0x3bead0 "Regexp"
从 5.12 开始,它们现在是标量的适当子类型,就像整数和字符串一样。当您将已编译的正则表达式存储在标量中时,您将存储(引用)已编译的正则表达式模式本身。
# 5.16.1
>perl -MDevel::Peek -e"Dump qr/abc/"
SV = IV(0x74b1b8) at 0x74b1bc
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x74b1cc
SV = REGEXP(0x33b8a4) at 0x74b1cc <--- REGEXP is a subtype of scalar
REFCNT = 1
FLAGS = (OBJECT,POK,FAKE,pPOK)
PV = 0x31f90c "(?^:abc)"
CUR = 8
LEN = 0
STASH = 0x74baec "Regexp"
EXTFLAGS = 0x680000 (CHECK_ALL,USE_INTUIT_NOML,USE_INTUIT_ML)
INTFLAGS = 0x0
NPARENS = 0
LASTPAREN = 0
LASTCLOSEPAREN = 0
MINLEN = 3
MINLENRET = 3
GOFS = 0
PRE_PREFIX = 4
SEEN_EVALS = 0
SUBLEN = 0
SUBBEG = 0x0
ENGINE = 0x280cfac0
MOTHER_RE = 0x328a54
PAREN_NAMES = 0x0
SUBSTRS = 0x326174
PPRIVATE = 0x351c04
OFFS = 0x74343c
这就是发行说明中“一流”的含义。不过,我确实相信这本书使用了 amon 的定义。
来自维基百科:
在编程语言设计中,在特定编程语言的上下文中,一等公民(也是对象、实体或值)是可以在运行时构造、作为参数传递、从子例程返回的实体,或赋值给变量。在计算机科学中,当指代使某物成为一流对象的过程(技术、机制)时,使用术语具体化。
一个对象在以下情况下是一流的:
可以存储在变量和数据结构中
可以作为参数传递给子程序
可以作为子程序的结果返回
可以在运行时构建
具有内在身份(独立于任何给定名称)
术语“对象”在这里使用松散,不一定指面向对象编程中的对象。最简单的标量数据类型,例如整数和浮点数,几乎总是一等的。