静的型付け言語原理主義者によるRailsチュートリアル(第4章)

image

第4章 Rails風味のRuby

  • 「Ruby は巨大な仕様を持つ言語ですが、幸い、Rails開発者にとって必要な知識は比較的少なくて済みます。」
    • 幸い…?

4.1 動機

  • この章で Ruby に関する知識と経験の限界に真正面から挑むらしい

4.1.1 組み込みヘルパー

  • 混乱を生じさせる可能性のあるRubyの概念
    • Rails の組み込み関数
    • カッコを使わないメソッド呼び出し
    • シンボル
    • ハッシュ

4.1.2 カスタムヘルパー

  • Railsのビューでは組み込み関数を使えるだけでなく、新しく作成することもできる
    • ApplicationHelper にカスタムヘルパーを定義
    • テストを Red にしてから Green へ
  • 定義したカスタムヘルパーに含まれている概念
    • モジュール
    • メソッド定義
    • 任意のメソッド引数
    • コメント
    • ローカル変数の割り当て
    • 論理値(boolean)
    • 制御フロー
    • 文字列の結合
    • 戻り値
      • 全く触れたことにない概念はモジュールくらいか

4.2 文字列とメソッド

  • Railsコンソール
    • Railsアプリケーションを対話的に操作するためのコマンドラインツール
    • 正常終了は Ctrl + D
    • 強制終了は Ctrl + C

4.2.1 コメント

  • Rubyでは #
    • // ではない

4.2.2 文字列

  • ダブルクォートで囲う
  • + で文字列同士の結合も可能
    • 式展開( #{} )という方法もある
      • C#では @ できる便利なやつ
  • 文字列を出力したいときに使われる puts
    • 戻り値は nil
      • null ではなく nilかあ…
  • Rubyはシングルクォートでも文字列をサポートしている
    • ただしシングルクォート文字列の中で式展開ができない
    • シングルクォートは入力文字列をエスケープせずにそのまま保持するときに便利

4.2.3 オブジェクトとメッセージ受け渡し

  • オブジェクトとはいついかなる場合にもメッセージに応答するもの
    • オブジェクト指向!
  • Ruby では boolean を返すメソッドの末尾に疑問符をつける慣習がある
    • わかりやすい
  • nil かどうかを調べる nil? メソッドもある
  • 後続 if という書き方
    • unless も同様

4.2.4 メソッドの定義

  • Ruby はデフォルト引数が使える
  • 暗黙の戻り値

    • メソッド内で最後に評価された式の値が自動的に返される
    • 例えば以下の二番目の return はなくても暗黙的に文字列が返される(ただ書いてあったほうが可読性は高い)

      >> def string_message(str = '')
      >>   return "It's an empty string!" if str.empty?
      >>   return "The string is nonempty."
      >> end
  • メソッドの引数の変数名はどんなものでも呼び出し元に影響は与えない

4.2.5 title ヘルパー、再び

  • やはり return がなくても暗黙的に戻り値が決まるのは気持ち悪い…
  • module ApplicationHelper という要素
    • モジュールは関連したメソッドをまとめる方法の一つ
    • include メソッドでモジュールを読み込むことができる
    • 単なる Ruby コードであればモジュールは明示できな include が必要だが、Rails の場合は自動的にヘルパーモジュールを読み込んでくれるため、 include が不要
      • つまり application_helper.rb 定義のモジュールは自動的にすべてのビューで参照できるようになっているということ
        • 便利すぎる
        • ただの static メソッドでは??(静的型付け脳)

4.3 他のデータ構造

4.3.1 配列と範囲演算子

  • Ruby の配列もゼロオリジン
    • 添字にはマイナスも使える
  • 比較演算子としての ==
    • 値と参照の比較みたいな話はないのだろうか…
  • 配列に対して sort reverse shuffle しても配列自体に影響はない
    • 配列自体を変更したい場合は sort! のように末尾に ! を追加して破壊的メソッドにするのが Ruby の慣習
  • 配列への要素の追加は push だったり << だったり
  • Ruby の配列は異なる型が配列の中で共存できる
    • これは耐えられないかも

4.3.2 ブロック

  • 短い1行のブロックには波カッコ、長い1行や複数行のブロックには do..end
  • 「ブロックを十分に理解するためには相当なプログラミング経験が必要です。」
    • たしかにプログラミング初心者には理解しづらいかもしれない
  • 今までやってきた単体テストにもブロックが使われている

4.3.3 ハッシュとシンボル

  • ハッシュは並び順が保証されていない
  • ハッシュロケットという簡単な記法
  • Ruby ではハッシュのキーに文字列ではなくシンボルを使うほうが普通
    • :name のような表現
  • シンボルとハッシュロケットの組み合わせは以下のようにも書ける(わかりやすい!)

    { name: "Michael Hartl", email: "michael@example.com" }
  • オブジェクトを表示するための inspect メソッド

    • p メソッドでショートカット可能

4.3.4 CSS、再び

  • Ruby では丸カッコは使用してもしなくてもよい
    • 紛らわしいのでどちらかに決めてほしい。。。
  • ハッシュがメソッド呼び出しの最後の引数である場合は波カッコを省略可能
  • Ruby は改行と空白を区別していないので、以下のコードでは stylesheet_link_tag メソッドを2つの引数で呼んでいることになる

    stylesheet_link_tag 'application', media: 'all',
                                   'data-turbolinks-track': 'reload'

4.4 Rubyにおけるクラス

  • Ruby にもクラスはある

4.4.1 コンストラクタ

  • クラス自身に対して呼び出すメソッド
    • クラスメソッド
  • インスタンスに対して呼び出すメソッド
    • インスタンスメソッド

4.4.2 クラス継承

  • Ruby におけるすべてのクラスは BasicObject を継承している
  • 継承の書き方は class Word < String のような感じ
  • 継承先クラスでの self. は省略可能

4.4.3 組み込みクラスの変更

  • Ruby では組み込みの基本クラスの拡張が可能
    • クラス設計者でなくともクラスにメソッドを自由に追加することができる
    • 正当な理由がない限りは組み込みクラスにメソッドを追加することは無作法
      • そりゃそうだ
  • Rails は blank? メソッドを Ruby に追加している
    • 😇

4.4.4 コントローラクラス

  • ApplicationController の継承階層がかなり深い
    • ApplicationController::Base::Base とは
      • ActionController モジュールの Base クラス
  • 「実は、Railsは確かにRubyで書かれていますが、既にRubyとは別物なのです。Railsのクラスは、普通のRubyオブジェクトと同様に振る舞うものもありますが、多くのクラスにはRailsの魔法の粉が振りかけられています。Railsは独特であり、Rubyとは切り離して学習する必要があります。」
    • 🙄

4.4.5 ユーザークラス

  • 属性に対するアクセサーである `attr_accessor’
    • @ 記号で始まるインスタンス変数にアクセスするメソッドが用意される
    • Rails ではインスタンス変数をコントローラ内で宣言するだけでビューで使えるようになる
  • オブジェクト初期化時にハッシュ引数を渡す技法
    • マスアサインメント

所感

本章は Rails ではなく Ruby にフォーカスした章だった。Rails と違い、素の Ruby の書き味は意外にも悪くなかった。というか書きやすかったと言ったほうが正しいかもしれない。基本クラスを拡張できる言語仕様は衝撃的だったが、かなり柔軟性の高い言語という印象を受けた。Rails はこの柔軟性を生かしてあの黒魔術を生み出しているのだろうか。。。


2448 Words

2019-12-14 11:34 +0000