とあるDTPオペレーターのInDesignスクリプト備忘録

デザイナー上がりですがいまはDTP命。InDesign用スクリプトの解説などを綴っています。読者登録して戴けると励みになります。

【入門者向け⑫】関数(呼出先)から関数(呼出元)へ値を戻す

今回は、関数間で「値を戻す」方法を書きます。
前回、関数間で「値を渡す」方法は書きましたね。

似ているように思えますが、その違いはこうです。

関数を呼び出した側 →→値→→ 呼び出された関数(値を渡す
関数を呼び出した側 ←←値←← 呼び出された関数(値を戻す

下の行が「値を戻す」です。こうして戻された値は「戻り値」とか「返り値」と呼びます。
戻り値と返り値を区別する場合もあるようですが、英語ではどちらも「return value」と呼ぶそうなので、単なる訳し方の違いみたいです。

それでは、前回も使用したスクリプトを使って、戻り値の説明をします。
まずは前回使ったスクリプトをそのまま転載。

[例1]東京本店関数から渡された「soup」の中身をアラート
/////本部/////
tokyoHonten ();//東京本店関数を呼び出し

/////東京本店関数/////
function tokyoHonten  () {
    var men = "麺";
    var soup = "スープ";
    var chashu = "チャーシュー"
      oomiyaTen (men,soup,chashu);//大宮店関数を呼び出し
}

/////大宮店関数/////
function oomiyaTen (men,soup,chashu) {
        alert (soup);//引数として受け取ったsoupの中身をアラートで表示
    }


前回の説明で、東京本店の関数内で宣言した変数は、引数に入れることで別な関数(大宮店)に渡せることが分かりましたね。
変数のみならず、引数にすれば値をそのまま渡したり、計算式なんかも渡すことができます。

それではこの逆をしたいとき、つまりデータを「戻したい」ときはどうするのか?
前回やったように引数にすれば渡せそうですが、すると大宮店関数が一度は東京本店関数を呼び出さなくてはなりません。

すると東京本店関数の処理まで実行されてしまいます。
東京本店関数内には大宮店を呼び出す処理があり、大宮店関数には東京本店を呼び出す関数ができるので、たがいを呼び出し合う無限ループになってしまいますね。

なので処理をさせることなく単に呼び出し元に値だけを渡したい(戻したい)ときは、別の書き方をしなくてはならなそうです。無限ループだけが戻り値を使う理由ではないですが。

それでは「大宮店」に新メニューの「担々麺」が登場したという設定でこの先の説明をします。
新メニューとして宣言された担々麺という「値」を、東京本社に戻し、東京本社が本部へ戻します。
少しでもスッキリさせるために、前回の説明で使用した麺、スープ、チャーシューはなくします。

[例2]大宮店から戻ってきた「tantanMen」の中身をアラート
var newMenu = tokyoHonten ();//……⑤
alert ("本部 "+ newMenu);

function tokyoHonten  () {

      var newMenu = oomiyaTen ();//……③
	alert ("東京本店 " + newMenu)
	return newMenu;//……④
}

function oomiyaTen () {
    var tantanMen = "担々麺";//……①
	alert ("大宮店 " + tantanMen)
      return tantanMen;//……②
    }

alertで受け取った戻り値の中身を表示するさいに、どこが出してるアラートか分かるように表示元の関数名を頭に付けています。
エリア名ごとに担々麺が3回表示されれば成功です。順番に説明します。

① 大宮店は新メニューの担々麺を、tantanMenという変数名で宣言しました。これを呼び出し元の東京本部に戻り値として渡す必要があります。
② 呼び出し元へ値を戻す方法は、関数の終わりに「return 戻したい値」を付けます。「return」だけだと単に関数を終わらせ、呼び出し元に処理を返す働きがありますが、その後ろに戻したい値を付ければ、処理だけでなく値も返してくれるというわけです。
③ 東京本店が大宮店から戻り値を受け取るためには、大宮店関数を呼び出すときに「var 変数名 = 呼び出したい関数()」というかたちで変数宣言します。すると変数名に戻り値が入ります。このときの変数名は、戻り値の変数名と揃える必要はありません。[例1]を見ても、大宮店が「tantanMen」という変数を戻しているのに、東京本店は「newMenu」という変数名で受け取っています。
④ 東京本店は本部へnewMenuを戻り値として渡します。
⑤ 本部はnewMenuを戻り値として受け取ります。

処理を無理矢理終わらせて呼び出し元へ処理を移行できるreturnメソッドはそれ単体でも便利で、例えばループでスクリプトがぐるぐる回っていてもreturn文で処理をぶった切ることができます。
無限ループしそうな関数(本来作っちゃだめですが)内で「if(i>100){return}」(適当)みたいなif文を追加すれば、ちょっとした安全装置にもなります。

それでは、もし大宮店が新メニューを複数(担々麺、回鍋肉、炒飯、魯肉飯)作ってしまい、それを東京本部へ全て渡さなきゃいけない場合はどうでしょう?
その場合の渡し方が次です。ためしに3番めの炒飯と4番めの魯肉飯は変数ではなく、値で返してみます。

[例3]大宮店関数から渡された「newMenu」の中身をすべてアラート
var newMenu = tokyoHonten ();
 for(ver i=0; i<newMenu.length; i++) {
    alert ("本部 "+ newMenu[i]);
}

function tokyoHonten  () {
      var newMenu = oomiyaTen ();
 for(ver i=0; i<newMenu.length; i++) {
    alert ("東京本店 "+ newMenu[i]);
}
	return newMenu;//呼び出し元の本部へ戻す
}

function oomiyaTen () {
    var tantanMen = "担々麺";
  var hoikoro = "回鍋肉";
      return [tantanMen,hoikoro,"炒飯","魯肉飯"];//呼び出し元の東京本店へ戻す
    }

この書き方で、4つのデータをいっぺんに戻すことができます。4つの新メニューが2回ずつ、計8回アラートされれば成功です。

複数の値を戻すときは、「return [値1,値2,値3…]」といった形で書きます。この[]見覚えがありますよね。そう、配列です。この書き方をすれば、「配列」として戻すことが出来るのです。
受け取る側は普通に変数で受け取れば、勝手に配列変数にしてくれます。とても気が利きますね。

関数は奥が深く、ここで書ききれないことがまだまだあります。
そもそも「書いてることがよく分からないよー。使いみちはもっと分からないよー」という方は必要になるまでは無理に覚えなくていいかもです。
少なくとも私は、「引数? 戻り値? 何それうまいの?」状態で1年以上誤魔化せていたので…

☆この記事が気に入った方は「★」を押して戴けると大変励みになります…