如果正则表达式是方法,则它们对应于哪个类?

jjm*_*elo 5 oop perl6

正则表达式实际上是方法:

say rx/foo/.^mro # ((Regex) (Method) (Routine) (Block) (Code) (Any) (Mu))
Run Code Online (Sandbox Code Playgroud)

在这种情况下,这意味着他们可以对自己采取行动,并且是阶级的一部分。那班是什么?我的直觉是这是Match类,它们实际上是在$ /上作用(它们实际上是)。还有其他表达方式吗?

Jon*_*ton 8

最终,所有正则表达式都希望收到类型为Match或的某些子类的倡导者Match。在Perl 6中,倡导者只是第一个论点,在任何其他方面都不特殊。

那些正则表达式与声明ruletokenregex在包内将安装上该包的方法。最典型的是,它们在中声明,grammar无非是class其默认父项为Grammar而不是AnyGrammar是的子类型Match

grammar G {}.^mro.say # ((G) (Grammar) (Match) (Capture) (Cool) (Any) (Mu))
Run Code Online (Sandbox Code Playgroud)

因此,将这些看作只是方法是很自然的,但是它的主体是用另一种语言编写的。实际上,这正是它们的本质。

只要不将匿名正则表达式安装在任何类型的方法表中,就很难看到它们。但是,如果我们要写:

class C {
    method foo() { 42 }
}
my $m = anon method () { self.foo }
say C.$m()
Run Code Online (Sandbox Code Playgroud)

然后我们看到self即使该方法实际上没有安装在类上,也可以通过它来解析请求者上的符号C。匿名正则表达式也是如此。这之所以重要的是断言喜欢<ident><.ws><?before foo>和朋友实际上编译成方法调用。

因此,匿名正则表达式是方法,因此将其第一个参数视为倡导者Match,才可以解决在上声明的各种内置规则。


Bra*_*ert 7

方法不必与任何类相对应:

my method bar () { say self, '!' }

bar 'Hello World'; # Hello World!


my regex baz { :ignorecase 'hello world' }

'Hello World' ~~ /<baz>/;
'Hello World' ~~ &baz;
&baz.ACCEPTS('Hello World'); # same as previous line

# baz 'Hello World';
Run Code Online (Sandbox Code Playgroud)

在默认方法和扩展名下,正则表达式has与它们在其中声明的任何类都有关系。

class Foo {
        method bar () { say self, '!' }
  # has method bar () { say self, '!' }

        regex  baz    { :ignorecase 'hello world' }
  # has regex  baz () { :ignorecase 'hello world' }
}
Run Code Online (Sandbox Code Playgroud)

正则表达式确实需要满足其要求的一些要求。

通过将其作为子例程运行,它告诉您第一个:

my regex baz { :ignorecase 'hello world' }

baz 'Hello World';
Run Code Online (Sandbox Code Playgroud)
No such method '!cursor_start' for invocant of type 'Str'
  in regex baz at <unknown file> line 1
  in block <unit> at <unknown file> line 1
Run Code Online (Sandbox Code Playgroud)

通常,在声明的类中声明正则表达式grammar

grammar Foo {
}

say Foo.^mro;
# ((Foo) (Grammar) (Match) (Capture) (Cool) (Any) (Mu))
Run Code Online (Sandbox Code Playgroud)

因此,要求可能是由满足GrammarMatchCapture在这种情况下。

它也可能来自与之融为一体的角色。

say Foo.^roles.map(*.^name);
# (NQPMatchRole)
Run Code Online (Sandbox Code Playgroud)

甚至更有理由相信它是MatchCapture

my regex baz {
    ^
    { say 'baz was called on: ', self.^name }
}
&baz.ACCEPTS(''); # baz was called on: Match
Run Code Online (Sandbox Code Playgroud)
my regex baz ( $s ) {
    :ignorecase
    "$s"
}
baz Match.new(orig => 'Hello World'), 'hello';
# ?Hello?
Run Code Online (Sandbox Code Playgroud)

我没有理由没有人在普通班级不能做到这一点。


请注意,这$/只是一个变量。因此,说将其传递给正则表达式是对情况的误解。

my regex baz ( $/ ) {
    :ignorecase
    "$/"
}
'Hello World' ~~ /<baz('hello')>/;
# ?Hello?
#  baz => ?Hello?
Run Code Online (Sandbox Code Playgroud)

准确地说,当从另一个内部调用一个正则表达式时,当前$/用作方法/正则表达式的调用者。
(我不完全确定这实际上是发生了什么。)

因此,前面的示例将如下所示:

'Hello World' ~~ /{ $/.&baz('hello') }/;
Run Code Online (Sandbox Code Playgroud)