2017-10-28 13 views
0

オブジェクトのすべてのインスタンスをグローバル変数に保存する必要があるため、別のオブジェクトからそのインスタンスにアクセスできます。パラメタのようにそれらを渡す必要はありません。グローバル変数にインスタンスを保存

私の解決方法では、インスタンスを変数に入れるメソッドを持つmixinがあります。また、オープンクラスのテクニックを使用してObjectにそのmixinを含めるので、他のオブジェクトもそのメソッドを使用します。

class Object 
    include Favourite 
end 

module Favourite 
    def favourite_it 
     #if the variable its not initialized: 
     @favourites.class == Array.class ? @favourites.push(self) : 
              @favourites = [].push(self) 
    end 

    def get_favourites 
     @favourites 
    end 
end 

#this class is only an example 
class Dog 
    def initialize age 
     @age = age 
    end 
end 

class Dog_T 
    #all instances of this class will be saved in the variable 
    def initialize age 
     @age = age 
     favourite_it 
    end 
end 

class Handler 
    def do_something 
     #here I need to access the variable with all the instances of favourites to do something to them 
    end 
end 

そして、ここで簡単なテスト

handler = Handler.new 
d1 = Dog_T.new(10) 
d2 = Dog_T.new(12) 
all_f = Handler.get_favourites 

expect(all_f[0].age).to eq 10 
expect(all_f[1].age).to eq 12 

d3 = Dog_T.new(15) 
all_f = Handler.get_favourites 
expect(all_f[3].age).to eq 15 

です(私はまだ、グローバル変数を使用していないので、それが理にかなって)私はこれを実行しようとしましたが、唯一の各インスタンスは、別のリストに自分自身を救います。

リストを1つだけ作成し、作成時にインスタンスを追加し、そのリストを空にして操作できるようにするにはどうすればHandlerか。

答えて

0

Rubyはモジュール内でクラス変数を使用することをサポートしています。また、Dog_Tオブジェクトがインスタンス変数にアクセスできるようにするには、リーダーメソッドが必要です。 Favoriteはオブジェクトについて何も知らないので、リスト内に存在しないメソッドを呼び出さないようにするには、respond_to?を使用します。たとえば、ageというメソッドを持たないが、それ自体を追加したDog_Rクラスがあった場合、配列のメンバでageメソッドを盲目的に呼び出すと、ランタイムエラーが発生します。

module Favourite 
    @@favourites = []   # you can use a class variable in module 
    def self.favourite_it(obj) # singleton method of the class 
     @@favourites.push(obj) 
    end 

    def self.get_favourites # singleton method of the class, see below for usage example 
     @@favourites 
    end 
end 

class Object 
    include Favourite 
end 

class Dog 
    def initialize age 
     @age = age 
    end 
end 

class Dog_T 
    attr_reader :age # you need a reader to able to access it 
    def initialize age 
     @age = age 
     Favourite.favourite_it(self) 
    end 
end 

d1 = Dog_T.new(10) 
d2 = Dog_T.new(12) 
all_f = Favourite.get_favourites 

all_f.each do |obj| 
    puts "#{obj.class}: #{obj.age if obj.respond_to?(:age)}" 
end 
puts '-' * 20 

d3 = Dog_T.new(15) 
all_f = Favourite.get_favourites 

all_f.each do |obj| 
    puts "#{obj.class}: #{obj.age if obj.respond_to?(:age)}" 
end 

このプログラムの出力は次のようになります。

Dog_T: 10 
Dog_T: 12 
-------------------- 
Dog_T: 10 
Dog_T: 12 
Dog_T: 15 
関連する問題