2010-06-26 5 views
8

Например, я всегда видел методы, называемые String#split, но никогда не String.split, что кажется несколько более логичным. Или, может быть, даже String::split, потому что вы могли бы рассмотреть #split, чтобы быть в пространстве имен String. Я даже видел метод один, когда предполагается/подразумевается класс (#split).Какое обоснование/история для # конвенции определения методов в Ruby?

Я понимаю, что именно так идентифицируются методы в ri. Что было первым?

Различия, например, от полей? Я также слышал, что это помогает отличать методы экземпляра от методов класса. Но где это началось?

+0

Я хочу знать, почему это соглашение не упоминается/объясняется в книгах/учебниках при обсуждении соглашений об именах рубинов. Я сбив с толку вижу имена методов с префиксом «#» в различных дискуссиях и только в состоянии угадать, какое значение имел префикс. Тот факт, что '#' начинает комментарий в источнике .rb, делает его вдвойне запутанным. Как вы можете себе представить, это не самая легкая вещь для поиска, поэтому спасибо, что спросили об этом где-нибудь, я смог наткнуться на нее. Интересно, смогу ли я снова найти его, когда забуду эти данные за 6 месяцев без рубиновой активности ... –

ответ

8

Разница указывает, как вы получаете доступ к методам.

Методы класса использовать :: разделитель, чтобы указать, что сообщение может быть отправлено на объект класса/модуля, в то время как методы экземпляра использовать # разделитель, чтобы указать, что сообщение может быть отправлено на объект экземпляра.

Я собираюсь выбрать класс Complex (в Ruby 1.9), чтобы продемонстрировать разницу. У вас есть как Complex::rect, так и Complex#rect. Эти методы имеют различную сущность, и они служат совершенно другим целям. Complex::rect принимает реальный и воображаемый аргумент, возвращая новый экземпляр Complex, а Complex#rect возвращает массив реальных и мнимых компонентов экземпляра.

ruby-1.9.1-p378 > x = Complex.rect(1,5) 
=> (1+5i) 
ruby-1.9.1-p378 > x.rect 
=> [1, 5] 
ruby-1.9.1-p378 > x.rect(2, 4) # what would this even do? 
ArgumentError: wrong number of arguments(2 for 0) 
    from (irb):4:in `rect' 
    from (irb):4 
    from /Users/mr/.rvm/rubies/ruby-1.9.1-p378/bin/irb:17:in `<main>' 

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

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

Что конкретно конкретно они выбрали :: и #? :: имеет смысл для меня, потому что он условно разделял пространства имен, но # был, вероятно, просто символом, который не использовался в другой номенклатуре и мог однозначно распознаваться как разделитель экземпляров.

+0

Теперь для бонусных очков: почему бы не использовать '::' для * вызова * методов класса при использовании ' # 'для вызова методов экземпляра? Тогда нет никакой двусмысленности как при чтении документов, так и в самом коде. –

+0

@JUST: Вы * можете * сделать 'Complex :: rect (1,5)'. Но поскольку '#' запускает комментарий строки, я не думаю, что последний будет принят в ближайшее время. –

+1

Я знаю об этом. Дело в том, что все еще довольно странно документировать с помощью '#' вместо '.'. ** Особенно **, поскольку вы можете ссылаться на '::'. Для меня это одна из этих невыразимых загадок Руби. Поскольку у нас уже есть правила префикса '@' и '@ @', почему бы не сделать то же самое для методов и методов класса (не разрешать, * force *), которые будут вызываться с помощью '::' и force (not allow, * force *) методы экземпляра, вызываемые с помощью '.'? –

3

Я понимаю, что именно так идентифицируются методы в ri. Что было первым?

Да, это то место, откуда оно исходило. Когда вы используете #, он автоматически связывает ваши методы, поэтому ссылки на другие методы в документации начинаются с префикса с помощью знака #.См here:

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

Вы не можете на самом деле вызывать метод таким образом. Но это не должно удивлять; в конце концов, <cref ...> является недопустимым выражением в C#, несмотря на то, что он является допустимым тегом документации.

+0

Итак, это методы первого места назывались хэшами? –

+0

@ Justin L .: Это то, что создало соглашение, да. –

+0

Было ли это потому, что файлы rdoc использовали имена методов как идентификаторы привязки, а html использует # для выделения хеша местоположения из идентификатора документа? –