2016-08-03 31 views
6

Tembelliği tembelleştirmenin en iyi yolu nedir?Tembel erişimciler nasıl yazılır

class I { 
    has $!cheezeburger; 

    method cheezeburger { 
     given $!cheezeburger { 
      when .so {return $_} 
      default { 
       # build $cheezeburger, set attribute to it, return 
      } 
     } 
    } 
} 

Bu bir sürü çizburger. Daha az ayrıntılı bir yol ne olabilir? $!lazy Eğer

+4

'yöntem cheezeburger {$! Cheezeburger // = ...}' –

cevap

2

pragmatik çözüm:

başka bir yaklaşım sırasında rolde karıştırılarak erişimci yöntemi yerine does kullanarak olurdu
class Foo { 
    has $!cheezeburger; 
    method cheezeburger { 
     $!cheezeburger //= do { ... } 
    } 
} 

özel öznitelik erişmek için kara büyü (aka NQP ops) kullanarak ilk çağrı:

class Foo { 
    has $!cheezeburger; 
    method cheezeburger { 
     self does role { 
      method cheezeburger { 
       use nqp; 
       nqp::getattr(self, Foo, '$!cheezeburger'); 
      } 
     } 
     $!cheezeburger = do { ... } 
    } 
} 
+0

Tanımlanmış ya da eşitlikli "do" bloğunu beğeniyorum – beasy

4
class A { 
    has $!lazy; 
    method BUILD { $!lazy := Nil }; 
    method lazy { $!lazy := (my $a = 42) if $!lazy =:= Nil; $!lazy } 
}; 
my $a = A.new; 
say [$a.lazy, $a.lazy]; 

birkaç döngüler aracılığıyla hop gereken tanımsız değerleri tutmak içindir. Önce Nil'u $!lazy'a bağlayıp, bir kabın tutmaması gereken bir değeri tutturuyoruz. $!lazy hala Nil'a bağlıysa, yeni bir kap oluşturup ona bir değer atarız. Eğer değer değişmez ise, ekstra konteynere ihtiyacınız yoktur. Gereksinim duyduğunuz herhangi bir tip kısıtlaması $! Tembelliğinin $a üzerinde olması gerekir, çünkü kısıtlar değişken/sınıf-özelliği olmayan bir kabın bir özelliğidir. birçok durum için yeterli olmalıdır tanımsız ise niteliğini başlatır Brad tarafından verilen

+0

: Yine de bunu anlamaya çalışıyorum. – beasy

+2

malzeme için thx Değişkenler, kapsayıcılara (atama operatörü '=') ve değişmez değerlere (bağlayıcılı işleç üzerinden ': =') bağlanabilir. Hangi kapsayıcıları görebildiğinizi anlamak için https://docs.perl6.org/language/containers#Custom_containers. –

4

Mevcut modüller

İki tane lazy attribute modules vardır.

Brad $!cheezeburger //= do { ... };

Olağan kod birçok kullanım durumları için yeterli olacak bir oldukça düz ileri çözüm gibi görünüyor.

Daha iyi bir şey?

# perl6 folk'ün istediğini bulabilir veya daha iyi bir şey sağlayabilirsiniz.

En son ciddi # perl6 tartışmaları hakkında temkinli öznitelik başlangıcından haberdar olduğumun farkındayım, 5, 7, 20 ve 5 Haziran, 8 ve 20 Mayıs 2015'te gerçekleşti. pages of #perl6 log with at least one "will lazy" match'da "tembel" ifadesini arayın. Bu tartışmaların TL; DR, rjbs, mst ve diğer Moose kullanıcılarının hoş tembelliğin başlangıcında kullanıldıkları ve Rakudo'ya bir çözelti eklendikleri; Masak ve diğerleri sorunları olduğunu düşündükleri ve modül alanında güzel çözümlerin oluşturulabileceğini düşündükleri ve daha sonra akıllıca göründükleri zaman çekirdeğe geri döndüklerini düşündükleri için geri çekildi.