すずかのプログラミング勉強記

元教員からエンジニアを目指す、プログラミング勉強記録です。

初心者でもわかるRubyのコマンドラインオプション

はじめに

Ruby Silverの勉強をしていた時、Ruby技術者認定試験合格教本に、ruby -cruby -vなどのRubyコマンドラインオプションが出てきました。 面白そうだと思ったので公式リファレンスを確認しましたが、初心者には難易度が高く、量も膨大でした😖

今回は、プログラミング始めたての私でも使えると思ったオプションを5つ紹介します。 文章中に「公式リファレンスの説明」とある場合は、すべてRubyの起動 (Ruby 3.2 リファレンスマニュアル)から引用しています。

実行環境


ruby -hまたはruby --help

どんなオプション?

オプションの一覧を見ることができます。

公式リファレンスの説明: コマンドラインオプションの概要を表示します。

使える場面

すべての始まりはここからです。「Rubyの実行オプションを使いたくなったけどなんだっけ?」という時に使いましょう。

ruby --helpを使うと、ruby -hにない細かいオプションや、詳細なオプションの説明を読むことができます。ただruby -hでも20個以上のオプションが出てくるので、初心者はこちらで事足りると思います。

ruby -hの実行結果

❯ ruby -h
Usage: ruby [switches] [--] [programfile] [arguments]
  -0[octal]       specify record separator (\0, if no argument)
  -a              autosplit mode with -n or -p (splits $_ into $F)
  -c              check syntax only
  -Cdirectory     cd to directory before executing your script
  -d              set debugging flags (set $DEBUG to true)
  -e 'command'    one line of script. Several -e's allowed. Omit [programfile]
  -Eex[:in]       specify the default external and internal character encodings
  -Fpattern       split() pattern for autosplit (-a)
  -i[extension]   edit ARGV files in place (make backup if extension supplied)
  -Idirectory     specify $LOAD_PATH directory (may be used more than once)
  -l              enable line ending processing
  -n              assume 'while gets(); ... end' loop around your script
  -p              assume loop like -n but print line also like sed
  -rlibrary       require the library before executing your script
  -s              enable some switch parsing for switches after script name
  -S              look for the script using PATH environment variable
  -v              print the version number, then turn on verbose mode
  -w              turn warnings on for your script
  -W[level=2|:category]     set warning level; 0=silence, 1=medium, 2=verbose
  -x[directory]   strip off text before #!ruby line and perhaps cd to directory
  --jit           enable JIT for the platform, same as --mjit (experimental)
  --mjit          enable C compiler-based JIT compiler (experimental)
  -h              show this message, --help for more info


ruby -c

どんなオプション?

指定したファイルに文法エラーが無ければ、Syntax OKと出力し、構文エラーがあれば教えてくれます。 ruby -c example.rbのように、ファイル名を指定して使います。

公式リファレンスの説明:スクリプトの内部形式へのコンパイルのみを行い, 実行しません。コンパイル終了後, 文法エラーが無ければ, "Syntax OK"と出力します。

使える場面

プログラムを実行せず、構文エラーがあるかどうかを調べたい時に使います。

「文法が正しいかどうかは、試しに実行してみてSyntax Errorが出るかどうかでわかるじゃん」と思っていたのですが、ruby -cを使った方が良い場面があります。

例えば、こんなコードがあります。

File.open("example.txt", mode = "a+") do |f|
  100.times {f.write("I love Ruby\n")
end

指定したファイルに"I love Ruby"を100行追記するコードです。 2行目に}が足りないため、このまま実行してもファイルは操作されず、SyntaxErrorとなります。

しかし、エラーの有無がわからない状態だとどうなるでしょう。「試しに実行」してみて、もし構文が正しかった場合、100行が追記されてしまいますね💦

実行はしたくないけど、構文が正しいか調べたい場合に使うと良さそうです。

注意点

  • コマンドの順番を間違える(例えばruby example.rb -cとしてしまう)と、構文か正しかった場合、通常通り実行されてしまいました。気をつけましょう。

  • メソッド名のスペルミスや未定義の変数名などのエラーは検出されません。 こんなメチャクチャなコードでも、Syntax OKとなりました。

name = "suzuka"
if nama == "suzuka" # 正しくはname
  put OK # 正しくは`puts "OK"`
end
❯ ruby -c example.rb
Syntax OK


ruby -v

どんなオプション?

Rubyのバージョン情報と警告を表示したい時に使います。警告を表示する場合、ruby -v example.rbのようにファイル名を指定します。

公式リファレンスの説明: 冗長モード。起動時にバージョンの表示を行い, 組み込み変数 $VERBOSEをtrueにセットします。この変数がtrueである時, いくつかのメソッドは実行時に冗長なメッセージを出力します。`-v'オプションが指定されて, それ以外の引数がない時にはバージョンを表示した後, 実行を終了します(標準入力からのスクリプトを待たない).

使える場面

こんなコードがあったとします。

name = "suzuka"
text = "I love Ruby"

puts text

このコードでnameという変数は使われていません。しかし文法の誤りはないので、オプションなしのruby example.rbでは普通に実行できてしまいます。

このプログラムを-vオプションをつけて実行してみます。

❯ ruby -v example.rb
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]
example.rb:1: warning: assigned but unused variable - name
I love Ruby

assigned but unused variable - nameという警告を出力して、「nameは使ってないよ」と教えてくれました。

別のファイルをrequireした場合、読み込んだファイルに対しても警告を表示してくれます。

require "./reference.rb"
text = "I love Ruby"
name = "suzuka"

puts text
❯ ruby -v example.rb
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]
/Users/suzuka/blog/reference.rb:2: warning: assigned but unused variable - name
I love Ruby

注意点

  • ruby -cと違い、ファイルが実行されます。 例えば、ファイルの書き込み処理を行うファイルに対してruby -vを実行した場合、警告が表示されると同時に書き込みが行われます。


ruby -e

どんなオプション?

文字列をRubyのプログラムとして実行します。ruby -e "実行したいコード"のように実行します。

公式リファレンスの説明:コマンドラインからスクリプトを指定します。-eオプションを付けた時には引数からスクリプトファイル名を取りません。 -e オプションを複数指定した場合、各スクリプトの間に改行を挟んで解釈します。

使える場面

コマンドラインからコードを実行したい時に使います。

❯ ruby -e "puts 'ruby'"
ruby

複数行のコードも実行できます。

❯  ruby -e "3.times do
      puts 'ruby'
    end"
ruby
ruby
ruby

これだけだとirbの方が便利な気がしますが、後述する-nオプションと組み合わせると、指定されたファイルや標準入力に対してコードを実行できるので、使える幅が広がります。

注意点

  • ""または''スクリプトを囲まないと何も実行できないので気をつけましょう。 NG: ruby -e puts 'hello'
    OK: ruby -e "puts 'hello'"
  • 他のオプションと組み合わせる時は、順番に注意しましょう。-eは実行したいスクリプトの直前に置きます。以下の例で-ne-enと書いた場合、私の環境ではNameErrorが出ました。
    NG: ruby -en 'puts $_' example.rb
    OK: ruby -ne 'puts $_' example.rb


ruby -n

どんなオプション?

ファイルや標準入力から与えられた値を一行ずつ処理し、各行が $_ (最後にgetsまたは readlineで読み込んだ文字列を表す特殊変数) に入ります。ruby -n example.txtのように、ファイル名を指定して使います。

公式ドキュメントの説明: このフラグがセットされるとプログラム全体が sed -nやawk のように while gets ... end で囲まれているように動作します.

使える場面

前述した-eオプションと組み合わせることで、指定されたファイルから一行ずつ読み込み、その各行に対してスクリプトを実行することができます。 下のexample.txtというファイルに対して、-n-eを組み合わせて使う例を紹介します。

Ruby is fun!
Ruby is good.
Programming is difficult.
例1:ファイルの各行をそのまま出力

ファイルに対し、ruby -ne 'puts "#{$.}行目 #{$_}"' example.txtを実行してみましょう。
-nで各行を読み込み、-eオプションで読み込んだ各行と行番号を出力するよう指示しています。$.は行番号、$_は最後に読み込まれた行の中身を示します。

❯ ruby -ne 'puts "#{$.}行目 #{$_}"' example.txt
1行目 Ruby is fun!
2行目 Ruby is good.
3行目 Programming is difficult.
例2:ファイルの各行を加工して出力

受け取った入力は、加工して出力することもできます。
gsubメソッドを使って、"Ruby"という文字列を青色の「ルビー」に置き換えてみましょう。ruby -ne 'puts $_.gsub(/Ruby/, "\e[34mルビー\e[0m")' example.txtを実行します。

ターミナルでの実行結果

例3:ファイル内に特定の条件を満たす文字が含まれるか検索

ifで条件分岐させると、条件を満たした場合のみ処理を行うことができます。 各行に"Ruby"が含まれていた場合、行数を出力するようにしてみます。

❯ ruby -ne 'puts "#{$.}行目にRubyがあります" if $_.include?("Ruby")' example.txt
1行目にRubyがあります
2行目にRubyがあります

正規表現だと複雑になりそうな、「0以上18未満または60以上の数値を検索したい」場合にも使えます。

0
21
80
50
13
6
46
61
❯ ruby -ne 'puts "#{$.}行目 #{$_} "if ($_.to_i >= 0 && $_.to_i < 18) || $_.to_i >= 60 ' integer.txt 
1行目 0
3行目 80
5行目 13
6行目 6
8行目 61


終わりに

今回は5つの実行オプションについて調べました。
調べた中でも、-e-nは私にとって難しかったです。加えてリファレンスを確認して、想像以上にオプションの数が多く、奥が深いなと思いました。

実際にコードを書いていて使いこなすのには程遠いですが、調べていると「開発の現場でも使える」オプションの使い方が結構出てきたので、今後も勉強します❣️

参考文献