Переменные класса и расширение модуля - PullRequest
2 голосов
/ 02 ноября 2010

У меня есть модуль, подобный следующему

module MyModule
  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    def foo
      @@var = 1
    end

    def bar
      puts @@var
    end
  end
end

class A
  include MyModule
  foo
end

class B < A; end

, так что

 B.bar outputs '1'.

Однако я хотел бы, чтобы .bar определялся только при вызове .foo.Я пытался

module MyModule
  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    def foo
      @@var = 1
      extend SingletonMethods
    end

  module SingletonMethods
    def bar
      puts @@var
    end
  end
end

Проблема в том, что

B.bar

возвращает ошибку "неинициализированная переменная класса @@ var в MyModule :: SingletonMethods".Как я могу сделать так, чтобы переменная, определенная в .foo, была доступна для .bar?

Ответы [ 2 ]

1 голос
/ 02 ноября 2010

используйте mattr_accessor вместо

0 голосов
/ 11 ноября 2012

Мне удалось получить доступ к переменным класса из модуля, используя собственный синтаксис

class User
  include Base
  @@attributes = [:slug, :email, :crypted_password]
end

module Base
  def self.included(base)
  base.extend ClassMethods
end

def headers
  if defined? self.attributes
    self.attributes
  end
 end
end

Теперь вызов User.headers дает мне ожидаемый результат [:slug, :email, :crypted_password]

Если кто-нибудь может пролить больше света на то, почему это работает именно так в ruby, пожалуйста, дайте мне знать!

...