10

“一等实体”这句话的定义是什么,它与“二等实体”有何不同?

当有人说“当使用 qr// 运算符创建正则表达式是现代 perl 中的一流实体”时,这是什么意思(摘自 Modern Perl: the book)。

4

3 回答 3

12

正如 MeNoMore 正确所说,一等实体是您可以自由分配给变量等的语言的数据类型。在 Perl 中,这些包括:

  • 标量
  • 数组
  • 哈希
  • Coderefs(例如匿名子程序)
  • IO
  • Typeglobs(符号表是 glob 的散列)
  • 格式

这些可以驻留在符号表中。此外,标量槽还可以被各种其他类型占用:

  • 有符号整数
  • 无符号整数
  • 浮点数字
  • 字符串
  • 参考
  • 正则表达式

其中一些实体在 tha 语言中具有内置构造函数:用于标量的数字和字符串字面量、用于数组和哈希的列表表示法、[]用于{}匿名数组和哈希引用、sub代码的关键字、openIO 对象的函数、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 的列表。
  • 标量上下文中的数组计算为数组的长度
  • 可以将(偶数)数组分配给哈希
  • 可以将哈希分配给数组,以便将此数组分配给另一个哈希将重新创建相同的哈希
  • 标量上下文中的哈希评估为 (a) 如果它为空,则为假值,或 (b) 为指示填充和分配的桶数的字符串,例如1/8,或 (c) 为数字上下文中的键数。
  • 字符串上下文中的正则表达式评估为一个模式字符串,其行为类似于它们指定的:qr(ab?c) eq "(?-xism:ab?c)",具体取决于 perl 的版本。

可以通过重载重载对象以显示类似的强制规则。

在正则表达式引用的情况下,包含此类引用的标量可以与正则表达式文字互换使用,例如在模式中

$string =~ /ab?c/

正则表达式可以替换为$regexif$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();
于 2012-11-19T08:49:04.067 回答
4

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 的定义。

于 2012-11-19T10:00:25.643 回答
1

来自维基百科

在编程语言设计中,在特定编程语言的上下文中,一等公民(也是对象、实体或值)是可以在运行时构造、作为参数传递、从子例程返回的实体,或赋值给变量。在计算机科学中,当指代使某物成为一流对象的过程(技术、机制)时,使用术语具体化。

一个对象在以下情况下是一流的:

  • 可以存储在变量和数据结构中

  • 可以作为参数传递给子程序

  • 可以作为子程序的结果返回

  • 可以在运行时构建

  • 具有内在身份(独立于任何给定名称)

    术语“对象”在这里使用松散,不一定指面向对象编程中的对象。最简单的标量数据类型,例如整数和浮点数,几乎总是一等的。

于 2012-11-19T07:52:00.700 回答