Comments 14
А еще я ненавижу маркдаун хабра (хабрдаун? О__О), который заставляет меня удалять переносы строк :(
ни о каком переопределении речь не идет. Где Вы это в посте увидели?
Речь идет о коллизии имен, которая происходит потому, что в Ruby не обязательно указывать полный путь до константы.
module M1
A = :m1
module M2
A = :m2
end
end
M1::A # ==> :m1
M1::M2::A # ==> :m2
module M1
puts A # which one?
module M2
puts A # and this?
end
end
module M A = 'm' end module Namespace A = 'ns' class C include M end end
Ну как по мне, то include как раз и переопределит одноименную константу, указанную выше, что как мне кажется вполне логично.
module M
A = 'm'
end
module Namespace
A = 'ns'
class C
include M
puts A
end
end
Выведет ns
. Если бы Вы внимательно прочитали пост, то знали бы это ;)
Опять же, не используйте слово "переопределит". В английском языке это называется, если не ошибаюсь, "shadowing", т.е. они могут "перекрывать" друг друга. Константы Namespace::A
и M::A
друг другу не мешают. Вопрос в том, на какую из них будет ссылаться просто A
deleted
Забавный факт: в недавно (месяц назад) выпущенном Ruby 2.5 кусок алгоритма, представленный вами в п. 3 ("проверяется верхний уровень") отпилен.
Прекрасное дополнение! Совсем вылетело это из головы.
Однако, это не совсем то, о чем я говорил (хотя стоило это добавить).
Фича, которую выпилили, подменяла константу в случае, если был указан неправильный путь к ней. Причем, там все достаточно хитро. Например:
# 1.rb
class A; end
class B; end
A::B # вернет A, но выдаст предупреждение
# 2.rb
class A; end
module M; end
M::A # ==> NameError
Эта фича срабатывает только при явных ошибках в коде (явное указание неправильного пути к константе) и действительно является поводом ненависти:) Хотя лично я проблемы с ней встречал всего пару раз в каком-то легаси коде.
Anyway, спасибо огромное за ценный комментарий
::Namespace::C::A
тогда результат у вас всегда будет ожидаемым
Почему бы тогда не проверять типы в каждом методе?
А лучше — сменить язык на джаву.
Это просто неудобно:) В быту знание таких "тонкостей" не так уж часто пригождается, однако кто предупреждает, тот вооружен.
я к тому что два двоеточия в начале это же не сложно, зато надежно. особенно если проект большой, особенно если писали его не вы один
Я ненавижу константы в Ruby