Доступ до змінної екземпляра поза межами класу


82

Якщо змінна екземпляра належить до класу, чи можу я отримати доступ до змінної екземпляра (наприклад @hello) безпосередньо за допомогою екземпляра класу?

class Hello
  def method1
    @hello = "pavan"
  end
end

h = Hello.new
puts h.method1

Відповіді:


148

Так, ви можете використовувати instance_variable_getтак:

class Hello
  def method1
    @hello = "pavan"
  end
end

h = Hello.new
p h.instance_variable_get(:@hello) #nil
p h.method1                        #"pavan" - initialization of @hello
p h.instance_variable_get(:@hello) #"pavan"

Якщо змінна не визначена (перший виклик instance_variable_getу моєму прикладі), ви отримуєте nil.


Як згадав Ендрю у своєму коментарі:

Ви не повинні робити це типовим способом доступу до змінних екземпляра, оскільки це порушує інкапсуляцію.

Кращим способом є визначення доступу:

class Hello
  def method1
    @hello = "pavan"
  end
  attr_reader :hello  
end

h = Hello.new
p h.hello #nil
p h.method1                        #"pavan" - initialization of @hello
p h.hello #"pavan"

Якщо ви хочете інше ім'я методу, ви могли б псевдонім аксессор: alias :my_hello :hello.

І якщо клас визначений не у вашому коді, а в самоцвіті: ви можете змінювати класи у своєму коді та вставляти нові функції до класів .


6
Ви не повинні робити це типовим способом доступу до змінних екземпляра, оскільки це порушує інкапсуляцію.
Ендрю Маршалл,

@knut ми не можемо просто робити це як h = Hello.newі h.method1та h.hello?
nik7

3
@nlingutla Ви можете визначити аксесуар за допомогоюattr_reader :hello
knut

Чи не так би було alias my_hello hello, чи не так alias :my_hello :hello?
Позовні фонди Моніки

1
Для мене це чудово підходить для специфікацій, де ви не хочете робити щось загальнодоступним.
baash05,

20

Ви також можете досягти цього, зателефонувавши attr_readerабо attr_accessorяк:

class Hello
  attr_reader :hello

  def initialize
    @hello = "pavan"
  end
end

або

class Hello
  attr_accessor :hello

  def initialize
    @hello = "pavan"
  end
end

Виклик attr_readerстворить getterдля заданої змінної:

h = Hello.new
p h.hello        #"pavan"

Виклик attr_accessorстворить getterІ setterдля заданої змінної:

h = Hello.new
p h.hello        #"pavan"
h.hello = "John"
p h.hello        #"John"

Як ви зрозуміли, використовуйте attr_readerі attr_accessorвідповідно. Використовуйте лише attr_accessorтоді, коли вам потрібне getterІ setterта, і використовуйте, attr_readerколи Вам потрібно лишеgetter

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.