web-dev-qa-db-ja.com

モジュールのインスタンス変数?

モジュールのインスタンスを作成できない場合でも、モジュールにインスタンス変数を含めることができますか?以下のモジュールStacklike@stackの目的は何ですか?

module Stacklike
  def stack
    @stack ||= []
  end
end
34
Hommer Smith

インスタンス変数は、モジュールを含むクラスに存在するものと考えてください。物事はもう少し理にかなっています。

module Stacklike
  def stack
    @stack ||= []
  end

  def add_to_stack(obj)
    stack.Push(obj)
  end

  def take_from_stack
    stack.pop
  end
end

class ClownStack
  include Stacklike

  def size
    @stack.length
  end
end

cs = ClownStack.new
cs.add_to_stack(1)
puts cs.size

「1」を出力します

43
mcfinnigan

以下を参照してください。

_p Ruby_VERSION
module Stacklike
  def stack
    @stack ||= []
  end

  def add_to_stack(obj)
    stack.Push(obj)
  end

  def take_from_stack
    stack.pop
  end
end

class A
include Stacklike
end

a = A.new
p a.instance_variables #<~~ E
p a.instance_variable_defined?(:@stack) #<~~ A
a.add_to_stack(10) #<~~ B
p a.instance_variable_defined?(:@stack) #<~~ C
p a.instance_variables #<~~ D
_

出力:

_"1.9.3"
[]
false
true
[:@stack]
_

説明:はい、クラス内でModuleを使用する場合、classincludeインスタンス変数が存在します。ただし、_[〜#〜] a [〜#〜]までは_@stack_がまだ定義されていないため、p a.instance_variable_defined?(:@stack)falseを示していることがわかります。ポイントで[〜#〜] b [〜#〜]インスタンス変数@stackを定義しました。したがって、ポイント[〜#〜] c [〜#〜]のステートメントは、trueとして出力されます。モジュール自体はモジュールインスタンス変数を作成していませんが、classにそのモジュールが含まれていれば、classインスタンスで作成できます。 [〜#〜] e [〜#〜]のステートメントは、_[]_を出力しますが、インスタンス変数は定義されていませんが、行の出力が表示される場合[〜#〜] d [〜#〜]、_@stack_が_class A_のオブジェクトa内にあることが証明されます。

なぜそのようなデザインですか?

これは設計であり、要件から生じる場合があります。たとえば、ABという2つのチケット予約会社が使用するスタック操作コードを記述するように求められたとします。現在、Aは、顧客がサービスを提供するスタックポリシーですが、それについても正式な手続きがあります。 B会社も、Aとは異なる独自の形式でスタックポリシーを使用しています。したがって、_class A_および_class B_内でStack操作を設計する場合は、ABの両方に共通の機能があるため、共通の場所に記述することをお勧めします。将来、別の会社Cが登場した場合、各ABおよびCに対して同じ機能を書き換えることなく、そのモジュールをクラスに使用することもできます。より多くの考えがありますが、これが質問の最後の部分であなたの自己に答えるのに役立つことを願っています。

それがコンセプトです。それが役に立てば幸い。

乾杯!!

13
Arup Rakshit

モジュールをクラスに含めると、そのすべてのインスタンスメソッドが実質的にHostクラスに「貼り付け」られます。あなたが持っている場合:

class Lifo
  include Stacklike
end

l = Lifo.new
l.add_to_stack(:widget)

lには、Stacklikeから取り込まれたインスタンス変数@stackがあります。

5
Chowlett

モジュールのStacklikeを他のクラスに含めると、そのインスタンス変数はそのクラスで定義されているかのように利用可能になります。これにより、モジュール自体から基本クラスのインスタンス変数を設定および処理するオプションが提供されます。

4
Erez Rabih