shimadama
5/11/2015 - 4:27 AM

よく使われているスタイルガイド

よく使われているスタイルガイド

ロールモデルが重要なのだ。
-- アレックス・マーフィー巡査 / ロボコップ

Rubyディベロッパーとして、私は常にあることに悩まされてきました - Pythonディベロッパーは偉大なプログラミングスタイルガイド (PEP-8) を持っていますが、 我々には公式のコーディングスタイルやベストプラクティスを 一切持ち合わせていません。 そして、私はそれこそが問題であると確信しています。 また、Rubyが持っているような素晴らしいハッカーコミュニティは、 誰もが羨むようなドキュメントを作り出す力があるはずであるとも確信しています。

このガイドは、私達の社内製Rubyコーディングガイドから生まれました (著者は)。 私がこのガイドを書くと決めたときは、一般のRubyコミュニティのメンバーに 興味を持ってもらえるだろうか、社内製のガイドはあまり必要とされていないのではないか と考えていました。 しかし、コミュニティ駆動の、コミュニティに認められた、 Rubyのための慣習、語法、スタイル規定は、 確実にRubyコミュニティに有益たりえるのではないでしょうか。

このガイドを発端に、私は世界中の優れたRubyコミュニティのメンバーから、 たくさんのフィードバックを受けています。 全ての提案、サポートに感謝します! お互いに、また全てのRubyディベロッパーにとって有益なリソースを、 一緒に作ることができています。

ところで、もしあなたがRailsが好きであれば、 こちらの補足も確認してみてください。 Ruby on Rails Style Guide.

The Ruby Style Guide

このRuby style guideは、他のRubyプログラマーが保守できるコードを書くための ベストプラクティスを採用することをおすすめします。 実際の使われ方を反映したスタイルガイドは使われるようになり、 理想論にとどまり、それを採用することがリスクと感じる人々に拒絶されるような スタイルガイドは全く使われなくなります – たとえそれがどんなに素晴らしいものであっても。

このガイドは、関連するルールに基づいていくつかのセクションに分かれています。 ルールの後ろにその論理的根拠も付け加えるように努めています (自明であると判断したもの以外は)。

私はこれら全てのルールをどこからともなく考えついたわけではありません - これらのほとんどは、私のプロフェッショナルソフトウェアエンジニアとしての 豊富な経験と、Rubyコミュニティのメンバーからの意見や提案、 また、"Programming Ruby 1.9"や、 "The Ruby Programming Language"のような、 様々な高度で評価の高いRubyプログラミングリソースに基づいています。

特定のスタイルに関して、Rubyコミュニティ内での明らかな意見の一致を得ていない箇所もいくつかあります (文字列リテラルの引用記号、ハッシュリテラルの内側のスペース、複数行のメソッドチェーンのドットの位置、などなど)。 そのようなシナリオでは、どの有名なスタイルも許容されるので、 どれを選んで、一貫して用いるかはあなた次第です。

このスタイルガイドは、追加の慣習を定めたり、 Ruby自身の変化によって過去に定めたルールが時代遅れになるとともに進化してきました。

多くのプロジェクトは、それ自身のコーディングスタイルガイドを持っています (しばしばこのガイドを基に生成されています)。 結果としてルールの衝突が発生した場合は、 そのプロジェクトにおいては、プロジェクト固有のガイドを優先します。

PDFやHTMLのコピーはこのガイドを使って作成できます Transmuter

RuboCopは、 このスタイルガイドに基づいたコード分析器です。

以下の言語の翻訳が利用可能です:

目次

レイアウト

ほとんどすべての人が、彼ら自身のではないスタイルは 不快で合理的でないと確信している。 「彼ら自身の」を除けば、おそらく正しいのだが、、、 -- Jerry Coffin (on indentation)

  • ソースファイルのエンコーディングにはUTF-8を用いましょう。 [link]

  • インデントには スペース 2つ(別名ソフトタブ)。 ハードタブを用いてはいけません。 [link]

    # 悪い例 - 4つのスペース
    def some_method
        do_something
    end
    
    # 良い例
    def some_method
      do_something
    end
    
  • Unix-styleの改行にしましょう。 (*BSD/Solaris/Linux/OS X ユーザーはデフォルトで設定されています。 Windows ユーザーは特に注意が必要です。) [link]

    • もしGitを使っていれば、プロジェクトにWindowsの改行が紛れ込まないように、以下の設定を追加したほうがよいかもしれません:

      $ git config --global core.autocrlf true
      
  • 命令文や式の区切りに;を用いてはいけません。 当然、1行につき式1つにしましょう。 [link]

    # 悪い例
    puts 'foobar'; # 余分なセミコロンです。
    
    puts 'foo'; puts 'bar' # 2つの式が1行にあります。
    
    # 良い例
    puts 'foobar'
    
    puts 'foo'
    puts 'bar'
    
    puts 'foo', 'bar' # 特にputsでは適用されます。
    
  • 本文のないクラスは1行のフォーマットが好まれます。 [link]

    # 悪い例
    class FooError < StandardError
    end
    
    # 悪くない例
    class FooError < StandardError; end
    
    # 良い例
    FooError = Class.new(StandardError)
    
  • 1行のメソッドは避けましょう。 いくらか使われているところもありますが、 それらの定義構文の仕様が望ましくないとさせるいくつかの特殊性があります。 ともかく - 1行メソッドには多くとも式1つまでにすべきです。 [link]

    # 悪い例
    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
    

    本文が空のメソッドはこのルールの例外です。

    # 良い例
    def no_op; end
    
  • 演算子の前後、コンマ、コロン、セミコロンの後ろに、{の前後、}の前にはスペースを入れましょう。 スペースはRubyのインタープリタには(ほとんどの場合)重要ではありませんが、 スペースの適切な使用は、読みやすいコードを容易に書くための鍵です。 [link]

    sum = 1 + 2
    a, b = 1, 2
    1 > 2 ? true : false; puts 'Hi'
    [1, 2, 3].each { |e| puts e }
    

    演算子についてただひとつの例外は、指数演算子です:

    # 悪い例
    e = M * c ** 2
    
    # 良い例
    e = M * c**2
    

    {}は、構文の明確化のために有用です。 だから、文字列に式を埋め込む時と同様に、 ブロックやハッシュ構文に使われます。 ハッシュ構文には、2つのスタイルが許容できます。

    # 良い例 - スペースを { の後と } の前に入れる
    { one: 1, two: 2 }
    
    # 良い例 - スペースを { の後と } の前に入れない
    {one: 1, two: 2}
    

    1つ目の構文は、わずかながら少し読みやすいです(そして、ほぼ間違いなく一般的なRubyコミュニティで人気があります)。 2つ目の構文は、ブロックとハッシュを視覚的に差別化できるという点で有利です。 どちらでも片方を採用すれば、常に同じ構文を採用しましょう。

    文字列に埋め込む構文も、2つのスタイルが許容できます:

    # 良い例 - スペースを入れない
    "string#{expr}"
    
    # 良い例 - ほぼ間違いなくにこちらのほうが読みやすい
    "string#{ expr }"
    

    1つ目の式は、他の式よりも非常に人気があり、一般的にこちらを使うように進められる書き方です。 一方2つ目は、(間違いなく)少し読みやすいです。 ハッシュと同じように - 片方を採用すれば、常に同じ方を採用しましょう。

  • ([の後と、])の前にはスペースは入れません。 [link]

    some(arg).other
    [1, 2, 3].size
    
  • !の後にはスペースは入れません。 [link]

    # 悪い例
    ! something
    
    # 良い例
    !something
    
  • 範囲リテラルの内側にスペースは不要です。 [link]

    # 悪い例
    1 .. 3
    'a' ... 'z'
    
    # 良い例
    1..3
    'a'...'z'
    
  • whencaseと同じ深さに揃えましょう。 多くの人が同意できないのを知っていますが、 このスタイルは"The Ruby Programming Language"、"Programming Ruby" 双方で確立されたものなのです。 [link]

    # 悪い例
    case
      when song.name == 'Misty'
        puts 'Not again!'
      when song.duration > 120
        puts 'Too long!'
      when Time.now.hour > 21
        puts "It's too late"
      else
        song.play
    end
    
    # 良い例
    case
    when song.name == 'Misty'
      puts 'Not again!'
    when song.duration > 120
      puts 'Too long!'
    when Time.now.hour > 21
      puts "It's too late"
    else
      song.play
    end
    
  • 条件式を変数に代入するときは、 その式の通常のアラインメントを維持しましょう。 [link]

    # 悪い例 - かなり複雑です
    kind = case year
    when 1850..1889 then 'Blues'
    when 1890..1909 then 'Ragtime'
    when 1910..1929 then 'New Orleans Jazz'
    when 1930..1939 then 'Swing'
    when 1940..1950 then 'Bebop'
    else 'Jazz'
    end
    
    result = if some_cond
      calc_something
    else
      calc_something_else
    end
    
    # 良い例 - 何が行われているか明らかです
    kind = case year
           when 1850..1889 then 'Blues'
           when 1890..1909 then 'Ragtime'
           when 1910..1929 then 'New Orleans Jazz'
           when 1930..1939 then 'Swing'
           when 1940..1950 then 'Bebop'
           else 'Jazz'
           end
    
    result = if some_cond
               calc_something
             else
               calc_something_else
             end
    
    # 良い例 (少しだけ幅の効率がよいです)
    kind =
      case year
      when 1850..1889 then 'Blues'
      when 1890..1909 then 'Ragtime'
      when 1910..1929 then 'New Orleans Jazz'
      when 1930..1939 then 'Swing'
      when 1940..1950 then 'Bebop'
      else 'Jazz'
      end
    
    result =
      if some_cond
        calc_something
      else
        calc_something_else
      end
    
  • 定義式の間には空行をいれ、 メソッド内の論理的段落ごとに分割しましょう。 [link]

    def some_method
      data = initialize(options)
    
      data.manipulate!
    
      data.result
    end
    
    def some_method
      result
    end
    
  • メソッド呼び出しの最後の引数の後ろのコンマは避けましょう。 引数が複数行にわかれていない時は、特に避けましょう。 [link]

    # 悪い例 - 簡単に引数を移動・追加・削除できますが、それでもお奨めできません。
    some_method(
                 size,
                 count,
                 color,
               )
    
    # 悪い例
    some_method(size, count, color, )
    
    # 良い例
    some_method(size, count, color)
    
  • メソッドの引数に初期値を割り当てるとき、 =演算子の周りにはスペースを入れましょう。 [link]

    # 悪い例
    def some_method(arg1=:default, arg2=nil, arg3=[])
      # do something...
    end
    
    # 良い例
    def some_method(arg1 = :default, arg2 = nil, arg3 = [])
      # do something...
    end
    

    いくつかのRuby本は最初のスタイルを提案しているけど、 2つ目の方が、実用的により優れています (そして、ほぼ間違いなく少し読みやすいです)。

  • 不要な\を用いた行の継続は避けましょう。 実際、文字列連結以外での行の継続は避けましょう。 [link]

    # 悪い例
    result = 1 - \
             2
    
    # 良い例 (しかしそれでも地獄のように醜い)
    result = 1 \
             - 2
    
    long_string = 'First part of the long string' \
                  ' and second part of the long string'
    
  • 一貫した複数行のメソッドチェーンのスタイルを採用しましょう。 Rubyコミュニティには2つの有名なスタイル - 先頭に.を付けるもの (Option A)、 末尾に.を付けるもの (Option B) - があり、 どちらも良いと考えられています。 [link]

    • (Option A) メソッドチェーンを次の行へつなげる時は、 .は次の行に置きましょう。

      # 悪い例 - 2行目を理解するのに1行目を調べなければなりません
      one.two.three.
        four
      
      # 良い例 - 2行目で何が行われているかすぐに理解できます
      one.two.three
        .four
      
    • (Option B) メソッドチェーンを次の行につなげる時は、 式が続くことを示すように最初の行に.を置きましょう。

      # 悪い例 - メソッドチェーンが続いているかを知るには、次の行を読む必要があります
      one.two.three
        .four
      
      # 良い例 - 最初の行を越えて式が続くか一目瞭然です
      one.two.three.
        four
      

    双方のスタイルのメリットに関する議論はこちら で見ることができます。

  • メソッド呼び出しが複数行に及ぶときは、引数は揃えましょう。 1行の長さの制約のために、引数を揃えるのに適していない時は、 最初の引数以降をインデント1つ分で揃えるスタイルも許容できます。 [link]

    # 初期値 (1行がとても長いです)
    def send_mail(source)
      Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text)
    end
    
    # 悪い例 (インデント2つで揃えています)
    def send_mail(source)
      Mailer.deliver(
          to: 'bob@example.com',
          from: 'us@example.com',
          subject: 'Important message',
          body: source.text)
    end
    
    # 良い例
    def send_mail(source)
      Mailer.deliver(to: 'bob@example.com',
                     from: 'us@example.com',
                     subject: 'Important message',
                     body: source.text)
    end
    
    # 良い例 (普通のインデントです)
    def send_mail(source)
      Mailer.deliver(
        to: 'bob@example.com',
        from: 'us@example.com',
        subject: 'Important message',
        body: source.text
      )
    end
    
  • 複数行に及ぶ配列は、要素を揃えましょう。 [link]

    # 悪い例 - インデント1つです
    menu_item = ["Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam",
      "Baked beans", "Spam", "Spam", "Spam", "Spam", "Spam"]
    
    # 良い例
    menu_item = [
      "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam",
      "Baked beans", "Spam", "Spam", "Spam", "Spam", "Spam"
    ]
    
    # 良い例
    menu_item =
      ["Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam",
       "Baked beans", "Spam", "Spam", "Spam", "Spam", "Spam"]
    
  • 可読性のため、大きな数値にはアンダースコアをつけましょう。 [link]

    # 悪い例 - 0はいくつありますか?
    num = 1000000
    
    # 良い例 - 人の頭でもより簡単に解析できます
    num = 1_000_000
    
  • APIのドキュメントのため、RDocの規約に従いましょう。 コメント行とdefの間に空行を入れてはいけません。 [link]

  • 1行は80字までにしましょう。 [link]

  • 行末のスペースは避けましょう。 [link]

  • ファイルの終端には改行を入れましょう。 [link]

  • ブロックコメントは使ってはいけません。 前にスペースが入ると機能しませんし、 通常のコメントと違い、簡単に見分けが付きません。 [link]

    # 悪い例
    == begin
    comment line
    another comment line
    == end
    
    # 良い例
    # comment line
    # another comment line
    

構文

  • ::は、定数(クラスやモジュールも含みます)や コンストラクタ(例えばArray()Nokogiri::HTML())を参照するときにのみ使いましょう。 通常のメソッド呼び出しでは::の使用は避けましょう。 [link]

    # 悪い例
    SomeClass::some_method
    some_object::some_method
    
    # 良い例
    SomeClass.some_method
    some_object.some_method
    SomeModule::SomeClass::SOME_CONST
    SomeModule::SomeClass()
    
  • 引数があるとき、def()と共に使いましょう。 引数がない場合は()は除きましょう。 [link]

    # 悪い例
    def some_method()
      # 本文省略
    end
    
    # 良い例
    def some_method
      # 本文省略
    end
    
    # 悪い例
    def some_method_with_parameters param1, param2
      # 本文省略
    end
    
    # 良い例
    def some_method_with_parameters(param1, param2)
      # 本文省略
    end
    
  • あなたが使ってはならない理由を正確に知っていなければ、決してforを使ってはいけません。 代わりにイテレータが使われるべきです。 foreachの観点で実装されています(だから、あなた方は遠回りでも使っています)が、 forは(eachと違い)新しいスコープを導入せず、 そのブロック内で定義された変数は、ブロックの外からも見えるようになってしまいます。 [link]

    arr = [1, 2, 3]
    
    # 悪い例
    for elem in arr do
      puts elem
    end
    
    # elemはルーブの外からも参照できることに注意しましょう
    elem # => 3
    
    # 良い例
    arr.each { |elem| puts elem }
    
    # elemはeachブロックの外からは参照できません
    elem # => NameError: undefined local variable or method `elem'
    
  • thenは複数行にまたがるif/unlessでは使ってはいけません。 [link]

    # 悪い例
    if some_condition then
      # 本文省略
    end
    
    # 良い例
    if some_condition
      # 本文省略
    end
    
  • 複数行にまたがるif/unlessでは、条件式は常にif/unlessと同じ行に置きましょう。 [link]

    # 悪い例
    if
      some_condition
      do_something
      do_something_else
    end
    
    # 良い例
    if some_condition
      do_something
      do_something_else
    end
    
  • if/then/else/end構文よりも三項演算子(?:)を好みます。 そちらの方がより明快で簡潔です。 [link]

    # 悪い例
    result = if some_condition then something else something_else end
    
    # 良い例
    result = some_condition ? something : something_else
    
  • 三項演算子は1つの式につき1つまでにしましょう。 つまり、三項演算子はネストしてはいけません。 このケースではif/elseの方がよいです。 [link]

    # 悪い例
    some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
    
    # 良い例
    if some_condition
      nested_condition ? nested_something : nested_something_else
    else
      something_else
    end
    
  • if x; ...を使ってはいけません。代わりに三項演算子を使いましょう。 [link]

    # 悪い例
    result = if some_condition; something else something_else end
    
    # 良い例
    result = some_condition ? something : something_else
    
  • 結果を返すifcase式の値を活用しましょう。 [link]

    # 悪い例
    if condition
      result = x
    else
      result = y
    end
    
    # 良い例
    retuls =
      if condition
        x
      else
        y
      end
    
  • 1行のcase文ではwhen x then ...を使いましょう。 代わりの表現であるwhen x: ...は、Ruby 1.9で廃止されました。 [link]

  • when x; ...を使ってはいけません。前のルールを見てください。 [link]

  • notの代わりに!を使いましょう。 [link]

    # 悪い例 - 評価順のため、()が必要になります
    x = (not something)
    
    # 良い例
    x = !something
    
  • !!は避けましょう。 [link]

    # 悪い例
    x = 'test'
    # obscure nil check
    if !!x
      # body omitted
    end
    
    x = false
    # 二重否定はbooleanとして役に立ちません。
    !!x # => false
    
    # 良い例
    x = 'test'
    unless x.nil?
      # body omitted
    end
    
  • andorの使用は禁止です。それらにその価値はありません。 常に、代わりに&&||を使いましょう。 [link]

    # 悪い例
    # boolean式
    if some_condition and some_other_condition
      do_something
    end
    
    # 制御構文
    document.saved? or document.save!
    
    # 良い例
    # boolean式
    if some_condition && some_other_condition
      do_something
    end
    
    # 制御構文
    document.saved? || document.save!
    

    留意しなければならないのは、このルールには例外(条件式中の安全な代入)があるということです。

  • 複数行にまたがる三項演算子?:は避けましょう; 代わりにif/unlessを使いましょう。 [link]

  • 本文が1行のときは、if/unless修飾子を利用するのが好まれます。 他の良い代替案としては&&/||を使った制御構文があります。 [link]

    # 悪い例
    if some_condition
      do_something
    end
    
    # 良い例
    do_something if some_condition
    
    # もう1つの良い例
    some_condition && do_something
    
  • 重要な複数行のブロックにif/unless修飾子を用いるのは避けましょう。 [link]

    # 悪い例
    10.times do
      # 複数行のbody省略
    end if some_condition
    
    # 良い例
    if some_condition
      10.times do
        # 複数行のbody省略
      end
    end
    
  • 否定形のときはifよりunlessが好まれます。(もしくは||構文を使いましょう)。 [link]

    # 悪い例
    do_something if !some_condition
    
    # 悪い例
    do_something if not some_condition
    
    # 良い例
    do_something unless some_condition
    
    # もう1つの良い例
    some_condition || do_something
    
  • unlesselse付きで使ってはいけません。 肯定条件を先にして書き換えましょう。 [link]

    # 悪い例
    unless success?
      puts 'failure'
    else
      puts 'success'
    end
    
    # 良い例
    if success?
      puts 'success'
    else
      puts 'failure'
    end
    
  • if/unless/while/until構文では()の使用は避けましょう. [link]

    # 悪い例
    if (x > 10)
      # body omitted
    end
    
    # 良い例
    if x > 10
      # body omitted
    end
    
  • 複数行のwhile/untilでは、while/until condition doを使ってはいけません。 [link]

    # 悪い例
    while x > 5 do
      # 本文省略
    end
    
    until x > 5 do
      # 本文省略
    end
    
    # 良い例
    while x > 5
      # 本文省略
    end
    
    until x > 5
      # 本文省略
    end
    
  • 本文が1行のときは、while/until修飾子を利用しましょう。 [link]

    # 悪い例
    while some_condition
      do_something
    end
    
    # 良い例
    do_something while some_condition
    
  • 否定形のときは、whileよりもuntilの方が好まれます。 [link]

    # 悪い例
    do_something while !some_condition
    
    # 良い例
    do_something until some_condition
    
  • 無限ループが必要な時は、while/untilの代わりにKernel#loopを用いましょう。 [link]

    # 悪い例
    while true
      do_something
    end
    
    until false
      do_something
    end
    
    loop do
      do_something
    end
    
  • 後判定ループの場合、begin/end/untilbegin/end/whileより、break付きのKernel#loopが好まれます。 [link]

    # 悪い例
    begin
      puts val
      val += 1
    end while val < 0
    
    # 良い例
    loop do
      puts val
      val += 1
      break unless val < 0
    end
    
  • 内部DSL(例えばRake,Rails,RSpecなど)、 Ruby内で"キーワード"となるステータスを持ったメソッド(例えばattr_readerputsなど)や アトリビュートにアクセスするメソッドでは、 引数の周りの()を省略しましょう。 それ以外のメソッドでは、メソッド呼び出しの時に()を付けましょう。 [link]

    class Person
      attr_reader :name, :age
    
      # 省略
    end
    
    temperance = Person.new('Temperance', 30)
    temperance.name
    
    puts temperance.age
    
    x = Math.sin(y)
    array.delete(e)
    
    bowling.score.should == 0
    
  • 暗黙のオプションハッシュの外側の{}は省略しましょう。 [link]

    # 悪い例
    user.set({ name: 'John', age: 45, permissions: { read: true } })
    
    # 良い例
    user.set(name: 'John', age: 45, permissions: { read: true })
    
  • 内部DSLの一部として使われるメソッドの引数では、外側の(){}は省略しましょう [link]

    class Person < ActiveRecord::Base
      # 悪い例
      validates(:name, { presence: true, length: { within: 1..10 } })
    
      # 良い例
      validates :name, presence: true, length: { within: 1..10 }
    end
    
  • 引数のないメソッド呼び出しの()は省略しましょう。 [link]

    # 悪い例
    Kernel.exit!()
    2.even?()
    fork()
    'test'.upcase()
    
    # 良い例
    Kernel.exit!
    2.even?
    fork
    'test'.upcase
    
  • 1行のブロックではdo...endより{...}の方が好まれます。 複数行のブロックでは{...}は避けましょう (複数行のメソッドチェーンは常に醜いです)。 "制御構文"や"メソッド定義"では常にdo...endを使いましょう (例えばRakefilesや特定のDSLなど) メソッドチェーンでのdo...endは避けましょう。 [link]

    names = ['Bozhidar', 'Steve', 'Sarah']
    
    # 悪い例
    names.each do |name|
      puts name
    end
    
    # 良い例
    names.each { |name| puts name }
    
    # 悪い例
    names.select do |name|
      name.start_with?('S')
    end.map { |name| name.upcase }
    
    # 良い例
    names.select { |name| name.start_with?('S') }.map { |name| name.upcase }
    

    {...}を用いた複数行のメソッドチェーンをOKと主張する人もいるかもしれないが、 自問してみてほしい - このコードは本当に読みやすいだろうか? また、このブロックの本文は素早く展開できるだろうか?

  • 単に他のブロックに引数を渡すだけのブロックリテラルを避けるため、 ブロック引数を明示することを検討しましょう。 ただしブロックがProcに変換されることでのパフォーマンスに気をつけましょう。 [link]

    require 'tempfile'
    
    # 悪い例
    def with_tmp_dir
      Dir.mktmpdir do |tmp_dir|
        Dir.chdir(tmp_dir) { |dir| yield dir }  # block just passes arguments
      end
    end
    
    # 良い例
    def with_tmp_dir(&block)
      Dir.mktmpdir do |tmp_dir|
        Dir.chdir(tmp_dir, &block)
      end
    end
    
    with_tmp_dir do |dir|
      puts "dir is accessible as parameter and pwd is set: #{dir}"
    end
    
  • 制御構文上不要なreturnは避けましょう。 [link]

    # 悪い例
    def some_method(some_arr)
      return some_arr.size
    end
    
    # 良い例
    def some_method(some_arr)
      some_arr.size
    end
    
  • 不要なselfは避けましょう (自身のアトリビュートへの書き込みでのみ必要です)。 [link]

    # 悪い例
    def ready?
      if self.last_reviewed_at > self.last_updated_at
        self.worker.update(self.content, self.options)
        self.status = :in_progress
      end
      self.status == :verified
    end
    
    # 良い例
    def ready?
      if last_reviewed_at > last_updated_at
        worker.update(content, options)
        self.status = :in_progress
      end
      status == :verified
    end
    
  • 当然の帰結として、ローカル変数でメソッドを隠すのは、 それらが等価なものでない限り避けましょう。 [link]

    class Foo
      attr_accessor :options
    
      # ok
      def initialize(options)
        self.options = options
        # both options and self.options are equivalent here
      end
    
      # 悪い例
      def do_something(options = {})
        unless options[:when] == :later
          output(self.options[:message])
        end
      end
    
      # 良い例
      def do_something(params = {})
        unless params[:when] == :later
          output(options[:message])
        end
      end
    end
    
  • 代入部分を()で囲まずに、=の返り値を条件式に用いてはいけません。 これは、Rubyistの中では 条件式内での安全な代入 としてとても有名です。 [link]

    # 悪い例 (+ 警告が出ます)
    if v = array.grep(/foo/)
      do_something(v)
      ...
    end
    
    # 良い例 (MRIはこれでも文句を言いますが、RuboCopでは問題ありません)
    if (v = array.grep(/foo/))
      do_something(v)
      ...
    end
    
    # 良い例
    v = array.grep(/foo/)
    if v
      do_something(v)
      ...
    end
    
  • 利用できるときには省略された自己代入演算子を用いましょう。 [link]

    # 悪い例
    x = x + y
    x = x * y
    x = x**y
    x = x / y
    x = x || y
    x = x && y
    
    # 良い例
    x += y
    x *= y
    x **= y
    x /= y
    x ||= y
    x &&= y
    
  • 変数の初期化には、||=を自由に使いましょう。 [link]

    # nameがnilかfalseでなければ、Bozhidarで初期化します
    name ||= 'Bozhidar'
    
  • boolean変数には||=を用いてはいけません (現在の値がfalseであったときに何が起こるか考えてみましょう)。 [link]

    # 悪い例 - たとえenabledがfalseでもtrueが入ります
    enabled ||= true
    
    # 良い例
    enabled = true if enabled.nil?
    
  • 値が入っているかわからない変数の前処理のは&&=を用いましょう。 &&=を使えば変数が存在するときのみ値を変更するので、 存在確認に用いている不要なifを除去できます。 [link]

    # 悪い例
    if something
      something = something.downcase
    end
    
    # 悪い例
    something = something ? something.downcase : nil
    
    # ok
    something = something.downcase if something
    
    # 良い例
    something = something && something.downcase
    
    # より良い例
    something &&= something.downcase
    
  • 等価演算子===の露骨な使用は避けましょう。 その名が示す通り、caseの条件判定で用いられており、 その外で用いられると混乱のもとになります。 [link]

    # 悪い例
    Array === something
    (1..100) === 7
    /something/ === some_string
    
    # 良い例
    something.is_a?(Array)
    (1..100).include?(7)
    some_string =~ /something/
    
  • Do not use eql? when using == will do. The stricter comparison semantics provided by eql? are rarely needed in practice. [link]

    # 悪い例 - eql? は 文字列に対する == と同じです
    "ruby".eql? some_str
    
    # good
    "ruby" == some_str
    1.0.eql? x # eql? はFixnumとFloatの1を識別したいのであれば意味があります
    
  • Perlスタイルの($:$;などのような)特別な変数の使用は避けましょう。 それらは極めて不可解で、 1行のスクリプト以外でそれらが使われるとやる気が削がれます。 Englishライブラリから提供される人にやさしいエイリアスを用いましょう。 [link]

    # 悪い例
    $:.unshift File.dirname(__FILE__)
    
    # 良い例
    require 'English'
    $LOAD_PATH.unshift File.dirname(__FILE__)
    
  • メソッド名と引数の始まりの(の間にスペースを入れてはいけません。 [link]

    # 悪い例
    f (3 + 2) + 1
    
    # 良い例
    f(3 + 2) + 1
    
  • メソッドの最初の引数が(で始まるならば、 常にメソッド呼び出しに()を用いましょう。 例えば次のように書きます f((3 + 2) + 1)。 [link]

  • Rubyインタープリタを走らせるときは、常に-wオプションを付けましょう。 これまでのルールのどれかを忘れてしまった時に警告を出してくれます! [link]

  • 1行の本文を持つラムダには新しいリテラルを持ちましょう。 lambdaは複数行にまたがるときに使いましょう。 [link]

    # 悪い例
    l = lambda { |a, b| a + b }
    l.call(1, 2)
    
    # 正しい例、ですがギクシャクしています
    l = ->(a, b) do
      tmp = a * 7
      tmp * b / 50
    end
    
    # 良い例
    l = ->(a, b) { a + b }
    l.call(1, 2)
    
    l = lambda do |a, b|
      tmp = a * 7
      tmp * b / 50
    end
    
  • Proc.newよりprocを好みます。 [link]

    # 悪い例
    p = Proc.new { |n| puts n }
    
    # 良い例
    p = proc { |n| puts n }
    
  • ラムダやprocの呼び出しにはproc[]proc.()よりproc.call()を好みます。 [link]

    # 悪い例 - 列挙型のアクセスに似ているように見えます
    l = ->(v) { puts v }
    l[1]
    
    # こちらも悪い例 - 珍しい構文です
    l = ->(v) { puts v }
    l.(1)
    
    # 良い例
    l = ->(v) { puts v }
    l.call(1)
    
  • 使わないブロック引数やローカル変数の先頭には_を付けましょう。 単に_を用いるのも許容されます (少し説明不足ではありますが)。 この慣習はRubyインタープリタやRubocopのようなツールには認識されており、 変数を使っていないという警告を抑えることでしょう。 [link]

    # 悪い例
    result = hash.map { |k, v| v + 1 }
    
    def something(x)
      unused_var, used_var = something_else(x)
    end
    
    # 良い例
    result = hash.map { |_, v| v + 1 }
    
    def something(x)
      _, used_var = something_else(x)
    end
    
  • STDOUT/STDERR/STDINの代わりに$stdout/$stderr/$stdinを用いましょう。 STDOUT/STDERR/STDINは定数であり、 Rubyでの定数は、実際は再割当てできますが(他のストリームへのリダイレクトも可能)、 もし再割当てするとインタープリタからの警告が出るでしょう。 [link]

  • $stderr.putsの代わりにwarnを用いましょう。 簡潔さや明快さはさておき、 warnは必要であれば警告を抑制することができます (警告レベルを-W0を用いて0に設定することによって実現できます)。 [link]

  • 不可解なString#%メソッドよりsprintfformatを好みます。 [link]

    # 悪い例
    '%d %d' % [20, 10]
    # => '20 10'
    
    # 良い例
    sprintf('%d %d', 20, 10)
    # => '20 10'
    
    # 良い例
    sprintf('%{first} %{second}', first: 20, second: 10)
    # => '20 10'
    
    format('%d %d', 20, 10)
    # => '20 10'
    
    # 良い例
    format('%{first} %{second}', first: 20, second: 10)
    # => '20 10'
    
  • 不可解なArray#*メソッドよりもArray#joinを好みます。 [link]

    # 悪い例
    %w(one two three) * ', '
    # => 'one, two, three'
    
    # 良い例
    %w(one two three).join(', ')
    # => 'one, two, three'
    
  • 引数が配列かどうかわからないが、それを配列として扱って処理したいとき、 配列のチェックを明示するより、[*var]Array()を代わりに使いましょう。 [link]

    # 悪い例
    paths = [paths] unless paths.is_a? Array
    paths.each { |path| do_something(path) }
    
    # 良い例
    [*paths].each { |path| do_something(path) }
    
    # 良い例 (そして少し読みやすいです)
    Array(paths).each { |path| do_something(path) }
    
  • 複雑な比較ロジックの代わりに、 可能な限りRangeComparable#between?を用いましょう。 [link]

    # 悪い例
    do_something if x >= 1000 && x <= 2000
    
    # 良い例
    do_something if (1000..2000).include?(x)
    
    # 良い例
    do_something if x.between?(1000, 2000)
    
  • ==を明示した比較よりも判定メソッドを用いましょう。 数値の比較はOKです。 [link]

    # 悪い例
    if x % 2 == 0
    end
    
    if x % 2 == 1
    end
    
    if x == nil
    end
    
    # 良い例
    if x.even?
    end
    
    if x.odd?
    end
    
    if x.nil?
    end
    
    if x.zero?
    end
    
    if x == 0
    end
    
  • ブーリアン値を扱わない限り、露骨なnilでないかの検査は避けましょう。 [link]

    # 悪い例
    do_something if !something.nil?
    do_something if something != nil
    
    # 良い例
    do_something if something
    
    # 良い例 - ブーリアン値を扱うとき
    def value_set?
      !@some_boolean.nil?
    end
    
  • BEGINブロックの使用は避けましょう。 [link]

  • ENDブロックを使ってはいけません。代わりにKernel#at_exitを使いましょう。 [link]

    # 悪い例
    
    END { puts 'Goodbye!' }
    
    # 良い例
    
    at_exit { puts 'Goodbye!' }
    
  • フリップフロップの使用は避けましょう。 [link]

  • 制御構文で条件式のネストは避けましょう。 [link]

    不正なデータをアサートするにはガード節を好みます。 ガード節は、可能な限り関数から出ていくために、 関数の先頭付近で宣言される条件式です。

    # 悪い例
    def compute_thing(thing)
      if thing[:foo]
        update_with_bar(thing)
        if thing[:foo][:bar]
          partial_compute(thing)
        else
          re_compute(thing)
        end
      end
    end
    
    # 良い例
    def compute_thing(thing)
      return unless thing[:foo]
      update_with_bar(thing[:foo])
      return re_compute(thing) unless thing[:foo][:bar]
      partial_compute(thing)
    end
    

    ループ内では条件判定ブロックよりもnextが好まれます。

    # 悪い例
    [0, 1, 2, 3].each do |item|
      if item > 1
        puts item
      end
    end
    
    # 良い例
    [0, 1, 2, 3].each do |item|
      next unless item > 1
      puts item
    end
    
  • collectよりmapdetectよりfindfind_allよりselect injectよりreducelengthよりsizeを好みます。 これは厳しい要件ではありません; もしエイリアスを用いるほうが可読性が上がるのであれば、 使うのもOKです。 それらの同韻のメソッドはSmalltalkから継承されており、 他の言語ではあまり一般的ではありません。 find_allよりもselectが推奨される理由は、 rejectと共に用いた時、その名前が極めて自己説明的だからです。 [link]

  • sizeの代わりにcountを用いてはいけません。 Array以外のEnumerableオブジェクトでは、 サイズを求めるためにコレクション全てをイテレートしてしまいます。 [link]

    # 悪い例
    some_hash.count
    
    # 良い例
    some_hash.size
    
  • mapflattenの組み合わせの代わりに、flat_mapを用いましょう。 これは深さが2以上の配列には適用できません。 すなわち、users.first.songs == ['a', ['b','c']]のときは、 flat_mapよりmap + flattenを用いましょう。 flattenは配列を全て平坦にするのに対し、flat_mapは配列を1次元だけ平坦にします。 [link]

    # 悪い例
    all_songs = users.map(&:songs).flatten.uniq
    
    # 良い例
    all_songs = users.flat_map(&:songs).uniq
    
  • reverse.eachの代わりにreverse_eachを用いましょう。 reverse_eachは新しい配列を作らないので、それが利点です。 [link]

    # 悪い例
    array.reverse.each { ... }
    
    # 良い例
    array.reverse_each { ... }
    

命名規則

プログラミングでただひとつ難しいことは、キャッシュの無効化と命名である。
-- Phil Karlton

  • 識別子は英語で名づけましょう。 [link]

    # 悪い例 - 識別子がnon-asciiな文字列です
    заплата = 1_000
    
    # 悪い例 - (キリル文字の代わりに)ラテン文字で書かれてはいますが、識別子がブルガリア語です
    zaplata = 1_000
    
    # 良い例
    salary = 1_000
    
  • シンボル、メソッド、変数にはsnake_caseを用いましょう。 [link]

    # 悪い例
    :'some symbol'
    :SomeSymbol
    :someSymbol
    
    someVar = 5
    
    def someMethod
      ...
    end
    
    def SomeMethod
     ...
    end
    
    # 良い例
    :some_symbol
    
    def some_method
      ...
    end
    
  • クラスやモジュールにはCamelCaseを用いましょう。(HTTP, RFC, XMLのような頭字語は大文字を保ちましょう)。 [link]

    # 悪い例
    class Someclass
      ...
    end
    
    class Some_Class
      ...
    end
    
    class SomeXml
      ...
    end
    
    # 良い例
    class SomeClass
      ...
    end
    
    class SomeXML
      ...
    end
    
  • ファイル名にはsnake_caseを用いましょう。例えばhello_world.rbのように。 [link]

  • ディレクトリ名にはsnake_caseを用いましょう。例えばlib/hello_world/hello_world.rbのように。 [link]

  • 1つのclass/moduleにつき、ちょうど1つのファイルを持つことを目指しましょう。 ファイル名はCamelCasesnake_caseに置き換えたclass/module名を用いて命名しましょう。 [link]

  • 他の定数はSCREAMING_SNAKE_CASEを用いましょう。 [link]

    # 悪い例
    SomeConst = 5
    
    # 良い例
    SOME_CONST = 5
    
  • 条件判定メソッド(boolean値が返る)には?を末尾に付けましょう (すなわちArray#empty?のように)。 メソッドがboolean値を返さなければ、末尾に?を付けてはいけません。 [link]

  • 危険 な可能性のあるメソッド (すなわちselfのアトリビュートに変更が加えられるものや、 exit!(exitと違ってファイナライザが走らない)のようなもの) は、 危険 であることを示すため、 末尾に!を付けましょう。 [link]

    # 悪い例 - '安全'なメソッドです
    class Person
      def update!
      end
    end
    
    # 良い例
    class Person
      def update
      end
    end
    
    # 良い例
    class Person
      def update!
      end
    
      def update
      end
    end
    
  • 可能な限り、危険なメソッドの観点から安全なメソッドを定義しましょう。 [link]

    class Array
      def flatten_once!
        res = []
    
        each do |e|
          [*e].each { |f| res << f }
        end
    
        replace(res)
      end
    
      def flatten_once
        dup.flatten_once!
      end
    end
    
  • 短いブロックと共にreduceを使うとき、引数は|a, e|と名づけましょう。 (accumulator, element). [link]

  • 二項演算子を定義するとき、引数はotherを用いましょう (<<[]は意味が違ってくるので、このルールの例外です)。 [link]

    def +(other)
      # body omitted
    end
    

コメント

良いコードは素晴らしいドキュメントを持っています。 あなたがまさにコードにコメントを追加しようとしている時、 自問してほしい、"どのようにコードを改善すれば、このコメントが不要になるだろうか?" コードを改善してドキュメントをより明快にしましょう。 -- Steve McConnell

  • コードそのものがドキュメントになるような説明的なコードを書いて、このセクションの残りのパートは無視しましょう。本当に! [link]

  • コメントは英語で書きましょう。 [link]

  • 最初の#とコメントの間にスペースを1つ入れましょう。 [link]

  • 1語より長いコメントを活用し、句読点を使いましょう。 ピリオドの後にone spaceを使いましょう。 [link]

  • 余計なコメントは避けましょう。 [link]

    # 悪い例
    counter += 1 # Increments counter by one.
    
  • コメントは最新に保ちましょう。 古くなったコメントは、コメントがないより悪いです。 [link]

良いコードは良いジョークのようだ - なんの説明もいらない。
-- Russ Olsen

  • 悪いコードを説明するコメントは避けましょう。 自己説明的なコードへのリファクタリングを行いましょう (やるかやらないか - "やってみる"はなしだ。 --Yoda)。 [link]

注釈

  • 注釈は、通常関連するコードのすぐ上に書きましょう。 [link]

  • 注釈のキーワードの後ろは:を続けましょう。 その後ろに問題点を書きましょう。 [link]

  • もし問題点の記述に複数行かかる場合は、 後続の行は#の後ろにスペース3つでインデントしましょう。 (通常の1つに加え、インデント目的に2つ) [link]

    def bar
      # FIXME: This has crashed occasionally since v3.2.1. It may
      #   be related to the BarBazUtil upgrade.
      baz(:quux)
    end
    
  • もし問題が明らかで、記述が冗長な場合は、 問題のある行の末尾に、本文なしの注釈だけ付けましょう。 この用法は例外であり、ルールではありません。 [link]

    def bar
      sleep 100 # OPTIMIZE
    end
    
  • あとで追加されるべき、今はない機能や関数を書き留めるにはTODOを使いましょう。 [link]

  • 直す必要がある壊れたコードを書き留めるにはFIXMEを使いましょう。 [link]

  • パフォーマンスに問題を及ぼすような、遅い、または非効率なコードを書き留めるにはOPTIMIZEを使いましょう。 [link]

  • 疑わしくリファクタリングで除去すべきコードの匂いを書き留めるにはHACKを使いましょう。 [link]

  • 意図したとおりに動くか確認する必要がある箇所を書き留めるにはREVIEWを使いましょう。 例: REVIEW: Are we sure this is how the client does X currently? [link]

  • 適切に感じるのであれば、他の独自のキーワードを用いても構いませんが、 それらのキーワードはREADMEやそれに類するものに書いておきましょう。 [link]

クラス

  • クラス定義は置いて一貫性のある構造にしましょう。 [link]

    class Person
      # extend や include を最初に行います
      extend SomeModule
      include AnotherModule
    
      # 定数定義はその次です
      SOME_CONSTANT = 20
    
      # その後ろはアトリビュートマクロです
      attr_reader :name
    
      # 他のマクロが続きます(もしあれば)
      validates :name
    
      # public class methods が次に来ます
      def self.some_method
      end
    
      # public instance methods が続きます
      def some_method
      end
    
      # protected and private methods は後ろの方にまとめます
      protected
    
      def some_protected_method
      end
    
      private
    
      def some_private_method
      end
    end
    
  • 複数行のクラスの中に複数行のクラスをネストさせてはいけません。 そのようにネストされたクラスは、それが含まれるクラス名のフォルダの中に それぞれのクラスのファイルを置くように努めましょう。 [link]

    # 悪い例
    
    # foo.rb
    class Foo
      class Bar
        # 中に30メソッド
      end
    
      class Car
        # 中に20メソッド
      end
    
      # 中に30メソッド
    end
    
    # 良い例
    
    # foo.rb
    class Foo
      # 中に30メソッド
    end
    
    # foo/bar.rb
    class Foo
      class Bar
        # 中に30メソッド
      end
    end
    
    # foo/car.rb
    class Foo
      class Car
        # 中に20メソッド
      end
    end
    
  • クラスメソッドしかないクラスはモジュールであることが好まれます。 クラスはインスタンスを生成することにのみ意味があります。 [link]

    # 悪い例
    class SomeClass
      def self.some_method
        # body omitted
      end
    
      def self.some_other_method
      end
    end
    
    # 良い例
    module SomeModule
      module_function
    
      def some_method
        # body omitted
      end
    
      def some_other_method
      end
    end
    
  • モジュールのインスタンスメソッドをクラスメソッドにしたいときは、 extend selfよりもmodule_functionが好まれます。 [link]

    # 悪い例
    module Utilities
      extend self
    
      def parse_something(string)
        # do stuff here
      end
    
      def other_utility_method(number, string)
        # do some more stuff
      end
    end
    
    # 良い例
    module Utilities
      module_function
    
      def parse_something(string)
        # do stuff here
      end
    
      def other_utility_method(number, string)
        # do some more stuff
      end
    end
    
  • クラス階層の設計を行うときは、 リスコフの置換原則. に従いましょう。 [link]

  • あなたのクラスを可能な限り SOLID に保ちましょう。 [link]

  • クラスの領分を説明するため、常にto_sメソッドを提供しましょう。 [link]

    class Person
      attr_reader :first_name, :last_name
    
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    
      def to_s
        "#{@first_name} #{@last_name}"
      end
    end
    
  • 単純なアクセサやミューテータの定義には、attr群を用いましょう。 [link]

    # 悪い例
    class Person
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    
      def first_name
        @first_name
      end
    
      def last_name
        @last_name
      end
    end
    
    # 良い例
    class Person
      attr_reader :first_name, :last_name
    
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    end
    
  • attrの使用は避けましょう。代わりにattr_readerattr_accessorを使いましょう。 [link]

    # 悪い例 - 1つのアクセサしか作れません(1.9で廃止されました)
    attr :something, true
    attr :one, :two, :three # attr_readerと同じです
    
    # 良い例
    attr_accessor :something
    attr_reader :one, :two, :three
    
  • Struct.newの使用を考えましょう、 それは、単純なアクセサ、コンストラクタや比較演算子を定義してくれます。 [link]

    # 良い例
    class Person
      attr_accessor :first_name, :last_name
    
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    end
    
    # より良い例
    Person = Struct.new(:first_name, :last_name) do
    end
    
  • Struct.newで初期化されたインスタンスを拡張してはいけません。 それは余分なクラスレベルをもたらし、 複数回requireされた時に、奇妙なエラーの原因にもなります。 [link]

    # 悪い例
    class Person < Struct.new(:first_name, :last_name)
    end
    
    # 良い例
    Person = Struct.new(:first_name, :last_name)
    
  • あるクラスのインスタンス生成する追加の方法を提供したいときは、 ファクトリメソッドの追加を検討しましょう。 [link]

    class Person
      def self.create(options_hash)
        # body omitted
      end
    end
    
  • 継承よりダック・タイピングが好まれます。 [link]

    # 悪い例
    class Animal
      # abstract method
      def speak
      end
    end
    
    # 継承
    class Duck < Animal
      def speak
        puts 'Quack! Quack'
      end
    end
    
    # 継承
    class Dog < Animal
      def speak
        puts 'Bau! Bau!'
      end
    end
    
    # 良い例
    class Duck
      def speak
        puts 'Quack! Quack'
      end
    end
    
    class Dog
      def speak
        puts 'Bau! Bau!'
      end
    end
    
  • 継承での振る舞いが"扱いづらい"ので、クラス変数(@@)の使用は避けましょう。 [link]

    class Parent
      @@class_var = 'parent'
    
      def self.print_class_var
        puts @@class_var
      end
    end
    
    class Child < Parent
      @@class_var = 'child'
    end
    
    Parent.print_class_var # => will print "child"
    

    クラス階層内の全てのクラスを見ることができるように、 実際にクラス変数を1つ共有してみましょう。 クラスインスタンス変数はクラス変数より好まれます。

  • 意図した使い方に沿って、可視性(privateprotected)を設定しましょう。 全てをpublic(デフォルトの設定)のままにしないようにしましょう。 結局私達は今 Ruby を書いているのだから。 Python ではなく。 [link]

  • publicprotectedprivateは、適用するメソッド定義と同じインデントにしましょう。 可視性を定義する識別子以降のメソッドに適用されることを強調するため、 識別子の上下に空行を入れましょう。 [link]

    class SomeClass
      def public_method
        # ...
      end
    
      private
    
      def private_method
        # ...
      end
    
      def another_private_method
        # ...
      end
    end
    
  • シングルトンメソッドを定義するときはdef self.methodを用いましょう。 クラス名を繰り返さないので、簡単にリファクタリングできるようになります。 [link]

    class TestClass
      # 悪い例
      def TestClass.some_method
        # body omitted
      end
    
      # 良い例
      def self.some_other_method
        # body omitted
      end
    
      # たくさんのシングルトンメソッドを定義しなければならない時
      # この書き方も便利で、許容できます。
      class << self
        def first_method
          # body omitted
        end
    
        def second_method_etc
          # body omitted
        end
      end
    end
    
  • 文脈上selfが静的に決定されるようなclassのレキシカルスコープ内でメソッドのエイリアスを与える時はaliasを好みます。 そうすれば実行時やどのサブクラスないでも、それを明示的に行わない限り あなたのエイリアスが変更されないことをユーザーに伝えることが出来ます。 [link]

    class Westerner
      def first_name
        @names.first
      end
    
      alias given_name first_name
    end
    

    aliasdefのと同じく予約語なので、シンボルや文字列よりもベアワードが好まれます。 言い換えると、alias :foo :barではなく、alias foo barと書きましょう。

    また、Rubyがエイリアスや継承をどのように扱うか注意しましょう。 aliasはそれが定義された地点で解決されたメソッドを参照します。 動的には解決されません。

    class Fugitive < Westerner
      def first_name
        'Nobody'
      end
    end
    

    この例では、Fugitive#given_nameは、Fugitive#first_nameではなく、オリジナルのWesterner#first_nameを呼び出します。 Fugitive#given_nameもオーバーライドしたい時は、継承したクラスでも 再定義しなければなりません。

    class Fugitive < Westerner
      def first_name
        'Nobody'
      end
    
      alias given_name first_name
    end
    
  • モジュールやクラス、実行時のシングルトンクラス等、 aliasの挙動が予期できないレキシカルスコープでは、 エイリアス定義には常にalias_methodを用いましょう。 [link]

    module Mononymous
      def self.included(other)
        other.class_eval { alias_method :full_name, :given_name }
      end
    end
    
    class Sting < Westerner
      include Mononymous
    end
    

例外

  • 例外発生にはfailを用いましょう。 raiseは例外をキャッチして、再度発生させるときにのみ使いましょう (何故なら、ここでは落ちるのではなく、明示的に目的を持って例外を発生させているからです)。 [link]

    begin
      fail 'Oops'
    rescue => error
      raise if error.message != 'Oops'
    end
    
  • 2引数のfail/raiseでは、RuntimeErrorを明示しないようにしましょう。 [link]

    # 悪い例
    fail RuntimeError, 'message'
    
    # 良い例 - デフォルトでRuntimeErrorが発生します
    fail 'message'
    
  • 例外インスタンスの代わりに、 例外クラスとメッセージが分かれているfail/raiseが好まれます。 [link]

    # 悪い例
    fail SomeException.new('message')
    # `fail SomeException.new('message'), backtrace`とする書き方が存在しないことに注意しましょう。
    
    # 良い例
    fail SomeException, 'message'
    # `fail SomeException, 'message', backtrace`の用法と一貫性があります
    
  • ensureブロックからreturnしてはいけません。 もしensureから明示的に値を返したい場合は、 returnはどの例外発生よりも前に書いておき、 例外など発生していなかったかのように値を返しましょう。 事実上、例外は静かに捨てられます。 [link]

    def foo
      fail
    ensure
      return 'very bad idea'
    end
    
  • 可能な場所では、 暗黙のbeginブロック を用いましょう。 [link]

    # 悪い例
    def foo
      begin
        # main logic goes here
      rescue
        # failure handling goes here
      end
    end
    
    # 良い例
    def foo
      # main logic goes here
    rescue
      # failure handling goes here
    end
    
  • 不確実性のあるメソッド(Avdi Grimmによって作られた言葉です) を用いてbeginの蔓延を和らげましょう。 [link]

    # 悪い例
    begin
      something_that_might_fail
    rescue IOError
      # handle IOError
    end
    
    begin
      something_else_that_might_fail
    rescue IOError
      # handle IOError
    end
    
    # 良い例
    def with_io_error_handling
      yield
    rescue IOError
      # handle IOError
    end
    
    with_io_error_handling { something_that_might_fail }
    
    with_io_error_handling { something_else_that_might_fail }
    
  • 例外をもみ消してはいけません。 [link]

    # 悪い例
    begin
      # an exception occurs here
    rescue SomeError
      # the rescue clause does absolutely nothing
    end
    
    # 悪い例
    do_something rescue nil
    
  • rescueを修飾子として利用するのは避けましょう。 [link]

    # 悪い例 - StandardErrorとそれを継承した全てのクラスをキャッチしてしまいます
    read_file rescue handle_error($!)
    
    # 良い例 - Errno::ENOENTとそれを継承したクラスのみをキャッチします
    def foo
      read_file
    rescue Errno::ENOENT => ex
      handle_error(ex)
    end
    
  • 制御フローに例外を使っては行けません。 [link]

    # 悪い例
    begin
      n / d
    rescue ZeroDivisionError
      puts 'Cannot divide by 0!'
    end
    
    # 良い例
    if d.zero?
      puts 'Cannot divide by 0!'
    else
      n / d
    end
    
  • Exceptionrescueするのは避けましょう。 これはexitのシグナルも捕捉するため、kill -9が必要になります。 [link]

    # 悪い例
    begin
      # calls to exit and kill signals will be caught (except kill -9)
      exit
    rescue Exception
      puts "you didn't really want to exit, right?"
      # exception handling
    end
    
    # 良い例
    begin
      # a blind rescue rescues from StandardError, not Exception as many
      # programmers assume.
    rescue => e
      # exception handling
    end
    
    # こちらも良い例
    begin
      # an exception occurs here
    
    rescue StandardError => e
      # exception handling
    end
    
    
  • より詳細な例外をrescueチェーンの上に配置しましょう。 そうでなければ、決してrescueされません。 [link]

    # 悪い例
    begin
      # 処理
    rescue Exception => e
      # エラー処理
    rescue StandardError => e
      # 決して到達しないエラー処理
    end
    
    # 良い例
    begin
      # 処理
    rescue StandardError => e
      # エラー処理
    rescue Exception => e
      # エラー処理
    end
    
  • 外部リソースの含まれるプログラムでは、ensureで開放しましょう [link]

    f = File.open('testfile')
    begin
      # .. process
    rescue
      # .. handle error
    ensure
      f.close if f
    end
    
  • 自動的にリソースを開放してくれる昨日を含むメソッドを利用可能な時は、そちらを使いましょう。 [link]

    # 悪い例 - 明示的にファイルディスクリプタを閉じる必要が有ります
    f = File.open('testfile')
      # ...
    f.close
    
    # 良い例 - ファイルディスクリプタは自動的に閉じられます
    File.open('testfile') do |f|
      # ...
    end
    
  • 新しい例外クラスを導入するより、基本ライブラリの例外クラスを用いることが好まれます。 [link]

Collections

  • 配列やハッシュのリテラルの方が好まれます。 (コンストラクタに引数を渡す場合を除けば、ということですが) [link]

    # 悪い例
    arr = Array.new
    hash = Hash.new
    
    # 良い例
    arr = []
    hash = {}
    
  • (空文字列や、文字列内にスペースが入っていない)文字列の配列構文は、 %wリテラルの方が好まれます。 このルールは要素が2つ以上の配列に適用されます。 [link]

    # 悪い例
    STATES = ['draft', 'open', 'closed']
    
    # 良い例
    STATES = %w(draft open closed)
    
  • シンボルの配列が必要なときは%iが好まれます (Ruby 1.9との互換性の維持が必要で無ければ)。 このルールは要素が2つ以上の配列に適用されます。 [link]

    # 悪い例
    STATES = [:draft, :open, :closed]
    
    # 良い例
    STATES = %i(draft open closed)
    
  • ArrayHashリテラルの最後の要素の後ろの,は避けましょう。 複数行にわかれていない時は特に避けましょう。 [link]

    # 悪い例 - 簡単に要素を移動・追加・削除できますが、それでも好まれません。
    VALUES = [
               1001,
               2020,
               3333,
             ]
    
    # 悪い例
    VALUES = [1001, 2020, 3333, ]
    
    # 良い例
    VALUES = [1001, 2020, 3333]
    
  • 配列に大きな隙間を作るのは避けましょう。 [link]

    arr = []
    arr[100] = 1 # now you have an array with lots of nils
    
  • 配列の最初や最後にアクセスしたいときは、 [0][-1]よりfirstlastが好まれます。 [link]

  • 要素が一意のものを扱うときは、Arrayの代わりにSetを用いましょう。 Setは重複がない要素が順序を持たないように実装されています。 これはArrayの直感的な内部操作と、Hashの要素発見の速さが合わさっています。 [link]

  • ハッシュのキーには文字列よりシンボルが好まれます。 [link]

    # 悪い例
    hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
    
    # 良い例
    hash = { one: 1, two: 2, three: 3 }
    
  • 変更のできるオブジェクトをハッシュのキーに使うのは避けましょう。 [link]

  • ハッシュのキーがシンボルの時は、Ruby 1.9のハッシュリテラル記法を用いましょう。 [link]

    # 悪い例
    hash = { :one => 1, :two => 2, :three => 3 }
    
    # 良い例
    hash = { one: 1, two: 2, three: 3 }
    
  • Ruby 1.9のハッシュ記法とハッシュロケットを同じハッシュリテラル内で混在させてはいけません。 シンボルでないキーがある場合は、ハッシュロケット記法を続けなければなりません。 [link]

    # 悪い例
    { a: 1, 'b' => 2 }
    
    # 良い例
    { :a => 1, 'b' => 2 }
    
  • Hash#has_key?よりHash#key?を、 Hash#has_value?よりHash#value?を用いましょう。 ここ でMatzが述べているように、長い記法は廃止が検討されています。 [link]

    # 悪い例
    hash.has_key?(:test)
    hash.has_value?(value)
    
    # 良い例
    hash.key?(:test)
    hash.value?(value)
    
  • 存在すべきキーを扱う時は、Hash#fetchを用いましょう。 [link]

    heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
    # 悪い例 - もし誤りがあってもすぐに気づくことができないかもしれません
    heroes[:batman] # => "Bruce Wayne"
    heroes[:supermann] # => nil
    
    # 良い例 - fetchはKeyErrorを投げるので、問題が明らかになります
    heroes.fetch(:supermann)
    
  • 独自のロジックを用いないようにするため、 Hash#fetch経由でデフォルト値を導入しましょう。 [link]

    batman = { name: 'Bruce Wayne', is_evil: false }
    
    # 悪い例 - falseと判定される値が入っていた場合、望んだとお降りに動かないかもしれません
    batman[:is_evil] || true # => true
    
    # 良い例 - falseと判定される値が入っていても正しく動きます
    batman.fetch(:is_evil, true) # => false
    
  • Hash#fetchでは、デフォルト値の代わりにブロックを用いることが好まれます。 [link]

    batman = { name: 'Bruce Wayne' }
    
    # 悪い例 - デフォルト値が使われると、先に評価してしまいます
    # だから、もし複数回呼ばれると、プログラムが遅くなります
    batman.fetch(:powers, get_batman_powers) # get_batman_powers は高価な呼び出しです
    
    # 良い例 - ブロックは後から評価されます。だから、KeyErrorが評価の引き金になります
    batman.fetch(:powers) { get_batman_powers }
    
  • ハッシュから連続して複数の値が必要になる時は、Hash#values_atを用いましょう。 [link]

    # 悪い例
    email = data['email']
    username = data['nickname']
    
    # 良い例
    email, username = data.values_at('email', 'nickname')
    
  • Ruby 1.9現在ではハッシュは順序付けられるということを信頼しましょう。 [link]

  • コレクションを走査している時に変更を加えてはいけません。 [link]

  • コレクションにアクセスするとき、[n]の代替のリーダーメソッドが提供されている場合に 直接[n]経由でアクセスすることは避けましょう。 nilに対して[]を呼ぶことを避けることが出来ます。 [link]

    # 悪い例
    Regexp.last_match[1]
    
    # 良い例
    Regexp.last_match(1)
    
  • コレクションに対するアクセサを提供するとき、 コレクション内の要素にアクセスする前に、 nilでアクセスするのを防ぐための代替のアクセス方法を提供しましょう。 [link]

    # 悪い例
    def awesome_things
      @awesome_things
    end
    
    # 良い例
    def awesome_things(index = nil)
      if index && @awesome_things
        @awesome_things[index]
      else
        @awesome_things
      end
    end
    

文字列

  • 文字列連結の代わりに文字列挿入や文字列整形を好みます。 [link]

    # 悪い例
    email_with_name = user.name + ' <' + user.email + '>'
    
    # 良い例
    email_with_name = "#{user.name} <#{user.email}>"
    
    # 良い例
    email_with_name = format('%s <%s>', user.name, user.email)
    
  • 文字列挿入時にはスペースを入れることを検討しましょう。 文字列から分かれたコードがより明確になります。 [link]

    "#{ user.last_name }, #{ user.first_name }"
    
  • 一貫した文字列リテラルの引用記号のスタイルを採用しましょう。 Rubyコミュニティには2つの有名なスタイル - デフォルトでシングルクォートを用いるもの (Option A)、 ダブルクォートを用いるもの (Option B) - があり、 どちらも良いと考えられています。 [link]

    • (Option A) 文字列挿入の必要がないときや、\t\n`’`等の特別な文字がない場合は、 シングルクォーテーションが好まれます。

      # 悪い例
      name = "Bozhidar"
      
      # 良い例
      name = 'Bozhidar'
      
    • (Option B) 文字列中に"を含んでいたり、エスケープ文字を抑えたいときでない限り、 ダブルクォーテーションが好まれます。

      # 悪い例
      name = 'Bozhidar'
      
      # 良い例
      name = "Bozhidar"
      

    Rubyコミュニティの中では、ほぼ間違いなく 2つ目のスタイルの方が有名です。 しかしながら、このガイド内の文字列リテラル表記は、 1つ目のスタイルを採用しています。

  • 文字リテラル構文?xを用いてはいけません。 Ruby 1.9からは基本的には冗長です - ?x'x'(1文字の文字列)に変換されます [link]

    # 悪い例
    char = ?c
    
    # 良い例
    char = 'c'
    
  • 文字列の中の挿入されるインスタンス変数やグローバル変数の周りの {}は省略してはいけません。 [link]

    class Person
      attr_reader :first_name, :last_name
    
      def initialize(first_name, last_name)
        @first_name = first_name
        @last_name = last_name
      end
    
      # 悪い例 - 有効ですが不格好です
      def to_s
        "#@first_name #@last_name"
      end
    
      # 良い例
      def to_s
        "#{@first_name} #{@last_name}"
      end
    end
    
    $global = 0
    # 悪い例
    puts "$global = #$global"
    
    # 良い例
    puts "$global = #{$global}"
    
  • 文字列に挿入するときにObject#to_sを使ってはいけません。 自動的に呼び出されます。 [link]

    # 悪い例
    message = "This is the #{result.to_s}."
    
    # 良い例
    message = "This is the #{result}."
    
  • 大きなデータの塊を作る必要があるときは、String#+の使用は避けましょう。 代わりに、String#<<を使いましょう。 連結String#<<は、文字列インスタンスを直接書き換えるため、 String#+よりも常に速いです、 String#+はたくさんの新しいオブジェクトを作ってしまいます。 [link]

    # 良く、そして速い例
    html = ''
    html << '<h1>Page title</h1>'
    
    paragraphs.each do |paragraph|
      html << "<p>#{paragraph}</p>"
    end
    
  • 利用するケースにより特化した速い代替手段がある場合、String#gsubは使わないようにしましょう。 [link]

    url = 'http://example.com'
    str = 'lisp-case-rules'
    
    # 悪い例
    url.gsub("http://", "https://")
    url.gsub("-", "_")
    
    # 良い例
    url.sub("http://", "https://")
    str.tr("-", "_")
    
  • 複数行のヒアドキュメントを用いるときは、 先頭のスペースも保持してしまうということを頭に入れておかなければなりません。 過剰なスペースを取り除くためのマージンを採用するのを実用的です。 [link]

    code = <<-END.gsub(/^\s+\|/, '')
      |def test
      |  some_method
      |  other_method
      |end
    END
    # => "def test\n  some_method\n  other_method\nend\n"
    

正規表現

問題に突き当たった時、"そうだ、正規表現を使おう"と考えます。 そこには2つの問題があります。
-- Jamie Zawinski

  • 単にプレーンテキストを文字列中から探すだけの時は、 正規表現を使ってはいけません: string['text']を使いましょう。 [link]

  • 単純化のため、文字列の添字に直接正規表現を渡しましょう。 [link]

    match = string[/regexp/]             # get content of matched regexp
    first_group = string[/text(grp)/, 1] # get content of captured group
    string[/text (grp)/, 1] = 'replace'  # string => 'text replace'
    
  • 捕捉した結果を使う必要のないとき、捕捉しないグループを用いましょう。 [link]

    /(first|second)/   # 悪い例
    /(?:first|second)/ # 良い例
    
  • 最後に正規表現にマッチした値を示すPerlレガシーの暗号的な変数を用いてはいけません ($1$2など)。 代わりにRegexp.last_match(n)を用いましょう。 [link]

    /(regexp)/ =~ string
    ...
    
    # 悪い例
    process $1
    
    # 良い例
    process Regexp.last_match(1)
    
  • どの値が入っているか追うのが困難になるので、 順序付けられたグループを使うのは避けましょう。 代わりに名付けられたグループを使いましょう。 [link]

    # 悪い例
    /(regexp)/ =~ string
    ...
    process Regexp.last_match(1)
    
    # 良い例
    /(?<meaningful_var>regexp)/ =~ string
    ...
    process meaningful_var
    
  • 文字クラスの中では、特別な意味を持つ文字が少ないので注意が必要です: ^-\]のみが特別な意味を持つので、 .[]の中でエスケープしてはいけません。 [link]

  • ^$は、文字列の先頭や末尾ではなく、 行頭や行末にマッチするので注意が必要です。 もし文字列全体の先頭末尾にマッチさせたいときは、 \A\zを使いましょう (\n?\zと等価である\Zと混同しないようにしましょう)。 [link]

    string = "some injection\nusername"
    string[/^username$/]   # matches
    string[/\Ausername\z/] # don't match
    
  • 複雑な正規表現にはx識別子を用いましょう。 これを用いることで、より読みやすくなり、 便利なコメントを使えるようになります。 スペースが無視されることに注意しましょう。 [link]

    regexp = /
      start         # some text
      \s            # white space char
      (group)       # first group
      (?:alt1|alt2) # some alternation
      end
    /x
    
  • sub/gsubでの複雑な置換は、ブロックやハッシュを用いることで実現できます。 [link]

パーセントリテラル

  • 挿入と"双方が入る1行の文字列には、 %()(%Q()の短縮形)を使いましょう。 複数行の時はヒアドキュメントを好みます。 [link]

    # 悪い例 (挿入の必要がありません)
    %(<div class="text">Some text</div>)
    # should be '<div class="text">Some text</div>'
    
    # 悪い例 (ダブルクォートがありません)
    %(This is #{quality} style)
    # should be "This is #{quality} style"
    
    # 悪い例 (複数行です)
    %(<div>\n<span class="big">#{exclamation}</span>\n</div>)
    # should be a heredoc.
    
    # 良い例 (挿入が必要、ダブルクォートがある、そして1行です)
    %(<tr><td class="name">#{name}</td>)
    
  • 文字列に'"双方が含まれない限り、 %qの使用は避けましょう。 たくさんの文字列をエスケープしなくてもよいときは、 通常の文字列リテラルのほうがより読みやすく、 推奨されるべきです。 [link]

    # 悪い例
    name = %q(Bruce Wayne)
    time = %q(8 o'clock)
    question = %q("What did you say?")
    
    # 良い例
    name = 'Bruce Wayne'
    time = "8 o'clock"
    question = '"What did you say?"'
    
  • '/'が1つ 以上の 正規表現に限り、%rを使いましょう。 [link]

    # 悪い例
    %r(\s+)
    
    # 良い例
    %r(^/(.*)$)
    %r(^/blog/2011/(.*)$)
    
  • 呼び出すコマンドにバッククォートが含まれる(かなり起こりえないが)ことがない限り、 %xの使用は避けましょう。 [link]

    # 悪い例
    date = %x(date)
    
    # 良い例
    date = `date`
    echo = %x(echo `date`)
    
  • %sの使用は避けましょう。 Rubyコミュニティは、スペース含むシンボルをを作る時は :"文字列"がよいと決めたようです。 [link]

  • パーセントリテラルの区切り文字は、%rを除いて()が好まれます。 正規表現の中では、()は色々なシーンで使われるので、 正規表現の内容によっては、より使われる機会の少ない{のほうが 良い選択となることがあるかもしれません。 [link]

    # 悪い例
    %w[one two three]
    %q{"Test's king!", John said.}
    
    # 良い例
    %w(one two three)
    %q("Test's king!", John said.)
    

メタプログラミング

  • 不要なメタプログラミングは避けましょう。 [link]

  • ライブラリに書かれているコアなクラスを汚すのはやめましょう (モンキーパッチを当ててはいけません)。 [link]

  • ブロック渡しのclass_evalのほうが、文字列挿入型よりも好ましいです。

    • 文字列挿入型を使う時は、バックトレースが働くように、常に__FILE____LINE__を渡しましょう: [link]
    class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__
    
    • define_methodの方が、class_eval{ def ... }よりも好まれます。
  • 文字列挿入型のclass_eval(または他のeval)を用いる時は、 挿入されたときのコードをコメントに追加しましょう(Railsでは活用されています)。 [link]

    # from activesupport/lib/active_support/core_ext/string/output_safety.rb
    UNSAFE_STRING_METHODS.each do |unsafe_method|
      if 'String'.respond_to?(unsafe_method)
        class_eval <<-EOT, __FILE__, __LINE__ + 1
          def #{unsafe_method}(*params, &block)       # def capitalize(*params, &block)
            to_str.#{unsafe_method}(*params, &block)  #   to_str.capitalize(*params, &block)
          end                                       # end
    
          def #{unsafe_method}!(*params)              # def capitalize!(*params)
            @dirty = true                           #   @dirty = true
            super                                   #   super
          end                                       # end
        EOT
      end
    end
    
  • method_missingを用いたメタプログラミングは避けましょう。 何故なら、バックトレースが面倒になり、 #methodsのリストの中に出てこず、 ミススペルしたメソッド呼び出しも無言で動いてしまいます、 例えばnukes.launch_state = falseのようにです。 代わりに、移譲、プロキシ、またはdefine_methodを使いましょう。 もしmethod_missingを使わなければならない時は: [link]

    • respond_to_missing?も実装されているか確かめましょう
    • 既知の接頭辞、find_by_*のようなものを捕捉しましょう -- 可能な限りアサートさせましょう
    • 最後にsuperを呼び出しましょう
    • アサートする、特別でないメソッドに移譲しましょう:
    # 悪い例
    def method_missing?(meth, *params, &block)
      if /^find_by_(?<prop>.*)/ =~ meth
        # ... lots of code to do a find_by
      else
        super
      end
    end
    
    # 良い例
    def method_missing?(meth, *args, &block)
      if /^find_by_(?<prop>.*)/ =~ meth
        find_by(prop, *args, &block)
      else
        super
      end
    end
    
    # それでも最も良い選択は、発見できる全てのアトリビュートにdefine_methodすることです
    
  • private/protected制約を避けないように、sendよりもpublic_sendを好みます。 [link]

雑則

  • ruby -wで安全なコードを書きましょう。 [link]

  • オプショナルな変数としてのハッシュの使用を避けましょう。やりすぎてはいませんか?(オブジェクトの初期化はこのルールの例外です) [link]

  • コードのある行が10行を超えるメソッドは避けましょう。 理想を言えば、多くのメソッドは5行以内がよいです。 空行は行数には含めません。 [link]

  • 3つや4つ以上引数を設定するのは避けましょう。 [link]

  • もし本当に"global"なメソッドが必要な場合は、 Kernelに定義し、privateに設定しましょう。 [link]

  • グローバル変数の代わりに、モジュールのインスタンス変数を使用しましょう。 [link]

    # 悪い例
    $foo_bar = 1
    
    # 良い例
    module Foo
      class << self
        attr_accessor :bar
      end
    end
    
    Foo.bar = 1
    
  • 複雑なコマンドラインオプションをパースするためにOptionParserを使いましょう。 また、些細なオプションにはruby -sを使いましょう。 [link]

  • 現在のシステム時間を読み出すには、Time.newよりもTime.nowを使いましょう。 [link]

  • それで問題ない時は、破壊的処理を避け関数型の手法でコードを書きましょう。 [link]

  • それがメソッドの目的でない限り、引数に破壊的変更をするのはやめましょう。 [link]

  • 3段階を超えるネストは避けましょう。 [link]

  • 一貫性を保ちましょう。理想を言えば、このガイドラインに沿いましょう。 [link]

  • 常識を用いましょう。 [link]

ツール

ここでは、このガイドに反するコードを自動的にチェックするのを支援するツールをいくつか紹介します。

RuboCop

RuboCopは、このガイドに基づいた Rubyコードスタイルチェッカーです。 Rubocopはすでにこのガイドの重要な部分をカバーしており、 MRI 1.9, MRI 2.0 双方をサポートし、Emacs向けのよいプラグインがあります。

RubyMine

RubyMine のコードインスペクションは、このガイドに 部分的に基づいています

Contributing

このガイドはまだ未完成です - いくつかのルールはサンプルがなく、 いくつかのルールは説明が不十分です。 そのようなルールの改善はRubyコミュニティを助ける素晴らしい(そしてシンプルな)手段です!

やがてこれらの課題は対応されます - 今後これらを記憶にとどめておきます。

このガイドに書いてあることには変更不能なものはありません。 Rubyのコードスタイルに興味のある全ての人と共に取り組むことが私の望みなので、 究極的には、全てのRubyコミュニティにとって有益なリソースを作ることができればと思っています。

改善のために、遠慮せずチケットを立てたりプルリクエストを送ったりしてください。 あなたの手助けに予め感謝します!

また、このプロジェクト(とRubocop)への金銭的な貢献は、 gittip経由で行うことができます。

貢献するには

簡単です! contribution guidelinesを読んでください!

ライセンス

この著作物は、Creative Commons Attribution 3.0 Unported License に従います。

広めましょう

コミュニティ駆動のスタイルガイドは、これを知らないコミュニティにはほとんど役に立ちません。 このガイドについてつぶやいたり、友達や同僚にシェアしてください。 全てのコメント、提案、オプションがこのガイドを少しだけでも良くしていきます。 そして、考えうるベストのガイドが欲しいですよね?

ありがとう
Bozhidar