Perl6Weekly(第二期)

:my $foo 的作用域和用途

regex写烤、tokenrule 中, 定義像下面這樣的變量是可能的:

token directive {
    :my $foo = "in command";
    <command> <subject> <value>?
}

在中提到了一點(diǎn)有關(guān)該變量的東西, 我引用過來:

任何 grammar regex 實(shí)際上是一種方法, 并且你可以在這樣一個(gè)子例程中使用一個(gè)冒號(hào)跟著任何作用域聲明符來聲明一個(gè)變量, 這些聲明符包括 my, our, stateconstant (作為類似的聲明符, temp 和 let 也能被識(shí)別). 單個(gè)語句(直到結(jié)尾的分號(hào)或行末尾的閉括號(hào)為止) 被解析為普通的 Perl 6 代碼:

token prove-nondeterministic-parsing {
    :my $threshold = rand;
    'maybe' \s+ <it($threshold)>
}

有誰能解釋下這段代碼的應(yīng)用場(chǎng)景嗎崖瞭?

what scope does :my $foo; have?

:my $foo 在它所出現(xiàn)的 rule/token/regex 中擁有詞法作用域(lexical scope)。你所得到的作用域要么很大要么很小:

grammar g {
    regex r1 {
        { my $foo; ...} # `$foo` 在該 block 的結(jié)尾超出作用域驯杜。
        ...
        { say $foo;   } # `$foo` 不在作用域中。
    }
}

grammar i {
    my $foo;
    regex r1   { ... } # 在 `r1` 內(nèi)部, `$foo` 被識(shí)別出核畴。
    ...
    regex r999 { ... } # 但是在 r999 中也是丑孩。
}

它的用途?

使用 :my $foo; 形式的變量聲明以在 rule/token/regex 中聲明本地作用域的變量, 如果沒有進(jìn)一步的聲明, 那么這些變量能在 rule/token/regex 中的任何地方通過所聲明的名字來引用仗岖。舉個(gè)例子, 你可以看看 Rakudo 的 Grammar.nqp 源代碼中的 token babble 中聲明的 @extra_tweaks 變量的用法檩电。

使用 :my $*foo; 形式的變量聲明來聲明動(dòng)態(tài)的詞法變量站绪。動(dòng)態(tài)變量能夠, 在沒有進(jìn)一步聲明的情況下, 在閉合詞法作用域和閉合動(dòng)態(tài)作用域中通過它們聲明的名字來引用。作為說明, 請(qǐng)查看 the declaration of @*nibbles in Rakudo's Grammar moduleits use in Rakudo's Actions module

一般的使用場(chǎng)景

regular expressions 中一般不使用 :… 風(fēng)格的聲明秋泳。:...; 結(jié)構(gòu)通常用在特別復(fù)雜和龐大的 grammars 中和敬。對(duì)于這些使用場(chǎng)景, 依靠 Perl 6 的正則表達(dá)式和閉包的一致性是合適的舱痘。正是這使得 rule/token/regex 級(jí)別的 :...; 變量聲明變得正當(dāng)。

Regexes 和 closures 的一致性

很多 grammars 都是上下文有關(guān)的.

Perl 6 使 regexes 和 closures 統(tǒng)一了:

say Regex.^mro; (Regex) (Method) (Routine) (Block) (Code) ...

mro 是方法解析順序, 這足以說明 regex 實(shí)際上是一種特殊類型的方法(就像方法是一種特殊類型的子例程一樣)。

Perl6: is there a phaser that runs only when you fall out of a loop?

#!/usr/bin/env perl6

use v6.c;

ROLL:
for 1..10 -> $r {
    given (1..6).roll {
        when 6 {
            say "Roll $r: you win!";
            last ROLL;
        }
        default {
            say "Roll $r: sorry...";
        }
    }
    LAST {
        say "You either won or lost - this runs either way";
    }
}

更優(yōu)雅的寫法:

constant N = 5;
for flat (1..6).roll xx * Z 1..N -> $_, $n {
    print "roll $n: $_ ";

    when 6 {
        put "(won)";
        last;
    }

    default {
        put "(lost)";
    }

    LAST {
        print "result: ";
        when 6 { put "winner :)" }
        default { put "loser :(" }
    }
}

怎么從命令行傳遞一個(gè)復(fù)數(shù)給 sub MAIN?

#!/usr/bin/env perl6

use v6.c;

sub MAIN($x)
{
    say "$x squared is { $x*$x }";
}

我要在命令行中傳遞一個(gè)復(fù)數(shù)給 MAIN:

% ./square i
Cannot convert string to number: base-10 number must begin with valid digits or '.' in '?i' (indicated by ?)
  in sub MAIN at ./square line 7
  in block <unit> at ./square line 5

Actually thrown at:
  in sub MAIN at ./square line 7
  in block <unit> at ./square line 5

當(dāng)我把腳本變?yōu)?

#!/usr/bin/env perl6

use v6.c;

sub MAIN(Complex $x)
{
    say "$x squared is { $x*$x }";
}

它竟然徹底罷工了:

% ./square i
Usage:
  square <x>

% ./square 1
Usage:
  square <x>

一種方法是使用 Coercive type declaration (強(qiáng)制類型聲明), 從 Str 到 Complex:

sub MAIN(Complex(Str) $x) {
    say "$x 的平方為 { $x * $x }";
}

那么:

% ./squared.pl 1
1+0i 的平方為 1+0i
% ./squared.pl 1+2i
1+2i 的平方為 -3+4i

但是:

$ ./test.pl6 2
Usage:
  ./test.p6 <x> 

所以你真正需要的是把其它 Numeric 類型強(qiáng)轉(zhuǎn)為 Complex 類型:

#!/usr/bin/env perl6

use v6.c;

sub MAIN ( Complex(Real) $x ) {
    say "$x squared is { $x*$x }";
}

我使用 Real 而非 Numeric, 因?yàn)?Complex 已經(jīng)涵蓋了其它的了螃壤。

Blessing a Hash into an object

為什么我寫的這段代碼不對(duì)呢?

class WordCount {
  has %!words; # Tried with both . and !
  method new($string) {
    my %words;
    my @sentence = split(/\s+/, $string);
    for @sentence -> $word {
      %words{$word}++;
    }
    return self.bless(:%words);
  }

  method sayCounts() {
    my @keys = keys(%!words);
    for @keys -> $key {
      say $key ~ " " ~ %!words{$key};
    }
  }
}

sub MAIN {
  my $sentence = "the boy jumped over the dog";
  my $wordCount = WordCount.new($sentence);
  $wordCount.sayCounts();
}

Perl6-ify:

use v6;

class WordCount {
  has Int %.words is default(0);

  method new($string) {
    my Int %words;
    for $string.split(/\s+/) -> $word {
      %words{$word}++;
    }

    self.bless(:%words)
  }

  method gist {
    %.words.map({.value ~ " " ~ .key}).join("\n")
  }
}

my $word-count = WordCount.new('the boy jumped over the dog');
say $word-count;

散列中的每一項(xiàng)都是一個(gè) Pair:

my %w = a => 1;
%w.map({ say $_.^name }) # OUTPUT?Pair
?

所以:

%.words.map({.value ~ " " ~ .key}).join("\n")

等價(jià)于:

%.words.kv.map( -> $word, $count { "$word $count" } ).join("\n")

你還可以使用 sub-signature(子簽名)來解構(gòu) .map 提供的 Pair

%.words.map( -> (:key($word), :value($count)) { "$word $count" } ).join("\n")
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市延都,隨后出現(xiàn)的幾起案子验夯,更是在濱河造成了極大的恐慌趁俊,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異右冻,居然都是意外死亡国旷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來详幽,“玉大人剥险,你說我怎么就攤上這事控乾⊥跋郑” “怎么了绵脯?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)休里。 經(jīng)常有香客問我蛆挫,道長(zhǎng),這世上最難降的妖魔是什么妙黍? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任悴侵,我火速辦了婚禮,結(jié)果婚禮上拭嫁,老公的妹妹穿的比我還像新娘可免。我一直安慰自己,他們只是感情好做粤,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布巴元。 她就那樣靜靜地躺著,像睡著了一般驮宴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上呕缭,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天堵泽,我揣著相機(jī)與錄音,去河邊找鬼恢总。 笑死迎罗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的片仿。 我是一名探鬼主播纹安,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了厢岂?” 一聲冷哼從身側(cè)響起光督,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎塔粒,沒想到半個(gè)月后结借,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卒茬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年船老,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片圃酵。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡柳畔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出郭赐,到底是詐尸還是另有隱情薪韩,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布堪置,位于F島的核電站躬存,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏舀锨。R本人自食惡果不足惜岭洲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坎匿。 院中可真熱鬧盾剩,春花似錦、人聲如沸替蔬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽承桥。三九已至驻粟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凶异,已是汗流浹背蜀撑。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留剩彬,地道東北人酷麦。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像喉恋,于是被迫代替她去往敵國(guó)和親沃饶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子母廷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)糊肤,斷路器琴昆,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 從匹配中返回值 Match 對(duì)象 成功的匹配總是返回一個(gè) Match 對(duì)象, 這個(gè)對(duì)象通常也被放進(jìn) $/ 中, (...
    焉知非魚閱讀 1,778評(píng)論 0 1
  • 標(biāo)題: Rakudo and NQP Internals子標(biāo)題: The guts tormented imple...
    焉知非魚閱讀 1,342評(píng)論 1 3
  • 允許的修飾符 有些修飾符能在所有允許的地方出現(xiàn), 但并非所有的都這樣. 通常, 影響 regex 編譯的修飾符(...
    焉知非魚閱讀 1,322評(píng)論 0 1
  • 捕獲 簽名不僅僅是語法,它們是含有一列參數(shù)對(duì)象的 first-class 對(duì)象 轩褐。同樣地椎咧,有一種含有參數(shù)集的數(shù)據(jù)...
    焉知非魚閱讀 546評(píng)論 0 0