Techioz Blog

Ruby “man” ドキュメント - “" を使用した複数行のコメント?

概要

Ruby の「man」ページを読んでいると、「-S」フラグについて次のような記述があります。

-S   Makes Ruby use the PATH environment variable to search for script, unless its name begins with a slash.  This is used to emulate #! on
     machines that don't support it, in the following manner:

           #! /usr/local/bin/ruby
           # This line makes the next one a comment in Ruby \
           exec /usr/local/bin/ruby -S $0 $*

     On some systems $0 does not always contain the full pathname, so you need the -S switch to tell Ruby to search for the script if necessary
     (to handle embedded spaces and such).  A better construct than $* would be ${1+"$@"}, but it does not work if the script is being
     interpreted by csh(1).

私が混乱しているのはこの部分です:

# This line makes the next one a comment in Ruby \
exec /usr/local/bin/ruby -S $0 $*

これは、man エントリが  文字によってその後の行がコメントとして扱われると言っているように聞こえます。

これをテストするために、「foo.rb」という名前の新しい Ruby スクリプトを作成してみました。これには、次の 2 行と単純な「puts」ステートメントが含まれています。

# This line makes the next one a comment in Ruby \
exec /usr/bin/env ruby -S $0 $*

puts "Hi"

/usr/local/bin に Ruby 実行可能ファイルがないため、スクリプトを /usr/local/bin/ruby から /usr/bin/env Ruby に変更しました。 (ドキュメントによると) その行は実行可能コードではなくコメントとして扱われる必要があるため、それが結果に意味のある影響を与えるべきではないと思います。

man エントリの解釈が正しければ、「ruby foo.rb」を実行するとターミナルに Hi が出力されると予想されます。しかし、そんなことは起こりません。代わりに、次のように表示されます。

$ ruby foo.rb
foo.rb:2: unknown regexp option - b
exec /usr/bin/env ruby -S $0 $*
foo.rb:2: syntax error, unexpected local variable or method, expecting `do' or '{' or '('
exec /usr/bin/env ruby -S $0 $*
foo.rb:2: syntax error, unexpected global variable, expecting `do' or '{' or '('
exec /usr/bin/env ruby -S $0 $*

私の何が間違っているのでしょうか?

解決策

Ruby のマニュアル ページのこの特定の部分は非常に古いようです。実際、これは元々、Ruby (当時) の SVN リポジトリへの最初の (データ) コミットで追加されました。

当時、Ruby のパーサーは、マニュアル ページの構文例に示されているように、コメントの最後にバックスラッシュを使用した行継続を実際にサポートしていたようです。

ただし、この機能は 1999 年 3 月 2 日の SVN リビジョン 520 で Ruby から削除されました (差分は非常に大きく、GitHub ではデフォルトではレンダリングされません。parse.y ファイルの 2433 行を確認してください)。

その変更の ChangeLog エントリは次のようになります。

Tue Mar  2 17:04:19 1999  Yukihiro Matsumoto  <[email protected]>

    * parse.y (yylex): backslashes do not concatenate comment lines
      anymore.

この変更は、1999 年 8 月に Ruby 1.4.0 でリリースされました。それ以来、24 年以上前、マニュアル ページのサンプルは機能しなくなりました。

その後の (それでもかなり古い) ドキュメントでは、別のアプローチが提案されています。

#!/bin/sh
exec ruby -S -x $0 "$@"
#! ruby
puts 'Hello World'

ここでは、exec は常に実行され、Ruby インタープリターで現在のファイルを実行するには -S フラグを使用します。ただし、-x フラグも使用します。これは、#!ruby (または明らかに #! Ruby) を含む行が見つかるまで、ファイルのすべての行をスキップするように Ruby に指示します。これは今でも機能します。