Hama Blog

Hama Blog

主にtech関連の記録

Macのディスプレイ間のマウスカーソル移動をショートカットで実現する (Karabiner-Elements を使用)

概要

以前以下の記事で、MacBook と外部ディスプレイ間 (2画面間) のマウスカーソル移動を AppleScript と Raycast を使ってショートカットでできるようにしたのだが、Karabiner-Elements を使えば簡単にできることに気づいたため、その方法をまとめた。
(※ おそらく3画面間には対応していないかも)

hama-engineer.hatenablog.com

記事執筆時の環境

  • macOS: Ventura 13.5.2

  • Karabiner-Elements: 14.12.0

適用方法

任意のキー1つで対応する方法

※ キー1つに割り当てることはほぼないと思いますが一応紹介。

任意のキーの組み合わせで対応する方法

公式の rule も提供されているかもしれないですが、今回は独自 rule を作成しました。

まず、独自 rule を定義するには以下に json ファイルを用意する必要があります。

/Users/ユーザ名/.config/karabiner/assets/complex_modifications

上記に適当な名前の json ファイルを作成してください。

作成したら以下の内容をコピペしてください。

※ 今回は left_control + 1 でメインウィンドウに、left_control + 2 でサブウィンドウにマウスカーソルがそれぞれ中央に移動できるようにしました。

(適宜、好きなキーの組み合わせに割り当ててください)

{
  "title": "mouse cursor movement between multiple windows [left_control + number key]",
  "rules": [
    {
      "description": "move mouse cursor to 1st window [left_control + 1]",
      "manipulators": [
        {
          "from": {
            "key_code": "1",
            "modifiers": {
              "mandatory": [
                "left_control"
              ]
            }
          },
          "to": [
            {
              "software_function": {
                "set_mouse_cursor_position": {
                  "x": "50%",
                  "y": "50%",
                  "screen": 0
                }
              }
            }
          ],
          "type": "basic"
        }
      ]
    },
    {
      "description": "move mouse cursor to 2nd window [left_control + 2]",
      "manipulators": [
        {
          "from": {
            "key_code": "2",
            "modifiers": {
              "mandatory": [
                "left_control"
              ]
            }
          },
          "to": [
            {
              "software_function": {
                "set_mouse_cursor_position": {
                  "x": "50%",
                  "y": "50%",
                  "screen": 1
                }
              }
            }
          ],
          "type": "basic"
        }
      ]
    }
  ]
}

json ファイルを作成したら、次に Karabiner-Elements の Complex Modifications から Add rule を押してください。

そうすると、表示された画面に先ほど追加した json の rule が新たに追加されていると思います。

該当の rule を個別に Enable もしくは Enable All をしたら適用完了です。

所感

めっちゃ簡単だった。

以前の記事 でも少し触れたように有料アプリもあるみたいだが、Karabiner-Elements (無料)で簡単にでき、しかも好きなキーに割り当てられるため、断然これで十分そう。

Karabiner-Elements ありがたい。。

Railsのform_withヘルパーと素のformタグのネスト(というかHTMLのformタグ自体のネスト)に注意

概要

先日、会社のフロントエンドエンジニアが Rails の view ファイルにモック的なのを書いてくれたのに対して、自分が実装をあてていったときにちょっとハマったのでメモ。

モックでは素の form タグが書かれていたのだけど、それに気づかずに別の箇所に form_with ヘルパーを書いてネストさせてしまったことがあり、期待どおりに submit が走らないことがあった。

(そもそもなぜ既存の form タグとは別の箇所に記述してしまったかは自分でもわからないw)

記事執筆時の環境

結論

form_with ヘルパーと素の form タグをネストしていると、  先(上位)に書いているほうが優先される。

というか、素の form タグ自体、ネストさせると先に書いたほうが優先されるみたいだった。1

なので、素の form タグを先に書くと form_with ヘルパーで自動生成される諸々の属性が反映されない。

form_with ヘルパーが先の場合

テンプレートファイル

(例として Post というモデルを使用)

<%= form_with model: @post, local: true do |f| %>
  <form>
    <div>
      <!-- 何らかの記述 -->
    </div>
  </form>
<% end %>

出力結果

action などの属性が設定されている。

素の form タグが先の場合

テンプレートファイル

<form>
  <%= form_with model: @post, local: true do |f| %>
    <div>
      <!-- 何らかの記述 -->
    </div>
  <% end %>
</form>

出力結果

action などの属性が何もない素の form タグになっている。

(自分はこのパターンで実装してしまい、submit が期待したとおりに動かず地味にハマってしまった)

そもそも素の form タグ自体をネストさせるとどうなるのか

テンプレートファイル

<form class="hoge">
  <form class="fuga">
    <div>
      <!-- 何らかの記述 -->
    </div>
  </form>
</form>

出力結果

Rubyで空配列に対してのArray#all?をtrueにしている理由を調査(考察)

概要

普段 Ruby を使って開発している中で、Array#all? を使うことがちょくちょくあるのだけど、空配列のときに true になるのがちょっと違和感があった。

とはいえ、all?? (boolean を返すもの) なので、true/false を返す必要があるが、false を返すのもなんか違和感はある。

なので、true にしている理由を調査(考察)してみた結果をまとめる。

記事執筆時の環境

結論

自分なりの考察

  • 他の言語でもほぼそうなっているから。(元も子もない、Ruby より新しい言語もあるし。。)

  • 空集合(くうしゅうごう)の性質1Vacuous truth の概念に従っているから。(空集合は高校数学で習ったらしい、全然覚えていない。。)

※ 興味本位で調べてみたものの、正直自分には難しかったので、途中で理解を諦めました🙇‍♂️

(一応) ChatGPT に聞いてみた結果

わかるような、わからないような。。

なぜ違和感を感じたか

Array#any? では、空配列のときに false になるから。

irb(main):001:0> [].all?(&:hoge?)
=> true
irb(main):002:0> [].any?(&:hoge?)
=> false

調べたこと

公式ドキュメント

https://docs.ruby-lang.org/ja/3.1/method/Array/i/all=3f.html

すべての要素が真である場合に true を返します。偽である要素があれば、ただちに false を返します。

ブロックを伴う場合は、各要素に対してブロックを評価し、すべての結果が真である場合に true を返します。ブロックが偽を返した時点で、ただちに false を返します。

要素の数が 0 である配列に対しては true を返します。

他の言語ではどうなのか

※※※

使ったことのない言語もあり、特に細かく見たわけではないため間違っている可能性はあります🙇‍♂️

※※※

思いつく限りの言語を調べた中では、PHP 以外は true を返すことがわかった。

言語 関数 空配列のときの結果 公式ドキュメント
C# Array.TrueForAll true Link
Elixir all?/2 true Link
Java Stream.allMatch() true Link
JavaScript Array.prototype.every() true Link
Kotlin all() true Link
Perl all() true Link
PHP array_reduce null
(initial が指定されていない場合)
Link
Python all() true Link
Rust Iterator::all() true Link
Scala forall() true Link
Swift allSatisfy() true Link

Elixir と Kotlin でなぜ true にするのかの説明があった

  • Elixir

    https://hexdocs.pm/elixir/Enum.html#all?/2

    In an empty enumerable there is no element for which fun returns a falsy value, so the result must be true. This is a well-defined logical argument for empty collections.

    (Google 翻訳) 空の列挙可能値には fun が false 値を返す要素がないため、結果は true になる必要があります。これは、空のコレクションに対する明確に定義された論理引数です。

  • Kotlin

    https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/all.html

    Note that if the array contains no elements, the function returns true because there are no elements in it that do not match the predicate. See a more detailed explanation of this logic concept in "Vacuous truth" article.

    (Google 翻訳) 配列に要素が含まれていない場合、述語に一致しない要素が配列中にないため、関数は true を返すことに注意してください。この論理概念の詳細な説明は、「空虚な真実」の記事を参照してください。

調査して思ったこと

空集合とか全然覚えていなかったし、今もちゃんと理解していない。(ので色々間違ってたらすみません)

興味本位で調べたらそれなりに深いところまで理解する必要があったが、今回はそこまでの元気がなかったため、ふわっとした記事になってしまった。

そもそも空配列に対して Array#all? の結果を気にしないといけないような実装がおかしい気もしている。

RailsアプリケーションをDokkuにデプロイする

概要

個人開発しているサービスを Heroku で運用していたのだが、無料プランが 2022/11/28 (だいぶ前)に終了したのもあり、いつか別の環境に変更しようと思っていた。

Heroku の代替サービスとなるものは色々な記事でまとめられているが、個人的に Dokku (オープンソースで提供されている PaaS) がよさそうだったので、今回は VPS + Dokku 環境にデプロイしてみた。

Dokku 自体は無料で利用できるので、VPS のレンタル先次第で Heroku より安く運用できる。

自分は Heroku で Redis も使用していた関係で $8/月 かかっていたが、今回は ConoHa で VPS をレンタルして Heroku より安く済んだ。

(1年プランにしたのもあって、月500円くらいになった)

記事執筆時の環境

手順

VPS の契約

Dokku は UbuntuDebian 上にインストールする必要がある1 ため、それらが使える環境を用意する。

今回は料金が安かったので、ConoHa の VPS をレンタルしてみた。

Dokku のドキュメントによると、メモリは1GB以上必要2 なので以下を選択した。
※以下は記事執筆時点の料金なので自分が契約したときよりちょっと高くなっていた。

https://www.conoha.jp/vps/?btn_id=top--commonHeader_vps-top

OS は Ubuntu の 22.04 (64bit) を選択した。

サーバー作成時のオプションで SSHキーの作成、登録も同時にできるので、ここであわせてやっておくと楽だった。

Dokku のインストール

VPS が用意できたら、Dokku のドキュメントに従いインストールする。

https://dokku.com/docs/getting-started/installation/#installing-the-latest-stable-version

wget https://dokku.com/install/v0.30.3/bootstrap.sh
sudo DOKKU_TAG=v0.30.3 bash bootstrap.sh

上記の実行に10分くらいかかった。

完了後、SSHキーを登録する。

cat ~/.ssh/authorized_keys | dokku ssh-keys:add admin

グローバルドメインの設定 (dokku domains:set-global) では IP アドレスを指定することも可能らしいが、今回はお名前.comで独自ドメイン (この記事内では example.com と呼ぶことにする) を取得してみたので、それを使う。

dokku domains:set-global example.com

Rails アプリケーションのデプロイ

これも基本的に Dokku のドキュメントに従えばよい。

https://dokku.com/docs/deployment/application-deployment/

ローカル環境で、デプロイしたいリポジトリをクローンする。

git clone https://github.com/[your_user_name]/[your_repository_name]

今度は SSH 接続したサーバー上でアプリの登録をする。(今回は rails-sample-app という名前で進めます)

dokku apps:create rails-sample-app

次に DB のインストールをする必要があるが、PostgreSQL を使っているならドキュメントのとおり進めればいけるはず。

sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git

dokku postgres:create railsdatabase

dokku postgres:link railsdatabase rails-sample-app

もし MySQL を使っているなら、上記の代わりに以下のようにする。

sudo dokku plugin:install https://github.com/dokku/dokku-mysql.git mysql

dokku mysql:create railsdatabase

dokku mysql:link railsdatabase rails-sample-app

再度、ローカル環境に戻り、クローンしたリポジトリディレクトリで以下を実行する。

git remote add dokku dokku@example.com:rails-sample-app
git push dokku main:master

git push 時に DB 未作成によるエラーが出るようであれば、ローカルで以下を実行後に再度 git push する。

※ ローカルで dokku コマンドを使うには、dokku-cli 3 をインストールしておく必要がある。

dokku run rails db:create
dokku run rails db:migrate

Dokku のドキュメントだと、これで http://rails-sample-app.example.com に接続できるようになっているが、自分の場合は以下を実行してからでないと接続できなかった。(単に自分がドキュメントに記載された手順を間違えていたり、すっ飛ばしていただけかもしれない)

dokku domains:set rails-sample-app rails-sample-app.example.com

※ この後に再デプロイ (dokku ps:rebuild rails-sample-app) が必要だったかもしれない。

以上で、http://rails-sample-app.example.com に接続でき、Rails アプリケーションを動作するための最低限の対応が完了。

SSL

このままだと http 接続しかできないため、これも Dokku のドキュメントに従えば容易に SSL 化できる。

https://dokku.com/docs/deployment/application-deployment/#setting-up-ssl

dokku certs:add rails-sample-app server.crt server.key

sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git

dokku letsencrypt:set --global email your-email@your.domain.com

dokku domains:set rails-sample-app rails-sample-app.example.com

dokku letsencrypt:enable rails-sample-app

dokku letsencrypt:cron-job --add

これで、https://rails-sample-app.example.com に接続できるようになる。

Redis の設定

もし Sidekiq で非同期処理をして Redis を使っていたら、これも Dokku の公式プラグインを利用すれば容易に対応できる。

https://github.com/dokku/dokku-redis#installation

sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis

dokku redis:create rails-sample-app_redis

dokku redis:link rails-sample-app_redis rails-sample-app

# 再デプロイが必要かも
dokku ps:rebuild rails-sample-app

# Procfile を用意していると思うので、これもデプロイ後に必要(毎回やる必要はないはず)
dokku ps:scale rails-sample-app web=1 worker=1

Cron の設定

定期実行処理をしている場合もドキュメントに従えば容易に Cron を設定できる。

https://dokku.com/docs/processes/scheduled-cron-tasks

リポジトリのルートディレクトリに、以下のような内容で app.json を用意し、dokku に push するとあとは勝手に設定されている。

e.g.

{
  "cron": [
    {
      "command": "rails hoge_batch",
      "schedule": "@daily"
    }
  ]
}
dokku cron:list rails-sample-app
ID                                                                                                   Schedule     Command
[ハッシュ値]                      0 * * * *   rails hoge_batch

Chrome, ChromeDriver のインストール

自分が作成している個人サービスではクローリングもできるようにしているため、Chrome と ChromeDriver も欲しかった。

これについてはネット上の記事が少なく、どうしたら実現できるかわからなかったのだが、ドキュメントを読み込んでいたら herokuish-buildpacks というのが用意されており、Heroku でも使っていた Buildpack がそのまま使えることがわかった。(めちゃくちゃありがたい)

なので、ドキュメントのコマンド例を参考に、以下を実行すればインストールできた。

https://dokku.com/docs/deployment/builders/herokuish-buildpacks

Buildpack を追加する。

# Chrome
dokku buildpacks:add rails-sample-app https://github.com/heroku/heroku-buildpack-google-chrome.git

# ChromeDriver
dokku buildpacks:add rails-sample-app https://github.com/heroku/heroku-buildpack-chromedriver.git

# Ruby
dokku buildpacks:add rails-sample-app https://github.com/heroku/heroku-buildpack-ruby.git

Chrome と ChromeDriver 用の Buildpack を追加すると、ビルド時に Ruby のバージョンが古くなってしまい bundle install でエラーになる可能性があるため、最後に Ruby の Buildpack も追加する。

あとは、インストールした Chrome の同等バージョンを CHROMEDRIVER_VERSION に設定しておく。

dokku config:set CHROMEDRIVER_VERSION=[Chromeと同等のバージョン]

GitHub Actions で自動デプロイ

今後も修正したコードを Dokku 環境に適用したいときは、毎度 git push dokku main:master をしないといけないため、せっかくならと思い、GitHub Actions で自動デプロイも設定してみた。

とてもありがたいことに、こちらもドキュメントが用意されており、ほぼそのまま使えた。

https://dokku.com/docs/deployment/continuous-integration/github-actions

まず、GitHub の該当リポジトリの secrets に好きな名前 (今回はサンプルと同じく SSH_PRIVATE_KEY) で ConoHa の VPS に接続するときの鍵情報を登録する。

https://github.com/[your_user_name]/[your_repository_name]/settings/secrets/actions/new

あとは、該当リポジトリ.github/workflows/deploy-to-dokku.yml とかという名前で以下の内容のファイルを作成し、main ブランチにマージすると自動デプロイができるようになる。

---
name: 'deploy'

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Cloning repo
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Push to dokku
        uses: dokku/github-action@master
        with:
          git_remote_url: 'ssh://dokku@example.com:22/rails-sample-app'
          ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}

所感

Dokku はとにかく便利だった。

日本語の関連記事が少なかったのと、Heroku と違って自分で VPS を用意して CLI で構築していかなければいけなかったので、そこらへんはいろいろと勉強になってよかった。

Macのディスプレイ間のマウスカーソル移動をショートカットで実現する ※環境制約あり

[※ 2023/9/12 追記]

この記事で書いた内容よりももっと簡単に、環境制約もなく実現できる方法があったため、以下で紹介しました。

なので基本的には以下の記事を参照していただいたほうがよいかと思います。

hama-engineer.hatenablog.com

概要

普段、Macbook を外部ディスプレイ1台に接続して使っていて、ディスプレイ間のマウスカーソル移動が地味に面倒だったので、AppleScript と Raycast を使って任意のショートカットキーで移動できるようにしてみた。

個人的には満足なものができたが、環境的な制約があるなどいろいろと課題はあるので気が向いたら対応したい。

AppleScript はドキュメント(Introduction to AppleScript Overview)がわかりにくく、関連記事もあまりなかったのですが、Apple Scriptを使ってマウスカーソルを移動させる : Lunar Eclipse をめちゃくちゃ参考にさせていただきました🙏

記事執筆時の環境

  • ディスプレイの解像度

    • Macbook Pro 2018: 1440 x 900

    • 外部ディスプレイ: 1920 x 1080

  • macOS Monterey: 12.6.5

  • AppleScript: 2.8

  • Raycast: 1.50.2

成果物(適用方法)

  • Raycast の Create Script CommandAppleScript (scpt ファイル) を登録する。

    ※ Template に AppleScript が出てこない場合は、一旦 Bash で作成して、そこから後述の AppleScript を呼び出すようにしてみてもいいかもしれない。

  • 作成された scpt ファイル(meta 情報の下)に以下のコードを貼り付け、DISPLAY_RESOLUTIONS, NEW_MOUSE_LOCATIONS の値を自分用にカスタマイズする。

      use AppleScript version "2.8"
      use framework "AppKit"
    
      set currentMouseLocation to current application's NSEvent's mouseLocation()
      set currentMouseX to x of currentMouseLocation
    
      -- Macbook:          1440 x 900
      -- External Display: 1920 x 1080
      set DISPLAY_RESOLUTIONS to {{1440, 900}, {1920, 1080}}
      set NEW_MOUSE_LOCATIONS to {{720, 380}, {2400, 540}}
    
      set firstDisplayWidth to item 1 of item 1 of DISPLAY_RESOLUTIONS
      if currentMouseX > firstDisplayWidth then
        set displayName to "Display1"
        set newMouseX to item 1 of item 1 of NEW_MOUSE_LOCATIONS
        set newMouseY to item 2 of item 1 of NEW_MOUSE_LOCATIONS
      else
        set displayName to "Display2"
        set newMouseX to item 1 of item 2 of NEW_MOUSE_LOCATIONS
        set newMouseY to item 2 of item 2 of NEW_MOUSE_LOCATIONS
      end if
    
      my moveTo(newMouseX, newMouseY)
    
      on moveTo(newX, newY)
        set point to current application's CGPointZero
        set x of point to newX
        set y of point to newY
    
        current application's CGPostMouseEvent(point, 1, 1, 0)
      end moveTo
    
      -- どのディスプレイに移動しているかわかるように最後に出力
      displayName
    
  • Raycast Preferences - Extensions で Hotkey に任意のキーを割り当てると完了。
    以下は Control + Tab を設定。

  • 以下のように動作する。
    (gif を取るために同一ディスプレイ間での移動にしている)

作った経緯

ディスプレイ間のマウスカーソル移動ができないか探していたところ、一応既存アプリで S2Mouse(有料) とか Multi Display Cursor Jump(有料) で実現できるみたいだったのでとりあえず S2Mouse を入れてみたが、ショートカットキーが固定されているっぽく個人的に困ったので、どうせならと思い今回自作してみた。

AppleScript の解説

set currentMouseLocation to current application's NSEvent's mouseLocation()
set currentMouseX to x of currentMouseLocation


-- Macbook:          1440 x 900
-- External Display: 1920 x 1080
set DISPLAY_RESOLUTIONS to {{1440, 900}, {1920, 1080}}
set NEW_MOUSE_LOCATIONS to {{720, 380}, {2400, 540}}
  • DISPLAY_RESOLUTIONS で自分の環境に合わせて各ディスプレイの解像度を定義する。
    (今回だと別に縦幅はなくてもいい)

  • NEW_MOUSE_LOCATIONS は移動後の座標を好きな値で定義する。



set firstDisplayWidth to item 1 of item 1 of DISPLAY_RESOLUTIONS
if currentMouseX > firstDisplayWidth then
  set displayName to "Display1"
  set newMouseX to item 1 of item 1 of NEW_MOUSE_LOCATIONS
  set newMouseY to item 2 of item 1 of NEW_MOUSE_LOCATIONS
else
  set displayName to "Display2"
  set newMouseX to item 1 of item 2 of NEW_MOUSE_LOCATIONS
  set newMouseY to item 2 of item 2 of NEW_MOUSE_LOCATIONS
end if
  • firstDisplayWidth (メインディスプレイ: 今回だと Macbook の横幅) を基準に currentMouseX (現在のx座標) によってどちらのディスプレイに移動するか決定する。


my moveTo(newMouseX, newMouseY)

on moveTo(newX, newY)
  set point to current application's CGPointZero
  set x of point to newX
  set y of point to newY

  current application's CGPostMouseEvent(point, 1, 1, 0)
end moveTo
  • CGPostMouseEvent 関数を使って指定した座標にマウスを瞬間移動させる。

    • CGPostMouseEvent は Deprecated になっているみたいだが、少なくとも今回の用途では問題なさそうだったのと、推奨されている CGEventCreateMouseEvent の使い方がいまいちわからなかった。

      CGPostMouseEvent | Apple Developer Documentation

      This function is not recommended for general use because of undocumented special cases and undesirable side effects. The recommended replacement for this function is CGEventCreateMouseEvent, which allows you to create a mouse event and customize the event before posting it to the event system.



-- どのディスプレイに移動しているかわかるように最後に出力
displayName
  • 以下のようにマウスが Display1Display2 のどちらにいるかがわかるようにしている。

課題

  • 解像度が変わったらコードも変えないといけない。

  • デュアルディスプレイ、かつ配置が左右でないと使えない。

  • ディスプレイを指定できず、交互にしか移動できない。

  • CGPostMouseEvent 関数が Deprecated になっている。(今回の用途では問題なさそう)

所感

最初はもっと簡単にできそうかと思ったけど、AppleScript は今回初めて触ったのと、あまりドキュメントを読み込まずに作ったので、書き方や使い方の正解がわからないまま妥協して作ってしまった。

心に余裕があるときにまた調べてみようと思う。

あと、JavaScript でも代替できそうだったが、マウスイベントを操作するなら AppleScript のほうがいいのかな〜と思っている。

【随時更新】これまでに読んだ書籍や使った学習教材のリスト

自己満足感を得るために、これまでに読んだことのある書籍や使った学習教材をまとめた。(随時更新していく)

(感想が書けていないものが多々あるので、それも随時更新していく...)

書籍

技術書

カテゴリー タイトル 個人的な満足度 感想
CS 『プロになるためのWeb技術入門』――なぜ,あなたはWebシステムを開発できないのか - -
モデリング かんたん UML入門 [改訂2版] (プログラミングの教科書) - -
モデリング UMLモデリング入門 - -
モデリング オブジェクト指向UIデザイン──使いやすいソフトウェアの原理 - -
設計 プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則 ★★★★★ 各原則の概要が要約されていて、かなり読みやすい。
設計原則についてさらっと学びたいとき、復習したいときによさそう。
あくまで各原則の概要だけなので深く学びたいときは専門書を別途読んだほうがいい。
設計 オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識 - -
設計 ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本 - -
設計 オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 - -
設計 良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方 ★★★★★ 技術書のなかですごく読みやすかった。
たまに読み返したい。
設計 現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法 ★★★★★ 全体的に読みやすい。
設計をちゃんと学びたいときの1,2冊目として最適。
一部、それもあり?となった部分はあったが、すごく学びになることが多く何度も読み返すことになるであろう感じだった。
設計 ドメイン駆動設計 モデリング/実装ガイド ★★★★☆ 題材が題材なだけにやっぱり難しい内容だった。各用語の定義を自分のなかで理解、腹落ちさせたうえで、再度読みたいと思った。あと、各章にあるQ&Aがわかりやすく、ありがたかった。
設計 達人に学ぶDB設計 徹底指南書 - -
設計 楽々ERDレッスン ★★★★★ 構成がいい感じだし、大事な箇所もぱっと目につく感じで、すごく読みやすかった。
身の回りにある題材を使って、実際にどういう風に手をつけていくかが豊富に書いてあって非常にイメージしやすかった。
設計 失敗から学ぶRDBの正しい歩き方 ★★★★★ 全体的に読みやすく、様々なアンチパターンを知るきっかけとなってよかった。
個人的には解決策の部分をもう少し詳細に解説して欲しいところではあった。
コーディング リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック - -
コーディング リファクタリング:Rubyエディション - -
コーディング 改訂2版 パーフェクトRuby - -
SQL 達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ - -
ネットワーク ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識 ★☆☆☆☆ 段落ごとの文章が多く読みづらく、けっこう読み飛ばしてしまった。
ネットワークの知識はある程度持っておかないと読むのはしんどいかもしれない。
ある程度ネットワークの基礎を勉強した後によさそう。
ネットワーク マスタリングTCP/IP 入門編(第6版) ★★★☆☆ 個人的な問題だがネットワークが苦手なので、それを払拭できるほどのわかりやすさはなく、けっこう読み飛ばした。
図解や例がわかりやすいので、その点は読みやすい。
ネットワークの知識をおさらいしたいときによさそう。
テスト 知識ゼロから学ぶソフトウェアテスト 【改訂版】 - -
Rails パーフェクト Ruby on Rails 【増補改訂版】 - -
雑誌 Software Design (ソフトウェアデザイン) 2021年3月号 - -
雑誌 Software Design (ソフトウェアデザイン) - -
Git GitHub実践入門 ~Pull Requestによる開発の変革 - -
Linux 新しいLinuxの教科書 - -
Linux ゼロからわかる Linux Webサーバー超入門 [Apache HTTP Server対応版] ★★★★☆ 基礎中の基礎といった感じで導入本によさそう。
ただ、誤植や説明不足な点がちらほらあったのは少し残念だった。
あとは、Windows向けなので、Macで試す場合はある程度自分で調べる必要がある。
デザイン UIデザイン必携 ユーザーインターフェースの設計と改善を成功させるために ★★★★★ 実在する各サービスを例にしながら、UIの基本について学べる。
デザイナーではない人がUIについて最初に学ぶためのものとしてすごくよさそう。
個人的には、特にCHAPTER5の「分かりやすさ、使いやすさ」が自分が開発をする上で大事にしたいことだったので学べてよかった。
その他 プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ ★★★☆☆ ちょっと難しい表現が多く頭に入ってこない部分はあるが、タイトルにもあるように認知科学に基づくアプローチから、どのような考えを持っておくとよいか勉強になって面白い。

ビジネス書

カテゴリー タイトル 個人的な満足度 感想
一般 イシューからはじめよ――知的生産の「シンプルな本質」 - -
一般 博報堂スピーチライターが教える 5日間で言葉が「思いつかない」「まとまらない」「伝わらない」がなくなる本 ★★★★★ ストーリー仕立てになっているのと、簡潔にまとまっているので、非常に読みやすかった。
各Dayの最後にそこまでで出てきたTipsがまとめられているので、読み返したくなったときもすっと頭に入ってきやすそう。
それに、自分の悩みにけっこう当てはまってありがたい内容だった。
ただ、今の自分の仕事の範囲では、Day1〜Day3だけで十分だと思った。
(Day1〜Day3は全社会人に必要なこと、Day4〜Day5はプレゼンとかを主にしている人向けなのかなと思った)
一般 入門『地頭力を鍛える』 32のキーワードで学ぶ思考法 - -
一般 地頭力を鍛える ★★★☆☆ 冗長な部分が多く読みづらさはあったが、地頭力を鍛えるための基本的な考え方が詳細に学べてよかった。
一般 メタ思考トレーニング 発想力が飛躍的にアップする34問 ★★★★★ メタ思考を鍛えるための考え方と、トレーニング方法がセットになっていて、この本を読むだけでもだいぶ鍛えられそう。
一般 具体と抽象 ★★★★★ 抽象化のメリット、デメリット、使い方、具体とセットで考える、など、すごく学びになった。
一般 「具体⇔抽象」トレーニング 思考力が飛躍的にアップする29問 ★★☆☆☆ 初めて読む分にはいいかもしれないが、上記の「具体と抽象」の後に読んだのと、内容もかなり似通っていたためかなり読み飛ばしてしまった。
一般 思考の質を高める 構造を読み解く力 ★★★★☆ 構造を考えることについては普段から何気なしに意識できていることが多かったが、改めて大事なことだと認識できた。あと、現実世界で色んな人の心情を読み取ることなどの大切さから、そこらへんを鍛えるという目的で小説などの物語を読むのが大事だということを知れたのがすごくよかった。
一般 ダイアグラム思考 次世代型リーダーは図解でチームを動かす ★★★★★ 図解が苦手な人が図解を頑張ろうと思ったときに読むにはちょうどよい内容だと思った。図解の種類とそれぞれの使い時、使い方、コツがまとめられているので、リファレンス的にも使える。それと、章立てや各章の構成も非常に読みやすかった。
IT関連 ITエンジニアのための【業務知識】がわかる本 第5版 ★★☆☆☆ 浅く広くという印象だった。個人的には全体的に難しい箇所が多く、かなり読み飛ばしてしまった。ざっと読んで頭の中にインデックスだけ貼っておいて、必要性を感じたときに辞書的に使うのがよいのかもと思った。
IT関連 システムを作らせる技術 エンジニアではないあなたへ - -
IT関連 現場で困らない!ITエンジニアのための英語リーディング - -
IT関連 武器がないエンジニアは肯定を続けることで武器を手にする。 - -
業務知識 図解即戦力 EC担当者の実務と知識がこれ1冊でしっかりわかる教科書 - -

学習教材

Udemy

カテゴリー タイトル 個人的な満足度 感想
CS もう怖くないLinuxコマンド。手を動かしながらLinuxコマンドラインを5日間で身に付けよう - -
フロントエンド JavaScriptで学ぶWebアプリ開発の必須知識〜Node.js・Web API・Ajax・async/await〜 - -
フロントエンド フロントエンドウェブ開発の無料チュートリアル - 現役エンジニアのためのWebpack環境構築入門 with Babel|Sass|Eslint - -
フロントエンド 【2023年最新】React(v18)完全入門ガイド|Hooks、Next.js、Redux、TypeScript - -
フロントエンド フロントエンドエンジニアのための React アプリケーション開発入門 2018年版 - -
フロントエンド 【Next.js入門】ReactフレームワークのNext.jsでマイクロブログを構築しながら基礎と本質を学ぶ講座 - -
フロントエンド 超Vue.js 2 完全パック (Vue Router, Vuex含む) - -
フロントエンド [2022年決定版] Vue3 x Typescriptによるアプリケーションづくり - -
インフラ AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得 - -
Git Git: もう怖くないGit!チーム開発で必要なGitを完全マスター - -
Vim 現役シリコンバレーエンジニアが教える NeoVim(VIM) + Tmux + Zsh 入門 ★★★★★ Vimを使いたいと思っている人がきっかけとして最初に観るのにちょうどよさそうな内容だった。自分はこの動画をきっかけにVImを本格的に使い始めることになった。

その他

カテゴリー タイトル 個人的な満足度 感想
- Ruby on Rails チュートリアル:プロダクト開発の0→1を学ぼう - -

コマンド履歴から任意の文字列に該当する履歴を削除するコマンドを自作した

概要

普段 zsh を使っているが、Ctrl + r でコマンド履歴から過去のコマンドを呼び出したいときに、タイポなどで実行してしまった不要な履歴が候補に含まれてしまうのが邪魔だった。

なので、それらを個別にキーワード指定して削除できるコマンドを自作してみた。(.zsh_history に対して sed コマンドを実行するのをちょっと楽にしただけ)

成果物

#!/bin/sh
#
# .zsh_history から指定した文字列が含まれる行を削除
#
# params:
# $1: コマンド履歴に含まれるキーワード
#

# sed コマンドは区切り文字が / なので、キーワードに含まれる / はエスケープする
TARGET_KEYWORD=${1//\//\\/}
sed -i -e "/$TARGET_KEYWORD/d" ~/.zsh_history

上記を任意のファイルに保存してパスを通せばOK。

自分の場合は delhis というファイル名で保存して、delhis {削除したいコマンド履歴に含まれる文字列} という風に実行できるようにした。

(e.g. delhis hoge と実行すると hoge だけでなく hoge fugahoge/fuga の履歴が削除される)

作った経緯

コマンドを実行するときにタイポだったり、オプションの指定順を間違ってコマンドを失敗させてしまうことがたまにあるので、それらが履歴に出てくるのが嫌だった。

例えば、hoge というコマンドを実行したかったのに、hofe としてしまった場合、次から ho で検索すると hofe まで出てきてしまう。

(以下は Warp のスクショ)

こういうときは無視するか、.zsh_history から該当履歴の行を削除してしまえばいいのだが、簡単に消せればいいのになあと思って、Linux の勉強がてらに自作してみた。

sed コマンドとか使ったことなかったし、シェルスクリプトも作ったことがほとんどなかったので少し勉強になった。


そもそもコマンドが失敗したときは .zsh_history に残らないようにすればいいので(そういうことをしている記事もあったので)、また時間があるときにそこらへんを見てみようと思う。