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

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

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 ' не дало мне никаких результатов.


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


Ответы (4)


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

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
person Andrew Grimm    schedule 23.01.2012
comment
Вы бы так подумали, но не здесь. Это как-то связано с наследованием — методы базового класса доступны в созданном объекте, а методы фактического класса — нет. Когда я меняю имя класса на HbProcessor, вдруг все в порядке. - person jcollum; 23.01.2012
comment
@jcollum: Можете ли вы предоставить минимальный пример кода, который воспроизводит ошибку, о которой вы говорите? В вашем вопросе есть код, который не имеет отношения к этой ошибке, и отсутствует код, который мне нужен для воспроизведения этой ошибки. - person Andrew Grimm; 24.01.2012
comment
В конце концов класс, который должен был иметь цифру в середине, оказался неиспользованным. Я отмечу это как ответ и пойду дальше. - person jcollum; 31.01.2012

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

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

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

>> load("/mnt/hgfs/kodiak/lib/processors/H2b_processor.rb")
TypeError: superclass mismatch for class H2bProcessor
person rio    schedule 23.01.2012
comment
Я отлаживал прямо перед строкой, которая создает регистратор. Создаваемый объект имеет методы базового класса, но не методы класса. Измените имя класса на HtoBProcessor, и вдруг все в порядке. - person jcollum; 23.01.2012

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

Сведен к простейшему фрагменту "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" помещается в конец строки.

person Ray Baxter    schedule 22.11.2015

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

person Al Katawazi    schedule 23.01.2012