第3章はRubyに残っているPerl風機能を排除(できるだけ使わないようにしよう)です。
Rubyは様々な言語から影響を受けながら作られた言語です。
影響を受けた言語の一つとしてPerlがあります。
僕はPerlを触ったことがなく、初めてRubyを触ったのも2系になってからなので(Perl風機能がだんだんと減っている?)実はこの章はあまりピンときませんでした。
Rubyの暗号名多Perl風機能を避けよう
Perl風機能とは何か次の例で示します
スポンサーリンク
def extract_error(message) if message =~ /^ERROR:\$s+(.+)/ $1 else "no error" end end
この中に2か所Perl風機能が含まれています。
一つ目は、=~
演算子です。
これは右の正規表現にマッチした文字列内の位置を返します。マッチする部分が無ければnilを返します。
nilはRubyでは偽になるので、マッチする部分が無ければ"no error"が返り値になりますね。
もう一つは、Perlではグローバル変数として使われる?$1変数です。
ですが、実際は$1はグローバル変数ではなく、メソッド内でのみ値を持つ特殊グローバル変数となっています。
すなわち、一度値が入っても、メソッドを抜けるとnilに戻ってしまいます。
例外的な動きをする変数があるとややこしいですよね。僕は「?」となります。というかなってました。
そこで、文字列のマッチや、マッチした文字列を見たいときは、String#matchメソッドを使いましょう
def extract_error(message) if m = message.match(/^ERROR:\s+(.+)$/) m[1] else "no error" end end
ずいぶんと分かりやすく、Rubyらしくなりました。
=~
演算子は僕もしょっちゅう使っているので、これからはこちらにしたいです。
$1はローカル変数でしたが、Rubyには$:、$;, $/などの暗号のようなグローバル変数がありますが、もっと意味の分かりやすい名前(例えば、$LOAD_PATHは$:の別名)の方を使うべきです。
これらの別名はEnglishライブラリをロードすることで使えます。
また、直接暗号のようなグローバル変数を使わなくても、暗黙のうちに使っている場合もあります。
while readline print if ~ /^ERROR:/ end
この処理の意味が分かるでしょうか?僕は全然わかりませんでした。
それも、そのはず、この処理の中では表に出てこない$_というグローバル変数を動かしているからです。
まず、Kernel#readlineメソッドは標準入力を$_へ代入します
次に、~演算子は、右の正規表現に$_の中身をマッチさせます。
もしERRORにマッチしなければnilが返るのでprintメソッドを実行しません。マッチしたとき、引数なしのprintメソッドを実行します。
最後にKernel#printメソッドは引数なしの場合、$_変数を標準出力へ表示します。
このように、Rubyに残っている暗号のようなPerl風機能を使うと読みにくくなり、メンテナンス性も下がります。Rubyにはこれらの機能を避ける方法がよういされているので、そちらを使うようにしましょう。
- 作者: Peter J. Jones,arton,長尾高弘
- 出版社/メーカー: 翔泳社
- 発売日: 2015/01/09
- メディア: 大型本
- この商品を含むブログ (13件) を見る
- 作者: 高橋征義,後藤裕蔵,まつもとゆきひろ
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2016/02/26
- メディア: 単行本
- この商品を含むブログ (2件) を見る
Ruby on Rails 5アプリケーションプログラミング
- 作者: 山田祥寛
- 出版社/メーカー: 技術評論社
- 発売日: 2017/04/14
- メディア: 大型本
- この商品を含むブログを見る