Где разместить частные методы в 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 01

Я считаю, что private также можно использовать в качестве блока, иначе говоря, включение некоторых частных методов в private 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 года. Я обычно не рекомендую его.
Marnen Laibow-

15

Я считаю, что публичные методы - это своего рода интерфейс объекта, и логично разместить их на самом видном месте, то есть в верхней части файла.


5
Да, размещайте общедоступные методы там, где вы, скорее всего, их найдете, обычно в верхней части файла, а то, на что вам, вероятно, не следует смотреть, следует закопать внизу. Как пишется газетная статья, ставьте самое важное на первое место.
tadman

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спецификатором.
Манро

3

У Денниса был идеальный ответ, то есть при использовании ruby> = 2.1 просто префикс def с помощью private (или protected, public)

Но я считаю, что теперь также можно использовать 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.