bjam AdC jp 2011 11日目
はいはいーすすめます。
sequenceモジュール
Boost 1.48.0時点でのsequenceモジュールのrule一覧です。
rule filter ( predicate + : sequence * ) rule transform ( function + : sequence * ) rule reverse ( s * ) rule less ( a b ) rule insertion-sort ( s * : ordered * ) rule merge ( s1 * : s2 * : ordered * ) rule join ( s * : joint ? ) rule length ( s * ) rule unique ( list * : stable ? ) rule max-element ( elements + : ordered ? ) rule select-highest-ranked ( elements * : ranks * )
はいー。いろいろあります。名前からして大体理解できると思うので、いくつか例を出せばまぁ他のも使えるでしょう。
そもそもsequenceってなんですか
sequenceとはスペースで区切られた任意の文字列です。文字列リテラルではないです。(多分この説明で合ってるような...
e.g.
hoge fuga piyo hoge fuga piyo という3要素からなるsequence
"hoge fuga piyo" "hoge fuga piyo" という1要素からなるsequence
間違えないように。
ちなみにruleの引数もsequenceをコロンで区切っているものです。ここらへんに付いては次回説明しましょう!(やったネタできた!
直接sequenceを渡す系
reverse/less/join/length/unique/max-elementは基本的にsequenceを投げると一定の処理をするruleです。内容は名前から解ると思います。lessのみbinary functionなので気をつけてください。
多分uniqueが一番使うんじゃないんでしょうか。こんな感じです
import sequence ; ECHO [ sequence.unique hoge fuga piyo hoge ] ;
出力が
fuga hoge piyo
でした。unique ruleの場合、stableに何かtrueになるもの渡せばstableなものになるようです。
まぁそんな感じでこいつらは楽です。
高階関数になってるやつ
filter/transform/insertion_sort/mergeは高階関数になっているのでまとめます。
高階関数ということはruleかactionsかクラスか渡すような気がしますが、これはruleを渡すことになります。何か特別な構文があるわけでもなく単にrule名を渡すだけです。transformは変換した値を返すだけで問題ないです。
transform以外はpredicateを要求しています。ところがbjamでpredicateの扱いは面倒です。例えば以下の例
rule always-false1 ( ) { return false ; } if [ always-false1 ] { ECHO "true !!" ; }
は多くの人の予想に反して
true !!
と表示されます。
predicateの場合、conditionがfalseになるようなものを返さないといけないのですが、bjamにおいて任意のトークンはすべてtrueとして評価されます。もちろん 0 や no 、大文字であろうとです。
では、どうやってfalseにするかですが、これはruleで何も返さないことでできます。もしくは空の変数を返すことで実現できます。
rule always-false2 ( ) { } if [ always-false2 ] { ECHO "true !!" ; } rule always-false3 ( ) { local false = ; return $(false) ; } if [ always-false3 ] { ECHO "true !!" ; }
これらはすべて false として評価されます。
ということでfilterを例にとってみます。
import sequence ; rule is_hoge ( val ) { if $(val) = hoge { return true ; } } ECHO [ sequence.filter is_hoge : hoge fuga piyo hoge ] ;
結果は
hoge hoge
となります。
それぞれ渡すruleは、filterはunary predicate、insertion_sort/mergeはbinary predicate、transformはunary functionです。
select-highest-ranked rule
こいつ面倒なんでこれだけで1回分作っていいですか...ネタ無いので...
まとめ
sequenceはbjamでかなり重要なものです。扱えるようになっくといいです。
あ、いい忘れてましたけどsequenceのランダムアクセスは
seq = hoge fuga piyo ; ECHO $(seq[0]) ; # => hoge ECHO $(seq[1]) ; # => hoge ECHO $(seq[2]) ; # => fuga ECHO $(seq[3]) ; # => piyo ECHO $(seq[4]) ; # =>
1-origです。存在しないところを参照するとなにも帰ってきません。conditionでfalseになるやつです。
あと
seq = hoge fuga piyo ; ECHO $(seq[2-]) ; # => fuga piyo ECHO $(seq[-3]) ; # => hoge ECHO $(seq[2-3]) ; # => fuga piyo
とかあります。真ん中は範囲ではなく負のindexとして扱われてる点に注意です。
まとめ部分が重要だった気がしましたが気のせいです。今日だけでネタが2つできたので今日は安心して寝れます。