Slide 1

Slide 1 text

Ruby as Shell script Gotanda.rb#58 2024-04-24 - Hayato Kawai (@fohte)

Slide 2

Slide 2 text

あなた誰 名前: @fohte (ふぉーて) 川井 颯人 (Hayato Kawai) 所属: ウォンテッドリー株式会社 趣味: 🎮 🎹

Slide 3

Slide 3 text

シェルスクリプト 書いてますか?

Slide 4

Slide 4 text

シェルスクリプト つらい

Slide 5

Slide 5 text

シェルスクリプトはつらい ● nc コマンドが OS によって 若干違う ○ 条件分岐の嵐 https://speakerdeck.com/fohte/ rubocop-daemon-li-hua-oss-noku-nao

Slide 6

Slide 6 text

Ruby で書こう

Slide 7

Slide 7 text

シェルスクリプトを書きたくなる場面 ● 一度しか使わないが、やや複雑な処理 ○ e.g. 何かを集計するバッチ ● 日常的なタスクの自動化 ○ e.g. Git hooks、リポジトリ固有の処理 (初期セットアップなど)

Slide 8

Slide 8 text

シェルスクリプト (bash) はここがつらい ● コマンドに環境差異がある ○ よくある例: sed コマンドは macOS でも BSD 版/GNU 版で動作が異なる ■ デフォルトでは BSD 版、gnu-sed を入れていると GNU 版

Slide 9

Slide 9 text

シェルスクリプト (bash) はここがつらい ● syntax が難しい ○ if [ -n "${1:-}"]; then … ■ -n 🤔 ● !$1.empty? と同じ ■ ${1:-} 🤔 🤔 ● defined?($1) ? $1 : '' と同じ

Slide 10

Slide 10 text

シェルスクリプト (bash) はここがつらい ● ハマりどころが多い ○ よくある例: 途中でコマンドが失敗しても処理が続行される ■ set -eo pipefail しよう、みたいなお作法はあるが、知らないとハマる ○ 未定義変数を参照してもエラーにならない ■ set -u すれば解決するが、 …

Slide 11

Slide 11 text

Ruby で書けば解決! ● コマンドに環境差異がある => Ruby のメソッドや標準ライブラリを使おう ● syntax が難しい => Ruby は平易 (ですよね?) ● ハマりどころが多い => Ruby なら慣れてる (人も多いと思いたい)

Slide 12

Slide 12 text

Ruby で簡単なスクリプトを書くときのお作法 お作法はたった 2 つ ● shebang (#!/usr/bin/env ruby) を書こう ● bundler/inline を使おう

Slide 13

Slide 13 text

shebang (#!/usr/bin/env ruby) を書こう ● #!/usr/bin/env ruby をファイルの 1 行目に書く ○ 簡単にいうと「Ruby で実行する」という定義になる ■ #!/bin/bash なら Bash、#!/usr/bin/env python なら Python

Slide 14

Slide 14 text

shebang の何が嬉しいのか ● ruby script.rb みたいに書かなくても ./script だけで実行できるようになる ○ (script というファイル名 & ファイルに実行権限がある前提 ) ○ 実行する人にとって、「そのスクリプトが何で実装されているのか」を 意識しなくて良くなる ● Git hooks も Ruby で実装できる ○ 例えば pre-commit は .git/hooks/pre-commit というパス ○ Ruby で書いて shebang 書いてこのパスに置けば良い

Slide 15

Slide 15 text

bundler/inline を使おう ● よくあるケース: Ruby スクリプトの中からも gem を使いたい! ○ 例: Faraday 使いたいな… ● そんなときに便利なのが bundler/inline

Slide 16

Slide 16 text

gem 使いたいときに簡単なのは gem install ● 一番簡単なのは gem install すること ○ gem install ではシステム全体に gem をインストールする ○ require で読み込めるようになる ● ただし他の環境で実行できなくなる ○ 実行前に gem install しておく必要がある

Slide 17

Slide 17 text

そこで bundler/inline が便利 ● bundler/inline を使えば解決!

Slide 18

Slide 18 text

bundler/inline の便利なところ ● 実行時に bundle install される ○ Gemfile 不要 ○ gem がなければインストールされるし、あればされない ○ 実行時に gem があることが保証される ■ gem install しておく必要がなくなる ● 記法は Gemfile と同じ

Slide 19

Slide 19 text

余談: コマンドライン引数を定義したい ! optparse が便利 (標準ライブラリ) https://docs.ruby-lang.org/ja/latest/library/optparse.html