$whenと$unlessというsyntaxを追加した

github.com

$whenと$unlessというsyntaxを追加した。$whenは以下の様な形で書く。

$when

$when: <predicate>
body:
  <body>

or

$when: <predicate>
<body>

body部分が不要なら省略できる(省略できるのはbody部分にactionの呼び出しがない場合に限る)。

$whenはpredicate部分が真ならbody部分を評価する。逆にいうと、predicate部分が偽ならbody部分は評価もされずに捨てられる。

ok0:
  $when: true
  body: ok
ng0:
  $when: false
  body: ng
ok1:
  $when: true
  body:
    message: ok
ok2:
  $when: true
  message: ok

評価結果は以下の様になる。

ok0: ok
ok1:
  message: ok
ok2:
  message: ok

$unless

$whenの逆

ok0:
  $unless: false
  body: ok
ng0:
  $unless: true
  body: ng
ok1:
  $unless: false
  body:
    message: ok
ok2:
  $unless: false
  message: ok

ok0: ok
ok1:
  message: ok
ok2:
  message: ok

になる

使い方

例えば、template的なものを共通化しようとした時に、不要な箇所を取り除いた形で出力するのに使える。 以下のようなtemplateがあった時に、それぞれ必要かどうかをusedb,usemailに保持しておく。

# when.yaml
db:
  $when: {$get: "data#/usedb"}
  body: localhost:270/foo
mail:
  $when: {$get: "data#/usemail"}
  body:
    {$format: "http://{me}@bar.ne.jp", me: {$get: "data#/me"}}

usedb,usemail自体は --data で渡される設定の中に書いておく。

#data.yaml
local:
  usedb: true
  usemail: false
  me: foo
dev:
  usedb: true
  usemail: true
  me: foo

--data でdev, localそれぞれの場合の設定を渡して結果を出力させる。

zenmai when.yaml --data "data.yaml#/local" > when.local.yaml
zenmai when.yaml --data "data.yaml#/dev" > when.dev.yaml

localの方はusemailがfalseだったのでmailが存在しない。

# when.local.yaml
db: localhost:270/foo

devの方はusemailがtrueだったのでmailが存在する。

# when.dev.yaml
db: localhost:270/foo
mail: http://foo@bar.ne.jp

なんとなく

なんとなく$ifは実装していない。たぶん見通しが悪くなるような気がする。条件分岐させたくないし。どちらかと言うと木に対する枝切りみたいな感じのイメージの操作に留めておきたい感じ。