Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Есть ли правило не помещать числа в имена классов?

Автор вопроса: jcollumОтветов: 4

Я создаю серию классов, которые наследуются от общего класса. Экземпляры классов создаются с помощью этого кода (реквизит этому парню):

def self.create(service, logger)
  classified_name = service.name.to_s.split('_').collect! { |w| w.capitalize }.join << "Processor"
  service_proc = Object.const_get(classified_name).new
  service_proc.logger = logger ||= Rails::logger

Итак, все работало нормально, пока я не столкнулся с сервисом, в названии которого была цифра. Это может показаться плохой идеей, но в данном случае процессор назван в честь внешней службы, в имени которой есть цифра. Я решил сохранить эту цифру, чтобы избежать путаницы. "HToB" не имеет значения, в то время как "H2B" действительно имеет значение в контексте моего приложения.

Ну и вдруг метод create умер:

NoMethodError: undefined method `logger=' for #<H2bProcessor:0xb737f20>

Хорошо, странно. Имейте в виду, что у меня есть еще 4 класса, которые строятся по тому же фабричному методу. Logger является свойством базового класса. Так что я немного возился с этим, а затем решил, что числительное, вероятно, все портит. Итак, я пытаюсь загрузить файл с цифрой в имени класса и без нее:

>> load("/mnt/hgfs/kodiak/lib/processors/H2b_processor.rb")
TypeError: superclass mismatch for class H2bProcessor
    from /mnt/hgfs/kodiak/lib/processors/H2b_processor.rb:1:in `<top (required)>'
[...]
[change the 2 in the name to "To"]
[...]
>> load("/mnt/hgfs/kodiak/lib/processors/H2b_processor.rb")
=> true

Итак, проблема решена. Тем не менее, это действительно заставило меня задаться вопросом: имеют ли цифры в именах классов какой-то недостаток в Ruby? Я немного погуглил, но не знал, что искать, такие вещи, как "соглашение об именах ruby ​​numeral ' не дало мне никаких результатов.

  • Где цифра? У вас не может быть номера в начале вашего класса, но в любом другом месте вы можете. Это часть формальной спецификации грамматики. d11wtq 23.01.2012
  • Вы можете увидеть имя класса в строке NoMethodError. jcollum 23.01.2012
  • Хотя вы можете использовать число, чтобы отличить один подкласс от другого, я думаю, что это приводит к запаху кода. Смысл наличия разных классов состоит в том, чтобы покрыть различные потребности в группировке данных и обработке. Подклассы предназначены для предоставления частичного набора функций, на которых можно основываться. Если класс достаточно важен для подкласса, я бы сказал, что он достаточно важен, чтобы иметь значимое имя, чтобы определить, что это такое. Если различия настолько незначительны, что вы можете использовать число, затем включить эти различия в родительский класс и. the Tin Man 23.01.2012
  • @theTinMan Я думаю, вы неправильно понимаете, почему там 2. В этом случае класс назван в честь сервиса, в имени которого действительно есть цифра 2. Я бы предпочел, чтобы имя класса было похоже на имя службы - в любом случае, я начал именно с этого шаблона. jcollum 23.01.2012
  • Понижение? Почему? Это то, что я действительно видел и очень хорошо задокументировал. Смешной. jcollum 25.01.2012
  • @jcollum: Потому что вы не предоставили достаточно кода, чтобы другие могли воспроизвести то, что происходит. Andrew Grimm 31.01.2012

rubynaming-conventions

Ответы

Ответ 1 · рейтинг 3 · Andrew Grimm

Вам не разрешено иметь числа в начале, но в остальном вы должны быть правы.

class H2O
end

H2O.new # Works fine

class 2Extreme
end

SyntaxError: compile error
(irb):5: trailing `E' in number
class 2Extreme
        ^
(irb):5: syntax error, unexpected tIDENTIFIER, expecting tCOLON2 or '[' or '.'
    from (irb):6
    from :0

Ответ 2 · рейтинг 1 · rio

NoMethodError: undefined method `logger=' for #<H2bProcessor:0xb737f20>

Судя по этому сообщению, загрузка класса прошла успешно. Я думаю, что просто не было метода 'logger='.

И для приведенной ниже ошибки посмотрите на этот вопрос. Вы получаете сообщение об ошибке, потому что у вас уже есть класс H2bPrecessor.

>> load("/mnt/hgfs/kodiak/lib/processors/H2b_processor.rb")
TypeError: superclass mismatch for class H2bProcessor

Ответ 3 · Ray Baxter

Эта проблема не имеет ничего общего с числительными. Вы неправильно используете заглавные буквы при создании имени класса.

Сведен к простейшему фрагменту "h2b".capitalize => "H2b", а не "H2B".

Вам не нужен H2bProcessor, вам нужен H2BProcessor, так что вместо

"h2b".to_s.split('_').collect! { |w| w.capitalize }.join << "Processor" => "H2bProcessor"

использовать

"h2b".to_s.split(/_|(?<=\d)/).collect! { |w| w.capitalize }.join << "Processor" => "H2BProcessor"

Метод String#split принимает литеральную строку или регулярное выражение. Регулярное выражение разбивает строку либо на знак подчеркивания, либо после строки цифр. Каждый элемент этого массива ["h2", "b"] пишется с заглавной буквы отдельно, ["H2", "B"], затем массив объединяется, образуя строку "H2B", и, наконец, "Processor" помещается в конец строки.

Ответ 4 · рейтинг -5 · Al Katawazi

В общем, не очень хорошая практика кодирования - начинать вводить числа. Мне больше всего нравится Textbox1, Textbox2 и т.д. По сути, хорошее эмпирическое правило состоит в том, чтобы описать, что представляет собой ваш класс, или вставить его в массив контейнеров, если у вас их несколько. Я признаю, что код сгенерирован, но я думаю, что его можно было бы сделать лучше.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы