メインコンテンツまでスキップ
バージョン: 18

メソッド

メソッドとは、1つ以上の動作を実行するコードのことです。 4D ランゲージにおいて、2種類のメソッドが存在します:

  • ビルトインメソッド: 4D またはサードパーティーによって提供されるもので、これらをコード内で利用することができます。 ビルトインメソッドには次のものが含まれます:

    • 4D API のコマンドや関数 (ALERTCurrent date など)
    • ネイティブオブジェクトやコレクションに付属しているメンバーメソッド (collection.orderBy()entity.save() など)
    • 4D やサードパーティーによって提供されるプラグインやコンポーネントのコマンド (SVG_New_arc など)

    ビルトインメソッドの詳細については、* 4D ランゲージリファレンス* マニュアルや、プラグイン・コンポーネントの専用マニュアルを参照ください。

  • プロジェクトメソッド: 任意の動作を実行するためにデベロッパー自身が作成するコードのことです。 作成されたプロジェクトメソッドは、そのデータベースの中でランゲージの一部となります。 プロジェクトメソッドは、ステートメントで構成されます。ステートメントとは、メソッドの 1行のことで 1つの命令を実行します。 ステートメントは 1つの命令を実行し、単純な場合もあれば複雑な場合もあります。 各ステートメントは常に 1行ですが最大 32,000文字まで使用することができます。 プロジェクトメソッドは最大 2GBのテキスト、または、32000行まで記述できます。

注: 4D では、データベースイベントやフォームイベントによって自動的に実行されるメソッドも各種提供されています。 特化されたメソッド 参照。

プロジェクトメソッドの呼び出し

その実行方法や使用方法に応じて、プロジェクトメソッドは次のような役割を果たします:

  • サブルーチンと関数
  • オブジェクトの付属メソッド
  • メニューメソッド
  • プロセスメソッド
  • イベントまたはエラー処理メソッド

サブルーチンと関数

サブルーチンは、処理の下請け的なプロジェクトメソッドです。 他のメソッドから呼ばれて、要求された処理を実行します。 関数は、呼び出し元のメソッドに値を返すサブルーチンのことです。

プロジェクトメソッドを作成すると、それは同データベースのランゲージの一部となります。 プロジェクトメソッドは、4Dのビルトインコマンドと同様に、ほかのプロジェクトメソッドや定義済みメソッドから呼び出すことができます。 このように使用されるプロジェクトメソッドをサブルーチンと呼びます。

サブルーチンは、以下のような目的で使います:

  • 重複コードの削減
  • メソッドの役割の明確化
  • メソッド改変の容易化
  • コードのモジュール化

たとえば、顧客データベースがあるとします。 データベースをカスタマイズしていくうちに、顧客を検索してレコードを修正するという一連の作業を繰り返しおこなっていることに気づいたとします。 そのコーディングは以下のようになっています:

  // 顧客を検索します
QUERY BY EXAMPLE([Customers])
// 入力フォームを選択します
FORM SET INPUT([Customers];"Data Entry")
// 顧客レコードを修正します
MODIFY RECORD([Customers])

サブルーチンを使用しなければ、顧客レコード修正のたびにコードを作成しなければなりません。 データベースの 10箇所で同じ処理が必要であれば、同じコードを 10回も書かねばなりません。 サブルーチンを使用すれば 1回コーディングするだけですみます。 これがコーディングの重複を減らすというサブルーチンの第一の利点です。

先ほど説明したコードが MODIFY CUSTOMER と呼ばれるメソッドであるとすれば、他のメソッド内でそのメソッド名を使うことで実行できます。 たとえば、顧客のレコードを修正し、それからレコードをプリントするために、以下のようなメソッドを書くことができます:

 MODIFY CUSTOMER
PRINT SELECTION([Customers])

この機能はメソッドを劇的にに簡素化します。 さきほどの例で言えば、MODIFY CUSTOMER メソッドがどのように動作するかは知る必要なく、何をおこなうかだけ知っていればよいのです。 これはメソッドをサブルーチン化することの2番目の理由、役割の明確化です。 このように、作成されたメソッドは 4Dランゲージを拡張します。

このデータベースの例で顧客の検索方法を変える場合、10箇所ではなく、たった1つのメソッドを変更するだけですみます。 これがサブルーチンを使うもう一つの理由、改変の容易化です。

また、サブルーチンの利用はコードをモジュール化します。 これはコードをモジュール (サブルーチン) に分割することを意味し、それぞれは論理的な処理を実行します。 小切手振り出し口座のデータベースから、以下のコードを見てみましょう:

 FIND CLEARED CHECKS // 決済された小切手の検索
RECONCILE ACCOUNT // 口座の照合
PRINT CHECK BOOK REPORT // レポートの印刷

データベースを知らない人でも、このプログラムが何をしているかはわかります。 各サブルーチンの処理手順を知る必要はありません。 各サブルーチンは長く、複雑な処理で構成されていることもありますが、それらが何を実行するのかだけを知っていれば十分なのです。 プログラムを論理的な処理単位やモジュールにできるだけ分割することをお勧めします。

オブジェクトの付属メソッド

プロジェクトメソッドは、フォーミュラ オブジェクトにカプセル化して、オブジェクトから呼び出すことができます。

Formula または Formula from string コマンドを使用すると、オブジェクトプロパティに格納可能な、ネイティブなフォーミュラオブジェクトを作成することができます: つまり、カスタムなオブジェクトメソッドを実装することが可能です。

オブジェクトプロパティに保存されているメソッドを実行するには、プロパティ名のあとに ( ) をつけます。 例:

// myAlert プロジェクトメソッド
ALERT("Hello world!")

この myAlert プロジェクトメソッドを任意のオブジェクトに格納し、呼び出すことができます:

C_OBJECT($o)
$o:=New object("custom_Alert";Formula(myAlert))
$o.custom_Alert() // "Hello world!" と表示します

大カッコを使用したシンタックスもサポートされます:

$o["custom_Alert"]() // "Hello world!" と表示します

4D プロジェクトメソッドのように、$1, $2, .... を使用して呼び出すことで、フォーミュラに 引数を渡す こともできます:

//fullName メソッド
C_TEXT($0;$1;$2)
$0:=$1+" "+$2

fullName メソッドをオブジェクトに格納し、呼び出します:

C_OBJECT($o)
$o:=New object("full_name";Formula(fullName))
$result:=$o.full_name("John";"Smith")
// $result = "John Smith"
// $result:=fullName("param1";"param2") と同義です

This 関数と組み合わせることで、オブジェクトメソッドを利用した汎用的なコードを書くことができます。 例:

//fullName2 メソッド
C_TEXT($0)
$0:=This.firstName+" "+This.lastName

このメソッドをオブジェクトに格納すると、オブジェクトの新しい計算属性のように使えます:

C_OBJECT($o)
$o:=New object("firstName";"Jim";"lastName";"Wesson")
$o.fullName:=Formula(fullName2) // メソッドをオブジェクトに追加します

$result:=$o.fullName()
// $result = "Jim Wesson"

たとえ引数を受け取らなかったとしても、オブジェクトメソッドを実行するためにはカッコ () をつけて呼び出す必要があるという点に注意してください。 オブジェクトプロパティのみを呼び出した場合、フォーミュラへの新しい参照が返されます (そしてフォーミュラは実行はされません):

$o:=$f.message // $o にはフォーミュラオブジェクトが返されます

メニューメソッド

メニューメソッドは、カスタムメニューから呼び出されるプロジェクトメソッドです。 メニューエディターまたは "メニュー" テーマのコマンドを使用して、メニューにメソッドを割り当てます。 メニューが選択されると、それに対応するメニューメソッドが実行されます。 この手順は、データベースをカスタマイズする主要な方法の一つです。 特定の処理を実行するメニューメソッドを割り当てたカスタムメニューを作成することで、データベースをカスタマイズすることができます。

メニューメソッドにより、単一または複数の処理を実行することができます。 たとえば、データ入力のメニューに、以下の2つの処理を実行するメソッドを割り当てられます。まず適切な入力フォームを表示し、次にユーザーがキャンセルするまでの間 ADD RECORD コマンドによるデータ入力を繰り返します。

連続した処理の自動化は、プログラミング言語の強力な機能の 1つです。 カスタムメニューを使用することで処理を自動化することができ、データベースのユーザーにより多くのガイダンスを提供することができます。

プロセスメソッド

プロセスメソッド とは、プロセスの開始時に呼び出されるプロジェクトメソッドのことです。 ワーカープロセスの場合を除いて、プロセスはプロセスメソッドが実行されている間だけ存続します。 メニューに属するメニューメソッドのプロパティとして 新規プロセス開始 をチェックしている場合、そのメニューメソッドは新規プロセスのプロセスメソッドでもあります。

イベント・エラー処理メソッド

イベント処理メソッド は、イベントを処理するプロセスメソッドとして、分離されたプロセス内で実行されます。 通常、開発者はイベント管理の大部分を 4Dに任せます。 たとえば、データ入力中にキーストロークやクリックを検出した 4Dは、正しいオブジェクトとフォームメソッドを呼び出します。このため開発者は、これらのメソッド内でイベントに対し適切に応答できるのです。 詳細については ON EVENT CALL コマンドの説明を参照してください。

エラー処理メソッド は、割り込みを実行するプロジェクトメソッドです。 エラーや例外が起こる度に、エラー処理メソッドは自身がインストールされたプロセス内で実行されます。 詳細については ON ERR CALL コマンドの説明を参照してください。

プロジェクトメソッドの再帰呼び出し

プロジェクトメソッドは、自分自身を呼び出すことができます。 例:

  • メソッドAがメソッドBを呼び出し、メソッドBはメソッドAを呼び出します。
  • メソッドAは自身を呼び出すことができます。

これは再帰呼び出しと呼ばれています。 4D ランゲージは再帰呼び出しを完全にサポートしています。

次に例を示します。 以下のフィールドから成る [Friends and Relatives] テーブルがあります:

  • [Friends and Relatives]Name
  • [Friends and Relatives]ChildrensName

この例題では、フィールドの値は重複しない、つまり同じ名前の人間はいないとします。 名前を指定することで、以下のような文を作成します: “A friend of mine, John who is the child of Paul who is the child of Jane who is the child of Robert who is the child of Eleanor, does this for a living!”:

  1. この文を以下のように作成できます:
 $vsName:=Request("Enter the name:";"John")
If(OK=1)
QUERY([Friends and Relatives];[Friends and Relatives]Name=$vsName)
If(Records in selection([Friends and Relatives])>0)
$vtTheWholeStory:="A friend of mine, "+$vsName
Repeat
QUERY([Friends and Relatives];[Friends and Relatives]ChildrensName=$vsName)
$vlQueryResult:=Records in selection([Friends and Relatives])
If($vlQueryResult>0)
$vtTheWholeStory:=$vtTheWholeStory+" who is the child of "+[Friends and Relatives]Name
$vsName:=[Friends and Relatives]Name
End if
Until($vlQueryResult=0)
$vtTheWholeStory:=$vtTheWholeStory+", does this for a living!"
ALERT($vtTheWholeStory)
End if
End if
  1. 以下の方法でも作成できます:
 $vsName:=Request("Enter the name:";"John")
If(OK=1)
QUERY([Friends and Relatives];[Friends and Relatives]Name=$vsName)
If(Records in selection([Friends and Relatives])>0)
ALERT("A friend of mine, "+Genealogy of($vsName)+", does this for a living!")
End if
End if

再帰関数 Genealogy of は以下の通りです:

  ` Genealogy of プロジェクトメソッド
` Genealogy of ( String ) -> Text
` Genealogy of ( Name ) -> Part of sentence

$0:=$1
QUERY([Friends and Relatives];[Friends and Relatives]ChildrensName=$1)
If(Records in selection([Friends and Relatives])>0)
$0:=$0+" who is the child of "+Genealogy of([Friends and Relatives]Name)
End if

Genealogy of メソッドが自分自身を呼び出していることに注目してください。

最初に挙げた方法は 反復性のアルゴリズム です。 2番目に挙げた方法は 再帰呼び出しのアルゴリズム です。

前述の例題のようなコードを実装する場合、反復性や再帰呼び出しを使用してメソッドを書くことができるということに留意してください。 再帰呼び出しは一般的に、より明瞭で読みやすく、維持しやすいコードを提供します。ただし、この使用は必須ではありません。

4D内での再帰呼び出しの代表的な使用方法は以下のとおりです:

  • 例題と同じく、互いに関連するテーブル内でのレコードの取り扱い。
  • FOLDER LISTDOCUMENT LIST コマンドを使用して、ディスク上にあるドキュメントとフォルダーをブラウズする。 フォルダーにはフォルダーとドキュメントが含まれており、サブフォルダーはまたフォルダーとドキュメントを含むことができます。

重要: 再帰呼び出しは、必ずある時点で終了する必要があります。 たとえば、Genealogy of メソッドが自身の呼び出しを止めるのは、クエリがレコードを返さないときです。 この条件のテストをしないと、メソッドは際限なく自身を呼び出します。 (メソッド内で使用される引数やローカル変数の蓄積を含む) 再帰呼び出しによって容量が一杯になると、最終的に 4Dは “スタックがいっぱいです” エラーを返します 。

特化されたメソッド

汎用的な プロジェクトメソッド とは別に、4D はイベント発生時に自動的に呼び出される特化されたメソッドをいくつかサポートしています:

自動呼び出しのコンテキスト引数の受け取り説明
オブジェクト (ウィジェット) メソッドメソッドが設定されたフォームオブジェクトに関連したイベント発生時に×フォームオブジェクト (ウィジェットとも呼びます) のプロパティです。
フォームメソッドメソッドが設定されたフォームに関連したイベント発生時に×フォームのプロパティです。 フォームメソッドを使用してデータとオブジェクトを管理することができます。ただし、これら目的には、オブジェクトメソッドを使用する方が通常は簡単であり、より効果的です。
トリガー (別名 テーブルメソッド)テーブルのレコード操作 (追加・削除・修正) の度に×テーブルのプロパティです。 トリガーは、データベースのレコードに対して「不正な」操作がおこなわれることを防ぎます。
データベースメソッド作業セッションのイベント発生時に○ (既定)4D には 16のデータベースメソッドがあります。 詳細はデータベースメソッドの項を参照ください。