2024年2月に別のブログに書いた記事を移動させました。
はじめに
プロを目指す人のためのRuby入門を読んだので、感想をまとめました。
よかった点
Rubyの特徴について詳しく書かれていること
- 例えば、戻り値についてreturnを用いる部分でRubyではreturnは不要であるなど、他の言語との差異をイメージしやすく解説してあるので理解しやすかったです。
学んだことの振り返りがしやすい
- 先の章に進んでも過去の章に振り返られるように、「〇〇の章で紹介したので忘れた人はそちらを読み返してください。」のように案内されているため、どこに書いてあったかな?と思うことがあった時にすぐに振り返られる点が親切だと思います。
学んだ点
2章
- 変数の宣言だけはできない、必ず値の代入が必要
- シングルクオートで文字列を囲むとバックスラッシュ記法と式展開が無効になるためそれらを利用したい場合はダブルクオートを利用する
- インクリメント、デクリメントは使用できない
- rubyではretuneを書かないことが主流(メソッドを抜ける場合に使われる)
- %記法(%q!=シングルクオート.%Q!=ダブルクオート. %!もダブルクオート !?などは区切り記号として利用する)
- and,orは演算子の優先順位が低いため条件分岐で利用しない方が良い
3章
- Minitest(ライブラリ)を利用する
- テストファイルはスネークケース、クラス名はキャメルケースで記述する
- Minitestのメソッド名はtest_で始まることが必須となる
- プログラムとテストはファイルを分ける(テストファイルでプログラム側のファイルを読み込むことを忘れない)
4章
- 配列の要素に数値と文字列を混在させることもできる
- 存在しない要素を指定してもエラーにならない(nilが返ってくる)
- 配列で返ってきた値に対して多重代入を使うことによって異なる変数に値を代入することができるのでコードがスッキリかけたりする
- forは使わずにn.each do でループを記述する
- ブロックではdo endを利用したり、{}で囲んだりうまく使い分ける
5章
- シンボルは破壊的変更が不可、内部的に整数として扱われる
- 擬似キーワード引数は非推奨
6章
- キャプチャ機能(抜き出したい箇所を指定)を使って、キャプチャに名前をつけることもできる
- 取り出したい箇所が複数ある場合など、メタ文字を利用して名前をつけることができ便利
?<name>
- 取り出したい箇所が複数ある場合など、メタ文字を利用して名前をつけることができ便利
- 正規表現オブジェクトの作成方法 %記法で式の値を埋め込んだりRegexp.new('\d{3}-\d{4}')のように記載するとバックスラッシュ囲みをしなくて良くなる
- case文のwhenに正規表現を使える
7章
- レシーバ(受信者、メソッドを呼び出された側など)
- メソッドをメッセージと読んで説明することがある
- Rubyでは大文字で記載してキャメルケースで書くのが一般的
- =で終わるメソッドを定義すると変数に代入するようにそのメソッドを呼び出せる
- クラスの継承で頂点にいるのはObjectクラス(正確にはBasicObjectだが特殊な場合のみ明確化するのであまり気にしなくて良い)
- privateメソッドはサブクラスでも呼び出せる(C#では呼び出せない)
- protectedはクラス外部からは呼び出せないが、同じクラスかサブクラスの場合にはレシーバ付きで呼び出せる
- メソッド内部での定数定義はできない
- 定数に再代入することができる(クラスをfreezeすることで外部からの再代入を防ぐ)
- ミュータブルなオブジェクトを扱う場合には気をつける(定数でも値の変更ができてしまうため)
- classにpublicやprivateは設定できない(privateにしたい場合はprivate_constantを利用する)
- オーバーロード自体はないがオーバーロードと同じような仕組みを実現することは可能
8章
- ミックスイン機能を持つ(モジュールをクラスでインクルードして利用できるようにする)
- 様々なクラスで利用できるメソッドを定義するためにモジュールが活用できる
- クラスにincludeされたモジュールを確認できる
- Enumerableモジュール(繰り返し処理ができるクラスにincludeされているモジュール)
- eachメソッドが実装されていればEnumerableクラスをincludeしてメソッドを利用できるようになる
- Comparableモジュール(比較演算を可能にする)
- include先のクラスで<=>を実装しているとincludeしたときに利用できるようになる
- Kernelモジュール(putsなど最初から使えるメソッドなど、Objectクラスがincludeしているため)
- 継承関係は左からスーパークラスでObject-Kernel-Classのようになっている
- トップレベルで定義したものを参照する場合は::をつけて記述すると参照できる(クラス名の前に::をつけるなど)
- prepend モジュールが先に呼ばれる
- refinements 変更の有効範囲を限定できる
9章
- 例外処理の実行(begin rescue ensure endで記述)
rescue
でexception
を記述しない(好ましくないコードになる)- 例外発生は
raise
で行う、その際にメッセージを渡すようにする(わかりづらいデバッグにしないため) - 条件分岐の方がパフォーマンスが良
- case文でelseを用意しない
- ensure(finally)の代わりにブロックを使って済ませることができる
- ensure(finally)にreturnは使わない
- メソッド全体が例外処理の範囲になる場合はbeginとendの記述を省略できる
10章
- yieldはブロックの処理を呼び出す(書いた回数だけ呼ばれる)
- ブロックが呼ばれたかの判定を行なってyieldを呼び出す
- 引数としてブロックを受け取ることもできる(call時にメソッドを使う)
- Procクラス(手続を表す) callメソッドで実行される
- ブロックの代わりにProcオブジェクトを渡すこともできる
- ブロックは引数として1つしか渡せないがProcオブジェクトはstringのオブジェクトなどと同じような"オブジェクト"なので数に制限がない
- メソッドチェーンは横にずらっと書くよりも改行したほうがすっきり見えて可読性が上がる
- 連結しすぎると過程がわかりづらくなるので適度に使用する
- クロージャについて(Rubyのブロックやプロシージャがこれにあたる)
11章
- パターンマッチ:1要素しかない配列[y] 2要素配列[y, m] 3要素配列[y, m, d] ymdはそれぞれローカル変数で、宣言と代入を同時に行なっているのでyに1つ目の要素、mに2つ目の要素、dに3つ目の要素が入る
- ハッシュの場合、値を省略してもキーと同じ名前でローカル変数を宣言して代入してくれる
- パターンマッチの変数スコープに注意、パターンマッチを抜けても変数を使えたり、同名の変数に上書きする可能性もある
難しかった点
クラスの理解について
- 例えばクラス作成で勉強したprivateメソッドは、Rubyだとサブクラスからも呼び出せてしまう部分が理解しづらかったです。 普段利用しているC#ではクラス内でしか呼び出せないので、サブクラスから呼び出したい場合ではprotectedでメソッドを定義します。(Rubyのprotectedもサブクラスとスーパークラスから呼び出せるようで、protectedとprivateの差の理解については苦しみました。現時点でも深く理解できていない気がしますが、自分なりの理解を記述しておきます。)
Rubyにおけるprivateメソッドとprotectedメソッドの違いについて
- privateは定義したクラスとそのサブクラスから呼び出すことができる
- protectedも同じく定義したクラスとそのサブクラスから呼び出せる
- protectedとprivateの違いは「レシーバ付き」で呼び出せるかどうか
- 同じクラスの中やサブクラスの中であれば異なるインスタンスメソッドであっても呼び出すことができる
最後に
記載の内容など、間違いなどがあればコメントなどでご指摘をお願いします!