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側でも真偽値のデータ型になる)