Rubyのnilガードは未定義の変数にも使うことができた
Ruby(ver. 2.7.2)で次のように未定義な変数に対してnilガードを書いたらNameError
だと思っていたのですが、普通に動きました。
# hogeは未定義な変数 hoge ||= "hogehoge" hoge # => "hogehoge"
nilガードは未定義な変数についても使えるんですね。リファレンスにも書いてありました。
a ||= 1 # a が偽か未定義ならば1を代入。初期化時のイディオムの一種。
調べて分かったこと
私が未定義な変数にnilガードが使えないと勘違いしていたのは、hoge ||= "hogehoge"
== hoge = hoge || "hogehoge"
で、この式の右辺を評価する際にNameError
が起きるかな、と思っていたためです。
# 右辺だけを評価したらエラー hoge || "hogehoge" # => NameError (undefined local variable or method `hoge' for main:Object)
調べていたら、ここで二つの勘違いをしていたことが分かりました。
1. hoge = hoge || "hogehoge"
はエラーにならない
そもそも hoge = hoge || "hogehoge"
は、代入が挟まると最初に変数の初期化が行われるようでエラーになりません。
hoge = hoge || "hogehoge" # => "hogehoge"
2. hoge ||= "hogehoge"
は hoge = hoge || "hogehoge"
ではなくて hoge || (hoge = "hogehoge")
基本的には自己代入式1 op= 式2
は式1 = 式1 op 式2
のように評価されます。
しかし、&&
と||
に限っては式1 op (式1 = 式2)
と評価されるようです。これもリファレンスに記載されていました。
ちなみに、次のコードはエラーになります。
hoge || (hoge = "hogehoge") # => NameError (undefined local variable or method `hoge' for main:Object)
じゃあ hoge ||= "hogehoge"
もエラーになるのでは、と思うのですが、||=
を使った場合は特別に変数の初期化をしてくれているためエラーにならないようでした。
||=
は変数の初期化に関しては1つのトークンとして機能し、未定義により参照に失敗すると、直ちに値の付与に移行します。マネーフォワード社内PRに見られるRubyの書き方について – (4) 真理値 | Money Forward Engineers' Blog
fishシェルでvimのキーバインドを設定するときは`--no-erase`オプションをつける
fishシェルでvimのキーバインドを設定するときは、fish_vi_key_bindings
をfish_user_key_bindings
関数の中に記述します。
このとき、基本的に--no-erase
オプションは付けた方が良いかと思います。
~/.config/fish/functions/fish_user_key_bindings.fish
function fish_user_key_bindings fish_vi_key_bindings --no-erase end
--no-erase
オプションがないとき、fish_vi_key_bindings
が実行されるタイミングでそれより前に設定されていたキーバインドが全てリセットされます(実装されているコード)。
他のプラグインで自動的にキーバインドが設定されている場合、--no-erase
を付けないとそれらも全てリセットされてしまうのでご注意ください。
本日このせいで一部のキーバインドが効かなくなり、少し困りました。
fishシェルのvimキーバインドでEsc以外でインサートモードからノーマルモードに変更する
~/.config/fish/functions/fish_user_key_bindings.fish
でfish_user_key_bindings
に以下のように追記すればOKです。
function fish_user_key_bindings ... fish_vi_key_bindings --no-erase bind -M insert -m default jk force-repaint # 追記 jkでノーマルモードへ end
やっていること
今回設定したもので、インサートモードでjk
が押されたらノーマルモード(default
モード)に変更して、プロンプトの再描画を行う、ということになります。プロンプトの再描画を行わないと、プロンプトに現在のモードを表示している場合に表示されているモードが書き変わりません。
詳細はman bind
もしくはfish-shellのbindのドキュメントをご確認ください。
ちなみにドキュメントにも書かれていますが~/.config/fish/config.fish
の方にカスタムキーバインドの設定を直接書いても動かないのでご注意ください。
neosnippet.vimで次のマーカーにジャンプできない
neosnippet.vimを使ってsnippetを登録して使おうとしたのですが、次のマーカーへのジャンプができませんでした。
とりあえず解決したので、同じような問題に出会う人用に記録を残しておきます。
さいしょに結論
907th/vim-auto-saveというプラグインでInsertLeave
イベントにフックしてオートセーブしているとうまく次のマーカーにジャンプしない。
907th/vim-auto-saveを使っている場合は、READMEを参考にしてg:auto_save_events
にInsertLeave
以外のイベントを指定するか、vim-auto-saveを使わずに、autocmd
を使って自分でInsertLeave
時に保存する設定を定義する。
augroup vimrc-auto-save autocmd! autocmd InsertLeave * w augroup END続きを読む
GASでTimeTreeの今日の予定をLINEに通知する
先日TimeTree(タイムツリー)でAPIを使って予定の取得ができるようになりました。
カレンダーシェアアプリ「TimeTree」の予定取得API公開、Alexaに対応:CodeZine(コードジン)
私は普段TimeTreeを使っているので、Google Apps Scriptを使ってTimeTreeの今日の予定をLINEに送るようにしてみました。
続きを読む