32日目
今日の学習
Ruby
クラス
クラスメソッドとインスタンスメソッド
クラスメソッド
はインスタンスメソッド
と違い、private
キーワードの下で定義してもprivateメソッド
にならないが、そもそもこの二つのメソッドはどう使い分けるんだったか...となったので、改めて学習しようと思った。今まで意図的にクラスメソッドを作成したことがないのだ。
過去の記事にしれっと書いているが、「結局何?」という感じになってしまったので。
メソッドとクラスメソッドとインスタンスメソッドが曖昧だった - Qiita
こちらの説明と、記事にあるイメージ図が分かりやすかった。
class Greeting def japanese(name) puts "#{name}さん、こんにちは" end end japanese("長谷川")
これで実行してみると、
undefined method
japanese' for main:Object (NoMethodError)`
そんなメソッドはない!と言われてしまう。
自分がクラスに含まれるメソッドを使う場合は、いつもインスタンスメソッド
の形で使っているので、その形式でやってみる。
class Greeting def japanese(name) puts "#{name}さん、こんにちは" end end greeting = Greeting.new greeting.japanese("長谷川") #=> 長谷川さん、こんにちは
.New
を使ってインスタンス
(greeting)を作成する。いつもならinitializeメソッド
を使用して、インスタンス作成時に情報を付与することが多い。
その後、作成したインスタンス
に対して、クラスにあるメソッドをつけるという形だ。
インスタンスメソッド
を使用するには、インスタンス
を作成しなくてはならない。
クラスメソッド
はどうやらそうではないらしい。
class Greeting # クラスメソッドとして使用したいメソッドに、[self.]をつける! def self.japanese(name) puts "#{name}さん、こんにちは" end end # クラスそのものに対してメソッドで呼び出す Greeting.japanese("長谷川") #=> 長谷川さん、こんにちは
書き方にかなり違いがあるが、出力される内容は同一になった。
手軽にメソッドを呼び出したい場合は、クラスメソッドの方が楽だなと感じた。
が、結局どのような使い分けをすればいいのか?
クラスメソッド、インスタンスメソッド。いつ使うのか。 - Qiita
インスタンスメソッド
の場合は、インスタンスごとで異なる動作をしたいときに使用して、クラスメソッド
の場合は、クラス全体で共通の動作を行うときに使用するとのこと。
クラスメソッド
: 全体
インスタンスメソッド
: 個々
確かに、インスタンスメソッドは、しっかりと情報を与えてから使うイメージがある。
適材適所なことは分かるのだが、今の自分にしっかり線引きして使い分けができるかどうかと聞かれるとNOになる。
個人的にはオブジェクト指向に対してそこまで拒否感はないつもりなのだが、やはりまだまだ理解できていないということなんだろう。
上の記事の例では、学校のクラスを作成し、全校生徒の管理はクラスメソッドで。各教室の先生や生徒に関してはインスタンスメソッドで管理をしていて、イメージ自体は掴むことができた。
インスタンスはインスタンスオブジェクト
であり、それに使うメソッドなのでインスタンスメソッド
。
クラスはクラスオブジェクト
であり、それに使うメソッドなのでクラスメソッド
。
こうして言葉にすれば当たり前だろうと言われそうなことだが、どうもRubyは全てが等しくオブジェクト!という考え方が自分に定着していないため、上のような書き方に気づいて今更「なるほど!」となってしまった。
クラス変数
先ほど貼った記事や、たまに目にする@@
を先頭につける変数。これはクラス変数と言うらしい。
@
をひとつだけつけて、インスタンス変数
として使用しているが、これも先ほどのクラス/インスタンスメソッドと同じく、使い方が違ってくるのだろう。
【まとめ】インスタンス変数、クラス変数、クラスインスタンス変数 - Qiita
メソッドのときと同じく、インスタンス変数
はインスタンスごとに独立して値を持つことができるが、クラス変数
はクラス全体で共有される変数のようだ。
インスタンス変数
は、クラスメソッドからはアクセスできないようだ。なぜ...?と思ったが、initializeメソッド
とオブジェクトのインスタンスメソッド
しかアクセスできないかららしい。
さらにクラスインスタンス変数
なるものがあるようだ。ぱっと見てもすぐ理解できなかったので、今回はとりあえずクラス変数
の理解に努める。
インスタンス変数
に値が入るのはインスタンス生成時だが、クラス変数
の場合はクラス内で定義するため、最初から変数に値が入っている。
自分がこれまでに見かけたクラス変数
の使い方は、クラスの中にあるものを数えたりするときだ。
やんばるエキスパート教材 | 八百屋プログラム(クラス)part3
ここでは、@id
というインスタンス変数に、@@count
というクラス変数を代入している。
class Student # 1から順番に@idを振っていく @@count = 0 # initializeの中で定義することで、インスタンスを生成するたびに@idに+1されるようにする def initialize(name) @id = @@count += 1 @name = name end def introduce puts "ID:#{@id}、#{@name}です。" end end student1 = Student.new("長谷川") student2 = Student.new("田中") student1.introduce student2.introduce #=> ID:1、長谷川です。 #=> ID:2、田中です。
initializeメソッド
に含めなくても、このメソッドを使った時に数を増やしたい、という場合には、そのメソッド内に数が増えるような処理を書くとよい。
このような限定的な使い方だけではないと思うが、とにかく使い方から覚えていって、どんどん応用できるようにしたい。
クラスメソッドをprivateメソッドにする
違いがそれとなく分かったところで、冒頭の「クラスメソッド
はインスタンスメソッド
と違い、private
キーワードの下で定義してもprivateメソッド
にならない」に戻る。
クラスメソッドをprivateメソッドで使いたいときは、class << self
構文を使用する。
class Animal class << self #この中でならprivateキーワードで定義が可能になる private #このメソッドはクラス内でしか使えない def hello puts "hello" end end end
もしくはprivateキーワードよりも手前に書き、後からprivate_class_method
でprivateメソッドに変更することができる。
上の例で言えば、まず普通にhelloメソッドを定義した後に、以下のようにする。
private_class_method :hello
private :hello
protectedメソッド
こちらのメソッドは使ったことがない。
Ruby本によると、「そのメソッドを定義したクラス自身と、そのサブクラスのインスタンスメソッドからレシーバ付きで呼び出せる」メソッドらしい。
使い所としては、「外部には公開したくないが、同じクラスやサブクラスの中であればレシーバ付きで呼び出したい」シーンで使うようで、Ruby本にある例を見て理解はできるものの、相変わらず具体的に自分がもし使うなら?というのをぱっと想像できない。
Ruby の private と protected 。歴史と使い分け - Qiita
せめて名前が出てきたときに「え、何?」とならないように覚えておきたい。
Ruby on Rails
最近、RubyやCSSにかまかけてRailsを全く触っていないので、まずいと思い前々からやってみようと思っていたRailsチュートリアルに手を出そうと思う。
やんばるエキスパートでは、同じ時期に入会した人たちと週に一回メンターの方も含めてミーティングをするのだが、その際にRailsチュートリアルはどうですか、と尋ねると、意外とそこまで必須でもないという感じの反応だったので、とりあえずあまりにも時間がかかりそうだったらやめておくという方向性で進めたい。
以前AWSに登録しようと思い、何度か試したがうまく登録できなくて途方に暮れていたが、今登録したら出来たのでよかった。
Railsチュートリアル
ディレクトリとファイルの構造
Rails new
を実行すると、自動的に必要な諸々のファイルが作成される。
が、今まで「このファイルに○○が入っている」「○○はここ」のような適当な暗記をしていた。
Railsチュートリアルに、ディレクトリとファイルの構造が分かりやすく記載されていた。
MVCモデル
面接で、「MVCモデルを説明してください」と問われることがそこそこあるらしい。
自分の言葉で説明できるように、曖昧にせずしっかり覚えないといけないなと感じた。
Railsチュートリアルでも、最初の段階でMVCモデルの説明が始まる。
MVCモデルは、アーキテクチャパターンの一種。アーキテクチャは、構造・構成という意味なので、平たく言えば構造パターンになる。
MVCモデルの処理の流れを覚えることが、デバッグツールを使う上で非常に重要だったことから、流れを理解しておく必要性を強く感じている。
①コントローラ
リクエストを処理する役割がある
モデルとビューを繋ぐ
②モデル
データベースとの通信を担当しているRubyのオブジェクト
データベースに関する命令を書く
③ビュー
リクエストされた内容をもとに、ユーザーが見るHTMLをブラウザに送り返す
この三つの役割に応じて、何のプログラムをどこに書くか決められている。
役割を三つに分けて、役割ごとにファイルが分かれているので、どこに何を書けばいいのかが分かりやすい。
そのため、プログラムの管理や追加がしやすいというメリットがある。
ルーター(router)
は、コントローラとブラウザの間に配置され、ブラウザからのリクエストをコントローラに振り分ける(これがルーティング)。
ルートルーティング
今ではもうすっかりresources
で簡略化するようになってしまったが、ルートの記述方法をもう一度確認しておく。
root "controllerの名前#actionの名前" # userコントローラのshowアクションに設定したい場合 root "user#show"
resources :user # 上のように設定するだけで、標準的なuserアクション # (index、create・new・edit・show・update・destroy) # を一括で作成してくれる!便利すぎる
Git
GitHubにpushできない
毎度pushできなくなっているが、Railsチュートリアル中にAWS Cloud9上からpushするぞ、と思ったら、GitHubでのusernameとpasswordを尋ねられる。
合っているはずなのに何度やっても上手くいかず、色々と解決策を探していたところ、こちらの記事の通りにやるとうまくpushすることができた。
Githubで2段階認証を設定しhttpsリポジトリにpushする - hatappi.blog
二段階認証を自分で設定しておきながら、「???」となってしまった。大変助かった。