Starlark 言語

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。
問題を報告する ソースを表示

このページでは、Bazel で使用されている言語である Skylark(旧称 Skylark)の概要について説明します。関数と型の完全なリストについては、Bazel API リファレンスをご覧ください。

言語の詳細については、Starlark の GitHub リポジトリをご覧ください。

Starlark の構文と動作の信頼できる仕様については、Starlark 言語仕様をご覧ください。

構文

Starlark の構文は Python3 に基づいており、これは Starlark の有効な構文です。

def fizz_buzz(n):
  """Print Fizz Buzz numbers from 1 to n."""
  for i in range(1, n + 1):
    s = ""
    if i % 3 == 0:
      s += "Fizz"
    if i % 5 == 0:
      s += "Buzz"
    print(s if s else i)

fizz_buzz(20)

Starlark のセマンティクスは Python と異なる場合がありますが、Starlark でエラーが発生する場合を除き、動作の違いはまれです。次の Python タイプがサポートされています。

可変性

Starlark は不変性を優先します。可変データ構造には、リスト辞書の 2 つがあります。リストに値を追加する、または辞書のエントリを削除するなど、変更可能なデータ構造に加えた変更は、現在のコンテキストで作成されたオブジェクトに対してのみ有効です。コンテキストが終了すると、その値は不変になります。

これは、Bazel ビルドが並列実行を使用しているためです。ビルド中、各 .bzl ファイルと各 BUILD ファイルは独自の実行コンテキストを取得します。各ルールも、それぞれ固有のコンテキストで分析されます。

ファイル foo.bzl の例を見てみましょう。

# `foo.bzl`
var = [] # declare a list

def fct(): # declare a function
  var.append(5) # append a value to the list

fct() # execute the fct function

Bazel は、foo.bzl の読み込み時に var を作成します。したがって、varfoo.bzl のコンテキストの一部です。fct() を実行すると、foo.bzl のコンテキスト内で実行されます。foo.bzl の評価が完了すると、環境には値 [5] を持つ不変エントリ var が含まれます。

別の bar.bzlfoo.bzl からシンボルを読み込むと、読み込まれた値は変更できなくなります。そのため、bar.bzl の以下のコードは不正です。

# `bar.bzl`
load(":foo.bzl", "var", "fct") # loads `var`, and `fct` from `./foo.bzl`

var.append(6)  # runtime error, the list stored in var is frozen

fct()          # runtime error, fct() attempts to modify a frozen list

bzl ファイルで定義されたグローバル変数は、それらを定義している bzl ファイルの外部で変更することはできません。bzl ファイルを使用する上記の例と同様に、ルールによって返される値は不変です。

BUILD ファイルと .bzl ファイルの違い

BUILD ファイルは、ルールを呼び出してターゲットを登録します。.bzl ファイルは、定数、ルール、マクロ、関数の定義を提供します。

ネイティブ関数ネイティブ ルールは、BUILD ファイルのグローバル シンボルです。bzl ファイルは、native モジュールを使用して読み込む必要があります。

BUILD ファイルには、2 つの構文上の制限があります。1)関数を宣言するのは誤りであり、2)*args**kwargs の引数は使用できません。

Python との違い

  • グローバル変数は不変です。

  • トップレベルでは for ステートメントを使用できません。代わりに、関数内で使用してください。BUILD ファイルでは、リスト表現を使用できます。

  • トップレベルでは if ステートメントを使用できません。ただし、if 式は first = data[0] if len(data) > 0 else None で使用できます。

  • 辞書順で反復処理を行うための決定論的な順序。

  • 再帰は許可されていません。

  • int 型は 32 ビット符号付き整数に限定されます。オーバーフローするとエラーがスローされます。

  • 反復処理中にコレクションを変更すると、エラーが発生します。

  • 等価テストを除き、比較演算子 <<=>=> などは値の型間で定義されていません。つまり、5 < 'foo' はエラーをスローし、5 == "5" は false を返します。

  • タプルの場合、末尾のカンマは、タプルがかっこ間にある場合にのみ有効です(1, ではなく (1,) を記述する場合)。

  • 辞書リテラルに重複するキーを含めることはできません。たとえば、{"a": 4, "b": 7, "a": 1} がエラーになります。

  • 文字列は二重引用符で表します(repr の呼び出しなど)。

  • 文字列は反復可能ではありません。

次の Python の機能はサポートされていません。

  • 暗黙的な文字列の連結(明示的な + 演算子を使用)。
  • チェーンされた比較(1 < x < 5 など)。
  • classstruct 関数を参照)。
  • importload ステートメントを参照)。
  • whileyield
  • float 型と set 型です。
  • 生成ツール。
  • is(代わりに == を使用)
  • tryraiseexceptfinally(致命的なエラーについては fail をご覧ください)。
  • globalnonlocal
  • ほとんどの組み込みの関数、ほとんどのメソッド、