perl中的第一类实体和第二类实体之间有什么区别?

时间:2012-11-19 07:38:38

标签: perl

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

当使用qr //运算符创建“正则表达式是现代perl中的第一类实体”时,这意味着什么(摘自Modern Perl:本书)。

3 个答案:

答案 0 :(得分:11)

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

  • 标量
  • 阵列
  • 散列
  • Coderefs(例如匿名子程序)
  • IO
  • Typeglobs(符号表是globs的散列)
  • 格式

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

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

其中一些实体具有内置构造函数,用于标量语言:标量的数字和字符串文字,数组和哈希的列表表示法,匿名数组和哈希值的[]{},{代码的{1}}关键字,IO对象的sub函数,格式的open内置函数,引用的引用运算符和正则表达式的format运算符。

Perl中的语言结构不是第一类实体,不能分配给标量或其他第一类实体。例如,包。此代码不起作用:

qr{}

Shell命令有自己的内置命令,但没有数据对象,所以这不起作用:

my $anonymous_package = package { ... };  # XXX

相反,这个陈述不应该终止(并且可能会破坏你的记忆)。

Perl中的列表是语言结构,但没有数据类型:

# don't execute `yes`, but store a handle to it in reference
my $shell_command = \qx{yes};

Perl中的内置类型可以有强制规则:

  • 数字和字符串来回强制。
  • 列表上下文中的单个标量是arity 1的列表。
  • 标量上下文中的数组计算为数组的长度
  • 可以将(偶数值)数组分配给散列
  • 可以将哈希分配给数组,以便将此数组分配给另一个哈希将重新创建相同的哈希
  • 标量上下文中的哈希评估为(a)如果为空的假值或(b)指示填充和分配的桶的数量的字符串,例如my $listref = \($x, $y, $z); # assigns reference to $z instead 或(c)数字上下文中的键数。
  • 字符串上下文中的正则表达式计算的模式字符串的行为类似于它们指定的模式字符串:1/8,具体取决于perl的版本。

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

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

qr(ab?c) eq "(?-xism:ab?c)"

如果$string =~ /ab?c/ 如上所述,则可以使用$regex替换正则表达式:

$regex

例如,coderefs需要更多的biolerplate代码:

my $regex = qr/ab?c/;
$string =~ $regex ### no dereferencing syntax!
# $string =~ /$regex/ will work too, but may invoke string overloading first (?)

sub foo {...}
foo();

答案 1 :(得分:4)

Perl 5.12的release notes包括以下内容:

  

REGEXP现在是第一类

     

在内部,Perl现在将编译的正则表达式(例如用qr //创建的正则表达式)视为第一类实体。需要针对此更改更新与Perl的内部数据结构进行序列化,反序列化或以其他方式深度交互的Perl模块。截至本文撰写时,大多数受影响的CPAN模块已经更新。

在5.12之前,只有正则表达式引擎知道有关编译的正则表达式的任何信息。当您将已编译的正则表达式存储在标量中时,您存储(引用)包含指向已编译的正则表达式模式的指针的包装器。

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

答案 2 :(得分:1)

来自Wikipedia

  

在编程语言设计中,一流的公民(也是对象,   实体或价值),在特定节目的背景下   language,是一个可以在运行时构造,传递为的实体   一个参数,从子程序返回或分配到一个   变量。在计算机科学中,术语“具体化”用于何时   指的是制造东西的过程(技术,机制)   一流的对象。

     

对象是第一类的:

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

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

  •   
  • 可以作为子程序

  • 的结果返回   
  • 可以在运行时构建

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

         

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

  •