我如何在 Perl 6 中的 class 中的子例程上调用 .WHY?
How can I call .WHY on a subroutine in a class in Perl 6?
调用 .WHY
声明 returns 围绕它构建的特殊注释。这很酷。如何引用 class 中定义的子例程?它总是隐藏的吗?我很好奇提供子例程而不是 classes 的模块(答案可能是 "don't do it that way")。我主要是在玩弄 .WHY
的极限以及我能走多远。
#| This is the outside bit
sub outside { 137 }
put &outside.WHY; # This works
#| Class Foo is an example
class Foo {
#| The bar method returns a number
method bar { 137 }
#| quux is a submethod
submethod quux { 137 }
#| qux is private
submethod !qux { 137 }
#| The baz method also returns a number
sub baz { 37 }
put &baz.WHY; # this works in this scope
}
put "---- With an object";
quietly {
my $object = Foo.new;
put "As object: ", $object.WHY;
# sub is not really a method?
put "As object - bar: ", $object.^find_method( 'bar' ).WHY;
# should this work? It *is* private after all
put "As object - qux: ", $object.^find_method( 'qux' ).WHY;
}
put "---- With class name";
quietly {
put Foo.WHY;
put "As class lookup: ", ::("Foo").WHY;
put "As class lookup (quux): " ~ Foo.^lookup( 'quux' ).WHY;
put "As class lookup (baz): " ~ Foo.^lookup( 'baz' ).WHY; # nope!
# this is the part where I need help
put "As :: lookup: ", ::("Foo")::("&baz").WHY; #nope
}
这是输出:
This is the outside bit
The baz method also returns a number
---- With an object
As object: Class Foo is an example
As object - bar: The bar method returns a number
As object - qux:
---- With class name
Class Foo is an example
As class lookup: Class Foo is an example
As class lookup (quux): quux is a submethod
As class lookup (baz):
As :: lookup:
这是我要问的最后一行输出。如何进入 class 中定义的子例程?
这只是工作中的词法范围:
Subs 默认为 my
,所以如果你想从外部获取它们,你必须添加一个 our
(或以其他方式手动公开它们 - 据我所知我知道,没有内置方法可以通过 MOP 或其他元编程功能(如 MY::
伪包)获取它们。
I'm curious about modules that provide subroutines instead of classes
这就是 is export
的目的。
# should this work? It *is* private after all
put "As object - qux: ", $object.^find_method( 'qux' ).WHY;
以下两项工作:
put "As object - qux: ", $object.^find_private_method('qux').WHY;
put "As object - qux: ", $object.^private_method_table<qux>.WHY;
(find_private_method
似乎没有在 p6doc 中记录,所以我不确定它是否是官方的 API。 private_method_table
有记录,虽然没有真正解释。 )
# this is the part where I need help
put "As :: lookup: ", ::("Foo")::("&baz").WHY; #nope
如果您将 sub baz { 37 }
声明为 our sub baz { 37 }
,则此方法有效。
您还可以更简单地编写查找:
put "As :: lookup: ", &Foo::baz.WHY;
our
声明符(在 Synopsis 3, section "Declarators" 中解释)将符号与当前包相关联——在本例中为 class——以便可以从包外部访问它使用 ::
语法。
默认情况下,子例程是词法范围的——即它们的默认声明符,如果指定了 none,则为 my
。 (语句 sub baz { 37 }
基本上 1 与在花括号分隔范围的顶部写入 [=20=] 相同的效果。)
通过编写 our sub baz { 37 }
,您告诉它使用 our
而不是 my
范围。
I'm curious about modules that provide subroutines instead of classes
要么用 our
声明它,如上所示 (在这种情况下,用户范围将必须使用完全限定名称 Foo::baz
),或者将其导出到用户范围 (在这种情况下,他们可以将其称为 baz
).
使符号可导出的最简单方法是使用 is export
特性:
module Foo {
#| The baz method also returns a number
sub baz is export(:ALL) { 37 }
}
import Foo :ALL;
say &baz.WHY;
A use
语句隐式调用了相关模块上的 import
。由于这里的模块定义在同一个文件中,我们可以直接调用import。
请注意,您也可以编写 sub baz is export { 37 }
(不带 :ALL
),在这种情况下,只要 class 为 use
,就会默认导入该符号' d 或 import
'ed。但在 Perl 5 / CPAN 社区中,这被认为是不好的做法,建议让用户导入单个符号。在 Perl 6 中,导入单个符号还不起作用,所以我建议现在使用 :ALL
标签。
1) 我知道的唯一区别是,在第一种情况下,例程知道自己的名称以进行内省。
调用 .WHY
声明 returns 围绕它构建的特殊注释。这很酷。如何引用 class 中定义的子例程?它总是隐藏的吗?我很好奇提供子例程而不是 classes 的模块(答案可能是 "don't do it that way")。我主要是在玩弄 .WHY
的极限以及我能走多远。
#| This is the outside bit
sub outside { 137 }
put &outside.WHY; # This works
#| Class Foo is an example
class Foo {
#| The bar method returns a number
method bar { 137 }
#| quux is a submethod
submethod quux { 137 }
#| qux is private
submethod !qux { 137 }
#| The baz method also returns a number
sub baz { 37 }
put &baz.WHY; # this works in this scope
}
put "---- With an object";
quietly {
my $object = Foo.new;
put "As object: ", $object.WHY;
# sub is not really a method?
put "As object - bar: ", $object.^find_method( 'bar' ).WHY;
# should this work? It *is* private after all
put "As object - qux: ", $object.^find_method( 'qux' ).WHY;
}
put "---- With class name";
quietly {
put Foo.WHY;
put "As class lookup: ", ::("Foo").WHY;
put "As class lookup (quux): " ~ Foo.^lookup( 'quux' ).WHY;
put "As class lookup (baz): " ~ Foo.^lookup( 'baz' ).WHY; # nope!
# this is the part where I need help
put "As :: lookup: ", ::("Foo")::("&baz").WHY; #nope
}
这是输出:
This is the outside bit
The baz method also returns a number
---- With an object
As object: Class Foo is an example
As object - bar: The bar method returns a number
As object - qux:
---- With class name
Class Foo is an example
As class lookup: Class Foo is an example
As class lookup (quux): quux is a submethod
As class lookup (baz):
As :: lookup:
这是我要问的最后一行输出。如何进入 class 中定义的子例程?
这只是工作中的词法范围:
Subs 默认为 my
,所以如果你想从外部获取它们,你必须添加一个 our
(或以其他方式手动公开它们 - 据我所知我知道,没有内置方法可以通过 MOP 或其他元编程功能(如 MY::
伪包)获取它们。
I'm curious about modules that provide subroutines instead of classes
这就是 is export
的目的。
# should this work? It *is* private after all put "As object - qux: ", $object.^find_method( 'qux' ).WHY;
以下两项工作:
put "As object - qux: ", $object.^find_private_method('qux').WHY;
put "As object - qux: ", $object.^private_method_table<qux>.WHY;
(find_private_method
似乎没有在 p6doc 中记录,所以我不确定它是否是官方的 API。 private_method_table
有记录,虽然没有真正解释。 )
# this is the part where I need help put "As :: lookup: ", ::("Foo")::("&baz").WHY; #nope
如果您将 sub baz { 37 }
声明为 our sub baz { 37 }
,则此方法有效。
您还可以更简单地编写查找:
put "As :: lookup: ", &Foo::baz.WHY;
our
声明符(在 Synopsis 3, section "Declarators" 中解释)将符号与当前包相关联——在本例中为 class——以便可以从包外部访问它使用 ::
语法。
默认情况下,子例程是词法范围的——即它们的默认声明符,如果指定了 none,则为 my
。 (语句 sub baz { 37 }
基本上 1 与在花括号分隔范围的顶部写入 [=20=] 相同的效果。)
通过编写 our sub baz { 37 }
,您告诉它使用 our
而不是 my
范围。
I'm curious about modules that provide subroutines instead of classes
要么用 our
声明它,如上所示 (在这种情况下,用户范围将必须使用完全限定名称 Foo::baz
),或者将其导出到用户范围 (在这种情况下,他们可以将其称为 baz
).
使符号可导出的最简单方法是使用 is export
特性:
module Foo { #| The baz method also returns a number sub baz is export(:ALL) { 37 } } import Foo :ALL; say &baz.WHY;
A use
语句隐式调用了相关模块上的 import
。由于这里的模块定义在同一个文件中,我们可以直接调用import。
请注意,您也可以编写 sub baz is export { 37 }
(不带 :ALL
),在这种情况下,只要 class 为 use
,就会默认导入该符号' d 或 import
'ed。但在 Perl 5 / CPAN 社区中,这被认为是不好的做法,建议让用户导入单个符号。在 Perl 6 中,导入单个符号还不起作用,所以我建议现在使用 :ALL
标签。
1) 我知道的唯一区别是,在第一种情况下,例程知道自己的名称以进行内省。