36日目
今日の学習
Ruby
クラスメソッドとインスタンスメソッド
まだまだこの二つへの理解が浅いので、再び学習。
二つがそれぞれ出来ること自体は分かるし、別物だと感じることもできているのだが、クラスメソッドを使用する場面がやはり思いつかない。
クラスに使えるメソッドということは分かるのだが、使い道が分からないと「じゃあ具体的にはいつ使うのか、モジュールのextendはいつすればいいか」の検討がつけられない。
【Ruby】 たい焼きで理解するオブジェクト指向におけるクラスの概念 | Pikawaka - ピカ1わかりやすいプログラミング用語サイト
【Ruby入門】クラスメソッドとインスタンスメソッドの使い方まとめ | 初心者向け完全無料プログラミング入門
上記のサイトを参考に、もう一度学習してみた。
インスタンスメソッド
インスタンスごとに保持している情報を使って処理を書くことができる
インスタンスごとに異なる結果となるクラスメソッド
インスタンスの持つデータを使う必要のない処理は、クラスメソッドで定義
クラス全体に関わる情報を変更したり 参照したりするメソッドを作成するときに使う
「〜のための」という言葉を付ければ分かりやすい気がする。
「インスタンスのための」メソッド。
「クラスのための」メソッド。
module
でextend
を使うときは、クラス全体に対して使用したいメソッドがある場合だと捉えると何となく分かったような。
モジュール
includeとextend
どうしてここまでクラスメソッド、インスタンスメソッドをはっきりさせようと思っているかというと、Ruby本でmoduleを活用する例題にextend
が出てきたからだ。
なぜinclude
ではなくextend
を使うのかの理由としては、「クラス構文の直下でモジュールのメソッドが呼ばれているため、クラスメソッド(特異メソッド)としてミックスインする必要があるから」と書かれている。
この言葉で混乱したが、include
が使用されているRuby本の例文を見てみると、クラスの中にあるメソッドの中で使われていることが分かった。
一方で、例題のモジュールはクラスの中にあるメソッド内で使われているのではなく、クラスの中でいきなり使われている。
クラスメソッドとしてミックスインする必要があるというのは、扱うモジュール自体をクラスのメソッドとしたい場合だという解釈に辿り着いた。
例となるコードを書いていないせいで、上記の文章だけだと分かりづらいだろうが、Ruby本のコードを丸写しというわけにもいかないので、出来るだけ後から見直しても分かるような書き方を心がけた。
名前空間
6日目で、よく見るとすでにモジュールについて学習していたようだが、書いてあることを見るに全く本質が掴めていない。
名前空間
というものも、この時うっすらと検索した記憶があるのだが、Ruby本で改めて学習をした。
一人で全体を把握した上でプログラミングをする分にはいいが、大規模な開発や、複数人で作業をしていると、知らずのうちにクラス名が重複してしまう可能性がある。
Ruby本では、「野球の二塁手」という意味のSecondクラス、「時計の砂」という意味のSecondクラスを例に説明されていた。
このクラスは、定義されている中身は違うかもしれないが、Second.newで新しくインスタンスを作成しようにも区別がつかない。
この問題を解決するためのものが名前空間
だ。
名前空間
は、モジュール構文を用いて定義をすることで、名前の衝突を防ぐことが出来る。以下、Ruby本から大まかな抜粋。
モジュール構文の中にクラス定義を書くと、「そのモジュールに属するクラス」という意味になるため、同名のクラスがあってもモジュール名が異なっていれば名前が衝突しなくなる。
# 「野球の二塁手の」Secondクラス module Baseball clas Second ... end end # 「時計に関する」Secondクラス module Clock class Second ... end end
上記クラスからインスタンスを新しく作りたい場合は、モジュール名::クラス名
として、モジュール名とクラス名を区切って表記する。
Baseball::Second.new Clock::Second.new
6日目の学習のときは、そもそも色々な用語の理解ができず、全然意味が分からなかったが、今はちゃんと理解できる。というか、Ruby本が非常に分かりやすいからだ。
名前空間
は、クラス名の衝突を防ぐ以外にも、クラスのグループ分け、カテゴリ分けを目的に使われることもあるようだ。
prepend
モジュールは、prepend
を使ってミックスインすることができる。
include
との違いは、prepend
でミックスインされたモジュールにあるメソッドは、ミックスイン先のメソッドよりも先に呼び出される。
include
を使用した場合
module A def hello puts "よろしく。こんにちは!" end end class Greeting include A def hello puts "こんにちは!よろしく。" end end greeting = Greeting.new greeting.hello #=> こんにちは!よろしく。
クラス内にあるhelloメソッドが優先されている。
prepend
を使用した場合
module A def hello puts "よろしく。こんにちは!" end end class Greeting prepend A def hello puts "こんにちは!よろしく。" end end greeting = Greeting.new greeting.hello #=> よろしく。こんにちは!
include
のときと違い、prepend
を使用することによってモジュールのhelloメソッドが優先されていることが分かる。
こうすることで、置き換えたい既存メソッドを置き換えることができる。
Ruby on Rails
Railsチュートリアルを無料で完走するはずが、現在有料版の第6版で学習していたことに気づいた。
Rails5.1の第4版は無料で閲覧できるようだが、新しくRailsのバージョンを下げたり、アプリを作り直す必要があることを考えて少し気が重くなってしまった。
自分はRails6.1を使用しているが、古いバージョンの学習も一応やっておいて損はないかも知れないので、明日以降挑戦したい。
PostgreSQLでエラー
rails new
でアプリを生成して、まず初めにrails db:create
をするとしょっぱなからエラーが出た。
could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.PGSQL.5432"? 以下略
Postgresで発生したエラー「PG::ConnectionBad: 〜"/tmp/.s.PGSQL.5432"?」に対処した - Qiita
エラー文などで検索してみると、似たようなエラーに見舞われた方の記事を発見。
postgres -D /usr/local/var/postgres
を実行したエラーも同じ。
というわけで、この記事通りにpostmaster.pidを削除&postgresの再起動をすると、正常に動作するようになった。深謝。