正则表达式实际上是方法:
say rx/foo/.^mro # ((Regex) (Method) (Routine) (Block) (Code) (Any) (Mu))
Run Code Online (Sandbox Code Playgroud)
在这种情况下,这意味着他们可以对自己采取行动,并且是阶级的一部分。那班是什么?我的直觉是这是Match类,它们实际上是在$ /上作用(它们实际上是)。还有其他表达方式吗?
最终,所有正则表达式都希望收到类型为Match或的某些子类的倡导者Match。在Perl 6中,倡导者只是第一个论点,在任何其他方面都不特殊。
那些正则表达式与声明rule,token或regex在包内将安装上该包的方法。最典型的是,它们在中声明,grammar无非是class其默认父项为Grammar而不是Any。Grammar是的子类型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,才可以解决在上声明的各种内置规则。
方法不必与任何类相对应:
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)
因此,要求可能是由满足Grammar,Match或Capture在这种情况下。
它也可能来自与之融为一体的角色。
say Foo.^roles.map(*.^name);
# (NQPMatchRole)
Run Code Online (Sandbox Code Playgroud)
甚至更有理由相信它是Match或Capture
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)