Обсуждение:Введение, или краткий обзор
Тема конфликтов расширений классов не раскрыта.
Re
Введение потому так и называется, что оно дает общее представление и не углубляется в детали. Если хочется прочитать подробнее — читайте подробнее. И вообще, что понимаете под конфликтом? --Korvin 04:15, 25 апреля 2008 (EDT).
PS: Представьтесь пожалуйста.
Re
Там тоже не раскрыта.
В прочем раскрыть ее всеравно не получится. Ибо конфликт фундаментальный. Примерно теже проблемы возникают у системы типов Haskell'я при попытке скрестить эту систему типов с компонентностью.
А конфликт прост:
Заводим 2 модуля A и B.
В обоих модулях расширяем класс int методом GetFactorial.
Далие в модуле C пытаемся использовать модули A и B.
Внимание вопрос: GetFactorial из какого модуля использовать будем?
Особенно весело становится если все 3 модуля пишут разные люди.
Еще веселее если изначально в модуле B небыло GetFactorial, а через некоторое время появился.
Сердитый Ученый.
ЗЫ Это я еще копать не начал...
ЗЗЫ С виду язык в целом приличный (видел и сильно хуже), а вот вся остальная система вызывает большие сомнения в работоспособности при попытке запустить ее в большой сети.
Re
Использован будет последний, то есть последний перекрывает всех предыдущих. И действовать будут естественно в рамках модуля, объявившего данное расширение и всех модулях, которые его используют. Видать примеры в книге корявые, надо придумать что нибудь более реальное.
В целом, расширения не предназначены для написания фундаментального кода. Основная идея в том, чтобы можно было подкрутить класс "под себя", без необходимости перелопачивать код. Ориентировка на то, что тебе дали объект, но ты хочешь от него чего то еще. Если проводить аналогию с тем же Ruby. Тебе возвращают объект, но ты хочешь чтобы он умел производить с собой некоторые действия, скажем выводить некоторую информацию (инспектировать себя). И эту информацию ты используешь в своем коде. Тогда просто создается расширение в котором объявляется необходимый метод. Притом что оно никоим образом не мешает другим пользователям (которые так же могут у себя делать расширения). Альтернатива этому подходу -- написание врапперов и преобразование там где надо. Но это уже изврат, однако. Особенно если надо всего пару фич объявить.
Ну или другой вариант: другая библиотека присылает некий контейнер, который приходится использовать в текущем модуле. Но вот беда, язык на котором написан "тот" модуль понятия не имеет о замыканиях и соответственно ни о каком методе each() не знает (скажем, используется принцип search-valid-next). А нам таки хочется пользоваться всеми преимуществами примеси Enumerable. Тогда берем и расширяем класс методом each() и добавляем в родители соответствующую примесь:
extend TheirWeirdCollection extends Enumerable { public const function each(block b) { for(this.search(); this.valid(); this.next()) b(this.current()); } }
И радуемся жизни:
var col = SomeMethod(); //скажем, возвращает этот самый TheirWeirdCollection var result = col.select() { |x| x > 5; }; //применяем примесь result.each() { |x| puts(x); } //тут уже конечно не TheirWeirdCollection, а array
А для написания основного кода надо использовать наследование, как и положено.
ЗЫ: Сомнения дело хорошее. До тех пор, пока порождают конструктивные диалоги а не флуд и прочие холивары
--Korvin 09:52, 25 апреля 2008 (EDT)