Raku'daki bir modülde Haskell gibi Prelude modülleri kullanın


11

Bazı bölümleri içeren bir çizim paketi yazıyorum ve işleçler ve veri türlerinin dağılması var. Ancak kullanıcıların her seferinde karşılık gelen modülleri eklemelerini istemiyorum, çünkü oldukça dağınık olurdu, örneğin bir Pointsınıf, bir Monoidrol ve Styleböyle farklı yollarda bir sınıf olurdu

unit module Package::Data::Monoid;
# $?FILE = lib/Package/Data/Monoid.pm6

role Monoid {...}
unit module Package::Data::Point;
# $?FILE = lib/Package/Data/Point.pm6

class Point {...}
unit module Package::Data::Style;
# $?FILE = lib/Package/Data/Style.pm6

class Style {...}

Bu tür komut dosyaları yazabileceğim etki ile haskellbenzer bir başlangıç ​​yapmak istiyorumlib/Package/Prelude.pm6

use Package::Prelude;

# I can use Point right away, Style etc...

yapmak yerine

use Package::Data::Style;
use Package::Data::Point;
use Package::Data::Monoid;

# I can too use point right away, but for users not knowing the
# inner workings it's too overwhelming

Birçok şey denedim:

  • Bu sürüm bana doğru efekti vermiyor, ben işaret etmek için tüm yolu yazmak zorunda, yani, Package::Data::Point...
unit module Package::Prelude;
# $?FILE = lib/Package/Prelude.pm6
use Package::Data::Style;
use Package::Data::Point;
use Package::Data::Monoid;
  • Bu sürüm bana Pointhemen veriyor , ancak operatörlerle ilgili sorunlar alıyorum ve bunun gibi, ben de sadece belirtilen örnek paketlerde dışa aktarılan rutinlerden her şeyi otomatik olarak eklemek istiyorum.
# $?FILE = lib/Package/Prelude.pm6
use Package::Data::Style;
use Package::Data::Point;
use Package::Data::Monoid;

sub EXPORT {
  hash <Point> => Point
     , <Style> => Style
     , <mappend> => &mappend
     ...
}

Böyle bir başlangıç ​​dosyası almanın daha iyi ve hızlı bir yolunu biliyor musunuz?


Kullanabilirsiniz unit class Package::Data::Point. Kullanmanıza gerek yok module.
Brad Gilbert

Yanıtlar:


12

Kullanımı EXPORTdoğru yöndedir. Bilmeniz gereken kilit noktalar:

  • İthalat sözeldir
  • Mevcut sözlük kapsamındaki sembolleri elde etmek ve bunlara erişmek için içgözlem kullanabiliriz

Yani tarif:

  • use içindeki tüm modüller EXPORT
  • Ardından, içe aktarılan tüm sembolleri çıkarın ve EXPORT

Örnek olarak, Foo::Pointbir operatör ve bir sınıf içeren bir modül oluşturuyorum :

unit module Foo::Point;

class Point is export {
    has ($.x, $.y);
}

multi infix:<+>(Point $a, Point $b) is export {
    Point.new(x => $a.x + $b.x, y => $a.y + $b.y)
}

Ve sadece birden fazla modülle çalışabileceğini göstermek için Foo::Monad:

unit module Foo::Monad;

class Monad is export {
    method explain() { say "Just think of a burrito..." }
}

Amaç bu işi yapmaktır:

use Foo::Prelude;
say Point.new(x => 2, y => 4) + Point.new(x => 3, y => 5);
Monad.explain;

Aşağıdakileri Foo::Preludeiçeren bir yazı yazarak elde edilebilir :

sub EXPORT() {
    {
        use Foo::Point;
        use Foo::Monad;
        return ::.pairs.grep(*.key ne '$_').Map;
    }
}

Burada açıklamak için birkaç tuhaflık var:

  1. A subve dolaylı tanımlamaya sahiptir $_, $/ve $!. Bunların dışa aktarılması, modül use'd olduğunda derleme zamanı sembolü çakışma hatasına neden olur . Bir bloğun yalnızca üstü kapalı bir yeri vardır $_. Böylece iç içe çıplak bir blokla hayatımızı kolaylaştırıyoruz.
  2. grepEmin bizim örtülü ilan ihraç yok yapmaktır $_(biz umurumda tek adres bu, iç içe bloğuna sayesinde) sembolü.
  3. ::mevcut kapsamı referans almanın bir yoludur (etimoloji: ::paket ayırıcıdır). ::.pairsböylece Pairgeçerli kapsamdaki her sembol için nesneler elde edilir .

Gelecekteki bir Raku dil sürümünde, bu ısıtıcı levha ihtiyacını ortadan kaldırabilecek bir yeniden ihracat mekanizması var.


Son olarak, bu tam olarak aradığım davranış, çok teşekkürler!
margolari
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.