関数の定義

PROCEDURE-FEND
戻値のない自作関数を定義する。
FUNCTION-FEND
戻値のある自作関数を定義する。

関数とは

関数とは、与えられた値をもとに決められた処理を実行しその結果を返す命令のことです。関数には標準関数(組み込み関数)ユーザー定義関数の2種類があります。

標準関数は、UWSCですでに定義されている関数のことです。スクリプト関数に使える関数を載せています。

ユーザー定義関数は、標準関数にない機能を独自に作成した関数のことです。自作関数に作った関数を色々載せています。

関数を使うメリット

内部構造を理解する必要がない

関数は与えられた引数によって結果を返します。そのため関数名と渡す引数さえ理解していればその関数を ブラックボックス として扱うことができます。

以下の例だとcircleArea関数に引数として半径を渡せば円の面積が返ってくることがわかっていれば、円の面積が「半径の2乗×円周率」で求めてるということは理解していなくても利用できることになります。

PRINT circleArea(5)

FUNCTION circleArea(r)
	RESULT = POWER(r, 2) * 3.1415926535
FEND

これは標準関数についても同じです。例えばGETID関数は引数に指定した文字列を含むウィンドウのIDを取得する関数ですが、GETIDがどのようにしてIDを取得しているのかは理解していなくても関数名と引数に何を指定すれば良いのか把握していれば使いこなすことができます。

デバッグ作業が楽になる

プログラミングでは同じ処理を場面が数多くあります。その度に同じコードを書くのは面倒です。コピーアンドペーストすれば簡単ですが、何か変更があった場合すべての箇所で修整をしなければなりません。

例えば、以下の税込み価格を求めるプログラムの場合。

PRINT 100 * 1.10
PRINT 200 * 1.10
PRINT 300 * 1.10

2021年現在消費税率は10%ですが将来税率が上がった場合、「1.10」の部分全て変更しなければなりません。

しかし消費税率を返すtax関数を作っておけば、税率が変わった際はtax関数の値を変更するだけでよくなります。

PRINT 100 * tax()
PRINT 200 * tax()
PRINT 300 * tax()

FUNCTION tax()
	RESULT = 1.10
FEND

この程度であれば手作業ですべて修整しても問題はないですが、プログラムを書く量が増えてくるとどこで何の処理をわからなくなってくるので修整し忘れることも出てきます。関数として作っておけばそういうミスも減らせます。

関数の作り方

戻り値がない場合

PROCEDURE 関数名(引数, …)
	// 処理
FEND

戻り値がある場合

FUNCTION 関数名(引数, …)
	// 処理
	RESULT = 戻り値
FEND

関数名

関数名は自由に付けることができますが、いくつか注意点があります。

  • 先頭に数字・一部の記号使用できない。
  • 予約語は使用できない。
先頭に使える記号
  • @
  • +
  • ^
  • ~
  • |
  • %
  • #
  • &
  • \
  • {
  • }
  • :
  • ]
  • ?
先頭に使えない記号
  • *
  • =
  • <
  • >
  • ,
  • /
  • (
  • )
  • ;
  • [
  • .

以下は先頭に使えない記号を使ったときのエラーメッセージ

式がおかしい or 型が合っていない
  • *
  • =
  • <
  • >
  • ,
  • /
(関数名)がありません
  • (
  • )
  • ;
[ ]内の構文が間違っています
  • [
pplay:List index out of bounds(-1)
  • .
命名規則

変数や関数名を付けるときは以下のいずれかの方法で統一しましょう。当サイトではキャメルケースでプログラムを書いています。

コンスタントケース・スネークケース・ケバブケースは単語間を記号で繋ぎ、その分文字数が長くなってしまうのであまり好きではありません。

コンスタントケース(CONSTANT_CASE)
  • 文字はすべて大文字
  • 単語間はアンダースコア(_)で繋げる
  • 例:GET_ALL_USERS
パスカルケース(PascalCase)
  • 単語の先頭は常に大文字
  • 単語間は詰めて繋げる
  • アッパーキャメルケースともいいます。
  • 例:GetAllUsers
キャメルケース(camelCase)
  • 最初の単語以外の文字の先頭は大文字
  • 単語間は詰めて繋げる
  • ローワーキャメルケースともいいます。
  • 例:getAllUsers
スネークケース(snake_case)
  • 単語はすべて小文字
  • アンダースコア(_)で単語を繋げる
  • 例:get_all_users
ケバブケース(kebab-case)・チェインケース(chain-case)
  • 単語はすべて小文字
  • ハイフン(-)で単語を繋げる
  • 例:get-all-users

関数名に迷った場合、日本語を入力するとネーミングを出力してくれるネーミング | codicを活用しましょう。

関数の呼び出し方

関数は定義しただけでは実行されず、呼び出すことで使うことができます。関数を実行するには以下のように記述します。

関数名()

外部に定義した関数を実行するには、CALL関数で使用する関数を含むファイルを呼び出してから「関数名()」と記述します。CALL関数で呼び出すファイルは 絶対パス でも 相対パス どちらで指定しても大丈夫です。

以下は「D:\Programs\UWSC\FUNCTIONS.uws」に定義した「tax関数」を呼び出す例。

CALL D:\Programs\UWSC\FUNCTIONS.uws

PRINT tax()

定義されていない関数を呼び出そうとすると、「関数: (関数名) がありません」とエラーが表示されます。

引数

値渡し

引数として変数などを指定する際、その値のみを渡す方法のこと。渡された引数の値を変更しても呼び出し元の変数の値は更新されません。

以下のプログラムの場合、「1」が出力されます。

DIM i = 1
increment(i)
PRINT i

PROCEDURE increment(n)
	n = n + 1
FEND

参照引数

引数として変数などを指定する際、変数を共有する渡し方のこと。仮引数に対する操作がそのまま実引数に反映されます。

以下のプログラムの場合、「2」が出力されます。

DIM i = 1
increment(i)
PRINT i

PROCEDURE increment(Var n)
	n = n + 1
FEND

実引数・仮引数

DIM a = 1
DIM b = 2

PRINT calcAdd(a, b)

FUNCTION calcAdd(x, y)
	RESULT = x + y
FEND

実引数

実引数とはその関数を実際に使用するときに関数に引き渡される引数のことです。上記プログラムではcalcAdd関数を呼び出すときの引数a,bが実引数です。

仮引数

仮引数とは関数定義時に使用される引数のことです。上記プログラムではcalcAdd関数の引数x,yが仮引数です。

デフォルト引数

デフォルト引数とは、引数に初期値を設定する機能のことです。関数を呼び出すときに、引数を指定していればその値が使用され、引数が省略された場合はデフォルト値が代わりに使用されます。デフォルトパラメータ以降に通常引数を書く事はNG。

例えば、GETID関数を自分で書くとすれば以下のような感じになります。

GETID( タイトル, [クラス名, 待ち時間秒, MDI子タイトル] )
FUNCTION GETID(title, class = NULL, waitTime = 0, mdiTitle = NULL)
	処理
FEND

タイトルは必須だが、クラス名・待ち時間秒・MDI子タイトルは必須ではなく、省略することができます。待ち時間秒はデフォルトの値が0なので「waitTime = 0」となります。これで値が指定されたときはその値、省略されたときは「0」が代入されます。

関数を定義する位置

自作関数は メインルーチン の最後に記述します。以下のように途中に記述すると「abc」は出力されますが、「123」は出力されません。

PRINT “abc”

PROCEDURE func()
	…処理…
FEND

PRINT “123”

以下のように記述すると「abc」も「123」も出力されます。

PRINT “abc”
PRINT “123”

PROCEDURE func()
	…処理…
FEND