Pull to refresh

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

Прекрасное дополнение! Совсем вылетело это из головы.


Однако, это не совсем то, о чем я говорил (хотя стоило это добавить).
Фича, которую выпилили, подменяла константу в случае, если был указан неправильный путь к ней. Причем, там все достаточно хитро. Например:


# 1.rb
class A; end
class B; end
A::B # вернет A, но выдаст предупреждение

# 2.rb
class A; end
module M; end
M::A # ==> NameError

Эта фича срабатывает только при явных ошибках в коде (явное указание неправильного пути к константе) и действительно является поводом ненависти:) Хотя лично я проблемы с ней встречал всего пару раз в каком-то легаси коде.


Anyway, спасибо огромное за ценный комментарий

опечатался. A::B вернет B

Точно. То есть, да, отпилен лишь частично. Похоже, что только для случаев, когда в качестве контекста поиска явно указан класс (а для модулей это и так не работало). Тесткейс.


Никак не заставлю себя открыть "Ruby Under a Microscope", там наверняка про это есть :/

а почему бы не взять себе за правило обращаться к константе из топ лвла?
::Namespace::C::A
тогда результат у вас всегда будет ожидаемым

Почему бы тогда не проверять типы в каждом методе?
А лучше — сменить язык на джаву.


Это просто неудобно:) В быту знание таких "тонкостей" не так уж часто пригождается, однако кто предупреждает, тот вооружен.

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

нет, это абсолютно та же самая ситуация. Вы предлагаете отказаться от динамики в пользу строгости.
Иногда это имеет смысл. Но не постоянно.


Поэтому и нужно знать язык, на котором пишешь, чтобы понимать, когда нужно написать строже, а когда нет.

Sign up to leave a comment.

Articles