🌊

「実践 Rails――強力なWebアプリケーションをすばやく構築するテクニック」の第1章2節の途中までを読んでの学びと感想

2021/07/11に公開

知り合いのエンジニアの方から「Rubyをするならこの本を読むといいよ」とお薦めを受けたので下記の本を購入。

https://www.oreilly.co.jp/books/9784873113869/

多分現時点での自分にとっては相当むずかしく、途中で放り出す可能性は大だが、とりあえずほんの少しずつ読み進めていきたい。気が向いたらこうして何か学んだことや感じたことを書きたい。

とりあえず本記事では、「1章 基本的な手法」の「1.1 メタプログラミングとは何か」と「1.2 Rubyの基礎」の途中までを読んだ学びと感想を書いていく(どういうことか気になったがよく分からないところはそのまま「よく分からない」と記載している)。

学び

メタプログラミングについて

メタプログラミング

  • メタプログラミングとはあるプログラムを実行すると別のプログラムが生成されるというプログラミング手法のこと
    • つまり「→」がプログラムだとして、入力と出力の関係が以下のようになるプログラムをメタプロと呼ぶっぽい
      1. プログラム → プログラム
      2. データ → プログラム
    • メタプログラミングは多くのプログラミング言語で使用されているが、最もよく使用されるのは、一般にプログラムをデータとして操作する機能が強化されているRubyやPythonなどの動的プログラミング言語
      • プログラムをデータとして操作するとはどういうことか?逆にプログラムをデータとしては操作しない言語があるということか?
        • よく分からない・・・
    • RubyやRailsにおけるメタプログラミングの実例は以下
      • Rubyにおいてdefine_methodで自分で新たにメソッドを定義すると普通のコントローラなどでそのメソッドを使えるようになる
      • RailsでUserモデルにname属性を付与してmigrationすると、name_changed?メソッドなどnameについてのいろんなメソッドが勝手に使えるようになる
    • 例えばRailsのアプリでメタプログラミングのファイルを作った場合、それはどのフォルダに置くものなのか?
      • よく分からない・・・

イントロスペクション

  • イントロスペクションとはざっくり、対象のプログラムの役割を調べる機能のこと。一般的に構文的イントロスペクションと意味的イントロスペクションの2つがある
    • このイントロスペクションはメタプロにおいてどのような用途?
      • よく分からない・・・。これはこの節以降で説明されるものかも
    • 構文的イントロスペクションとは何か?
      • プログラムの文字列などを直接調べること
    • 意味的イントロスペクションとは何か?
      • 言語の高水準なデータ構造を通じてプログラムを調べること
        • 言語の高水準なデータ構造とはどういうことか?
          • よく分からない・・・
        • Rubyでは、メソッドの作成と書き換え、エイリアスの作成、メソッド呼び出しのインターセプト、継承チェインの操作など、クラスおよびメソッドレベルで作業を行うことを意味する。つまり普通にコントローラとかでアクションの規定をしているのとかはこの意味的イントロスペクションに該当しそう。
          • エイリアスとは何か?
            • メソッドAが存在した時に、内容は同じでメソッド名が違うメソッドBを生成すること
          • メソッド呼び出しのインターセプトとは何か?
            • メソッドが呼び出されるのを中断させること・・・?
          • 継承チェーンとは何か?
            • クラスが継承されている状態のこと。Rubyの全てのクラスはObjectクラスを継承しており、ObjectクラスはBasicObjectクラスを継承している

DRY

  • DRYとは「Don't Repeat Yourself」の略であり、システムにおいて特定の情報を表現する必要があるのは一度だけでよいという意味のプログラミングの原理
    • DRYを実現する方法の1つにメタプログラミングがある。どういうことかというと・・・メタプログラミングをすることによって、アプリケーション内で重複している同様の概念を意味したプログラムを抽象化すれば1つDRYに近づくということ

Rubyの基礎の仕組みについて

全てのRubyオブジェクトに含まれるフィールド

  • 全てのRubyオブジェクトはメモリの中に以下のフィールドを持っている。
    • klass
      • このオブジェクトのclassクラスへのポインタ
        • ポインタとは何か?
          • 変数やメソッドなどが置かれているメモリ上のアドレスを指し示す変数
        • ググった限りの情報だがRubyでは全てのクラスはclassクラスのオブジェクトらしく・・・かつ全てのデータはオブジェクトらしいので、全てのRubyオブジェクトのメモリの中にklassポインタが含まれているのは納得のいく話
      • Rubyではclassは予約語なので・・・・classの代わりにklassという文字列が用いられている。もしこのフィールドにclassという文字列を用いた場合はなんか不具合が起きるらしい。このような意図的なミススペルはRubyに散在している模様。
        • 予約語とは何か?
          • 開発者が変数名やメソッド名としては用いることができない文字列
          • ポインタは変数なので、自身の名前に予約語の文字列を用いることはできない。そのためクラスオブジェクトへのポインタはclassでなくklassとしているよう
    • iv_tbl
      • このオブジェクトに属するインスタンス変数のデータが入っているフィールド
    • flags
      • オブジェクトの汚染状態、ガベージコレクションマークビット、オブジェクトがフリーズされているかどうかといった、何らかのステータス情報が含まれたBooleanフラグのビットフィールド
        • ステータス情報の具体例を示した用語がよく分からない・・・
    • m_tbl(オブジェクトがクラスまたはモジュールだった場合のみ)
      • インスタンスメソッドのデータが入っているフィールド
    • super(オブジェクトがクラスまたはモジュールだった場合のみ)
      • スーパークラスへのポインタ

クラスの継承について

  • クラスの継承についての図は以下。これはこの「実践 Rails」の本に書いてある図を少し修正した図
    • klassポインタの矢印が、全てのクラスはclassクラスのオブジェクトであるという関係を示している
    • superポインタの矢印が、自作したクラスがObjectクラスを継承しているという関係を示している

メソッドとメッセージとレシーバ

  • Rubyではメソッドが呼び出されるときのことを「メッセージを送信している」と言い、メッセージの送信先となるオブジェクトを「レシーバ」と言う。

    • メソッド=メッセージではなく、メソッドというものが呼び出されることをメッセージを送信すると呼称するよう。
  • 以下伊藤淳一さん著のプロを目指す人のためのRuby入門のP211を丸々参考にさせていただいた図だが・・・レシーバとメッセージの関係性はこんな感じだと思う

感想

  • メタプロは重複してる複数のプログラムを抽象化するのにも使われるんだ。というかそれが主な用途なんかな・・・?分からん。
  • データの入力を受け取るとデータの出力を吐き出すプログラムが普通のプログラムで、それ以外のパターンのプログラムがメタプロになるんかな(プログラムを受け取ってプログラムを吐き出すとか)。
  • コードとプログラムという用語を今日まで使い分けせずにきたけど、調べると意味の差は一応あるらしい。プログラムがコンピュータ側が理解できるもの、コードが人間側でRubyとかを用いて書いたもの・・・。とはいえそんなに意識されてなさそうなとこな感じはしたので、この記事では一旦「プログラム」で統一しようと思う。
  • 翻訳系の本はそうなんかもしれんけど、とりあえず自分にとってこの本の文章は分かりづらい・・・
  • 1.1節からいきなりかなりむずいので、一旦は今持ってる上述したRuby入門書とネットの記事を都度頼りながら読んでく他なさそう。

参考文献・参考リンク

Discussion