Подтвердить что ты не робот

Попытка узнать/понять методы Ruby setter и getter

Я просто учился программировать и решил попробовать Ruby. Я уверен, что это глупый вопрос, но инструктор говорит о методах сеттера и геттера, и я в замешательстве. Вот пример:

class Human
  def noise=(noise)
    @noise = noise
  end

  def noise
    @noise
  end
end

Из этого создается экземпляр класса, и я могу это сделать:

man = Human.new
man.noise=("Howdie!")
puts man.noise

В результате получается Howdie!

Теперь меня смущает то, что инструктор говорит без метода геттера (второй из двух методов), нет возможности взаимодействовать с переменной экземпляра @noise.

Но когда я удаляю метод getter, я могу получить доступ к @noise, см. пример:

class Human
  def noise=(noise)
    @noise = noise
  end
end

man = Human.new
puts man.noise=("Howdie!")

Это работает так же, как при использовании метода геттера.

Итак, теперь я смущен. Почему нужен геттер? Что означает инструктор, не имея возможности получить доступ к переменной экземпляра без нее? Возможно ли, что он использует более старую версию Ruby?

Заранее благодарим за помощь.

4b9b3361

Ответ 1

Вы можете взаимодействовать с этой переменной экземпляра из других методов, принадлежащих этому экземпляру, даже если у него нет геттера:

def noise=(noise)
  @noise = noise
end

def last_noise
  @noise
end

Не обязательно, чтобы геттер определялся с тем же именем, что и метод; эти два не связаны вообще. Геттер необходим для "получения" значения переменной экземпляра, но только в коротком синтаксисе.

В вашем примере происходит то, что вы инициализируете новый объект (Human.new), а затем с помощью метода (noise=, да имя метода содержит символ =), который просто так происходит определить переменную экземпляра (т.е. переменную только для этого экземпляра), а затем, наконец, вернуть эту переменную экземпляра другим вызовом метода.

Фактически вы можете использовать instance_variable_get для получения переменной экземпляра без определения какого-либо getter вообще:

man = Human.new
man.noise = "Howdie"
man.instance_variable_get("@noise")

Это приведет к возврату "Howdie", даже если он не определен.

И нет, я не думаю, что он использовал более старую версию Ruby.

Ответ 2

Строка кода

puts man.noise=("Howdie!")

НЕ использует метод getter, поэтому для его работы не нужно определять метод getter. Эта строка просто использует метод setter. Возвращаемое значение метода сеттера автоматически равно всем, что находится на правой стороне знака равенства, поэтому "Howdie!" получает значение puts.

Строка кода

puts man.noise

Использует метод getter, и это не сработает, если вы удалите метод getter.

Ответ 3

Конечно, оба они возвращают значение, но их поведение отличается.

Скажем, что уже есть член @a.

с геттером, то получается текущее значение @a, не изменяя его.

с установщиком, один изменяет @a и получает его новое значение как возвращаемое значение.

когда вы думаете о поведении установщика, обратите внимание:

  • старое значение @a не может быть получено с установщиком и перезаписано.

  • то, что возвращается setter, на самом деле уже известно до вызова setter.

Ответ 4

Может быть, внимание для геттеров и сеттеров связано с тем, что некоторые другие языки позволяют вам напрямую обращаться к переменным класса. Python:

class k:
    i = 100

print k.i # 100
k.i = 200
print k.i # 200

В отличие от этого Ruby сохраняет все свои переменные полностью закрытыми для класса и только предоставляет их с помощью методов доступа.

В вашем примере, если вы удалите getter, вы действительно можете взаимодействовать с переменной (то есть: изменить ее) через setter, но вы не можете вернуть ее (в обычном порядке), когда вам это нужно.