2012-01-05 3 views
42

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

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

    def noise 
    @noise 
    end 
end 

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

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

Это приводит к Howdie!

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

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

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

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

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

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

Заранее за вашу помощь.

+0

Вы действительно можете получить доступ к @noise, или это то, что вы видите побочный эффект функции, которую вы вызываете ... – LVB

ответ

31

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

def noise=(noise) 
    @noise = noise 
end 

def last_noise 
    @noise 
end 

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

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

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

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

Это возвращает «Howdie», несмотря на то, что нет геттера определено.

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

+2

+1 Райан. Как обычно, ваш опыт превосходит, и я не знал об экземпляре_variable_get! –

+0

эй, который не слишком по-аттракцион, attr_protected делает это? –

+0

Ответил на мой вопрос: - api говорит: «Атрибуты, названные в этом макросе, защищены от массового присвоения» –

14

Строка кода

puts man.noise=("Howdie!") 

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

Строка кода

puts man.noise 

ДЕЛАЕТ использовать метод получения, и он не будет работать, если вы удалите метод получения.

+0

Итак, я думаю, мой вопрос: зачем использовать методы getter & setter? Почему бы просто не использовать метод setter (или базовый метод, который позволяет мне передать значение методу) и иметь «возврат» на это? Я не предлагаю лучший способ делать вещи, я искренне спрашиваю, почему? Я не понимаю. – Nathan

+1

Вам нужен метод getter, потому что иногда вы хотите получить значение переменной без ее изменения. Метод setter всегда присваивает значение чему-то, поэтому невозможно использовать метод setter для получения значения без его модификации! –

+0

Вам нужен только метод getter, если вы хотите, чтобы переменная читалась методами вне класса. Если вы просто хотите прочитать переменную из метода в классе, вы можете просто использовать '@ noise' вместо метода getter. –

5

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

Предположим, что уже существует член @a.

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

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

, когда речь идет о поведении сеттера, обратите внимание:

  1. старое значение @a не может быть получен с сеттер, и получил перезаписаны.

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

+0

Я не понял вашего ответа, пока не прочитал все остальные , теперь, когда я сделал (и подумал немного больше), я думаю, что ваш ответ помогает вернуть мне вопрос. Если вы повышаете свой ответ, так это уменьшает потребность в новичках, подобных мне, чтобы сначала прочитать ответы всех остальных, а затем я хотел бы выбрать ваш. – Nathan

+0

рад, что это помогло;) – Jokester

1

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

class k: 
    i = 100 

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

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

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

Смежные вопросы