DigDag ifメモ(Hishidama's DigDag if Memo) S-JIS[2021-08-26/2021-08-27] 変更履歴

DigDag if

DigDagのifオペレーターのメモ。


概要

digファイル内にifオペレーターを書くことで、条件に応じてタスクを実行することが出来る。

_export:
  flag: true
# flag: false

+example1:
  if>: ${flag}
  _do:
    echo>: execute task

+example2:
  if>: ${flag}
  _do:
    echo>: then
  _else_do:
    echo>: else

条件を指定する方法

ifオペレーターに指定できる値は、(booleanの)trueかfalseのみ。
文字列の「true」「false」も可。

直接的に演算を書くことは出来ない。
ただ、${ }の中にはJavaScriptの式を書くことが出来るので、何か演算したい場合はこれを利用する。

_export:
  flag1: true
  flag2: false

+example:
  if>: ${flag1 || flag2}
  _do:
    echo>: execute task

&&や||の注意点


曜日を判定する例

timezone: Asia/Tokyo

+example:
  if>: ${moment(session_date).day() == 0} # 日曜日のみ実行
  _do:
    echo>: execute task

DigDagでは日付時刻を扱うためにMoment.jsが入っているらしい。
session_dateはDigDagのワークフローを実行した際の日付であり、moment(session_date)でMomentのオブジェクトを作る。
day()は曜日を取り出すメソッドで、0が日曜日、1が月曜日、…、6が土曜日。


timezone: Asia/Tokyo

_export:
  sunday: ${moment(session_date).day() == 0}

+example:
  if>: ${sunday} # 日曜日のみ実行
  _do:
    echo>: execute task

${ }の中(JavaScript)でbooleanの値は、_exportでDigDagの変数に入れた時点でstringになるが、
if>: ${sunday}」のように変数単独で使う分には問題ない。
(&&や||で複数の判定を行おうとすると上手くいかないので注意)


&&や||の注意点

以下のような判定は上手くいかない。

_export:
  flag1: ${1 != 1} # false
  flag2: true

+debug:
  echo>: ${typeof flag1} ${typeof flag2}

+example:
  if>: ${flag1 || flag2}
  _do:
    echo>: execute task

flag1は${ }の中(JavaScript)ではbooleanだが、_exportでDigDagの変数に入れた時点でstringになる。(つまり「true」や「false」という文字列になる)
flag2はbooleanである。
この状態で${flag1 && flag2}${flag1 || flag2}を使うと、期待した結果にならないケースがある。

結果 備考
${'true' && true} true  
${'true' && false} false  
${'false' && true} true 期待した結果でない
${'false' && false} false  
${'true' || true} true  
${'true' || false} true  
${'false' || true} false 期待した結果でない
${'false' || false} false  

※演算子の左オペランドがbooleanで右オペランドがbooleanまたはstringの場合は、&&も||も期待通りの結果になる。
※左右のオペランドが共にstringの場合は、「左オペランドがstringで右オペランドがboolean」の場合と同じく、期待した結果にならないパターンがある。


JavaScriptでは、文字列を真偽値として扱う場合、空文字列をfalse、それ以外をtrueとする。[2021-08-27]
つまり「false」という文字列は、真偽値としてはtrueになる。

また、JavaScriptの&&や||は、オペランドの値をそのまま返す。
つまり「${'false' && true}」は、左オペランドが真と判定され、右オペランドのtrueが返る。
${'false' || true}」は、左オペランドが真と判定され、左オペランドの'false'が返る。DigDagのifオペレーターでは「false」という文字列は偽として扱われる。

参考: MDN Web Docsの論理積 (&&)論理和 (||)


JavaScriptでは「false」という文字列は真として扱われ、
DigDagのifオペレーターでは「false」という文字列は偽として扱われるのが、混乱の元。

そして、JavaScriptの値にはbooleanやstringというデータ型があり、
DigDagの変数も真偽値と文字列というデータ型があるにも関わらず、
_exportで変数に代入するときに真偽値を文字列に変換してしまうDigDagが悪い。

(ちなみに、Pythonのdigdag.env.storeで真偽値を代入すると、DigDag側でも真偽値のデータ型になる)


オペレーターへ戻る / DigDagへ戻る / 技術メモへ戻る
メールの送信先:ひしだま