diff --git a/doc/vim9.jax b/doc/vim9.jax index 7d02fa2dd..af710c8d1 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -1,4 +1,4 @@ -*vim9.txt* For Vim バージョン 9.1. Last change: 2023 Dec 09 +*vim9.txt* For Vim バージョン 9.1. Last change: 2024 Jan 12 VIMリファレンスマニュアル by Bram Moolenaar @@ -1063,8 +1063,11 @@ Vim9 script では以下の定義済みの値が使えます: > また、それらの値は引数の既定値とするのにも便利です: > def MyFunc(b: blob = null_blob) - if b == null_blob - # 引数 b が与えられなかった + # Note: null_blob ではなく null と比較し、 + # デフォルト値と空 blob を区別する。 + if b == null + # 引数 b が与えられなかった +null に対するテストについての詳細は、|null-compare| を参照。 `null` はどんな値と比較すること可能で、型エラーが発生することはありません。 しかし、`null` と数値、浮動小数点数、真偽値との比較は常に `false` になります。 @@ -1267,10 +1270,13 @@ Note 認識されていないコマンドを "|" でつなぐと、その後の なりません。それらは関数内で、旧来の関数内でも作成することはできません。 *:defc* *:defcompile* -:defc[ompile] 現在のスクリプトで定義されている関数のうち、まだコンパ - イルされていないものをコンパイルします。これはコンパイ - ル時に見つかったいかなるエラーも報告します。 - クラス内部で定義された関数は除きます。 +:defc[ompile] 現在のスクリプトで定義されている関数とクラス + (|class-compile|) のうち、まだコンパイルされていないも + のをコンパイルします。これはコンパイル時に見つかったい + かなるエラーも報告します。 + +:defc[ompile] MyClass クラス内のすべてのメソッドをコンパイルします。 + |class-compile| :defc[ompile] {func} :defc[ompile] debug {func} @@ -1697,6 +1703,157 @@ Vim9 script ではこれは厳格にされています。使われている値 *E1297* *E1298* *E1301* 間違いを発見しやすくするために、ほとんどの組み込み関数で型がチェックされます。 +変数のカテゴリー、デフォルトおよび null の扱い ~ + *variable-categories* *null-variables* +変数には次のカテゴリがあります: + プリミティブ number, float, boolean + コンテナ string, blob, list, dict + 特殊 function, job, channel, user-defined-object + +初期化子を使用せずに変数を宣言する場合は、明示的に型を指定する必要があります。 +各カテゴリには、異なるデフォルトの初期化セマンティクスがあります。カテゴリごと +の例を次に示します: > + var num: number # プリミティブのデフォルトは 0 相当 + var cont: list # コンテナのデフォルトは空コンテナ + var spec: job # 特殊変数のデフォルトは null +< +Vim にはおなじみの null 値はありません。|null_string|、|null_list|、|null_job| +など、さまざまな null_ があらかじめ定義されています。プリミティブは +null_ を持ちません。null_ の典型的な使用例は以下の通りです: +- 変数をクリアし、そのリソースを解放。 +- 関数定義内のパラメータのデフォルトとしては、|null-compare| を参照。 + +`job` などの特殊な変数の場合、リソースをクリアするために null_ が使用さ +れます。コンテナ変数の場合、空コンテナを変数に割り当てることによってリソースを +クリアすることもできます。例: > + var j: job = job_start(...) + # ... ジョブはその仕事を行う + j = null_job # 変数をクリアしてジョブのリソースを解放する + + var l: list + # ... リストにたくさんのものを追加 + l = [] # 変数をクリアしてコンテナリソースを解放する +null_ ではなく空コンテナを使用してコンテナ変数をクリアすると、 +|null-anomalies| で説明されているように null の複雑な問題を回避できる可能性が +あります。 + +コンテナ変数と特殊な変数の初期化セマンティクスは異なります。初期化されていない +コンテナはデフォルトで空コンテナになります: > + var l1: list # 空コンテナ + var l2: list = [] # 空コンテナ + var l3: list = null_list # null コンテナ +"l1" と "l2" は同等で区別できない初期化です。ただし、"l3" は null コンテナで +す。null コンテナは空コンテナに似ていますが、異なります。|null-anomalies| を参 +照してください。 + +特殊変数のデフォルトは null です。これらのジョブの初期化は同等であり、区別でき +ません: > + var j1: job + var j2: job = null_job + var j3 = null_job + +リストまたは辞書が宣言されている時に、項目の型が指定されておらず推論できない場 +合、型は "any" になります: > + var d1 = {} # 型は "dict" + var d2 = null_dict # 型は "dict" + +関数の宣言は特に独特です。|vim9-func-declaration| を参照。 + + *null-compare* +一般的な null 比較セマンティクスでは、null コンテナが空コンテナと等しくない場 +合、比較で null_ を使用しないでください: > + vim9script + def F(arg: list = null_list) + if arg == null + echo "null" + else + echo printf("not null, %sempty", empty(arg) ? '' : 'not ') + endif + enddef + F() # 出力: "null" + F(null_list) # 出力: "null" + F([]) # 出力: "not null, empty" + F(['']) # 出力: "not null, not empty" +上記の関数は文字列のリストを取得し、それについてレポートします。 +さまざまな種類の引数を受け入れるように、上記の関数シグネチャを変更します: > + def F(arg: list = null_list) # あらゆるタイプのリスト + def F(arg: any = null) # あらゆるタイプ +< +上記の例では、null リストと空リストを区別することが目的であり、`null_list` で +はなく `null` と比較することが正しい選択です。基本的な理由は、 +"null_list == null" および "[] != null" であるためです。 +"[] == null_list" であるため、`null_list` との比較は失敗します。次のセクション +で比較結果の詳細が記載されています。 + + *null-details* *null-anomalies* +このセクションでは、null および null_ の使用に関する問題について説明しま +す。以下に、null 比較の列挙結果を示します。場合によっては、vim9 の null セマン +ティクスに精通している場合、プログラマは比較やその他の状況で null_ を使 +用することを選択することがあります。 + +ドキュメントの他の場所には次のように書かれています: + 多くの場合、null 値は空の値と同じように処理されますが、常にそうとは限 + りません +以下に例を示します: > + vim9script + var s1: list + var s2: list = null_list + echo s1 # 出力: "[]" + echo s2 # 出力: "[]" + + echo s1 + ['a'] # 出力: "['a']" + echo s2 + ['a'] # 出力: "['a']" + + echo s1->add('a') # 出力: "['a']" + echo s2->add('a') # E1130: Can not add to null list +< +null_ に等しい 2 つの値は、必ずしも互いに等しいとは限りません: > + vim9script + echo {} == null_dict # true + echo null_dict == null # true + echo {} == null # false +< +他のコンテナとは異なり、初期化されていない文字列は null と等しくなります。`is` +演算子を使用して、null_string かどうかを判断できます: > + vim9script + var s1: string + var s2 = null_string + echo s1 == null # true - これは想定外 + echo s2 == null # true + echo s2 is null_string # true + + var b1: blob + var b2 = null_blob + echo b1 == null # false + echo b2 == null # true +< +null_ に初期化された変数はすべて、null_ と等しく、また null と等し +くなります。例: > + vim9script + var x = null_blob + echo x == null_blob # true + echo x == null # true +< +初期化されていない変数は通常、null と等しくなります。それはそのタイプによって +異なります: + var s: string s == null + var b: blob b != null *** + var l: list l != null *** + var d: dict d != null *** + var f: func f == null + var j: job j == null + var c: channel c == null + var o: Class o == null + +空に初期化された変数は null_ と同等です。null ではありません: + var s2: string = "" == null_string != null + var b2: blob = 0z == null_blob != null + var l2: list = [] == null_list != null + var d2: dict = {} == null_dict != null + +NOTE: ジョブなどの特殊な変数はデフォルトで null 値になり、対応する空の値はあり +ません。 + ============================================================================== 5. 名前空間、Import と Export diff --git a/en/vim9.txt b/en/vim9.txt index b4a30326a..b246fcbce 100644 --- a/en/vim9.txt +++ b/en/vim9.txt @@ -1,4 +1,4 @@ -*vim9.txt* For Vim version 9.1. Last change: 2023 Dec 09 +*vim9.txt* For Vim version 9.1. Last change: 2024 Jan 12 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1055,8 +1055,11 @@ variable, since they cannot be deleted with `:unlet`. E.g.: > The values can also be useful as the default value for an argument: > def MyFunc(b: blob = null_blob) - if b == null_blob - # b argument was not given + # Note: compare against null, not null_blob, + # to distinguish the default value from an empty blob. + if b == null + # b argument was not given +See |null-compare| for more information about testing against null. It is possible to compare `null` with any value, this will not give a type error. However, comparing `null` with a number, float or bool will always @@ -1257,10 +1260,12 @@ Script-local variables in a |Vim9| script must be declared at the script level. They cannot be created in a function, also not in a legacy function. *:defc* *:defcompile* -:defc[ompile] Compile functions defined in the current script that - were not compiled yet. - This will report any errors found during compilation. - This excludes functions defined inside a class. +:defc[ompile] Compile functions and classes (|class-compile|) + defined in the current script that were not compiled + yet. This will report any errors found during + compilation. + +:defc[ompile] MyClass Compile all methods in a class |class-compile|. :defc[ompile] {func} :defc[ompile] debug {func} @@ -1698,6 +1703,155 @@ argument type checking: > Types are checked for most builtin functions to make it easier to spot mistakes. +Categories of variables, defaults and null handling ~ + *variable-categories* *null-variables* +There are categories of variables: + primitive number, float, boolean + container string, blob, list, dict + specialized function, job, channel, user-defined-object + +When declaring a variable without an initializer, an explicit type must be +provided. Each category has different default initialization semantics. Here's +an example for each category: > + var num: number # primitives default to a 0 equivalent + var cont: list # containers default to an empty container + var spec: job # specialized variables default to null +< +Vim does not have a familiar null value; it has various null_ predefined +values, for example |null_string|, |null_list|, |null_job|. Primitives do not +have a null_. The typical use cases for null_ are: +- to `clear a variable` and release its resources; +- as a `default for a parameter` in a function definition, see |null-compare|. + +For a specialized variable, like `job`, null_ is used to clear the +resources. For a container variable, resources can also be cleared by +assigning an empty container to the variable. For example: > + var j: job = job_start(...) + # ... job does its work + j = null_job # clear the variable and release the job's resources + + var l: list + # ... add lots of stuff to list + l = [] # clear the variable and release container resources +Using the empty container, rather than null_, to clear a container +variable may avoid null complications as described in |null-anomalies|. + +The initialization semantics of container variables and specialized variables +differ. An uninitialized container defaults to an empty container: > + var l1: list # empty container + var l2: list = [] # empty container + var l3: list = null_list # null container +"l1" and "l2" are equivalent and indistinguishable initializations; but "l3" +is a null container. A null container is similar to, but different from, an +empty container, see |null-anomalies|. + +Specialized variables default to null. These job initializations are +equivalent and indistinguishable: > + var j1: job + var j2: job = null_job + var j3 = null_job + +When a list or dict is declared, if the item type is not specified and can not +be inferred, then the type is "any": > + var d1 = {} # type is "dict" + var d2 = null_dict # type is "dict" + +Declaring a function, see |vim9-func-declaration|, is particularly unique. + + *null-compare* +For familiar null compare semantics, where a null container is not equal to +an empty container, do not use null_ in a comparison: > + vim9script + def F(arg: list = null_list) + if arg == null + echo "null" + else + echo printf("not null, %sempty", empty(arg) ? '' : 'not ') + endif + enddef + F() # output: "null" + F(null_list) # output: "null" + F([]) # output: "not null, empty" + F(['']) # output: "not null, not empty" +The above function takes a `list of strings` and reports on it. +Change the above function signature to accept different types of arguments: > + def F(arg: list = null_list) # any type of list + def F(arg: any = null) # any type +< +In the above example, where the goal is to distinguish a null list from an +empty list, comparing against `null` instead of `null_list` is the correct +choice. The basic reason is because "null_list == null" and "[] != null". +Comparing to `null_list` fails since "[] == null_list". In the following section +there are details about comparison results. + + *null-details* *null-anomalies* +This section describes issues about using null and null_; included below +are the enumerated results of null comparisons. In some cases, if familiar +with vim9 null semantics, the programmer may chose to use null_ in +comparisons and/or other situations. + +Elsewhere in the documentation it says: + Quite often a null value is handled the same as an + empty value, but not always +Here's an example: > + vim9script + var s1: list + var s2: list = null_list + echo s1 # output: "[]" + echo s2 # output: "[]" + + echo s1 + ['a'] # output: "['a']" + echo s2 + ['a'] # output: "['a']" + + echo s1->add('a') # output: "['a']" + echo s2->add('a') # E1130: Can not add to null list +< +Two values equal to a null_ are not necessarily equal to each other: > + vim9script + echo {} == null_dict # true + echo null_dict == null # true + echo {} == null # false +< +Unlike the other containers, an uninitialized string is equal to null. The +'is' operator can be used to determine if it is a null_string: > + vim9script + var s1: string + var s2 = null_string + echo s1 == null # true - this is unexpected + echo s2 == null # true + echo s2 is null_string # true + + var b1: blob + var b2 = null_blob + echo b1 == null # false + echo b2 == null # true +< +Any variable initialized to the null_ is equal to the null_ and is +also equal to null. For example: > + vim9script + var x = null_blob + echo x == null_blob # true + echo x == null # true +< +An uninitialized variable is usually equal to null; it depends on its type: + var s: string s == null + var b: blob b != null *** + var l: list l != null *** + var d: dict d != null *** + var f: func f == null + var j: job j == null + var c: channel c == null + var o: Class o == null + +A variable initialized to empty equals null_; but not null: + var s2: string = "" == null_string != null + var b2: blob = 0z == null_blob != null + var l2: list = [] == null_list != null + var d2: dict = {} == null_dict != null + +NOTE: the specialized variables, like job, default to null value and have no +corresponding empty value. + ============================================================================== 5. Namespace, Import and Export