hotoolong's blog

プログラムのことやエンジニアリングに関することを記事にしています。

パーフェクトRuby on Rails 【増補改訂版】を読んで

イントロ

パーフェクト Ruby on Rails 【増補改訂版】を読みました。 Rails本の中では異質な量と質ではないかとおもいます。

誰が読むべきか

  • 最近のRailsをキャッチアップしたい方
  • Railsをある程度は長く使っている方
  • よりRailsを理解したい方

Rails初心者の人もRoute, MVC周りの基礎的な理解をしている状態で読むことで理解が進みそうです。 というのも章立てがわかりやすく、掻い摘んで自分がほしい情報を手に入れやすい構成になっているからです。 逆に基本的なところは詳細に記載されてないので別の本などで知識を得るのが良さそうです。

良かったところ

正直たくさんあるのですが、特によかったのは以下になります。

  • Rackに関して
  • Webpacker
  • Early Hints
  • CSP対応
  • ActiveStorage
  • 秘密情報の取扱い方
  • searchkickを使った検索機能
  • RuboCopの活用方法
  • Stimulusの機能説明
  • Docker
  • GitHub Actions

特に秘密情報の取り扱いは過去バージョンからの歴史があるのでまとめられているのがとても参考になりました。
上記にとりあげている内容は自分が持っている知識をアップデートできる内容になっているのでこれから業務でも活かしていけそうです。

記載してほしかったところ

とても質も高い内容がおおくて参考になるのですが、個人的に知りたかったこともありました。

  • APIに関するgemの活用方法
  • GraphQL
  • デバックに関して
  • like文のサニタイズ

APIとしてサーバを立てるケースは少し触れられていたのですが、 jsonapi-serializer を使った serialized 周りの処理に関してあると嬉しかったなとおもいました。 
GraphQLに関しては出てこなかったです。この辺は少し触れてくれるといいのかと思いました。
デバッグに関してもpryもしくはirbでのbindingして実施する方法があると嬉しかったです。
ここまでの3点に関してはgem の機能説明になってしまいそうなので、少し方向性がずれてしまうと感じで外していたのかもしれません。
最後のlike文の記載が 2-2-2 モデル同士のリレーション であったのですが、サニタイズの処理がなかったので追加してほしかったなとおもいました。
随分前に以下のような記事も書いているので気になる方は確認してみてください。
hotoolong.hatenablog.com

総括

すごくボリュームがあるのですが、中身が濃くて参考になる内容が多く読み応えがありました。
あー読むのに時間かかったw
初心者向けではないのは明らかなのですが、Railsの書籍には入門書から先に進むときに見るべき本としてはいい道標になりそうです。
Rails6系になり機能がとても増えているのでキャッチアップできていなかった機能もこれを一読することである程度網羅的に知識を得ることができた本でした。
Rails初心者であっても本書の構成が章によって別々の機能説明になっているのでつまみ食いできて、わからなかったところは飛ばしてわかるようになるまで見ていけば徐々に力がついてきそうだなという内容になっています。
著者の皆様には感謝が大きいです。ありがとうございました。

(11/20~12/1)[Kindle]【インプレスグループ】Kindle本キャンペーン ~ブラックフライデー&サイバーマンデー~

イントロ

今回は11月20日(金)~12月1日(火)にかけてインプレスグループKindle本キャンペーン ~ブラックフライデー&サイバーマンデーが開催されています。
いつものようにpickupしていきます。

pickup

  • Ruby on Rails 6 実践ガイド[機能拡張編] impress top gearシリーズ (¥1,760)

  • スクレイピング・ハッキング・ラボ Pythonで自動化する未来型生活 (技術の泉シリーズ(NextPublishing)) (¥990)

  • レベルアップNode.js (技術の泉シリーズ(NextPublishing)) (¥880)

  • Goプログラミング実践入門 標準ライブラリでゼロからWebアプリを作る impress top gearシリーズ (¥1,870)

  • 実践Firestore (技術の泉シリーズ(NextPublishing)) (¥880)

  • Docker実践ガイド 第2版 impress top gearシリーズ (¥2,090)

  • CentOS8 実践ガイド [システム管理編] impress top gearシリーズ (¥1,980)

  • はじめての人のための Terraform for AWS (技術の泉シリーズ(NextPublishing)) (¥990)

  • 実践Terraform AWSにおけるシステム設計とベストプラクティス (技術の泉シリーズ(NextPublishing)) (¥1,210)

  • RustではじめるOpenGL (技術の泉シリーズ(NextPublishing)) (¥880)

  • 実践入門 Kubernetesカスタムコントローラーへの道 (技術の泉シリーズ(NextPublishing)) (¥880)

  • 解体kubeadm フェーズから読み解くKubernetesクラスタ構築ツールの全貌 (技術の泉シリーズ(NextPublishing)) (¥990)

  • これでできる!はじめてのOSSフィードバックガイド 「つよいエンジニア」になるための実績の育て方 (技術の泉シリーズ(NextPublishing)) (¥990)

  • 1週間でPythonの基礎が学べる本 (¥1,320)

1週間でPythonの基礎が学べる本

1週間でPythonの基礎が学べる本

  • 実践Helm─自作アプリをKubernetesクラスタに簡単デプロイ! (技術の泉シリーズ(NextPublishing)) (¥1,100)

  • ラズパイとEdge TPUで学ぶAIの作り方 (技術の泉シリーズ(NextPublishing)) (¥880)

  • Python機械学習ライブラリ scikit-learn活用レシピ80+ impress top gearシリーズ (¥2,145)

  • Machine Learning実践の極意 機械学習システム構築の勘所をつかむ! impress top gearシリーズ (¥1,870)

  • やさしく学べるWeb Components (技術の泉シリーズ(NextPublishing)) (¥880)

  • mruby/cの小さな世界 (技術の泉シリーズ(NextPublishing)) (¥880)

  • 個人開発をはじめよう!クリエイター25人の実践エピソード (技術の泉シリーズ(NextPublishing)) (¥990)

まとめ

インプレスグレープはIT系の書籍も多く、最近のトレンドの本が多いのでとても参考にしています。
積読が増え気味ですが少しずつ読んでいきます。
他の書籍が気になる方はこちらのリンクからどうぞ!

Krisp を使ってみた

リモートでの会議が多くなり、Google Meets, Zoom, Discord を使う機会が徐々に増えてきました。 リモートで会議をしながらタイピングをしているケースもあり、 相手のキーボードの打刻音が煩わしく感じたり、 自分の打刻音が相手にどれくらい不快にさせるのかが気になったりしていました。

そこで打刻音などをフィルターしてくれるツールが無いかと調べていたらKrispがありました。

krisp.ai

マイクとスピーカーのノイズのON/OFFを設定することができます。

2週間ほど使っていますが、かなり快適に使えています。 こちらの打刻音もそこまで大きな音にならずに聞こえてるようです。

無料で利用することができるのですが、 1週間120分の制約があり少し試す程度であればいいと思います。

以下のURLから登録すると1ヶ月無料で利用することができます。 https://ref.krisp.ai/u/u098838e52

打ち合わせでタイピングしてもとても快適に参加することができます。 よかったら試してみてください。

よい、リモートライフを!

vimのプラグインマネージャをdein.vimに変更しようとして読み込めないプラグインがある?

イントロ

現在vim-plugを使っています。 プラグインが増えてきて遅延させてロードを対応したこともあったんですけど、 設定が必要なプラグインの場合ロード前に設定がエラーなるようなケースもあり、 deinに乗り換えることにしました。

github.com

以前もdeinを使っていたのですが、vim-plugに移行して、戻ろうとしています。 以前はtomlファイルで管理していなかったのですが、非同期で読み込みませるため、tomlで管理することにしました。

dein.vim の設定

dein.vim は 非同期にプラグインの設定を読み込むことができるのでドキュメントを読みながら設定をしていきました。 以前使っていたときにはtomlファイルで管理していなかったのですが、今回はtomlファイルで管理してみようかと思います。

hookの複数設定

hookを複数設定することはできそうです。 hook_add と hook_source を設定して遅延して読み込みたいものは後で読み込ませることは出来ました。 同じhook(例えば hook_addとhook_add)を設定すると後勝ちになります。 誤って設定して場合には気をつける必要があります。

depends の振る舞い

ドキュメントを確認すると以下のようになっています。

depends      (List or String)
        Specify a list of plugins a plugin depends on.
        List items are '{plugin-name}'.
        Those specified in the list are NOT installed automatically.
        Note: The loading order is not guaranteed in non lazy plugins.

注:レイジーでないプラグインでは、ロード順序は保証されません。 とあります。

tomlファイルをlazy 0と1の2ファイルを用意しました。

私は使わなかったのですが、
ドキュメントを読んでいるとlazyはNumberで設定できるので2以上でも設定できそうです。

以下が用意した設定です。

  call dein#load_toml('dein.toml',      {'lazy': 0})
  call dein#load_toml('dein_lazy.toml', {'lazy': 1})

呼び出すプラグインは dein.tomlにA,Bというプラグインを 呼び出す設定をして hook_add で コメントを出力しました。 上から順番に呼ばれることが予想されるのでB,Aの順にプラグインを記載しています。 同じくdein_lazy.tomlにC,Dというプラグインを呼び出す設定をしてコメントを出力しています。 こちらも同様にD,Cの順に記載しいます。

BのdependsにAを DのdependsにCを設定しました。

この状態でどのような順序で呼ばれるのかを確認してみました。

B hook_add
A hook_add
D hook_add
C hook_add

という順で呼び出されました。 記述順に呼び出されています。 hook_addはdependsに影響しないようです。

AからDのプラグインにhook_sourceを追加してみました。

B hook_add
A hook_add
D hook_add
C hook_add
A hook_source
B hook_source

lazyでないファイルのA,Bはhook_sourceが呼び出されていますが、 lazyなファイルのC,Dは呼び出されませんでした。

ドキュメントを確認すると

dein#end() の後、または VimEnter で autoloadされるようです。

非遅延型プラグインの hook_source は使用できません。
必要に応じてdein#call_hook() で呼び出す必要があります。

ということでした。

dein#call_hook('source')

を明示的にconfigに記載することで呼び出すことができます。 ドキュメントを見ると、 on_eventがあり

on_event (String) or (List)
        dein will call |dein#source()| on the events.

設定することでsourceが呼べるそうです。

先程 呼びだされなかったCとDに

on_event = 'CursorMoved'

を設定してカーソルを移動してみます。

B hook_add
A hook_add
D hook_add
C hook_add
A hook_source
B hook_source
A hook_source
B hook_source
C hook_source
D hook_source

何故かA,Bのhook_sourceが2回呼ばれています。
初回のA,Bのhook_sourceは何も設定しないでdein#end()の後に呼び出されるもので、
その後ろのA,B,C,Dのhook_sourceはカーソル移動させたときによばれるようです。
設定されてるhook_sourceは何度も呼ばれるかもしれないです。
とりあえずこれで設定が呼び出されることはわかりました。

on_ft の振る舞い

次にon_ftです。 ドキュメントを見てみましょう。

on_ft        (List) or (String)
        If it is matched to 'filetype', dein will call
        |dein#source()|.

ファイルタイプを設定することで呼び出されるようです。
先程のA,B,C,Dにon_ftを設定してみます。

今回はrubyを設定してみます。

一旦jsファイルを開いてみます。

B hook_add
A hook_add
D hook_add
C hook_add
A hook_source
B hook_source
A hook_source
B hook_source
C hook_source
D hook_source

すべてのhookが呼び出されました。

rubyファイルを呼び出してみます。

A hook_add
B hook_add
C hook_add
D hook_add

予想では逆の挙動になるかと思ったのですが、
rubyファイルでhook_sourceが呼ばれなくなりました。
lazyではないA,Bのhook_sourceも呼ばれなくなりました。
lazy側のC,Dのon_eventとバッティングしてるのか気になったので一旦外して
再度rubyファイルを確認してみました。

B hook_add
A hook_add
D hook_add
C hook_add
A hook_source
B hook_source

A,Bのhook_sourceは呼ばれるようになりました。 jsファイルも確認してみたのですが同様の結果になりました。
on_ft と on_event で挙動がおかしくなるのかもしれないです。

on_ftを設定している場合はhook_addに設定を記載するほうがいいかもしれないです。

on_idle の振る舞い

先程のon_eventを設定していましたが、 on_idleを設定するのが便利そうです。

on_idle      (Number)
        If set to non-zero, dein will call |dein#source()| on
        |FocusLost| or |CursorHold| autocmd.
        Note: This is deprecated option.  You should use
        |dein-options-on_event| instead.

on_idle を設定すると FocusLost CursorHold のイベントで dein#source() が 呼び出されるようです。 イベントを設定するよりもこのオプションでカバーできそうです。

上手くいかないこと

いろいろ試しながらわかったこともはあるのですが、 スニペットが上手く動かなくなってしましました。 調べてみたのですが、よくわからない状態です。

lazyでのhook_source

lazyに high-moctane/asyncomplete-nextword.vimリポジトリを設定して

[[plugins]]
repo = 'high-moctane/asyncomplete-nextword.vim'
depends = ['asyncomplete.vim']
on_idle = 1
hook_source = '''
call asyncomplete#register_source(asyncomplete#sources#nextword#get_source_options({
  \   'name': 'nextword',
  \   'whitelist': ['*'],
  \   'args': ['-n', '20'],
  \   'completor': function('asyncomplete#sources#nextword#completor')
  \   }))
'''

このような設定をしていたのですが、

[dein] Error occurred while executing hook: asyncomplete-nextword.vim
[dein] Vim(call):E117: 未知の関数です: asyncomplete#sources#nextword#get_source_options

ファイル読み込み時にエラーになってしまいました。 検証していたようにhook_addであれば先に読み込まれるのでhook_source を hook_addに変更してみたのですが、 同様のエラーになりました。 plugins自身のfunctionなのですが、参照出来ない状態になりました。 asyncomplete-nextword.vim は上手く読み込まれないのかもしれないです。

scriptnamesを確認するとasyncomplete-nextword.vimは含まれてなさそうです。

filter /async/ scriptnames

で関連する

'prabirshrestha/asyncomplete.vim'
'prabirshrestha/async.vim'

が読み込まれているか確認してみると

 50: ~/.cache/dein/.cache/init.vim/.dein/plugin/async.vim
 51: ~/.cache/dein/.cache/init.vim/.dein/plugin/asyncomplete-lsp.vim
 52: ~/.cache/dein/.cache/init.vim/.dein/plugin/asyncomplete.vim
167: ~/.cache/dein/.cache/init.vim/.dein/autoload/asyncomplete.vim
168: ~/.cache/dein/.cache/init.vim/.dein/autoload/asyncomplete/utils/_on_change/textchangedp.vim
169: ~/.cache/dein/.cache/init.vim/.dein/autoload/asyncomplete/sources/ale.vim
192: ~/.cache/dein/.cache/init.vim/.dein/autoload/gitgutter/async.vim

と出力されているので関連するプラグインは読み込まれていそうです。
自身のプラグインは読み込まれていないので、何かが起因で読み込まれないのかもしれないです。

同様に

[dein] Error occurred while executing hook: asyncomplete-ultisnips.vim
[dein] Vim:E492: エディタのコマンドではありません: asyncomplete#sources#ultisnips#get_source_options

とエラーになっています。 こちらは関連するプラグインが以下の通りで 'SirVer/ultisnips'
'honza/vim-snippets'

filter /snip/ scriptnames

プラグインが見つからなかったので読み込まれてないようです。

他の影響があるかもしれないので以下のプラグインを読み込むだけの設定ファイルを作ってみました。

[[plugins]]
repo = 'Shougo/dein.vim'

[[plugins]]
repo = 'SirVer/ultisnips'

これをlazy 0 で読み込んで確認してみました。

call dein#load_toml('dein_test.toml', {'lazy': 0})

この設定でファイルを開いて

filter /snip/ scriptnames

再度scriptnamesで確認してみるとプラグインは見つかりませんでした。 読み込まれるプラグインと読み込まれないプラグインがあるかもしれないです。

ちなみにキャッシュファイル配下にはSirVer/ultisnipsのディレクトリは存在しているので読み込みに時に何かあるやもしれません。

*追記* UltiSnips.vimリポジトリ名とvimファイル名が異なっていた為、scriptnamesで確認できました。

~/.cache/dein/.cache/init.vim/.dein/plugin/UltiSnips.vim

まとめ

一旦ここまで移行してきたのですが、
vimデバッグする方法がわからなさすぎるので、どうすればいいかわからない状態です。
解決方法が分からない場合はまたvim-plugに戻して動かそうかとも思います。 私にはdein.vimは早すぎたのか、vimで嵌って時間が取られるケースがとても増えてきているので、VSCodeに移行時期かもしれません。
vimって難しいですね。

*追記*

Shougoさんに確認いただけてプラグインの読みこみはされている状態でした。
現状自分が設定している環境でhook_sourceでプラグインが上手く読み込まれてないことは確認出来ている状態なので、
時間があるときに最小構成で確認していこうかと思います。

参考にしたサイト

https://www.youtube.com/watch?v=B6rhg9uAWi8 https://qiita.com/kawaz/items/ee725f6214f91337b42b https://qiita.com/delphinus/items/cd221a450fd23506e81a

fish shellのprompt_pwdを少し改造する

イントロ

日々fish shellを使っているのですが、
プロントの表示を変更したくなりました。 ただ、単純には変更できなかったのでカスタマイズしてみました。 というお話です。

一般的なやり方

fish shell で プロンプト を変更する場合は以下のコマンドを打ちます。

fish_config

ブラウザが起動して設定を選択することでプロンプトを変更できます。
選択して好きな設定にできます。

fish.rubikitch.com

変更した点

例えば以下のディレクトリで作業していた場合

/Users/hotoolong/.ghq/github.com/hotoolong/translate.nvim

変更前のプロンプトの表示は以下になります。(私の設定の場合)

~/.g/g/h/translate.nvim (master|✔) $ 

これでもいいのですが、 現在作業しているディレクトリと親のディレクトリも省略しないで表示してほしいのです。

なぜなら、githubディレクトリ構造だとオーナー名/リポジトリ名 になっているため、 自分が作業しているディレクトリがどのリポジトリ配下のかというのいちいちチェックしたくなかったからです。

ということで
いろいろ調べてみたのですが、
デフォルトでは省略されている名称のサイズは変更可能なのですが、
ディレクトリだけ省略を変更するようなオプションは見受けられませんでした。

ちなみに 省略名称のサイズを3に変更したい場合はconfigに以下のように設定します。

set -g fish_prompt_pwd_dir_length = 3

こうすることで

~/.ghq/git/hot/translate.nvim (master|✔) $

というように表示されます。
これはこれで便利ですが、やはり親ディレクトリもフルで表示されてほしい。

プロンプトで表示しているディレクトリ情報は prompt_pwd で取得できます。
コードは以下にあります。

https://github.com/fish-shell/fish-shell/blob/master/share/functions/prompt_pwd.fish

prompt_pwd の内容はfish_prompt_pwd_dir_length 以外の 変更できないようです。
そこで関数を上書きしてみました。

最後の処理が省略して表示している処理になります。

string replace -ar '(\.?[^/]{'"$fish_prompt_pwd_dir_length"'})[^/]*/' '$1/' $tmp

この処理を変更して

set -l folders (string split -rm2 / $tmp)
echo (string replace -ar '(\.?[^/]{'"$fish_prompt_pwd_dir_length"'})[^/]*/' '$1/' $folders[1]'/')$folders[2]'/'$folders[3]

として/の右2つ分を取得してそれ以前のデータは既存のように省略データにしてつなぎ合わせています。
こうすることで

~/.g/g/hotoolong/translate.nvim (master|✔) $

となりました。 これで少し作業が捗りそうです。

Neovim用の翻訳プラグインを作った

イントロ

DeepLなどで翻訳が比較的簡単にできるようになっているのですが、
vimから離れずに翻訳したいと思いプラグイン入れてみるとNeovimに対応されてなかったのがプラグインを作ろうと思ったきっかけです。

ただ、よく調べると同様のプラグインは既にあり、
それを使えばよかったのですが勉強の為、作ることにしました。

使い方

リポジトリは以下にあり、興味がある方は使ってください。

github.com

訳したい行で以下のコマンドで翻訳してくれます。

:Tranclate

翻訳した範囲を選択しても同様に翻訳できます。

まとめ

完全に個人用に作成していますが、
機能変更なの要望があればお待ちしています。

(9/28-10/14)[Kindle] Kindle本 プライムデーセール インプレスグループ

イントロ

今回は 9月28日(月)~10月14日(水)にかけてプライムデーセール インプレスグループが開催されています。
いつものようにpickupしていきます。

pickup

  • 個人開発をはじめよう!クリエイター25人の実践エピソード (技術の泉シリーズ(NextPublishing)) (¥990)

  • これでできる!はじめてのOSSフィードバックガイド 「つよいエンジニア」になるための実績の育て方 (技術の泉シリーズ(NextPublishing)) (¥990)

  • AWSを使って学ぶ監視設計 (技術の泉シリーズ(NextPublishing)) (¥880)

  • レベルアップNode.js (技術の泉シリーズ(NextPublishing)) (¥880)

  • スターティングgRPC (技術の泉シリーズ(NextPublishing)) (¥880)

  • 迷わない!困らない!レガシーフロントエンド安全改善ガイド (技術の泉シリーズ(NextPublishing)) (¥880)

  • AWS音声活用術!Amazon Connect実践入門 (技術の泉シリーズ(NextPublishing)) (¥880)

  • 雰囲気で使わずきちんと理解する!整理してOAuth2.0を使うためのチュートリアルガイド (技術の泉シリーズ(NextPublishing)) (¥880)

  • 「Auth0」で作る!認証付きシングルページアプリケーション (技術の泉シリーズ(NextPublishing)) (¥880)

  • はじめて学ぶバイナリ解析 不正なコードからコンピュータを守るサイバーセキュリティ技術 (OnDeck Books(NextPublishing)) (¥880)

  • スクレイピング・ハッキング・ラボ Pythonで自動化する未来型生活 (技術の泉シリーズ(NextPublishing)) (¥990)

  • Markdownライティング入門 プレーンテキストで気楽に書こう! (技術の泉シリーズ(NextPublishing)) (¥990)

  • Scratch本格入門 命令機能詳細・プログラミング作法・デバッグがわかる (OnDeck Books(NextPublishing)) (¥880)

  • mruby/cの小さな世界 (技術の泉シリーズ(NextPublishing)) (¥880)

まとめ

インプレスグレープはIT系の書籍も多く、最近のトレンドの本が多いのでとても参考にしています。
積読が増え気味ですが少しずつ読んでいきます。
他の書籍が気になる方はこちらのリンクからどうぞ!