В Ruby, как написать код внутри класса, чтобы getter foo и setter self.foo = ... выглядели более похожими? - PullRequest
3 голосов
/ 20 марта 2011

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

foo

и мы используем сеттер

self.foo = something

Одному не нужно иметь self., а другому - есть, есть ли способ заставить их выглядеть более похожими, и не использовать что-то вроде self.foo в качестве получателя, так как это также выглядит многословно.

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

Ответы [ 3 ]

10 голосов
/ 20 марта 2011

Поскольку локальная область имеет приоритет, когда вы говорите foo = something, будет создана локальная переменная foo, которой будет присвоено содержимое something.

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

Если существует локальная переменная с тем же именем, что и у метода get, Ruby будет использовать ее значение вместо:

class Foo

  attr_accessor :foo

  def initialize
    @foo = :one
  end

  def f
    foo = :two
    foo
  end
end

Foo.new.f
# => :two

Чтобы прояснить, что вы хотите получить доступ к установщику, вы должны написать self.foo = something. Это скажет Ruby, что вы хотите выполнить метод foo= для объекта self с something в качестве параметра.

5 голосов
/ 20 марта 2011

Если вы хотите нарушить соглашения, вы можете написать свои сеттеры, используя стиль jQuery, используя один и тот же метод для геттера и сеттера, в зависимости от того, имеет ли он аргументы или нет:

def foo *args
  return @foo if args.empty?
  @foo = args.first
end
# => nil

foo
# => nil 
foo(:bar) # foo = :bar
# => :bar 
foo
# => :bar 
1 голос
/ 20 марта 2011

Насколько я знаю, в Ruby нет способа обойти это.Я уверен, что именно так Ruby оценивает выражения.

Когда задано значение, Ruby сначала проверит, существует ли локальная переменная в контексте, соответствующая вызываемой.Если есть (возможно, 'foo' в вашем случае), это будет используемое значение.Если такого значения нет, то Ruby попытается найти значение как вызов метода (переходя к «self» в качестве вызывающей стороны).Если в пути поиска такого метода не существует, возникает ошибка.

Необходимость использования «self» в установщике состоит в том, чтобы избежать установки Ruby значения в качестве локальной переменной, в то время как отсутствиеИспользование «self» работает только в экземпляре getter, когда в этом контексте не используется локальная переменная с тем же именем.Вероятно, лучше и яснее, хотя и немного более многословно, быть явно при использовании себя, чтобы избежать путаницы относительно того, откуда берутся ценности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...