4D v14.3

型指定ガイド

ホーム

 
4D v14.3
型指定ガイド

型指定ガイド  


 

 

この節では変数型に生じる矛盾の主な原因と問題を解決するための方法について説明します。

単純なデータ型の矛盾には以下のパターンがあります:

  • 2種類の用途による矛盾
  •  用途とコンパイラコマンドの矛盾
  •  暗黙の型変更による矛盾
  • 2つのコンパイラコマンドによる矛盾

最も単純な型の矛盾は、1つの変数名が2つの異なるオブジェクトを示す場合です。例えば、以下のように書いたとします。

 Variable:=5

また、同じアプリケーションのどこかで次のように書いたとします。

 Variable:=True

この記述は、データ型の矛盾を引き起こします。これはどちらか一方の変数名を変えることで解決できます。

例えば、以下のように書き、

 Variable:=5

また、同じアプリケーション内で、次のように書いたとします。

 C_BOOLEAN(Variable)

コンパイラ指示子が最初に処理されるので、Variableはブール型に設定されますが、

 Variable:=5

というステートメントがあるため、これを型の矛盾と見なします。変数名かコンパイラコマンドのどちらかを変更することで、問題は解決します。

1つの式の中で異なるデータ型の変数を使うと矛盾が生じます。コンパイラはそれを型の不一致として指摘します。簡単な例を紹介します。

 vBool:=True `コンパイラはvBoolをブール型と推測します。
 C_INTEGER(<>vInteger`コンパイラ指示子により整数ととして宣言されます。
 <>vInteger:=3 `コンパイラ指示子と互換のある記述
 Var:=<>vInteger+vBool `この操作は、式に非互換のデータ型が混在している

 

関数の中には戻り値のデータ型が明確に決まっているものがあります。このような関数の戻り値を不注意に異なった型の変数に代入すると、データ型の矛盾が起ります。

例えば、インタプリタで以下のように書いた場合、

 IdentNo:=Request("Identification Number") `IdentNo はテキスト型
 If(Ok=1)
    IdentNo:=Num(IdentNo) `IdentNo は実数型
    QUERY([Contacts]Id=IdentNo)
 End if

この例では、3行目で型の矛盾が生じます。これを解決するためには変数の動作を制御する方法が考えられます。異なる名前の中間変数を作成する必要がある場合や、次の例のようにメソッドの構造を変更することで修正できる場合もあります。

 IdentNo:=Num(Request("Identification Number")) `IdentNo は実数型
 If(Ok=1)
    QUERY([Contacts]Id=IdentNo)
 End if

同じ変数に対して2つの異なるコンパイラ指示子を使用すると、型の再定義になります。例えば、1つのデータベースで次のように書いたとします。

 C_BOOLEAN(Variable)
 C_TEXT(Variable)

この場合、コンパイラによって矛盾が検出され、エラーファイルに出力されます。通常、どちらか一方の変数名を変えることで問題は解決します。

C_STRINGを使用する場合、最大の文字長を変更することでデータ型の矛盾が生じることがあるので、注意してください。例えば、次のように書くと、コンパイラは型の矛盾と見なします。

 C_STRING(5;MyString)
 MyString:="Hello"
 C_STRING(7;MyString)
 MyString:="Flowers"

文字列型の変数を定義する際には、十分なサイズのエリアが必要ですが、デフォルトによりコンパイラは短い方を採用してしまいます。解決するには、文字列に最大値を与えるためのコンパイラコマンドを使用することができます。以下のように書くことができます。

 C_STRING(7;String)
 String:="Flowers"
 String:="Hello"

:以下のようにC_STRING(7; String)を2回記述することは可能です。

 C_STRING(7;String)
 String:="Flowers"
 C_STRING(7;String)
 String:="Hello"

コンパイラは上記の記述を受け入れますが、2番目の指示子は余分です。

ローカル変数におけるデータ型の矛盾は、プロセス変数やインタープロセス変数とほとんど同じものです。唯一の違いは、指定されたメソッドの中のみ型が一貫していればよいという点です。
プロセス変数やインタープロセス変数では、データベースの全体のレベルで型の矛盾が起きましたが、ローカル変数の場合は、メソッドレベルで矛盾が起きます。
例えば、同じメソッドの中で、

 $Temp:="Flowers"

を記述し、さらに

 $Temp:=5

を記述することはできません。

しかし、

 $Temp:="Flowers"

をメソッド1で記述し、

 $Temp:=5

をメソッド2で記述することは出来ます。これは、ロカール変数の有効範囲が同じメソッド内のみであり、データベース全体ではないからです。

型の矛盾に配列の要素数は無関係です。コンパイル前のデータベースと同様、配列も動的に管理されます。配列の要素数はメソッドを通して変更可能で、 配列用に最大値を定義する必要はありません。このため、要素数を0にすることも、追加や消去、もしくは内容の削除を行うことも可能です。

コンパイルを前提にデータベースを作る場合は、以下の原則に従ってください。

  • 配列要素のデータ型を変えないこと
  • 配列の次元数を変えないこと
  • 文字列では、文字の長さを変えないこと

整数として定義された配列は、データベース全体を通して整数配列でなければなりません。データベース内で、ブール型などの要素を使用することはできません。
例えば、

 ARRAY INTEGER(MyArray;5)
 ARRAY BOOLEAN(MyArray;5)

と書いた場合、MyArrayの型を決定できません。どちらか一方の配列名を変える必要があります。

コンパイル前のデータベースでは、配列の次元数を変更することができます。コンパイラでシンボルテーブルを作成す る際、1次元配列と2次元配列は別々に管理されます。このため、1次元配列を2次元配列として、もしくは2次元配列を1次元配列として再定義することはで きません。したがって、同じデータベースの中で以下のように定義することはできません。

 ARRAY INTEGER(MyArray1;10)
 ARRAY INTEGER(MyArray1;10;10)

ただし、同じアプリケーションの中に次のステートメントを書くことはできます。

 ARRAY INTEGER(MyArray1;10)
 ARRAY INTEGER(MyArray2;10;10)

データベース内で配列の次元数を変更することはできませんが、配列のサイズを変更できます。2次元配列の1つの配列のサイズを変更するには次のように書きます。

 ARRAY BOOLEAN(MyArray;5)
 ARRAY BOOLEAN(MyArray;10)

:2次元配列は実際には複数の1次元配列から構成されています。詳細は、の節を参照してください。

文字列には固定長文字列と同じ規則が適用されます。

次のように書いた場合、

 ARRAY STRING(5;MyArray;10)
 ARRAY STRING(10;MyArray;10)

コンパイラにより長さの不一致が検出されます。これは最大の文字列の長さを定義することで簡単に解決できます。短い方の文字列は、コンパイラが自動的に処理します。

コマンドのCOPY ARRAYLIST TO ARRAYARRAY TO LISTSELECTION TO ARRAYSELECTION RANGE TO ARRAYARRAY TO SELECTION、またはDISTINCT VALUESの使用により、データ型の要素、次元数、もしくは文字列や文字の長さが(意図的にもしくは無意識的に)変更されてしまう場合があります。その場合、前に述べた3つの状況のいずれかに該当します。
コンパイラはエラーメッセージを出力します。通常、修正が必要な点は非常に明確です。
暗黙の配列の型変更の例は、の節を参照してください。

ローカル配列(これを生成したメソッドによってのみ見ることができる配列)が含まれるデータベースをコンパイルする場合、使用前に4Dで明示的にこの配列を定義する必要があります。明示的に配列を定義するとは、ARRAY REALコマンドやARRAY INTEGERコマンドなどを使い、配列を定義することをいいます。メソッドにより10要素のローカル整数配列を生成する場合、メソッドの中に次の行が必要です。

 ARRAY INTEGER($MyArray;10)

フォーム内で作成された変数型(例えば、ボタン、ドロップダウンリストボックスなど)は、すべてプロセスもしくはインタープロセス変数です。

インタプリタのデータベースでは、フォーム変数のデータ型は重要ではありませんが、コンパイルされたアプリケーションの場合は重要です。ただし、規則は非常に明確です。

  •  コンパイラコマンドでフォーム変数の型を定義します、もしくは
  • 環境設定(Design Referenceマニュアルを参照)のコンパイルオプションでデフォルト型を割り当てるように設定することができます。

次のフォーム変数は、デフォルトとして実数型として設定されます。

チェックボックス
3Dチェックボックス
ボタン
ハイライトボタン
透明ボタン
3Dボタン
ピクチャボタン
グリッドボタン
ラジオボタン
3Dラジオボタン
ラジオピクチャ
ピクチャメニュー
階層ポップアップメニュー
階層リスト
ルーラ
ダイヤル
サーモメータ

:ルーラ、ダイアルおよびサーモメータのフォーム変数については、例えば環境設定のボタン型に倍長整数を選んだとしても、常に実数型に設定されます。

上記いずれかの変数に対して、データ型の矛盾が起こるとすれば、それは同一の変数名がデータベース内に存在する場合です。この場合は、いずれか1つの変数名を変更してください。

グラフエリアは自動的にグラフ(倍長整数)のデータ型に設定されるので、型の不一致が生じることはありません。もしデータ型の矛盾が起こるとすれば、それは同一の変数名がデータベース内に存在する場合です。この場合は、いずれか1つの変数名を変更してください。

プラグインエリアは常に倍長整数型に設定されるので、型の不一致が生じることはありません。もしデータ型の矛盾が起こるとすれば、それは同一の変数名がデータベース内に存在する場合です。この場合は、いずれか1つの変数名を変更してください。

テキスト型に設定されるフォーム変数は以下のとおりです。

入力不可変数
入力可変数
ドロップダウンリスト
メニュー、ドロップダウンリスト
スクロールエリア
コンボボックス
ポップアップメニュー
タブコントロール

これらの変数は2つのカテゴリーに分類できます。

- 単純変数:入力可、入力不可の変数
- 表示変数:ドロップダウンリスト、メニュー/ドロップダウンリスト、スクロールエリア、ポップアップメニュー、コンボボックスおよびタブコントロール
  • 単純変数
    デフォルトのデータ型はテキストです。メソッドやオブジェクトメソッドで使用される場合は、ユーザが選択したデータ型が割り当てられます。同じ名前で異なる型の変数が存在する場合以外は、データ型の矛盾が起こることはありません。
  • 表示変数
    変数はフォーム内で配列を表示するために使用されます。フォームエディタにデフォルト値が設定されている場合、配列を定義するためのARRAY STRINGコマンドやARRAY TEXTコマンドを使い、対応する変数を明確に定義する必要があります。

ポインタを使うと、4Dツールの強力で多彩な機能を活用することができます。
コンパイル後もポインタの利点をそのまま活用できます。1つの ポインタでデータ型の異なる変数を指定することができます。1つの変数に異なるデータ型を代入して矛盾を引き起こさないようにしてください。また、ポイン タで参照する変数のデータ型を変更しないよう注意してください。
この問題の例を示します。

 Variable:=5.3
 Pointer:=->Variable
 Pointer->:=6.4
 Pointer->:=False

この例では、ポインタで参照する変数の型は実数です。これにブール値を代入しているので、データ型の矛盾が起こります。
1つのメソッド内で、異なった目的のためにポインタを使う場合には、参照先の変数型を決定してください。

 Variable:=5.3
 Pointer:=->Variable
 Pointer->:=6.4
 Bool:=True
 Pointer:=->Bool
 Pointer->:=False

ポ インタは、常に参照するオブジェクトとの関連で定義されています。このため、ポインタによるデータ型の矛盾をコンパイラが検知することはできません。矛盾 があっても、変数設定フェーズやコンパイルフェーズでは、エラーメッセージが出力されません。ただし、ポインタに関係する矛盾を見つける方法がまったくな いわけではありません。コンパイラの環境設定の範囲チェックオプションでポインタの使用状況を確認することができます(詳細はDesign Referenceマニュアルを参照してください)。

コンパイルの際、コンパイラはデータベースで使用されるプラグインコマンドのパラメータの数や型定義などについて解析します。メソッドからのプラグイン呼び出しが、プログラム記述の段階で一致していれば、矛盾が生じる危険はありません。

プラグインは、PlugIns フォルダに入れることでインストールします。フォルダは、4Dに許可されている次のいずれかの場所に置きます。
ス トラクチャファイルと同階層または、Windowsでは実行可能なアプリケーションの隣、またはMacintoshではソフトウェアパッケージ内です。互 換性のためにストラクチャと同階層のWin4DXまたはMac4DXフォルダを使用することも出来ます。詳細はインストールガイドを参照してください。

コンパイラは、これらのファイルを複製しませんが、これらを分析して、これらのルーチンの適切な定義を決定します。
プラグインを見つけることができない場合、コンパイラはファイルを開くダイアログボックスを表示してプラグインの場所を確認します。

特定のプラグイン(例えば4D Write)コマンドの中には、暗黙に4Dコマンドを呼び出すものがあります。例えば4D Writeの場合、WR ON EVENTコマンドのシンタックスは次のようになります。
WR ON EVENT(area;event;eventMethod)

最後の引数は、4Dで作成したメソッドの名前です。このメソッドはイベントが受け取られるたびに4D Writeによって呼び出され、自動的に次の引数を受け取ります。

引数説明
$0倍長整数戻り値
$1倍長整数4D Write エリア
$2倍長整数Shift key
$3倍長整数Alt key (Windows); Option key (Mac OS)
$4倍長整数Ctrl key (Windows), コマンド key (Mac OS)
$5倍長整数イベント型
$6 倍長整数イベント引数の値

コンパイラがこれらの引数の存在を認識し、これらを考慮するためには、引数をコンパイラコマンド、またはメソッド内での使用法によって型設定しなければなりません。メソッドで使用する場合には、型を明確に推測できるように使用する必要がありま
す。

4Dを使い、4Dコンポーネントの作成および管理が可能です。(マトリクスデータベースと呼ばれる) 4Dコンポーネントは一連の4Dオブジェクトで、ストラクチャファイルにいくつかの機能がまとめられています。コンポーネントは他のデータベース (ホストデータベース) にインストールできます。

インタプリタモードで動作するホストデータベースは、インタプリタおよびコンパイル済みのコンポーネントを使用できます。一つのホストデータベース にインタプリタおよびコンパイル済みのコンポーネントを同時にインストールできます。他方、コンパイルモードのホストデータベースは、インタプリタモード のコンポーネントを使用できません。コンパイル済みのコンポーネントのみが使用できます。

インタプリタモードのコンポーネントを含むインタプリタのホストデータベースは、インタプリタモードのコンポーネントメソッドを呼ばない限り、コンパイルできます。もし呼び出している場合は、警告ダイアログが表示され、コンパイルに失敗します。

コンポーネントの共有メソッドがホストデータベースのプロジェクトメソッドと同じ名前の場合、名前の衝突が発生します。この場合、ホストデータベー スのコンテキストでコードが実行される際、ホストデータベースのメソッドが呼び出されます。これはコンポーネントのメソッドをカスタムメソッドでマスクす ることが可能であることを意味します (例えば異なる機能を実装するために)。コンポーネントのコンテキストでコードが実行されるときは、コンポーネントのメソッドが呼び出されます。ホスト データベースをコンパイルする際、このマスクは警告として記録されます。

二つのコンポーネントが同じ名前の共有メソッドを公開している場合は、ホストデータベースのコンパイルの際、エラーが生成されます。

コンポーネントに関する詳細は、Design Referenceマニュアルを参照してください。

ローカル変数の処理はこれまでに述べた規則に従います。他の変数と同様、メソッドの実行中にデータ型を変更することはできません。ここでは、型の矛盾を起こす可能性のある2つのケースについて検証します。

  • 型変更が必要な場合。ポインタの使用によりデータ型の矛盾を避けることができます。
  • 引数の間接参照が必要な場合

変数型を変更することはできませんが、ポインタを使用して異なるデータ型を参照することはできます。例えば、1次元配列 のメモリサイズを返す関数を考えてみてください。この場合、メモリサイズを数字で表せないテキスト配列とピクチャ配列を除き、実数の結果のみを返します(の節を参照してください)。
また、テキスト配列とピクチャ配列については、文字列の結果を返します。この関数の引数は、メモリサイズを調べようとする配列へのポインタです。この操作を行うには2つの方法があります。

  •  ローカル変数のデータ型を気にせずに使用する方法。このメソッドはインタプリタでしか動作しません。
  • ポインタを使用し、インタプリタおよびコンパイルモードで処理する方法。

MemSize機能のインタプリタモードでのみ動作する例(Macintoshを使用する場合の例)

 $Size:=Size of array($1->)
 $Type:=Type($1->)
 Case of
    :($Type=Real array)
       $0:=8+($Size*10) ` $0は実数
    :($Type=Integer array)
       $0:=8+($Size*2)
    :($Type=LongInt array)
       $0:=8+($Size*4)
    :($Type=Date array)
       $0:=8+($Size*6)
    :($Type=Text array)
       $0:=String(8+($Size*4))+("+Sum of text lengths") ` $0はテキスト
    :($Type=Picture array)
       $0:=String(8+($Size*4))+("+Sum of picture sizes") ` $0はテキスト
    :($Type=Pointer array)
       $0:=8+($Size*16)
    :($Type=Boolean array)
       $0:=8+($Size/8)
 End case

このメソッドでは、$0のデータ型が$1の配列によって異なるため、コンパイルできません。

MemSize機能のインタプリタモードおよびコンパイルモードで動作可能なバージョン(Macintoshを使用する場合の例)
これはポインタを使用する方法です。

 $Size:=Size of array($1->)
 $Type:=Type($1->)
 VarNum:=0
 Case of
    :($Type=Real array)
       VarNum:=8+($Size*10) ` VarNumは実数l
    :($Type=Integer array)
       VarNum:=8+($Size*2)
    :($Type=LongInt array)
       VarNum:=8+($Size*4)
    :($Type=Date array)
       VarNum:=8+($Size*6)
    :($Type=Text array)
       VarText:=String(8+($Size*4))+("+Sum of text lengths")
    :($Type=Picture array)
       VarText:=String(8+($Size*4))+("+Sum of picture sizes")
    :($Type=Pointer array)
       VarNum:=8+($Size*16)
    :($Type=Boolean array)
       VarNum:=8+($Size/8)
 End case
 If(VarNum#0)
    $0:=->VarNum
 Else
    $0:=->VarText
 End if

2つの関数は、以下の点が違っています。

  • 1番目の関数では、結果が変数であること
  • 2番目の関数では、結果が変数へのポインタであること。結果はポインタで簡単に参照できます。

コンパイラは、引数の間接参照の機能をサポートしています。インタプリタでは、引数のデータ型と数値を自由に設定でき ます。データ型の矛盾を起こさない限り(呼ばれた側でセットされていない引数を使用しないこと)、コンパイルモードでも同様に自由に設定することができま す。

型の矛盾の元になるので、間接参照する引数は、すべて同じデータ型でなければなりません。

この間接参照は以下の条件を守ることにより、正しく動作します:引数の一部のみを間接参照する場合、直接参照の引数の後に間接参照引数を配置するようにします。

メソッド内で、間接参照は${$i}のように表示します。$iは数値変数です。${$i}を「ジェネリックパラメータ(generic parameter)」と呼びます。

以下は間接参照の例です。数値を合計し、引数として渡されたフォーマットに編集して返すような関数を考えてください。合計される元の数値は、メソッドが呼ばれるたびに変わります。このメソッドでは数値と編集フォーマットを引数としてメソッドに渡さなければなりません。
この関数は、以下のようにして呼び出します。

 Result:=MySum("##0.00";125,2;33,5;24)

この場合、数値を合計し、指定したフォーマットに編集された"182.70"が返されます。関数の引数は正しい順序で渡してください。最初にフォーマット、次に値です。

以下はMySum関数です。

 $Sum:=0
 For($i;2;Count parameters)
    $Sum:=$Sum+${$i}
 End for
 $0:=String($Sum;$1)

この関数は次の方法で呼び出すことができます。

 Result:=MySum("##0.00";125,2;33,5;24)
 Result:=MySum("000";1;18;4;23;17)

他のローカル変数と同様、ジェネリックパラメータはコンパイラに指示する必要はありません。ただし、曖昧になりそうな場合や最適化のために必要な場合は以下のシンタックスを使用することができます。

 C_INTEGER(${4})

このコマンドは、4番目以降に間接参照されたすべての引数のデータ型が整数であることを意味します。$1、$2、$3には、いかなるデータ型も使用できますが、$2を間接参照した場合には影響を受けます。このため、実数であってもデータ型は整数と見なされます。

:コンパイラはこのコマンドを変数設定フェーズで使います。定義に使用する数値は変数ではなく、定数でなくてはなりません。

4Dの変数および定数には、コンパイラによってデータ型および識別子が割り当てられているものがあります。このため、ユーザはこれらの変数名や定数 を、新しい変数やメソッド、関数、プラグインコマンドに使用することはできません。インタリタモードで行うのと同じ方法で、これらの値を検証し使用するこ とができます。

4Dのおよび対応するデータ型の完全なリストを紹介します。

変数
OK倍長整数
Documentテキスト
FldDelimit倍長整数
RecDelimit倍長整数
Error倍長整数
Error methodテキスト
Error line倍長整数
MouseDown倍長整数
KeyCode倍長整数
Modifiers倍長整数
MouseX倍長整数
MouseY倍長整数
MouseProc倍長整数

クイックレポートで計算用のカラムを作成する際、最初のカラムに変数C1を2番目にはC2を、そして3番目のカラムにはC3をというように4Dが自動的に変数を作成します。この処理はユーザには見えません。
これらの変数をメソッド内で使用する場合、他の変数と同様C1、C2...Cnは型変更することができませんので、留意してください。

4Dで定義されている定数は定数テーマリストを使用して見つけることができます。4Dの定数は、デザインモードのエクスプローラーにも表示されます。

 
プロパティ 

プロダクト: 4D
テーマ: コンパイラ

 
参照 

エラーメッセージ
コンパイラ指示子の使用
システム変数
シンタックスの詳細
最適化のヒント

 
ARTICLE USAGE

ランゲージリファレンス ( 4D v12.4)
ランゲージリファレンス ( 4D v14 R2)
ランゲージリファレンス ( 4D v14 R3)
ランゲージリファレンス ( 4D v13.5)
ランゲージリファレンス ( 4D v14.3)
ランゲージリファレンス ( 4D v14 R4)

Parent of : 型指定ガイド ( 4D v11 SQL Release 6)