Обсуждение:Введение, или краткий обзор

Материал из Deeptown Manual
Перейти к: навигация, поиск

Тема конфликтов расширений классов не раскрыта.

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)

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
информация
документация
Инструменты