如何编写惰性访问器

bea*_*asy 6 perl6

懒惰地构建属性的最佳方法是什么?

class I {
    has $!cheezeburger;

    method cheezeburger {
        given $!cheezeburger {
            when .so {return $_}
            default { 
                # build $cheezeburger, set attribute to it, return 
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是很多cheezeburger.什么可能是一个不那么冗长的方式?

rai*_*iph 5

现有模块

有两个惰性属性模块.

普通代码

Brad $!cheezeburger //= do { ... };似乎是一个相当简单的解决方案,足以满足许多用例.

更好的东西?

您可能会发现#perl6民众想要或可以提供更好的东西.

关于懒惰属性初始化的最新认真的#perl6讨论发生在2015年5月5日,7日,20日和6月5日,8日和20日.在#perl6 log的页面中搜索"will lazy" ,并且至少有一个"将懒惰"匹配.这些讨论的TL; DR是rjbs,mst和其他Moose用户习惯了懒惰的属性初始化,并且为Rakudo添加了一个解决方案; 然后它被退出了,因为masak和其他人认为它有问题,他们认为可以在模块空间中创建好的解决方案,然后在看起来很明智的情况下移回核心.


Chr*_*oph 3

Brad 给出的实用解决方案(如果属性未定义则对其进行初始化)对于许多情况来说应该足够好了:

class Foo {
    has $!cheezeburger;
    method cheezeburger {
        $!cheezeburger //= do { ... }
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是通过does在第一次调用期间混合角色来替换访问器方法,使用黑魔法(又名 NQP 操作)来访问私有属性:

class Foo {
    has $!cheezeburger;
    method cheezeburger {
        self does role {
            method cheezeburger {
                use nqp;
                nqp::getattr(self, Foo, '$!cheezeburger');
            }
        }
        $!cheezeburger = do { ... }
    }
}
Run Code Online (Sandbox Code Playgroud)