LoginSignup
1
2

More than 3 years have passed since last update.

Jsonnet のイディオム

Posted at

これはJsonnetのイディオム(よくある書き方)を見たときに生まれる疑問「Jsonnetのこの記述は、どういう意味なの?」について、つらつらと列挙するためのノートです。随時更新。
質問や、「もっといい書き方があるよ」等あればコメント欄に残していただけると助かります。

フィールド定義

field:: value って何? field: value とどう違うの?

: ではなく、:: でフィールドを定義すると、隠しフィールドになり、最終的な出力に含まれなくなる。
出力しようとするとエラーになるオブジェクト(関数など)を定義する際に使われることが多い。
出力されないだけで存在はしているので、下記の field2 の値のように、値を評価するときには参照可能。

{
  hidden_field:: 'hidden',

  filed1: 'value1',
  filed2: 'value2' + self.hidden_field,
}

{
   "filed1": "value1",
   "filed2": "value2hidden"
}

field::: value って何? field: valuefield:: value とどう違うの?

同盟のフィールドを持つ2つのオブジェクトを + などでマージしたとき、ベースとなる左側のオブジェクトに :: で定義した隠しフィールドがあると、右側のオブジェクトに : で定義した通常フィールドがあっても、出力からそのフィールドは取り除かれてしまう。(次の例で obj4_hidden_normal が該当)

ここで右側のオブジェクトのフィールドを ::: で可視フィールドとして定義しておくと、ベースとなるオブジェクトに同一の名前の隠しフィールドがあっても、フィールドが出力される。(obj6_hidden_visible が該当)

ただし、可視フィールドを持つオブジェクトをベースに隠しフィールドを持つオブジェクトをマージすると、出力からフィールドは取り除かれる。(obj8_visible_hidden が該当)

{
  local normal = { field: 1 },
  local hidden = { field:: 2 },
  local visible = { field::: 3 },

  obj1_normal_normal: normal + normal,
  obj2_normal_hidden: normal + hidden,
  obj3_normal_visible: normal + visible,

  obj4_hidden_normal: hidden + normal,
  obj5_hidden_hidden: hidden + hidden,
  obj6_hidden_visible: hidden + visible,

  obj7_visible_normal: visible + normal,
  obj8_visible_hidden: visible + hidden,
  obj9_visible_visible: visible + visible,
}

{
   "obj1_normal_normal": {
      "field": 1
   },
   "obj2_normal_hidden": { },
   "obj3_normal_visible": {
      "field": 3
   },
   "obj4_hidden_normal": { },
   "obj5_hidden_hidden": { },
   "obj6_hidden_visible": {
      "field": 3
   },
   "obj7_visible_normal": {
      "field": 1
   },
   "obj8_visible_hidden": { },
   "obj9_visible_visible": {
      "field": 3
   }
}

field+: value って何? field: value とどう違うの?

オブジェクトをマージする場合に、 : ではなく、+: でフィールドを定義すると、親オブジェクトの同フィールドの値と '+' した結果に評価される。値がオブジェクトであればマージされ、配列や文字列であれば連結、数字であれば加算される。
filed: super.field + value と書いた場合と同じ。

local parent = {
  field1: {
    field2: 2,
  },
  field3: [3.1, 3.2],
};

{
  obj1: parent {
    field1+: {
      field4: 4,
    },
    field3+: [3.4, 3.5],
  },
  obj2: parent {
    field1: super.field1 {
      field4: 4,
    },
    field3: super.field3 + [3.4, 3.5],
  },
}

{
   "obj1": {
      "field1": {
         "field2": 2,
         "field4": 4
      },
      "field3": [
         3.1000000000000001,
         3.2000000000000002,
         3.3999999999999999,
         3.5
      ]
   },
   "obj2": {
      "field1": {
         "field2": 2,
         "field4": 4
      },
      "field3": [
         3.1000000000000001,
         3.2000000000000002,
         3.3999999999999999,
         3.5
      ]
   }
}

値の定義

filed: variable { ... } って何?

オブジェクトをマージする '+' の簡略記法。 filed: variable + { ... } と書いた場合と同じ。

{
  obj:: {
    field1: 1,
  },

  merged1: self.obj {
    field2: 2,
  },
  merged2: self.obj + {
    field2: 2,
  },
}

{
   "merged1": {
      "field1": 1,
      "field2": 2
   },
   "merged2": {
      "field1": 1,
      "field2": 2
   }
}

標準関数

std.mergePatch って何?

オブジェクトを再帰的にマージするときに使う。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2