2017-01-02 79 views
3

在声明的东西上调用.WHY会返回围绕它构建的特殊注释。这很酷。我怎样才能引用一个在类中定义的子程序?它总是隐藏的吗?我很好奇提供子程序而不是类的模块(对此,答案可能是“不要这样做”)。我主要是玩.WHY的限制,我可以走多远。如何在Perl 6的类中的子例程上调用.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: 

这是输出的最后一行,我问。我怎样才能到达在一个类中定义的子程序?

回答

2

这是在工作中只是词法范围:

替补默认为my,所以如果你想在他们从外界获得,你必须添加一个our(或以其他方式人工揭露他们 - 为就我所知,无法通过MOP或其他元编程功能(如MY::伪包)获得它们的内置方式。

我很好奇的是提供的子程序,而不是类

这就是is export是模块。

3
 # 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"解释)在这种情况下相关联与当前包–符号,类–,以便它可以从外部访问它使用::语法。

默认情况下,子例程的词汇范围为–,即它们的缺省声明符(如果没有指定)是my。 (声明sub baz { 37 }已基本写作my &baz := sub { 37 }在大括号分隔范围的顶部同样的效果。)
通过写our sub baz { 37 },你告诉它使用的our代替my作用域。


我好奇的,其提供的子程序,而不是类

模块要么如上所示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;

一个use声明隐式调用import有问题的模块。由于这里模块是在同一个文件中定义的,我们可以直接调用import。

注意,你也可以写sub baz is export { 37 }(不:ALL),在这种情况下,符号将被默认进口每当类是use“d或import”版。但在Perl 5/CPAN社区中被认为是不好的做法,并且建议让用户导入各个符号。在Perl 6中,导入各个符号不起作用,所以我建议现在使用:ALL标记。


1)我所知道的唯一的区别是,在第一种情况下的常规知道自己的内省目的名。

相关问题