Де розмістити приватні методи в Ruby?


95

Більшість блогів, навчальних посібників чи книг мають приватні методи внизу будь-якого класу / модуля. Це найкраща практика?

Я вважаю, що використання приватних методів, як і коли потрібно, є більш зручним. Наприклад:

public
def my_method
  # do something
  minion_method
end

private
def minion_method
  # do something
end

public
def next_method
end

Таким чином, я вважаю код більш читабельним, замість того, щоб постійно прокручувати вгору і вниз, що дуже дратує.

Чи є щось страшенно неправильне у цьому підході? Мати приватні методи внизу - це не просто найкраща практика та щось інше?


насправді ваш шлях теж непоганий. Я також дотримуюсь того самого в кількох випадках, це відчуває себе більш зручноprivate def my_method...end
r3bo0t

Відповіді:


131

Найкраща практика на мою точку зору - послідовно йти і заявляти про свої методи, не дотримуючись приватної точки зору.

Зрештою, ви можете зробити будь-який метод приватним, просто додавши: private :xmethod

Приклад:

class Example
 def xmethod
 end

 def ymethod
 end

 def zmethod 
 end

 private :xmethod, :zmethod

end

Чи виправдовує це ваше запитання?


19
Я не думаю, що це чудова ідея з точки зору читабельності, оскільки клас стає довшим і довшим.
Олександр Сурафель

2
Я справді думаю, що вам слід сортувати методи за порядком важливості і за тим, що називає, коли всі інші речі здаються рівними. Приватні методи - це деталі реалізації, і вони повинні бути останнім, що читач бачить, тому належить нижче у файлі. Я погоджуюсь із наведеним вище коментарем, що це не буде працювати з більшими файлами. Це не повинна бути прийнятою відповіддю, на цій сторінці є набагато кращі поради.
Люк Коуелл

58

Також існує можливість додавання privateдо визначення методу, починаючи з Ruby 2.1.

class Example

 def xmethod
 end

 private def ymethod
 end

 private def zmethod 
 end

end

Переглядаючи визначення, ви миттєво знаєте, чи є метод приватним, незалежно від того, де у файлі він визначений. Це трохи більше набору тексту (якщо ви не виконуєте автозаповнення), і не всі ваші defs будуть добре вирівняні.


5
Ви повинні були додати, що це доступно в Ruby 2.1, де методи повертають ключ із власним іменем: bugs.ruby-lang.org/issues/3753
konole

Я вважаю, що приватний також може бути використаний як блок, він же включає деякі приватні методи у приватний begin ... end
edx

див. відповідь @devpuppy тут для примітки про те, як це робити за допомогою методів класу.
манро

Додавання privateлише один раз, до ymethod, також працює. Немає необхідності додавати його кілька разів.
Юліан Онофрей

@IulianOnofrei Якщо у вас інший метод нижче zmethodбез private, цей метод не буде приватним. Отже, вам потрібно повторити це (принаймні з Ruby 2.3).
tsauerwein

52

Як вже вказували інші, конвенція полягає в тому, щоб помістити приватні методи внизу, під один приватний клас. Однак, мабуть, вам також слід знати, що багато програмістів використовують для цього метод подвійного відступу (4 пробіли замість 2). Причина полягає в тому, що часто в текстовому редакторі ви не побачите "приватний" і припускаєте, що вони можуть бути загальнодоступними. Див. Ілюстрацію нижче:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

    def some_private_method
    end

    def another_private method
    end

end

Цей метод повинен уникнути необхідності прокручувати вгору і вниз і зробить інших програмістів зручнішими у вашому коді.


4
Це була вся лють, коли я залишив цей коментар ще в 12 році. Я бачу це вже не так часто, і це не вдалося.
Ноа Кларк

рядові також можуть бути відформатовані всередині begin..endвідразу після private. Тоді редактор може автоматично встановити відступ, оскільки код всередині begin(у прикладі вище) має семантичний відступ із 4 пробілами.
Petrus Repo

Я дотримуюсь того самого підходу ... спочатку, publicа потімprivate
Рахул Гоял

1
Я ніколи цього не бачив, і я працюю з Ruby з 2007 року. Я б взагалі не рекомендував цього.
Марнен Лейбоу-Козер

15

Я думаю, що загальнодоступні методи - це якийсь інтерфейс об’єкта, і логічно розміщувати їх на найвидатнішому місці, тобто у верхній частині файлу.


5
Так, розмістіть загальнодоступні методи там, де ви їх найімовірніше знайдете, зазвичай у верхній частині файлу, а речі, на які ви, мабуть, не слід дивитись, повинні бути поховані внизу. Як написано газетну статтю, викладайте найважливіше на перше місце.
тадман

14

Вам не потрібно ставити publicабо privateнад кожним методом. Я зазвичай ставлю всі свої приватні методи внизу свого класу. Крім того, не потрібно чітко говорити, publicоскільки методи є загальнодоступними за замовчуванням. Наприклад:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

  def some_private_method
  end

  def another_private method
  end

end

Будь ласка, прочитайте моє запитання ще раз. Відредагували це, щоб бути більш конкретним
ZX12R

1
Це більше умовний зв’язок, ніж будь-що інше. Те, що ви робите, є дійсним, і якщо для вас це має більше сенсу, то слід дотримуватися цього. Я вважаю конвенцію більш читабельною, але це, мабуть, тому, що саме так мене навчили писати, тому я просто звик до неї.
Кайл Деко

що насправді означає / робить оголошення методу "загальнодоступним"?
ZX12R

6

Я походжу з фону Java, і я ненавиджу прокручувати, щоб побачити тип методу. Я думаю, це божевільно, що не можна визначити видимість методу для кожного методу без потворності. Тож я закінчив додавати коментарі #privateперед кожним методом смоктання, а потім оголошувати private :....


1
а нещодавній рубін можна просто поставити, private def method...щоб було приємніше
Акостадінов

5

Мені не подобається вказувати відкритий або приватний для кожного методу. Розміщення всіх приватних методів внизу дозволяє мені мати один екземпляр "приватного" на файл. Думаю, це справа смаку.


5

Один стиль для групових методів разом , так що ви використовуєте тільки privateі protectedодин раз в класі максимум. Інший стиль - це вказати видимість відразу після визначення методу:

class Example
  def my_private_method
  end
  private :my_private_method

  def my_public_method
  end
end

Починаючи з Ruby 2.1.0, defповертає назву методу як символ, тому можливий більш впорядкований стиль:

class Example
  private def my_private_method
  end

  def my_public_method
  end

  protected def my_protected_method
  end

  private_class_method def self.my_private_class_method
  end
end

(Зверніть увагу, що ми використовуємо private_class_methodдля методів класу - інакше ми отримаємо, NameError: undefined methodоскільки privateочікуємо методу екземпляра. Навіть використовуючи його як макрос, як у вихідному прикладі, це впливає лише на видимість методів екземпляра.)

Мені найбільше подобається цей стиль вбудованої видимості, оскільки він дозволяє впорядковувати методи за вашим бажанням. Це зменшує ризик додавання нового методу в неправильному місці та ненавмисне перетворення його на приватний.

Що стосується синтаксису методу класу, замість цього ви можете впоратися з ним таким чином:

class Example
  private def my_private_method
  end

  class << self
    private def my_private_class_method
    end
  end
end

це єдине місце, де я вже бачив згадування про private_class_methodдзвінок, і остання частина про використання class << selfблоку, щоб уникнути необхідності його використання, є гарною підказкою. До цього часу я не знав, що методи "норнального" класу (оголошені def self.foo; endзамість class << self; def foo; endне будуть впливати на privateспецифікатор.
manroe

3

Денніс мав ідеальну відповідь, тобто, коли використовується ruby> = 2.1, просто додайте префікс def до приватного (або захищеного, загальнодоступного)

Але я вважаю, що тепер також можна використовувати private як блок, як у:

private begin
   def foo
   end
   def bar
   end
end

def zip
end

0

Як правило, я замовляю свої методи наступним чином:

  1. Конструктор
  2. Інші публічні методи в алфавітному порядку
  3. private, написаний лише один раз
  4. Приватні методи, в алфавітному порядку

Я використовую функції "перейти до визначення" у своєму редакторі, щоб це не вимагало великої прокрутки, і в будь-якому випадку, якщо клас досить великий, що прокрутка стає проблематичною, її, мабуть, слід розбити на кілька класів.


Слід також зазначити, що я зазвичай розміщую методи перетворення (наприклад, to_s) в кінці загальнодоступного розділу.
Марнен Лейбоу-Козер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.