見出し画像

GASで自作ライブラリの関数が全く動作しないキミへ(Google Apps Script)

備忘録ともいいます。あまりにトラップ過ぎて全然気づかず3時間を無駄にしたので、共有して他の人の役に立てればと思います。

対象

この記事にたどり着いた人はこんな人だと思います。

  • 自作GASライブラリを作ってデプロイして公開するところまでは行った

  • 関数が全く他のシートから呼び出せず泣いている

またはこんな人だと思います。

  • これから自作GASライブラリを作りたい

どちらの人にもお役に立てます。一方、以下の特徴を持つ人には無用の記事ですのでUターンしてください。

  • 令和になって未だにvarとか使ってる人

本題

結論から言うと、ライブラリとして使わせたい関数は

function test(){
  console.log('Goodbye World');
}

のように書いてください。決してカッコつけて

const test = () => {
  console.log("This function can't be called")
}

と書いてはいけません。

経緯

自作GASを作っていました。

完璧なスクリプトができた!ローカルでの動作確認もバッチリです。

→せや!このスクリプトをスタンドアロンにして配布したろ!

→沼る

こんな感じです。
具体的にどう沼ったのかは以下に述べます。

ライブラリのデプロイ・読み込み自体は成功した

ライブラリ自体はバッチリ読み込んでました。

エラーがないことが確認済みのスクリプトが動かなかった

明らかにおかしいですよね。

すでにライブラリ化したいスクリプトにいろんな処理が入っており、複雑だった

思い当たる原因は無数にあります。外部のライブラリを導入したのが原因か、ライブラリの作り方を間違えたか、全く特定に進みません。

入力補完が働いた

例えば上の例のライブラリ名を「TestLib」にしたとしましょう。
これをライブラリとして導入します。成功。

次にこれを右のスクリプトエディタで呼び出してみます。
「T」と入れると「TestLib」と勝手に補完してくれます。
「TestLib.t」と入れると「TestLib.test() method」と保管してくれます。しかもご丁寧に「これはメソッドですよ~~~~~」といってくれています。親切。
明らかに正常に読み込めているのです。

でも返ってくるのは無慈悲な「TestLib.test() is not a function」。意味がわかりません。

console.logでライブラリ関数の中身を調べたら「{}」になった。

この記号はその時の私の気分をよく表しています。

試しに適当なライブラリを別に作ってみたら動いた

中身が

function test(){
  console.log('Goodbye World');
}

だけのライブラリを作成し、導入して実行しました。普通に動きました。なんでや。

最後にどうなったか

「適当なライブラリ」に実際のスクリプトの一部(関数の中身)をコピペして試してみたら、普通に動きました(エラーは出ましたが、is not a functionではないのでセーフです)。

今度は関数全文をコピペしました。
すると途端に動かなくなるのです。

ほとんど中身は一緒なのになぜ????と思いながらCtrl+ZとYを交互に連打していると…関数の宣言方法が違う

const test = () => {}からfunction test(){}にしてみよう…動いた

つまるところ、悪かったのは関数の中身でもなんでもなく、単にfunctionで関数を宣言していなかったことだったことが判明したのです。

ちなみにconstで動かないのは発見しましたが、varのアロー関数で動くかどうかはわかりません。後で試して追記するかもしれません。

追記:varだったら動いた

なんと、varだったら動きました。

var test = () => {
  console.log('Good morning World');
}

constやletはローカルスコープという性質があります。詳しい内部処理はよくわからないのですが、十中八九その仕様が原因だと思っています。

varが推奨されてconstが推奨されないの、GASぐらいじゃないでしょうか。ほんとに。

これを見つけるためだけに3時間を使いました。時間返せ。マジで。

結論

Googleが全て悪いです。

じゃなかった。
つまり、ライブラリとして配布するときは普通にfunction()またはvarのアロー関数で宣言してください。そうじゃないと痛い目を見る、という話でした。

GASってJavaScriptに超そっくりですし、constやletなど現代的な機能も使えますが、結局は別物ということがはっきりわかりました。

というかそもそも現代の開発で、function()で宣言するのはナシだと思っているのですが、皆様はいかがでしょうか。是非コメントなどで教えていただければと思います。


この知識が身についたので、GAS付きの面白いスクリプトが配布できそうです。ライブラリを配布するのも面白いかもしれませんね。
どんなものになるかはわかりませんが、いつかお見せできればと想います。

それではこのへんで。よいGASライフを。

noteのサポートは投げ銭のようなもので、月額ではなく一度のみ課金されます。 この記事が役に立った、面白いと感じてくださった場合に、サポートしていただけると大変励みになります。