Help us understand the problem. What is going on with this article?

Railsコードを読んでみた

More than 1 year has passed since last update.

はじめに

以前から、いろんなライブラリや人の書いたコードを読んで理解できるようになりたい、エンジニアを目指す身としてはコードを読めるようにならなくてはと思いつつ、読もうとしては挫折を繰り返しておりました。
しかし、項目をとっても狭く絞れば自分でも読むことができました。
そこで今回、自分なりにRailsのソースコードを読んでみた時のやり方や、コードを読んでみてよかったことなどについてまとめてみようと思います。

Railsのコードは膨大なので、今回は普段からしばしば使っているlink_toメソッドの定義元を読んでみることに限定して書いてみようと思います。

何か間違いなどございましたらご指摘くださるとありがたいです。

対象読者

プログラミングを学び始めて数ヶ月の人。
これからライブラリなどのソースコードを読んでみたいと言う人。

コードを読むメリット

・他の人が書いたコードを理解する練習になる。
・メソッドやハッシュ、条件分岐などの、自分では使ったことのない使い方を知ることができる。
・正体を暴いたようなスッキリ感が得られる。

準備

まず、github上にあるソースコードをそのまま読むのは読みづらかったため、以下のコマンドでローカル環境にソースコードをクローンしました。

git clone https://github.com/rails/rails

そして普段使い慣れたエディターでクローンしたファイルを開きます。

ちょっと読みたいだけでgit cloneする程でもない、という時にはOctotreeというchromeの拡張機能が非常に便利です!以下はそのリンクです。
https://chrome.google.com/webstore/detail/octotree/bkhaagjahfmjljalopjnoealnfndnagc
これは、githubのリポジトリを、見やすくツリー構造にしてサイドバーを表示してくれるツールです。
これを導入すると、以下のように、階層構造がとてもわかりやすくなります。

rails_rails__Ruby_on_Rails_と_Slack_-_TECH__CAMP.png

大まかな枠組みを把握

railsフォルダ直下にどんなフォルダがあるかざっと把握します。
RELEASING_RAILS_md_—_rails.png

フォルダの名前で何に関するコードのまとまりなのか、なんとなくわかります。
さらにRuby on Rails Guides( https://railsguides.jp/ )も参照しながらコードを読むようにしました。
自分にはコードだけをみて何をしているのか理解するのは難しかったので、RailsGuideを読んである程度理解した上でコードを読みました。
それでもなお、コードの意味が理解しづらい時には、Ruby on Rails API ( https://api.rubyonrails.org/ )を参考にしつつコードを読みました。
Ruby on Rails APIの方がRuby on Rails Guidesに比べ、ソースコードに基づいて解説してくれています。しかし英語です。

検索

エディターに搭載されている検索機能を使ってlink_toメソッドの定義元を探して行きます。
sublimetextの場合は、command + shift + Fで出てくるフォルダ内全検索を使いました。
検索に関しては、ジャンプ機能のついているRubyMineなどのエディターが非常に便利なようです。
以下の画像は、実際に全ファイル内検索を行った結果のスクリーンショットです。
Find_Results_—_rails_と_Railsコードを読んでみた話_-_Qiita.png

rails/actionview/lib/action_view/helpers/url_helper.rbの169行目にlink_toメソッドの定義がなされていることがわかりました。
また、検索機能を使っても、検索結果がたくさん出てくることもあるので、命名規則やrailsの慣習でどのフォルダに入っていることが多いかなどから、ある程度探したいメソッドや変数がどこにあるか予測をつけておくことも大切なようです。

コードを読む

以下はlink_toメソッドの定義元のコードです。

url_helper.rb
def link_to(name = nil, options = nil, html_options = nil, &block)
  html_options, options, name = options, name, block if block_given?
  options ||= {}

  html_options = convert_options_to_data_attributes(options, html_options)

  url = url_for(options)
  html_options["href"] ||= url

  content_tag("a", name || url, html_options, &block)
end

以下、Ruby on Rails GuidesやRuby on Rails APIを参考にしながら読んでみた自分なりの解釈です。

1行目: 第一引数にname、第二引数にoptions、第三引数にhtml_options、第四引数にblockを設定しています。nameとoptionsは必須なようで、初期値はnilです。

2行目:block_given?はブロックの有無を判定してくれます。ブロックが存在すれば引数の中身を入れ直します。

3行目:optionsがnilなら空のハッシュを返します。

4行目:url_forを使ってoptionsからアプリケーションを参照するurlを生成しurlと言う変数に代入します。

5行目:html_option["href"]があればその値を、なければurlを返します。

6行目:content_tagを使ってhtmlのaタグを生成しています。nameがなければurlやhtml_option、ブロックを表示させます。

読んでいく中で、よくわからないメソッドや変数が出来てたら、検索→定義元を読む、ということを繰り返します。

まとめ

・項目をすごく狭く限定すればプログラミング歴が浅い自分でも読むことができました。
・メソッドやハッシュ、条件分岐などの、自分では使ったことのない使い方を知れるので、rubyの書き方の勉強になります。
・普段使っているメソッドの中身を知ることで、安心感や納得感を持ってそのメソッドを使うことができます。
・他の人が書いたコードを理解する練習になります。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした