Hammerspoonが不調の時はLuaのGCを疑うべし

ここ最近 Hammerspoon を触っていて、少しハマったことがあったので共有します。Hammerspoon は設定ファイルをLua で記述しますが、Lua にはGC(Garbage Collection) の機能があって、GC の結果回収してほしくないものまで回収されてしまい、キーバインド等が効かなくなってしまうことがあります。

init.lua でグローバル変数として保持しないとGCされる

事の発端はissue1103 にて確認できます。 また、公式のGetting Started Guideにも記載があります。 「A quick aside about variable lifecycles」の内容のとおりなのですが、init.lua の中で作成したオブジェクトは、グローバル変数(localとつけない変数)に代入しておかないとGC で回収されちゃうよ、ということらしいです。

実例

まずは駄目な例。 上記コードは、左 Command 単発押しで「英数」ボタンがおされたことにする、右コマンド単発押しで「かな」ボタンが押されたことにするというものです。ご存知英かな の動作です。High Sierra で英かなが動かないという情報を耳にしたので、Hammerspoonで代替するコードを書いていました。 hs.eventtap.new で作成されたオブジェクトをグローバル変数に代入せず、そのまま start を呼んで開始しています。このままでもひとまず動きますが、そのうちLua のGC が走って動かなくなります。 正しくは下記 一旦グローバル変数に代入しておきます。これでGCされることはなくなります。全文はGithubにあげてます ので詳細はそちらを確認してください。

GCが起きても問題ないかを確認する方法

LuaのGCが発生するタイミングは予測できないですが、GCを強制的に発生させる方法があります。init.lua を読み込んだ直後にGCを発生させてから動作確認をすることで、GCが起きても問題ない設定になっているかを確認できます。 やり方は Hammerspoon のメニューからコンソールを起動し、入力欄に collectgarbage() と打ち込むだけです。

最後に

Hammerspoon 楽しいです。とりあえずこれさえ動けばキーバインド系は大体解決できそう。 SlackとSkypeが Enter で改行せずに送信してしまう問題も Hammerspoon で解決できたので、良ければそちらもご覧ください。
最後まで読んでいただきありがとうございます。 このブログを「いいな」と感じていただけましたら、Twiter にてフォローいただけるとうれしいです。ブログ更新情報などもお届けします。



りゅーた
フリーランスのエンジニアしてます。Android、iOS アプリの開発、対向サーバの開発、C/C++のライブラリ開発が現在のメイン。趣味はテニス・ゲーム・自転車。2児の父

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA