感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

モジュールの使い方入門

スポンサーリンク

・目次

  1. インスタンス変数
  2. インスタンスの初期化
  3. キーワード引数
  4. モジュールの使い方
  5. Mix-in

インスタンス変数

インスタンス変数は頭に@をつけて記述します。
クラスのスコープになるので、インスタンス変数はメソッドの中に定義します。


インスタンスの初期化

インスタンスを生成したあとでデータを設定するのではなく、生成した時点でデータを保持したい場合は、初期化用のメソッドinitializeをクラス内に配置し得t、データをインスタンス変数に代入します。
Javaなどではこれをコンストラクタといいます。


キーワード引数

引数の種類が増えてくると順番を覚えておくのが面倒になります。
こういうときに、引数に名前を付けることができます。
キーワード引数といいます。

class Book
  attr_accessor :author, :title, :isbn
  def initialize(author:"", title:"")
  	@author = author
  	@title = title
  end
end

book = Book.new(title: "hoge", author: "fuga")

puts book.author #hoge
puts book.title #fuga


モジュールの使い方

モジュールはクラスに似ていて、「インスタンス化できないクラス」のようなものです。

インスタンスを生成することはできず、継承することもできません。

使い方には以下のようなものがあります。

  • Rubyにはパッケージという概念がないので、その代わりにモジュールやクラスを入れ子にすることで、名前空間を形成する
  • モジュールのメソッドを、あるクラスのインスタンスメソッドとして取り込む
  • モジュールのメソッドを、あるクラスのオブジェクトのクラスメソッドとして取り込む
  • モジュール関数を定義して使う

ある名前空間のクラスやモジュールを参照するには::演算子を用います。

module Person
  class Friend
    def say_hallo
      puts "hello"
    end
  end
end

friend = Person::Friend.new

friend.say_hallo

メソッドをクラスのインスタンスメソッドとして取り込むこともできます。

module Greetable
  def say_hello
    puts "Hello!!"
  end
end

class Takashi
  include Greetable
end

takashi = Takashi.new

takashi.say_hello

Mix-in

Rubyクラスはスーパークラスは1つしか持てません。
しかし、モジュールはいくつでもインクルードすることができます。
これらのインクルードしたモジュールのことをミックスインといいます。

includeはprivateメソッドなので、関数として呼び出さなければならないことも覚えておきましょう。
includeの引数はクラスではなく、moduleで宣言されたモジュールでなければいけません。

class MultiArray
  include Enumerable

  def initialize(*arrays)
  	@arrays = arrays
  end

  def each
  	@arrays.each { |a| a.each { |x| yield x} }
  end
end

ma = MultiArray.new([1,2],[3],[4,5,6])

ma.collect

puts ma.detect {|x| x > 3}

puts ma.map{ |x| x * 3}
ma.each_with_index{|x,i| puts "Element #{i} is #{x}"}

ミックスインを使うことで、Enumerableが持つeach_with_indexやmap,detectなどのメソッドを使うことができるクラスを作ることができました。
module Enumerable


moduleによって定義されたインスタンス変数を初期化するには、superを使います。

module Timeable
  attr_reader :time_created

  def initialize
    @time_created = Time.now
  end

  def age
  	Time.now - @time_created
  end
end


class Character
  include Timeable
  attr_reader :name
  def initialize( name )
  	@name = name
  	super()
  end
end

c = Character.new "Hoge"
puts c.time_created #2014-07-11 08:28:08 +0900