Эта проблема иногда возникает в списках рассылки. Это также проблема, которая возникает в Rails. Решение, как вы уже подозревали, в основном состоит в использовании Regexp.
Однако существует более фундаментальная проблема: в Ruby у классов нет имени! Класс - это просто объект, как и любой другой. Вы можете назначить его переменной экземпляра, локальной переменной, глобальной переменной, константе или даже вообще не назначать ей что-либо . Метод Module#name
в основном просто вспомогательный метод, который работает следующим образом: он просматривает список определенных констант, пока не найдет тот, который указывает на получателя. Если он находит один, он возвращает первый, который может найти, в противном случае он возвращает nil
.
Итак, здесь есть два режима отказа:
a = Class.new
a.name # => nil
B = a
B.name # => "B"
A = B
A.name # => "B"
- класс может вообще не иметь имени
- класс может иметь более одного имени, но
Module#name
вернет только первое найденное
Теперь, если кто-то попытается вызвать As
, чтобы получить список A
с, он будет очень удивлен, обнаружив, что этот метод не существует, но вместо этого он может вызвать Bs
, чтобы получить тот же результат.
Это действительно действительно происходит в реальности. Например, в MacRuby String.name
возвращает NSMutableString
, Hash.name
возвращает NSMutableDictionary
и Object.name
возвращает NSObject
. Причина этого заключается в том, что MacRuby объединяет среду выполнения Ruby и среду Objective-C в одну, и поскольку семантика изменяемой строки Objective-C идентична строке Ruby, вся реализация строкового класса Ruby по существу представляет собой одну строку : String = NSMutableString
. А поскольку MacRuby находится поверх Objective-C, это означает, что Objective-C запускается первым, что означает, что NSMutableString
вставляется в таблицу символов первым, что означает, что сначала он получает found на Module#name
.