セクション

section-document とは、複数の名前付き式で構成される M プログラムです。

section-document:
      section
section:
      literal-attributesopt
sectionsection-name;section-membersopt
section-name:
      identifier
section-members:
      section-member section-membersopt
section-member:
      literal-attributesopt
sharedopt section-member-name=expression;
section-member-name:
      identifier

M では、セクションは、関連する式のドキュメント内での名前付けとグループ化を可能にする組織概念です。 各セクションには、section-name があります。これにより、セクションが識別され、セクション内で宣言された section-members の名前が修飾されます。 section-member は、member-nameexpression で構成されます。 セクション メンバー式は、同じセクション内の他のセクション メンバーを、メンバー名によって直接参照する場合があります。

section-document の例を次に示します。

section Section1; 

A = 1;                          //1
B = 2;                          //2 
C = A + B;                      //3

セクション メンバー式は、section-access-expression を使用して、他のセクション内にあるセクション メンバーを参照する場合があります。これにより、含まれるセクションの名前でセクション メンバー名が修飾されます。

section-access-expression:
      identifier
!identifier

次の例は、相互参照するセクションを含む 2 つのドキュメントのセットを示しています。

section Section1; 
A = "Hello";                    //"Hello" 
B = 1 + Section2!A;             //3

section Section2; 
A = 2;                          //2 
B = Section1!A & " world!";     //"Hello, world"

セクション メンバーは、必要に応じて shared として宣言される場合があります。これにより、含まれるセクションの外部の共有メンバーを参照するときに、section-access-expression を使用するための要件が省略されます。 外部セクション内の共有メンバーは、参照セクション内で同じ名前のメンバーが宣言されておらず、かつ類似する名前の共有メンバーを持つ他のセクションがない限り、その非修飾メンバー名によって参照される場合があります。

次の例は、同じドキュメントのセット内のセクション間で使用されているときの共有メンバーの動作を示しています。

section Section1;  
shared A = 1;        // 1 

section Section2; 
B = A + 2;           // 3 (refers to shared A from Section1) 

section Section3; 
A = "Hello";         // "Hello" 
B = A + " world";    // "Hello world" (refers to local A) 
C = Section1!A + 2;  // 3

同じ名前の共有メンバーを異なるセクション内に定義すると、有効なグローバル環境が生成されます。ただし、その共有メンバーにアクセスすると、アクセス時にエラーが発生します。

section Section1; 
shared A = 1; 

section Section2; 
shared A = "Hello"; 
 
section Section3; 
B = A;    //Error: shared member A has multiple definitions

section-document のセットを評価するとき、次が当てはまります。

  • section-name は、グローバル環境内で一意である必要があります。

  • セクション内では、各 section-member が一意の section-member-name を持つ必要があります。

  • 複数の定義を持つ共有セクション メンバーでは、共有メンバーにアクセスすると、エラーが発生します。

  • section-member の式コンポーネントは、セクション メンバーにアクセスする前に評価することはできません。

  • section-member の式コンポーネントの評価中に発生したエラーは、外側に反映される前にそのセクション メンバーに関連付けられ、セクション メンバーにアクセスするたびに再び発生します。

ドキュメントへのリンク

M セクション ドキュメントのセットは、セクション ドキュメントの共有メンバーごとに 1 つのフィールドを持つ不透明なレコード値にリンクされます。 共有メンバーの名前があいまいな場合は、エラーが発生します。

結果のレコード値は、リンク プロセスが実行されたグローバル環境で完全に閉じられます。 したがって、そのようなレコードは、M ドキュメントの他の (リンクされた) セットから M ドキュメントを構築するのに適したコンポーネントとなります。 名前付けの競合が起こる可能性はありません。

標準ライブラリ関数である Embedded.Value を使用すると、再利用された M コンポーネントに対応する "埋め込み" レコード値を取得できます。

ドキュメント イントロスペクション

M では、#sections および #shared のキーワードを使用して、グローバル環境にプログラムでアクセスできます。

#sections

#sections 組み込み変数は、グローバル環境内のすべてのセクションをレコードとして返します。 このレコードは、セクション名によってキー指定されます。各値は、セクション メンバー名でインデックス付けされた対応するセクションのレコード表現です。

次の例は、2 つのセクションで構成されるドキュメントと、そのドキュメントのコンテキスト内の #sections 組み込み変数を評価することで生成されるレコードを示しています。

section Section1; 
A = 1; 
B = 2;  

section Section2;
C = "Hello"; 
D = "world"; 
 
#sections 
//[ 
//  Section1 = [ A = 1, B = 2], 
//  Section2 = [ C = "Hello", D = "world" ] 
//] 

#sections を評価するとき、次が当てはまります。

  • #sections 組み込み変数によって、ドキュメント内のすべてのセクション メンバー式の評価状態が保持されます。
  • #sections 組み込み変数は、未評価のセクション メンバーの評価を強制しません。

#shared

#shared 組み込み変数は、グローバル環境のコンテンツをレコードとして返します。 (グローバル環境は、すべての共有セクション メンバーと、式エバリュエーターによってグローバル環境に直接含まれる識別子で構成されます) このレコードは識別子名でキー付けされ、各値は関連付けられた識別子の値になります。

次の例は、2 つの共有メンバーを持つドキュメントと、そのドキュメントのコンテキスト内の #shared 組み込み変数を評価することで生成される、対応するレコードを示しています。

section Section1;
shared A = 1; 
B = 2; 
 
Section Section2;
C = "Hello";
shared D = "world"; 
 
//[ 
//  A = 1, 
//  D = "world" 
//] 

#shared を評価するとき、次が当てはまります。

  • #shared 組み込み変数には、グローバル環境の評価状態が保存されます。

  • #shared 組み込み変数は、未評価値の評価を強制しません。