LoginSignup
1
0

More than 5 years have passed since last update.

Ruby の module を使って特定のインスタンスにのみ 特定のインスタンス変数をもたせた

Last updated at Posted at 2018-07-17

インスタンスにだけmoduleをインクルードすることで実現する.

ruby の include を使ってみることにしました。
ruby2.5.0 instance method Module#include

extendを使います。
ruby リファレンス extend

参考資料:Qiita::いつも忘れるRubyの include, prepend, extend の意味。そしてActiveSupport::Concernについても。


# 今回の例では人間を使います。
class Human
  def initialize(name)
    @name = name
  end
end

# 人間は別名をいろいろ持っているのでこちらのmoduleでそれを設定できるようにしようと思います。
module OtherNames
  attr_reader :nickname, :pseudonym, :twitter_name # アクセサはなくても平気です。
  def set_nickname(nickname)
    # 宣言するときにチェインできるようにtapを使います。
    tap { @nickname = nickname }
  end

  # pseudonym は ペンネームのことだそうです。
  def set_pseudonym(pseudonym)
    tap { @pseudonym = pseudonym }
  end

  def set_twitter_name(twitter_name)
    tap { @twitter_name = twitter_name }
  end
end

# taroを用意します。
taro = Human.new('taro')
            .extend(OtherNames)
            .set_nickname('tarohiko')
            .set_pseudonym('taronosuke')
            .set_twitter_name('卍とんかつDJほげ☆太郎卍')
# 対照実験用にhanakoも用意しました。
hanako = Human.new('hanako')

# 同じクラスが生成元です
taro.class #=> Human
hanako.class #=> Human

# インスタンス変数を比較すると以下のようになっていました。
taro.instance_variables #=> @name, @nickname, @pseudonym, @twitter_name
hanako.instance_variables #=> @name

これで特定のインスタンスにのみ特定のインスタンス変数を持たせることができました。

extendの新境地に達しました。

追記(2018/07/18)

もともとincludeにしていたんですが、クラスをレシーバにしてincludeを利用するとクラスに対してのincludeとなっており、狙いである特定のインスタンスへのmoduleの追加ができていませんでした。
こちらはextendで実装可能でしたので修正しました。m(_ _)m

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0