-2
module Module1
  class Base1
    class << self
      attr_accessor :attr1, :attr2
      def configure
        yield(self) if block_given?
      end
    end
  end
end 

module Module1
  class Child1 < Base1
     def self.some_method1
       #... some stuff
       "#{attr1}_123"  #for some reason attr1 is nil
     end
  end
end 


  Module1::Base1.configure do |item|
    item.method1 = "43243243"
    item.method2 = "fdsfdsfd"
  end




  data1 = Module1::Child1.some_method1 #it doesn't return what I expect

何らかの理由 attr1で、inは値がある場所とChild1#some_method1nil異なりModule1::Base1.method1ます。それを取り除くためになぜそして何をすべきか疑問に思いますか?

4

2 に答える 2

1

attr_accessorインスタンス変数を作成するため、コードはクラスインスタンス変数を作成します。クラスはオブジェクトであるため、インスタンス変数も持つことができます。これらの変数は継承されません。

クラス変数(@@foo)もありますが、これは驚くべきことです。派生クラスの値を変更すると、階層全体の値が変更されます。

Rubyには、メソッド継承が機能するのと同じ方法で継承されるタイプの変数はありません。アクティブサポートなどのライブラリは、このように動作するアクセサを作成するための適切なフックを設定するバージョンattr_accessor(アクティブサポートはそれを呼び出します)を追加します-そのソースを見ることができますclass_attribute

于 2013-02-04T08:02:13.210 に答える
1

まず第一に、私はそこにあるべきだと思いますs/method/attr/g

Module1::Base1.configure do |item|
  item.method1 = "43243243"
  item.method2 = "fdsfdsfd"
end

二次的に、some_method1私たちはeigenclass'attrと呼びます:

#... some stuff
"#{Base1.attr1}_123"  #for some reason attr1 is nil

降伏:

#!/usr/bin/ruby

module Module1
  class Base1
    class << self
      attr_accessor :attr1, :attr2
      def configure
        yield(self) if block_given?
      end
    end
  end
end 

module Module1
  class Child1 < Base1
     def self.some_method1
       #... some stuff
       "#{Base1.attr1}_123"  #for some reason attr1 is nil
     end
  end
end

Module1::Base1.configure do |item|
  item.attr1 = "43243243"
  item.attr2 = "fdsfdsfd"
end

puts Module1::Child1.some_method1 #it does return what I expect

与える:

$ /tmp/a.rb
43243243_123
于 2013-02-04T09:28:16.300 に答える