Должен ли метод ruby ​​изменять метод экземпляра класса? - PullRequest
1 голос
/ 04 августа 2011

Я пишу класс в Ruby, где у меня есть переменные экземпляра (например, @person_summary_info, @name, @dob, @favorite_food) для класса.

Для анализа фрагмента текста,У меня есть открытый метод, который я вызываю извне класса (давайте назовем его interpret).

Этот метод вызывает некоторые методы частного класса, такие как get_name, которые используют @person_summary_info для извлечения соответствующего фрагментаинформация (в данном случае имя человека).Если эти частные методы:

a) используют экземпляр @person_summary_info или получают эту информацию через передаваемый им параметр (т. Е. get_name vs get_name(person_summary_info))

b) изменяют экземплярпеременная напрямую и ничего не возвращает, или не изменяет ничего вне области действия функции и возвращает результат (т. е. внутри get_name, задает @name = 'John' или return 'John')?

Какова лучшая практика здесь?Спасибо!

Ответы [ 3 ]

1 голос
/ 08 мая 2012

использование @instance напрямую из другого класса - хороший способ решить проблемы.Каждый класс должен иметь свои собственные переменные, и все, что вы хотите обработать или вернуть обратно, должно быть назначено / возвращено напрямую ... это означает, что

@instance = my_class.get_name(person_summary_info)

, а не

my_class.get_name

Простопопытайтесь представить, как протестировать этот код с помощью переменных @instance и шанс повторно использовать этот фрагмент кода ..

только мой 2c

1 голос
/ 10 мая 2012

Я включил мое лучшее представление вашего вопроса в код в нижней части моего ответа, но я хотел бы представить свое решение, поскольку я сначала понимаю вашу дилемму ...

Сделайте это, если ваш атрибут name предназначен для публичного доступа:

class Person
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def interpret(text_to_parse)
    # I have no idea what you are parsing in real life
    self.name = text_to_parse.split.last
  end
end

person = Person.new("Frederick")
puts person.name
# => "Frederick"
person.interpret("Please, call me Fred")
puts person.name
# => "Fred"

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

class Person
  def initialize(name)
    @name = name
  end

  def interpret(text_to_parse)
    # I have no idea what you are parsing in real life
    @name = text_to_parse.split.last
  end
end

person = Person.new("Frederick")
puts person.instance_variable_get("@name")
# => "Frederick"
person.interpret("Please, call me Fred")
puts person.instance_variable_get("@name")
# => "Fred"

И, как уже упоминалось выше, вот мой лучший перевод вашего вопроса в код:

class Person
  def initialize
    @person_summary_info = { name: "foo" }
    @name = "bar"
    @dob = "baz"
    @favorite_food = "beer"
  end

  def interpret(text_to_parse)
    # Some kind of parsing?
    get_name_1
    # OR
    get_name_2(@person_summary_info)
    # OR
    get_name_3
    # OR
    @name = get_name_4
  end

  private
  def get_name_1
    @person_summary_info[:name]
  end

  def get_name_2(person_summary_info)
    person_summary_info[:name]
  end

  def get_name_3
    @name = 'John'
  end

  def get_name_4
    'John'
  end
end

Надеюсь, вы можете понять, почему в комментариях возникает путаница относительно того, что именно вы спрашиваете. Если ничего другого, возможно, это поможет вам сформулировать ваш вопрос более четко, чтобы мы могли помочь!

Наконец, вам следует избегать написания собственных методов получения / установки в Ruby, если только вам не нужно подключать некоторый пользовательский код к процессам получения / установки - используйте макросы уровня класса attr_reader / attr_writer / attr_accessor создать их для вас.

1 голос
/ 07 мая 2012

Если функция interpret () не предназначена для изменения состояния конкретного экземпляра Person, подумайте над тем, чтобы присвоить методу имя что-то вроде get_name_from_string (string) и, возможно, сделать его статическим, поскольку он ничего не делает для состояния экземпляра.

Если вы хотите, чтобы interpret () изменил состояние определенного экземпляра Person, подумайте об изменении имени метода, добавив к нему префикс set и включив имя устанавливаемого атрибута (set_name_from_string ()).Если задано несколько атрибутов, то, возможно, set_from_string () и включить комментарий кода, указывающий, какие переменные экземпляра изменяются.Внутренне метод может вызывать get / set_name (), как описано ниже.

Как правило, методы getter / setter являются публичными и должны быть достаточно простыми, делая то, что предполагает их имя: - getName () возвращает переменную экземпляра @name- setName (name) устанавливает или перезаписывает переменную экземпляра @name с переданным значением и ничего не возвращает

В Java это тип POJO , в частности Java Beans (исключая частьо необходимости быть сериализуемым) Очень распространенная практика программирования на нескольких разных языках, чтобы иметь общедоступные методы установки / получения для переменных экземпляра, а также иметь конструктор по умолчанию (тот, который не принимает аргументов) и другой конструктор, позволяющий устанавливать переменные экземплярапосле создания объекта.

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