プログラミングの土地勘がない状態で、RubyやRailsを勉強しだすとまあ100%挫折しますね。なんでかっていうと、Webやインターネットの知識や、数学やプログラミングの原理など下地になる考え方やお作法があって、それに慣れていないと1つ1つの概念が頭に入ってこないから。
これは会計でも同じで、例えば税効果会計って、費用収益対応の原則や法人税に対する理解がないと1つ1つの処理がなぜそうなっているのか腹落ちしない。
なので、この投稿では、僕が仕事の合間を縫って悶絶しながらRubyを勉強して、あーでもないこーでもないと考えて、現時点でこの考え方を押さえておけばもっと学習時間を短縮できたなーということをまとめようと思う。正直まだ僕は初心者レベルなので、もしかしたら間違っていることもあるかもしれないので、その場合はその都度修正させてください。
1. オブジェクトとメソッドと変数の関係を正しく捉える
オブジェクト=Rubyで扱える全てのデータ
メソッド=オブジェクトを操作/処理するもの
変数=オブジェクトを繰り返し呼び出すためにオブジェクトを格納するもの
だと思うのですが、最初はデータ=変数だと思っていて、どこかでつまずいた記憶がある。オブジェクトをメソッドで操作する、オブジェクトを変数に格納する、という関係が整理できたときになにかしっくりきた。
2. ハッシュと配列は変数の進化系(のようなもの)
ハッシュはキーバリューストアの形式で複数のオブジェクトを1つの変数に格納するもの、配列は順番の形式で複数のオブジェクトを1つの変数に格納するものだと思うのですが、ハッシュも配列も1つの変数に格納しているんだ、ということをもっと強く意識していれば混乱しなかった場面があった。
3. メソッドと変数の関係(クラス、インスタンスは関係ない世界で)
メソッド外で定義した変数はメソッドの中で使えないので、引数を使ってメソッドの呼び出し側からその変数をメソッド側に渡すと思うのですが、変数を使うときに常に変数のスコープを意識する癖をつければよかった。。 変数を適当に使ってエラーが出ること多数。
4. なぜクラスを用いるのか
クラスに限らずですが、1つ1つの仕組みって、これを実現したいということがあるからその仕組みを作ったと思うんですよね。共通のメソッドと、共通の変数を定義しておきたいから、クラスで定義する。なんでそれが必要なの?と深く考えること大事。例えば、HTMLにstyleに関することを直書きせずに、共通するものはCSSにまとめるっていうことは前から知ってたから、その感覚でクラスを定義する意義を捉えられたかもしれない。
5. クラスとインスタンスの違い
クラスはあくまで型で、インスタンスはその型をつかって生成されるもの。設計図と車でも、タイ焼きの型とタイ焼きでもいいんだけど、クラスとインスタンスがかなり違うものだと意識しないと、このあとのそれぞれのメソッドと変数のところの学習でつまずいた。
6. メソッドと変数の関係ふたたび(インスタンスで定義した場合)
もう一度振り返ると、共通のメソッドと、共通の変数を定義しておきたいから、クラスを定義する。クラスを元に複数のインスタンスを生成する。インスタンスでのみ使える共通のメソッドと共通の変数をクラスで定義できて、それがインスタンスメソッドとインスタンス変数。
ちょっとややこしい話ですが、インスタンス変数がインスタンスでのみ使用できるを裏返せば、あるクラスで定義していないインスタンス変数はそのあるクラスから生成したインスタンスの中では使えないということだと思うのですが、これと上記3.でのメソッドで定義していない変数はメソッドの中で使えない(から引数を使ってね)ということが、クラスが絡んでいるかで別次元の話だと捉えられるようになるのに時間がかかった。
7. クラスの継承の意義
複数のクラスに同じメソッド、同じ変数を定義したいときに、楽をしたいからクラスの継承を行うと思うのですが、この意義を明確に理解しておけば、なぜモデルクラスが大体
class Modelname < ActiveRecord::Base
end
となっているかが一発で理解できたと思う。
8. RailsはRubyのGemの1つ
これ僕だけかもしれませんが、最初はソースコードをみて、どこがRubyでどこがRailsか分からないとか発言していました。そうではなく、RailsはRubyのGemの1つという話を聞いて、これがいいか分かりませんが、そんなにRailsがどうだとか意識しなくなりしっくりくるようになりました。
9. リクエストからレスポンスまでの処理の流れ
MVCの概念は初見では苦しみますね。これはリクエストからレスポンスまでの一連の流れを教えてもらったときに初めて理解できた気がします。
1.クライアントがどのURLをリクエストしたら、どのコントローラのどのアクション(=コントローラークラスで定義するインスタンスメソッド)を呼び出すかをルーティングで設定しておく
2.コントローラーのアクションでモデルを利用して、データベースにあるテーブル(テーブルの設計図であるマイグレーションファイルを実行して生成)からデータを引き出し、インスタンス変数でビューに渡す
3.コントローラーのインスタンスメソッド1つにつきビューファイルを基本的に1つ作り、コントローラーがレンダリングしたviewをクライアントにレスポンスとして返す
とくにURLのリクエストがメソッドの呼び出しなんだ、というところが盲点でした。
10. MVCモデルでのインスタンス変数のスコープ
上記6.のとおり、インスタンス変数はインスタンスでしか使えないのでした。ただし、上記9.のようにコントローラークラスのアクション(=コントローラークラスで定義するインスタンスメソッド)にインスタンス変数を定義したら、そのインスタンスメソッドに対応したviewの中でインスタンス変数を呼び出せる。これは2つ違う話として押さえないとこんがらがった。