Как получить доступ к переменной экземпляра ребенка в классе super / parent - PullRequest
0 голосов
/ 12 октября 2018

У меня есть следующий пример:

class A
   @Values = {}

   def initialize()
     @Values.each{ |_key, _val|
        puts("Key: #{_key}, Val: #{_val}")
     }
   end
end

class B < A
  @Values = { "Test1": "1", "Test2": "2"}

  def initialize()
    super()
  end
end

Моя проблема:

B.new()

Не создает выходных данных - поэтому значения @ из класса B недоступны в классе A. Почему?Как я могу получить к ним доступ?

========= Обновить ========= Спасибо за ваши ответы!

@ Мосаб Мухаммед: Да - я действительно не уверен, когда использовать {}, а когда использовать do end ... Я посмотрю на оба варианта, когда использовать.

{} (обычно используется для однострочных блоков) или do..end (используется для многострочных блоков).

Правильно - я читал, что это вродесоглашения Rail, чтобы сделать это, но есть больше - {} и конец и ведут себя иначе.

@@ будет вариант, но я не думаю, что это хорошая идея для редактирования переменных класса - так как выупомянуто, это может иметь очень неприятные побочные эффекты.

@ Алексей Матюшкин - Спасибо!Я посмотрю на self.class.instance_variable_get и посмотрю, как он себя поведет и решит ли он мою проблему!

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Ответ на ваш вопрос @Values from class B are not available in class A. Why? таков: переменная экземпляра, объявленная на уровне класса, недоступна на уровне объекта.

И ответ на ваш вопрос How can i access them?: Вы можете объявить класспеременная @@values вместо переменной экземпляра @values в методе initialize.

Ваш пример будет изменен на:

class A
  @@values = {}

  def initialize()
    @@values.each{ |_key, _val|
      puts("Key: #{_key}, Val: #{_val}")
    }
  end
end

class B < A
  @@values = { "Test1": "1", "Test2": "2"}
end

Now B.new Будет выводить

Key: Test1, Val: 1
Key: Test2, Val: 2

Другой ответ:

class A

   def initialize()
     @values ||= {}
     @values.each{ |_key, _val|
        puts("Key: #{_key}, Val: #{_val}")
     }
   end
end

class B < A

  def initialize()
    @values = { "Test1": "1", "Test2": "2"}
    super()
  end
end

Примечание. Переменные класса являются общими для связанных классов и могут быть перезаписаны из дочернего класса.Это означает, что если вы переопределите переменную класса @@values в классе B, @@values в классе A будет перезаписан.

Другое примечание: {} (обычно используется для однострочных блоков) или do ..конец (используется для многострочных блоков).

Например: используйте

def initialize()
  @Values.each{ |_key, _val| puts("Key: #{_key}, Val: #{_val}") }
end

Вместо:

def initialize()
  @Values.each{ |_key, _val|
    puts("Key: #{_key}, Val: #{_val}")
  }
end

ИЛИ

Использовать

def initialize()
  @Values.each do |_key, _val|
    puts("Key: #{_key}, Val: #{_val}")
  end
end

Вместо:

def initialize()
  @Values.each{ |_key, _val|
    puts("Key: #{_key}, Val: #{_val}")
  }
end
0 голосов
/ 12 октября 2018

Что ж, у этого кода очень много проблем, поэтому я отвечу на поставленный вопрос.Если вы хотите, чтобы переменная была доступна как из класса, так и из мгновенного контекста, используйте вместо нее переменную класса :

class A
  @@values = {}
  def initialize
    @@values.each{ |key, val|
      puts("Key: #{key}, Val: #{val}")
    }
  end
end

class B < A
  @@values = { "Test1" => "1", "Test2" => "2"}
  def initialize
    super
  end
end

B.new
#⇒ Key: Test1, Val: 1
#  Key: Test2, Val: 2
...