パーフェクトRubyお勉強フェスティバル 第4章

oftonkingdom.hatenablog.com

こんにちは.おふとん王国の王です!!!

布団乾燥機はおふとんがとても暖かくなって王国の統治が捗ります!

さて4章,クラスとモジュールです.

オブジェクト指向言語であるRubyの仕様を見ていきます.

クラス

attr_accessor

まず,普通にインスタンス変数を定義した場合,オブジェクトの外からは参照・代入できない.

class Ofton
  #インスタンス変数「status」を持たせる
  
  def initialize
    @status = 'あたたかいおふとん'
  end
end

#Oftonクラスのインスタンスを生成
ofton = Ofton.new

#インスタンス変数を参照
puts ofton.status # => undefined method `status' for #<Ofton:0x000000014e5718 @status="あたたかいおふとん"> (NoMethodthodError)

この例だと「status」メソッド,「status=」メソッドをクラスで定義してやることで,オブジェクトの外からはofton.statusで参照,ofton.status=ほげほげ で代入ができるようになる.がしかし,2つのメソッド(Javaでいうgetter setterみたいな)をいちいち定義するのは面倒なので,

class Ofton
  #インスタンス変数「status」を持たせる
  attr_accessor :ofton
end

のように書いてやると2つのメソッドが定義されたことになる.

Javaとは違いデフォルトの動作としてインスタンス変数は外から隠されたものとなっている.

クラスメソッド

Javaでいうstaticメソッドのようなものであり,以下のように定義する.

class Ofton

  #クラスメソッド「dryer」
  def self.dryer
    'おふとんを乾燥させます'
  end
end

#クラスメソッドを呼び出す
Ofton.dryer

継承時にメソッドは引き継ぐがインスタンス変数は引き継がれない

とあるが,Rubyではクラスの直下でインスタンス変数は定義されず,インスタンス変数はあくまでインスタンスメソッドの中で定義される」ため,

インスタンス変数の宣言を含むインスタンスメソッドが継承されることで結果的に同名のインスタンス変数が子クラスでも定義されることになる.

class Cat
  def initialize
    @kawaisa = 'かわいい'
  end
end

class Kuroneko < Cat
end

#子クラスでも親クラスのインスタンス変数が定義されている
p kuroneko = Kuroneko.new # => #<Kuroneko:0x0000000140d570 @kawaisa="かわいい">

#アクセサを定義していないのでこちらはエラー!
kuroneko.kawaisa  # => undefined method `kawaisa' for #<Kuroneko:0x0000000140d570 @kawaisa="かわいい"> (NoMethodError)

特異メソッド

オブジェクト固有のメソッドをもたせることができ,それを「特異メソッド」という.

内部的な仕組みは以下が詳しいです,,,

blog.livedoor.jp

モジュール

Rubyならではの.

クラスのようだがクラスでない.インスタンス生成と継承ができない.

がしかし,モジュールの中にクラスやモジュールを書けたりすることで名前空間を作ることができるなど様々な利点がある.

大規模なアプリケーションを作るようになってくると,こういった仕組みは便利なのでしょう.

普段,仕事でJavaソースコードを読みますが,色んな種類の共通処理をいっしょくたに親クラスにまとめて,それを継承させるということをよくやっているのですが(おそらくバッドプラクティス),

これをやると共通処理をまとめたクラスが「何でも屋さん」みたいになってしまって,読む側としてはよくわからんとなってしまうんですよね….

Mix-in

モジュールで定義したメソッドをクラスのインスタンスメソッドとして取り込むためのものです.

「include モジュール名」で,何個でもモジュールを取り込むことができる.

このMix-inで面白いと思ったのが以下(引用)

Enumerableモジュールをeachメソッドの定義されているクラスにincludeすると、eachによる繰り返し処理を用いたいくつかのメソッドが利用できるようになります。

自前のクラスであっても「あるメソッドが定義されている」という条件が整っていれば,それを利用した様々な便利メソッドが使えるようになる.記述量は少なくてもいろいろな処理を呼び出せる.柔軟ですね!

まとめ

今回はそんなに疑問もなくすっと理解できたのでなんだか味気ない内容です.

5章は内容が分量が多いのでもっといろいろ考える!はず!