擴(kuò)展 Perl 6 中的類型

擴(kuò)展 Perl 6 中的類型

使用繼承

class BetterInt is Int {
    method even { self %% 2 }
}

my BetterInt $x .= new: 42;
say $x.even; 

$x .= new: 71;
say $x.even;

say $x + 42;

# OUTPUT:
# True
# False
# 113

my BetterInt $x 約束 $x 只能包含 BetterInt 或它的子類這種類型的對(duì)象肪笋。.= new: 42 等價(jià)于 = BetterInt.new: 42碎绎。
下面的子例程期望接收一個(gè) Int 型的參數(shù)鸦难,但是你給它傳遞一個(gè) BetterInt 類型的參數(shù)它會(huì)很高興:

sub foo(Int $x) { say "\$x is $x"}

my BetterInt $x .= new: 42;
foo $x;

# OUTPUT:
# $x is 42

But... But... But...

另外一個(gè)選擇是摻合進(jìn)一個(gè)角色(role)珍语。but 中綴操作符創(chuàng)建對(duì)象的一份拷貝并為該對(duì)象添加一個(gè)方法:

my $x = 42 but role { method even { self %% 2 } };
say $x.even;

# OUTPUT:
# True

當(dāng)然角色不一定是內(nèi)聯(lián)的强衡。這兒有另外一個(gè)例子使用了一個(gè)預(yù)定義的角色并且還展示了我們的對(duì)象確實(shí)被拷貝了一份:

role Better {
    method better { "Yes, I am better" }
}

class Foo {
    has $.attr is rw
}

my $original = Foo.new: :attr<original>;
my $copy     = $original but Better;
$copy.attr   = 'copy'; 

say $original.attr;  # still 'original'
say $copy.attr;      # this one is 'copy'

say $copy.better;
say $original.better; # fatal error: can't find method

# OUTPUT:
# original
# copy
# Yes, I am better
# Method 'better' not found for invocant of class 'Foo'
#   in block <unit> at test.p6 line 18

這看起來挺不錯(cuò)的,但是對(duì)于我們?cè)瓉淼哪繕?biāo)來說合呐,這個(gè)方法還是相當(dāng)弱的:

my $x = 42 but role { method even { self %% 2 } };
say $x.even; # True
$x = 72;
say $x.even; # No such method!

那個(gè)角色被混合進(jìn)我們?nèi)萜骼锩娲鎯?chǔ)的對(duì)象中了暮的;所以一旦我們?cè)谌萜髦蟹胚M(jìn)了一個(gè)新的值,或高級(jí)點(diǎn)的東西淌实,那么 .even 方法就不見了冻辩,除非我們?cè)俅伟涯莻€(gè)角色混合進(jìn)來猖腕。

子例程

你知道你可以把子例程當(dāng)做方法用嘛? 你接收那個(gè)對(duì)象作為子例程的第一個(gè)位置參數(shù)并且你甚至能繼續(xù)使用鏈?zhǔn)椒椒ㄕ{(diào)用恨闪,但是不能把那些鏈子分解成多行:

sub even { $^a %% 2 };
say 42.&even.uc;

# OUTPUT:
# TRUE

這確實(shí)是為核心類型添加額外功能的一種得體方式倘感。我們的子例程定義中的 $^a 引用第一個(gè)參數(shù)(我們?cè)谡{(diào)用的那個(gè)對(duì)象)并且整個(gè)子例程也可以被寫為:

sub ($x) { $x %% 2 }

飛龍?jiān)谔?/h2>

不管Javaccript 的那些人們?cè)趺锤阏f, 然而擴(kuò)充原生類型是危險(xiǎn)的。因?yàn)槟阏绊懗绦虻乃胁糠至省I踔量床坏侥愕臄U(kuò)充的模塊也受到影響侠仇。

現(xiàn)在我有權(quán)告訴你,我跟你說過犁珠,你工作的核電廠融化了,讓我們看看一些代碼:

# Foo.pm6
unit module Foo;
sub fob is export {
    say 42.even;
}

# Bar.pm6
unit module Bar;
use MONKEY-TYPING;
augment class Int {
    method even { self %% 2 }
}

# test.p6
use Foo;
use Bar;

say 72.even;
fob;

# OUTPUT:
# True
# True

所有的行為都發(fā)生在 Bar.pm6 中互亮。首先犁享,我們寫了一行 use MONKEY-TYPING 聲明,它告訴我們正在做一些危險(xiǎn)的行為豹休。然后我們?cè)陬?class Int 的前面使用了 augment 關(guān)鍵字以擴(kuò)充這個(gè)已經(jīng)存在的類炊昆。我們的擴(kuò)充添加了一個(gè)叫 even 的方法以告訴我們那個(gè) Int 是否是偶數(shù)。

所有的整數(shù)都可以使用 even 方法了威根,這雖然達(dá)到了我們的要求但是有點(diǎn)危險(xiǎn)凤巨。

我邪惡了

我們來擴(kuò)充 Cool 類型以涵蓋所有的西文排版行長(zhǎng)單位:

use MONKEY-TYPING;
augment class Cool {
    method even { self %% 2 }
}

.say for 72.even, '72'.even, pi.even, ?.even;

# OUTPUT:
# Method 'even' not found for invocant of class 'Int'
# in block <unit> at test.p6 line 8

糟糕,程序奔潰了洛搀!原因是在我們擴(kuò)充 Cool 類型的時(shí)候敢茁,派生自 Cool 的所有類型已經(jīng)成型了(composed)。所以為了讓它能工作留美,我們必須使用 .^compose 元對(duì)象協(xié)議方法來重新構(gòu)成它們:

use MONKEY-TYPING;
augment class Cool {
    method even { self %% 2 }
}

.^compose for Int, Num, Rat, Str, IntStr, NumStr, RatStr;

.say for 72.even, '72'.even, pi.even, ?.even;

# OUTPUT:
# True
# True
# False
# False

它現(xiàn)在能工作了彰檬!Int, Num, Rat, Str, IntStr, NumStr, RatStr 類型擁有了 .even 方法(注意:這些不是繼承自 Cool 的僅有的類型)! 這既邪惡又讓人吃驚。

結(jié)論

當(dāng)擴(kuò)充 Perl 6 的核心類型或其它任意類的功能時(shí)谎砾,你有幾種選擇逢倍。

  • 使用 is Class 子類
  • 使用 but Role 混合一個(gè)角色
  • 使用 $objec.&sub 調(diào)用子例程作為方法使用
  • 使用 augment(注意安全)

Perl 6 — There Is More Than One Way To Extend it.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市景图,隨后出現(xiàn)的幾起案子较雕,更是在濱河造成了極大的恐慌,老刑警劉巖挚币,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件亮蒋,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡忘晤,警方通過查閱死者的電腦和手機(jī)宛蚓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來设塔,“玉大人凄吏,你說我怎么就攤上這事远舅。” “怎么了痕钢?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵图柏,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我任连,道長(zhǎng)蚤吹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任随抠,我火速辦了婚禮裁着,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拱她。我一直安慰自己二驰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布秉沼。 她就那樣靜靜地躺著桶雀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪唬复。 梳的紋絲不亂的頭發(fā)上矗积,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音敞咧,去河邊找鬼棘捣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛休建,可吹牛的內(nèi)容都是我干的柱锹。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼丰包,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼禁熏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起邑彪,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤瞧毙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后寄症,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宙彪,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年有巧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了释漆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡篮迎,死狀恐怖男图,靈堂內(nèi)的尸體忽然破棺而出示姿,到底是詐尸還是另有隱情,我是刑警寧澤逊笆,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布栈戳,位于F島的核電站,受9級(jí)特大地震影響难裆,放射性物質(zhì)發(fā)生泄漏子檀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一乃戈、第九天 我趴在偏房一處隱蔽的房頂上張望褂痰。 院中可真熱鬧,春花似錦症虑、人聲如沸脐恩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至苟翻,卻和暖如春韵卤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背崇猫。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工沈条, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诅炉。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓蜡歹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親涕烧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子月而,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Functions and Functional Programming in Perl 6 例程(Routine...
    焉知非魚閱讀 700評(píng)論 0 1
  • 第一章 概要 Comming soon! 第二章 基礎(chǔ) 假設(shè)有一場(chǎng)乒乓球比賽,比賽結(jié)果以這種格式記錄:Player...
    焉知非魚閱讀 330評(píng)論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理议纯,服務(wù)發(fā)現(xiàn)父款,斷路器,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • 標(biāo)題: Rakudo and NQP Internals子標(biāo)題: The guts tormented imple...
    焉知非魚閱讀 1,343評(píng)論 1 3
  • Set Series Operator flip_flop.txt 內(nèi)容如下: 輸出: Grammars 只能在葉...
    焉知非魚閱讀 867評(píng)論 0 0