Rubyスタイルガイドを読む: ソースコードレイアウト(1)エンコード、クラス定義、スペース

こんにちは、hachi8833です。

今回から、Rubyのコーディングスタイルガイドとして最もポピュラーなbbatsov/ruby-style-guidをベースに、スタイルガイドを読みつつ、そのスタイルになった理由などを考えてみたいと思います。よろしくお願いします。

注: この記事はいわゆる翻訳ではありません。スタイルガイドは最新の英語版をベースにしますが、単に翻訳するつもりはありません。英語を読むのが面倒な方は日本語版を参照するか、Google翻訳でも使ってください。

コーディングスタイルガイドについて

コーディングスタイルには、開発者のさまざまな智慧やノウハウが集約されています。また、議論の余地のあるスタイルについても標準を定めることで、余分な論争を避ける効果もあります。

既存プロジェクトなどで独自のスタイルが使われている場合も、標準的なスタイルガイドとの差分だけを示すことで指示の手間を軽減できます。

このスタイルガイド「bbatsov/ruby-style-guid」は、Rubyコミュニティが育て上げたものであるとのことです。

1. ソースコードレイアウト(1)エンコード、クラス定義、スペースなど

Nearly everybody is convinced that every style but their own is ugly and unreadable. Leave out the “but their own” and they’re probably right…
— Jerry Coffin (on indentation)

大意: だいたいどんな開発者も、コーディングスタイルは自分で手作りしたものだけが素晴らしく、それ以外はすべて醜悪で読むに耐えないと思っているものだ。「自分で手作りしたものだけが素晴らしく、それ以外は」の部分を除けばまあそのとおりかもしれない。

ファイルエンコーディングはUTF-8

Use UTF-8 as the source file encoding.

Ruby 2.0からはコードファイルのデフォルトのエンコーディングがUTF-8になったので、UTF-8を標準にするのが自然ですね。

UTF-8ASCIIと完全上位互換なので、ASCIIで書かれたコードファイルであってもそのまま開くことができますし、UTF-8で万一日本語などが文字化けるようなことがあったとしてもASCII部分は影響を受けずに済みます。

これは実は凄いことで、Rob PikeとKen Thompsonによる設計の筋のよさに震えてしまいます。

なお、UTF-16やUTF-32はASCII上位互換ではありません

参考

インデントはスペース2文字で表現する

Use two spaces per indentation level (aka soft tabs). No hard tabs.

インデントはスペース2つで表現し、Tab文字(\tで表される)は使いません。

# 不可: スペース4つのインデント
def some_method
    do_something
end

# 良好: スペース2つ
def some_method
  do_something
end

インデントは昔から論争の種になってきています。さまざまなプログラミング言語でスペース2つ派、スペース4つ派、Tab文字派などがそれぞれ主張を繰り広げていますし、それぞれにもっともな言い分があります。

だからこそ、スタイルをどれかに定める必要があるのです。このスタイルガイド(および多くのRuby/Railsスタイルガイド)ではそれがスペース2つだったというだけのことだと理解しています。

なお、Go言語ではTab文字が(スタイルレベルではなく)言語レベルで必須になっていますが、Tab文字だとブラウザからコピペがしづらいんですよね。

改行文字はUnixスタイル(LFのみ)とする

Use Unix-style line endings. (*BSD/Solaris/Linux/OS X users are covered by default, Windows users have to be extra careful.)
If you’re using Git you might want to add the following configuration setting to protect your project from Windows line endings creeping in:
$ git config –global core.autocrlf true

Rubyに限らず、改行文字が開発者ごとに異なっているとGitなどで余分な差分が生じるので読みづらくなります。それを防ぐために改行文字を統一するのが目的です。

※ 文中にもありますが、コマンドプロンプトでgit config --global core.autocrlf trueを実行すると、Windows環境の場合のみ改行文字=CRLFで作業できるようになります。

参考までに、以下は環境ごとの主な改行文字です。これはあくまで目安であり、エディタやシステムでの用途によって異なることがありますのでご注意ください。

多くのLinux(Mac OS Xを含む)
LF(\nで表される) — 本スタイルガイドではこれを採用
Windows
CRLF(\r\nで表される)
OS 9 以前のMac
CR(\rで表される)

参考

セミコロン;は文の区切りとしては使わない

Don’t use ; to separate statements and expressions. As a corollary—use one expression per line.

Rubyではセミコロン;を文の区切りとして使うことができますが、これを許すと1行に複数の文を押し込めた読みにくいコードになってしまうので、それを避けるための指示です。

# 不可
puts 'foobar'; # なくてもよいセミコロンがある

puts 'foo'; puts 'bar' # 1行に式が2つあるのはよくない

# 良好
puts 'foobar'

puts 'foo'
puts 'bar'
puts 'foo', 'bar' # 特にputsはセミコロンではなくこのスタイルで書くこと

本文のない、空のクラス定義は1行で書くのが好ましい

Prefer a single-line format for class definitions with no body.

Preferとあるので絶対というより「好ましい」「望ましい」というニュアンスですが、いろんな人が寄ってたかって書いているスタイルガイドなので思惑は違うかもしれませんね。みんながみんな英語ネイティブとは限らないことを思い出しましょう。

「ここにこう書いてあるんだから」絶対正しいのだと考える前に、そこにいたるまでの成り立ちを考えてみて損はないと思います。

# 不可
class FooError < StandardError
end

# 少しまし(でもセミコロンがある)
class FooError < StandardError; end

# 良好
FooError = Class.new(StandardError)

1行に多数の式を書くメソッド(シングルラインメソッド)は避ける

Avoid single-line methods. Although they are somewhat popular in the wild, there are a few peculiarities about their definition syntax that make their use undesirable. At any rate—there should be no more than one expression in a single-line method.

「そういうのが一部で人気があるが、定義のスタイルとして望ましくないので、どうしてもシングルラインメソッドを使うならせいぜい式1つにとどめるべき」

# 不可(式が2つ以上)
def too_much; something; something_else; end

# 少しまし(でもセミコロンが最初の式で必要)
def no_braces_method; body end

# 少しまし(でもセミコロンが2番目の式で必要)
def no_braces_method; body; end

# 少しまし(文法は合っているが、セミコロンなしでは読みづらい)
def some_method() body end

# 良好
def some_method
  body
end

One exception to the rule are empty-body methods.

「以下のような中身が空のメソッドは例外として許される」

# 良好
def no_op; end

演算子の前後にはスペースを置く、カンマ・コロン・セミコロンの後ろにもスペースを置く

Use spaces around operators, after commas, colons and semicolons. Whitespace might be (mostly) irrelevant to the Ruby interpreter, but its proper use is the key to writing easily readable code.

このスタイルは読みやすさのためのものであり、スペース文字(ホワイトスペース)がRubyインタプリタではほとんど意味を持たない性質を利用しています。

sum = 1 + 2
a, b = 1, 2
class FooError < StandardError; end

演算子の前後にスペースを置くか置かないかはスタイルの問題であって、どっちが正しいかではないと思います。

ただし、少なくとも両方のスタイルが混じっているのは読みやすさのうえでも自動整形のためにもよくありません。このスタイルガイドでは、演算子の前後にスペースを置くスタイルを選択しています。

The only exception, regarding operators, is the exponent operator:

累乗演算子**の前後にスペースを置くと、乗算演算子*を間違えて重ねたように見えるからだと思われます。

# 不可
e = M * c ** 2

# 良好
e = M * c**2

ところで累乗演算子といえばハット記号^を使う言語をよく見かけますが、Rubyで**が累乗に使われているのはどこからきたのでしょうか。

hydroculのメモ > プログラミング言語の比較 > 数値型 > べき乗演算子によると、PHPやPythonのほかにPerlでも**が使われています。論拠はありませんが、Perlから持ち込まれたのではないかと推測しています。

ちなみにRubyのハット演算子^XORを表します。その他に正規表現のメタ文字としても使われます。

()[]のすぐ内側にはスペースを置かず、{}のすぐ内側にはスペースを置く

No spaces after (, [ or before ], ). Use spaces around { and before }.

# 不可
some( arg ).other
[ 1, 2, 3 ].each{|e| puts e}

# 良好
some(arg).other
[1, 2, 3].each { |e| puts e }

{ and } deserve a bit of clarification, since they are used for block and hash literals, as well as string interpolation.

For hash literals two styles are considered acceptable. The first variant is slightly more readable (and arguably more popular in the Ruby community in general). The second variant has the advantage of adding visual difference between block and hash literals. Whichever one you pick—apply it consistently.

3種類のかっこのスタイルを「すぐ内側はスペースなし」で統一できたらどんなにキモチイイかと思いますが、少なくとも波かっこ{}には複数の機能があり、読みやすさや美観上、すぐ内側のスペースの置き方を機能に応じて使い分けています。現実的なソリューションだと思います。

# 良好 -- {}のすぐ内側にスペースを置くスタイル
{ one: 1, two: 2 }

# 良好 -- {}のすぐ内側にスペースを置かないスタイル
{one: 1, two: 2}

With interpolated expressions, there should be no padded-spacing inside the braces.

式展開(interpolation)では例外として「波かっこ{}のすぐ内側にはスペースを置かない」にしています。これは、ただでさえ長くなりがちな文字リテラルを長くしないためではないかと思いました。

# 不可
"From: #{ user.first_name }, #{ user.last_name }"

# 良好
"From: #{user.first_name}, #{user.last_name}"

今回はここまでとします。次回はソースコードレイアウト(2)をお送りします。ご期待ください。

関連記事

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833 コボラー、ITコンサル、ローカライズ業界を経てなぜかWeb開発者志願。 これまでにRuby on Rails チュートリアルの大半、Railsガイドのほぼすべてを翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

BPSアドベントカレンダー

人気の記事