LINUX.ORG.RU

[C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?


0

0

Рассмотрим "полноценные" в смысле смоллтолка объекты, т.е. те, в которых можно вызывать виртуальные методы.

Для таких объектов надо написать функцию f, которая на входе получает любой полноценный объект класса К, а на выходе возвращает тоже полноценный объект класса К1, причем К1 является потомком класса К и имеет все приватные, защищенные и открытые поля и методы класса К, и еще одно открытое поле -- счетчик. Вы расслабились? рано! Каждый вызов метода объекта класса К1 должен сначала инкрементировать то самое новое открытое поле-счетчик, а затем уже вызывать соответствующий метод своего родителя.

1. Порутчикам Ржевским со своими динамическими языками -- молчать. Я и так знаю, что вы скажете.

2. Почему рассматриваем только полноценные объекты -- если объект не полноценный, то при путешествии объекта класса К1 он быстро станет рассмативаться как объект класса К и перестанет инкрементировать счетчик (то, что в плюсах возможны "неполноценные" объекты я не собираюсь обсуждать -- это уведет далеко).

3. Для хаскелистов -- как я понимаю, у вас нет объектов, а только алгебраические типы данных. Для вас нужно задачу как-то переформулировать (или взять какую-то реализацию объектной системы, но в этом будет сложно разбираться).

4. На плюсах я сейчас вижу только "грязный" способ реализации -- использовать прямой доступ к vtbl на запись. Может кто предложит получше?

5. Дополненительное усложение: перед своим уничтожением объект должен записать счетчик в лог.

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

На жабе можно сгенерить .class файл и загрузить его класслодером.

Absurd ★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?


hm. мне почему то кажется, что по крайней мере в плюсах такого не получится. тебе ж поди это ещё и в рантайме нужно для произвольного класса?

// wbr

klalafuda ★☆☆ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> На жабе можно сгенерить .class файл и загрузить его класслодером.

сгенерить -- это как? генерить ведь придется коды виртуальной машины (или можно остаться в рамках именно явы, в чем я сомневаюсь)?

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

Рефлексия и генерация кода во время исполнения решит все проблемы. Реализуется как минимум на Си/Си++/Яве.

tailgunner ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> hm. мне почему то кажется, что по крайней мере в плюсах такого не получится. тебе ж поди это ещё и в рантайме нужно для произвольного класса?

( мне это не нужно, я пофлеймить вышел :-) но пример видимо таки напишу )

для произвольного класса с вирт. функциями -- вполне реально ИМХО.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Рефлексия и генерация кода во время исполнения решит все проблемы. Реализуется как минимум на Си/Си++/Яве.

На плюсах похоже можно без рефлексии и точно -- без генерации кода в рантайме.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> для произвольного класса с вирт. функциями -- вполне реально ИМХО.

можно пример?

// wbr

klalafuda ★☆☆ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> можно пример?

завтра-послезавтра напишу сюда. сегодня совсем уже устал.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

Нихрена не понял. Ты собираешься динамически создавать _класс_? Если да, то в языке без концепции метаклассов это не сделаешь. Только путем грязных хаков. Если нет, то какие проблемы? Включай объект класса K в объект класса K1 и переделывай соответствующие методы. Только право на самостоятельную смерть объект класса K иметь уже не будет. Другого способа, особенно если ты хочешь чтобы объекты K и K1 были между собой связаны в "традиционном" ООП-е нет.

В принципе, такая проблема должна хорошо решаться в рамках CLOS...

Macil ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>генерить ведь придется коды виртуальной машины

Например hibernate что-то подобное делает.

Macil ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> На плюсах похоже можно без рефлексии

Вот когда покажешь, тогда и будет можно.

tailgunner ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>> На жабе можно сгенерить .class файл и загрузить его класслодером.

>сгенерить -- это как? генерить ведь придется коды виртуальной машины (или можно остаться в рамках именно явы, в чем я сомневаюсь)?

Коды виртуальной машины известны. Если нет проблем с лицензией, то можно использовать компилятор который написан на яве и лежит в отдельном jar файле в jdk. Зависимостей у компилятора нет за исключением собственно jre. Для генерации класса-прокси надо просканировать проксируемый класс при помощи рефлексии. Мой коллега такое делал.

Absurd ★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Ты собираешься динамически создавать _класс_?

Да, именно так, причем на ужасном статическом С++ :-) как сделать это хаком, я придумал, вот думаю сейчас, как без хака...

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Рефлексия и генерация кода во время исполнения решит все проблемы. Реализуется как минимум на Си/Си++/Яве.

ты имеешь ввиду генерацию машинного кода? если да, то я бы не сказал, что 'это на c++'. это скорее какой-то грязный хак :-/

// wbr

klalafuda ★☆☆ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> ты имеешь ввиду генерацию машинного кода?

Можно просто текста на Си++ :)

> я бы не сказал, что 'это на c++'. это скорее какой-то грязный хак :-/

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

tailgunner ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Для генерации класса-прокси надо просканировать проксируемый класс при помощи рефлексии.

С возможностью просканировать никаких споров нет.

А вот возможность создать новый класс -- это вопрос. Т.е. я не знаю языковых механизмов явы, позволяющих создать такое. Только использование комманд виртуальной машины.

______________________

Да, в условии я не написал -- желательно сгенерить весь код на этапе компиляции, и в рантайме *ничего* не генерить.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> ты имеешь ввиду генерацию машинного кода?

> Можно просто текста на Си++ :)

не-не-не. можно обойтись и без того, и без другого.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>> Ты собираешься динамически создавать _класс_?

>Да, именно так, причем на ужасном статическом С++

Может быть глянуть в сторону LLVM?

Macil ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Да, в условии я не написал -- желательно сгенерить весь код на этапе компиляции, и в рантайме *ничего* не генерить.

вот и я о том же. иначе, это будет уже нечестно.

// wbr

klalafuda ★☆☆ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Можно просто текста на Си++ :)

для с++ сразу ставим условие -- имеются классы с ЗАКРЫТЫМ исходником, и для них f тоже должна работать.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>как сделать это хаком, я придумал, вот думаю сейчас, как без хака...

Дык может это лучше через шаблоны а-ля паттерн Strategy (Александреску взрывает моск). Типа если нам нужен некий счетчик, создаем внутре целевого объекта еще один объект, тип которого задаем через С++шный шаблон, а в каждом методе целевого класса ставим вызов методов шаблонного класса.

Macil ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Только право на самостоятельную смерть объект класса K иметь уже не будет.

Он должен иметь право самостоятельно умирать, только перед этим должен записать счетчик в лог.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Дык может это лучше через шаблоны а-ля паттерн Strategy (Александреску взрывает моск). Типа если нам нужен некий счетчик, создаем внутре целевого объекта еще один объект, тип которого задаем через С++шный шаблон, а в каждом методе целевого класса ставим вызов методов шаблонного класса.

AFAIU это не то. это просто. если я правильно понял условие, то есть базовый класс A и унаследованный от него B. ни в А ни в B никакого счетчика нет и добавлять руками в декларацию B мы его не можем, а тем более модифицировать поведение B. иначе, если можем, задача теряет всю соль.

// wbr

klalafuda ★☆☆ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>А вот возможность создать новый класс -- это вопрос. Т.е. я не знаю языковых механизмов явы, позволяющих создать такое. Только использование комманд виртуальной машины.

java.lang.reflect.Proxy. Только оно создает класс на основе списка наследуемых интерфейсов, класса-предка ему задать нельзя.

>Да, в условии я не написал -- желательно сгенерить весь код на этапе компиляции, и в рантайме *ничего* не генерить.

В D наверно можно воспользоваться миксином и compile-time рефлексией. В С++ даже compile-time проверка существования метода "void foo()" у класса "Bar" требует трехэтажного SFINEA-шаблона с задействованием буста. А задачу генерации класса из списка типов полей Александреску смог решить только с помощью наследования от каждого из типов полей (Loki::GenScatterHierarchy<>, Loki::GenLinearHierarchy<>).

Absurd ★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> В D наверно можно воспользоваться миксином и compile-time рефлексией. В С++ даже compile-time проверка существования метода "void foo()" у класса "Bar" требует трехэтажного SFINEA-шаблона с задействованием буста. А задачу генерации класса из списка типов полей Александреску смог решить только с помощью наследования от каждого из типов полей (Loki::GenScatterHierarchy<>, Loki::GenLinearHierarchy<>).

ужас... как упражнения для [больноо] мозга - потянет. как практика... не приведи господь увидеть такое творение в живую :-/ уж на что я в принципе положительно отношусь к плюсам, но в указанном случае могу лишь выдать что-нить a'la 'Use Ruby Luke'.

// wbr

klalafuda ★☆☆ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>> Только право на самостоятельную смерть объект класса K иметь уже не будет.

>Он должен иметь право самостоятельно умирать, только перед этим должен записать счетчик в лог.

Т.е. объект класса К (базовый объект) еще должен знать, что у него есть прокси (объект класса K1)?

Macil ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> не приведи господь увидеть такое творение в живую

пропатчить указатель на vtbl гораздо проще

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>AFAIU это не то.

Ну да, условиям это противоречит. Но эффект дает тот же, дополнительно решая кучу проблем с жизненным циклом, количеством экземпляров прокси, исключениями. Главная проблема в том, что сложновато будет реализовать динамическую природу. По идее, чтобы получить/убрать возможность использовать счетчик, объект придется клонировать. Но поскольку клонирование идет практически само в себя, больщих проблем быть не должно. Плюс открывается возможность использовать один и тот же объект-счетчик в объектах разных классов, т.е. сделать их жизненные циклы полностью независимыми.

Здесь еще важно, кто отвечает за жизненный цикл. Если объект создается фабрикой, то это одно, если нет - совсем другое.

Macil ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> пропатчить указатель на vtbl гораздо проще

если я буду патчить потроха рантайма, то я смогу сделать хоть черта в ступе. но это 1) явное читерство 2) бред, т.к. см. п.1

// wbr

klalafuda ★☆☆ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

ЗЫ: А вообще, ну его в топку! Убей в себе ООП! Даешь моделирование и DSL'ы!

Macil ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Т.е. объект класса К (базовый объект) еще должен знать, что у него есть прокси (объект класса K1)?

Пусть у нас есть g(K* k), причем исходников g у нас нет. Тогда мы имеем право подсунуть ей указатель на К1, т.е. вызвать g(f(k)). Внутри g объект k1==f(k) какое-то время пропутешествует, на нем отработают K-шные методы, потом он там умрет и запишет счетчик в лог.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> но в указанном случае могу лишь выдать что-нить a'la 'Use Ruby Luke'.

Добрый ты... другой бы выдал волчий билет с занесением в лицевую панель :)

tailgunner ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

на самом деле прототип f должен быть такой: K1* f(K*)

а вовсе не K1 f(K) как я писал в условии.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>Пусть у нас есть g(K* k), причем исходников g у нас нет.

Да, но что будет, если кто-то вдруг вызовет деструктор объекта k? Одно дело, если ты подсовываешь только k1. А что делать, если ты не имеешь контроля над жизненным циклом k?

Macil ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> ЗЫ: А вообще, ну его в топку! Убей в себе ООП! Даешь моделирование и DSL'ы!

А вот нифига. Это я так изучаю границы применимости плюсов и как их красиво расширить.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Да, но что будет, если кто-то вдруг вызовет деструктор объекта k?

Надо вначале проверять, что деструктор у К виртуальный, а раз виртуальный, то будет вызываться деструктор K1.

Кстати: если это не так, то желательно на этапе компиляции сказать "я отказывась работать, у вас класс К плохой!"

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>Это я так изучаю границы применимости плюсов и как их красиво расширить.

Типа реальные пацаны красиво расширяют границы С++ с помощью LLVM. :))

Macil ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> А вот нифига. Это я так изучаю границы применимости плюсов и как их красиво расширить.

когда то давно я тоже занимался расширением границ сознания. правда, то было желание компилировать паскалевский код под 32х бытный DOS4G. и ведь почти расширил. взял дельфю, перешерстил её RTL с Win32 на DOS и ещё куча прчих веществ. почти что заработало. так хотелось поиметь полноценный компилятор+обвязку с поддержкой 32х битного защищённого режима. слава богу, что вовремя отпустило.

// wbr

klalafuda ★☆☆ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> если я буду патчить потроха рантайма, то я смогу сделать хоть черта в ступе. но это 1) явное читерство 2) бред, т.к. см. п.1

Сделай, только чтобы оно было короче и понятнее, чем на яве (а потом можно будет уже начать флейм с динамическими языками).

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Сделай, только чтобы оно было короче и понятнее, чем на яве (а потом можно будет уже начать флейм с динамическими языками).

зачем :-? под задачу и инструмент. мне лично кажется, что те же с++ тут явно не под задачу. разве что хочется внедриться в существующий объектник и понарасставлять там, скажем, брекпоинты счетчики или ещё какую гадость. но для этого есть другие средства.

// wbr

klalafuda ★☆☆ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>а раз виртуальный, то будет вызываться деструктор K1.

Не будет. Хотя это проблема чисто теоретическая. У нас есть _объект_ k. Для "вкусноты" будем считать, что контроля за ЖЦ мы не имеем, т.е. его неконятно кто и главное когда создает, и непонятно кто и главное когда уничтожает.

Мы делаем объект-прокси k1 типа K1, который является потомком K. Объект k1 перенаправляет сообщения объекту k, по крайней мере это традиционное определение прокси. Как только кто-то пытается уничтожить k, с k1 начинаются большие проблемы.

Вроде это решается с помощью "умных" указателей.

Macil ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> слава богу, что вовремя отпустило.

я свою задачку оцениваю в 50 строк. ну если всякий лишний сервис добавить, то в 100. а иначе язык надо признать непригодным для нее.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>>но в указанном случае могу лишь выдать что-нить a'la 'Use Ruby Luke'.

>Добрый ты... другой бы выдал волчий билет с занесением в лицевую панель :)

Типо извращаться никогда не надо? А вот хрен - надо. Иногда. Для тестирования хреново написанного модуля с тучей зависимостей в изолированном окружении например.

Absurd ★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Типа реальные пацаны красиво расширяют границы С++ с помощью LLVM. :))

А над этим стоит подумать.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Типа реальные пацаны красиво расширяют границы С++ с помощью LLVM. :))

А над этим стоит подумать. Подумать не в качестве способа решения данной задачи, а в качестве способа расширить свое сознание :-)

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Например hibernate что-то подобное делает.

Кстати да. Можно подумать, как следует сформулировать эту задачку в следущий раз... но для собственно hibernate-а вроде как достаточно умных указателей.

www_linux_org_ru ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

>> Добрый ты... другой бы выдал волчий билет с занесением в лицевую панель :)

> Типо извращаться никогда не надо? А вот хрен - надо.

"Не держись устава яко слепой за стенку" (c). Любые правила можно нарушить, если готов к последствиям.

tailgunner ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

> Для хаскелистов -- как я понимаю, у вас нет объектов, а только алгебраические типы данных. Для вас нужно задачу как-то переформулировать (или взять какую-то реализацию объектной системы, но в этом будет сложно разбираться).

Олег Киселёв сделал более чем полноценную реализацию объектной системы на Хаскеле. Там это, по моим воспоминаниям, вполне возможно. Собственно, ЕМНИМЭ, каждый объект получается там как расширение другого объекта одним полем (кроме пустых объектов, естественно), так что тип объекта получается по несложным правилам. Тип K1 получается примерно по таким же правилам. это, в свою очередь, означает, что можно соорудить тайпкласс, делающий, в общем, то, что ты и хочешь.

Другой вопрос, что я этой объектной системой реально не пользовался, только читал, причём давно. Так что полноценной реализации не будет.

Miguel ★★★★★ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?


в общем, я реквистирую живой пример решения задачи на C++. потому что лично мне кажется, что я все-таки не понял, чего же на самом деле хочется :-/

// wbr

klalafuda ★☆☆ ()

Re: [C++][Haskell][Ocaml][Java][C#][?] позволяет ли ваш язык создать полноценный прокси для объектов?

1. У тебя в блоге прекрасная флеймообразующая тема насчет template virtual. Предлагаю запостить ее на ЛОР, только приведи несколько примеров на плюсах, КАК ты этот шаблон собираешься использовать. Твои примеры на хаскеле мне ничего не говорят о желаемом использовании, видимо они слишком абстрактны.

2. Насчет системы Олега Киселева -- кинь ссылку.

Возникают вопросы -- а для чего она делалась, что-то неудобно делать напрямую через тайпклассы?

3. Для хаскеля мою задачу можно переформулировать. Допустим у нас есть тайпклассы с понятным наследованием Animal Mammal Cat Bird, и хочется чтобы

А. готовый код, работающий с Животным, так же умел работать с Котом

Б. при вызове методов Животного, которое на самом деле Кот, оно оставалось Котом

В. ну собственно f -- придумай что-нить в этом духе, что попроще делать -- я не знаю, как она записывается:

-- если f на входе получает объект c типом, являющимся инстансом хорошего тайпкласса, то на выходе она отдает объект с типом, являющимся инстансом этого же тайпкласса и одновременно инстансом тайпкласса CountedInvocations

-- определять "хороший ли тайпкласс" должна сама f, если плохой -- ругаться во время компиляции

Как минимум, я хочу знать, достаточно ли для этого Хаскеля/Template Haskell/еще-чего-то. И правильно ли я описал задачу, может она должна формулировать по-другому.

www_linux_org_ru ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.