Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.05.07 07:37
Оценка: 102 (10)
Добавил поддержку auto-property (как в C# 3.0).

Теперь для описания свойства которой только пишет и читает перменные можно использовать синтаксис:
public Prop1 : int { get; private set; }
public Prop2 : int { get; set; }


Пример использования:
using System.Console;

public class A
{
  public this(i : int) { Prop1 = i; }
  public Prop1 : int { get; private set; }
  public Prop2 : int { get; set; }
}
 
module Program
{
  Main() : void
  {
    def a = A(123);
    a.Prop2 = 789;
    WriteLine($"a.Prop1=$(a.Prop1); a.Prop2=$(a.Prop2);");
    _ = ReadLine();
  }
}


Особую гордость вызывает объем и чистота кода котрый пришлось добавить для реализации этой возможности.
Вот он весь:
// Support autoproperty (see C# 3.0 specification).
// убеждаемся, что это не абстракное или extern- свойсво, что это не индексер (т.е. нет параметров) и не член интерфейса.
when (!(propertyAst.Attributes %&& (NemerleAttributes.Abstract | NemerleAttributes.Extern)) 
      && !IsIndexer && !par.IsInterface)
  match (propertyAst.get, propertyAst.set)
  {
    | (Some(PT.ClassMember.Function(_, _, FunBody.Abstract) as getr), // распознаем, что getter и setter абстрактны (не имеют тел)
       Some(PT.ClassMember.Function(_, _, FunBody.Abstract) as setr)) => // за одно "выцепляем" ссылки на сами getter и setter.

      def field = Macros.NewSymbol("field"); // Генерируем новое имя для поля, которое будет хранить значение свойства
      par.Define(<[ decl: mutable $(field : name) : $(propertyAst.ty); ]>); // Добавляем поле это поле

      // Формируем тела getter-а и setter-а, так чтобы они использовали добавленное выше поле.
      getr.Body = <[ $(field : name) ]>;
      setr.Body = <[ $(field : name) = value ]>;

    | _ => ()
  }

Этот код находится в http://nemerle.org/svn/nemerle/trunk/ncc/hierarchy/ClassMembers.n

ЗЫ

Казалось бы сколько времени пользуюсь паттерн-матчингом и квази-цитированием, но блин вот от таких вещей порой просто прет (в хоршем смысле этого слова (с)).
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Добавил поддержку auto-property (как в C# 3.0)
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 16.05.07 07:42
Оценка: 24 (2) +1
VladD2,

IT>>Нет. А ты можешь доказать, что такое применение не найдётся в будущем?


VD>Самая большая ошика программистов — это попытки реализовать супер универсальные вещи учитывающие все что может произойти в будущем.


Для прикладных программистов это стопудова +1.

Но language designer-ы — это особые фрукты. От их деятельности зависят (потенциально) тысячи людей. Поэтому они (LD) должны обладать даром предвидения (и чем больше дар, тем лучше) и теоретической базой для создания наиболее общих решений, иначе язык погрязнет в десятках несовместимых версий (или тяжёлом наследии с другой стороны) и кривых воркэраундах. Примеров предостаточно (те же указатели на члены в C++).
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[9]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.05.07 01:06
Оценка: 1 (1) +2
Здравствуйте, IT, Вы писали:

Кстати... чем мне действительно нравится ОпенСорс, так это тем, что нет нужды долго ждать от дяди когда он проникнится нужностью той или иной фичи и реализует ее для меня. Я могу просто сесть и сделать. В закрытом софте создание фич на всякий пожаерный стандартная практика. Вдруг не сделаем что-то что нужно народу? В ОпенСорсе же все с точностю до наоборот. Нужную фичу всегда можно добавить. Так что если возникнет реальная потребность, то нет особых проблем. Можно даже макросом то что нужно реализовать. Посему жить по принципу "вдруг" просто бессмысленно. Как толко это вдруг станет очевидным, то можно воплотить свои мечты в реальность.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: Блудов Павел Россия  
Дата: 11.05.07 01:00
Оценка: 6 (1) +1
Здравствуйте, _FRED_, Вы писали:

_FR>
_FR>get { return field ?? String.Empty; }
_FR>

_FR>Макрос же таким фокусам (без хардкодинга) не научить :о(
Ну почему, можно доработать напильником примерно до такого вида
[NullValue("")]
public Foo : string { get; set; }

Соответственно если задано NullValue и тип свойства есть ref или nullable, то можно добавить проверку и возвращать подправленное значение.
Только лучше оставить auto-property в покое и доработать макрос Accessor.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[2]: Вы оба не правы.
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.05.07 05:32
Оценка: 24 (1)
Здравствуйте, VladD2, Вы писали:

Пока Янус обновлялся, подумал, что переусложнил. Так как используется переключение в цвета области использования (PushUseSiteColor()), то все имена и так будут браться из области использования, так что вместо:
$("ViewState" : usesite)

можно просто писать
ViewState

Вот упрощенный вариант.
when (!(propertyAst.Attributes %&& (NemerleAttributes.Abstract | NemerleAttributes.Extern)))
    match (propertyAst.get, propertyAst.set)
    {
        | (Some(PT.ClassMember.Function(_, _, FunBody.Abstract) as getr), 
             Some(PT.ClassMember.Function(_, _, FunBody.Abstract) as setr)) =>
            
            def ctx = Nemerle.Macros.ImplicitCTX();
            ctx.Env.Manager.MacroColors.PushUseSiteColor();
            try
            {
                getr.Body = <[
                    def val = ViewState[$(propertyAst.Name : string)];
                    if (val == null) $defaulteValue else (val :> $(propertyAst.ty))
                ]>;
                setr.Body = <[ ViewState[$(propertyAst.Name : string)] = value ]>;
            }
            finally { ctx.Env.Manager.MacroColors.PopColor(); }
            
        | _ => Message.Error(propertyAst.Location, "Property should have empty getter and setter!")
    }  
}
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.07 15:03
Оценка: 15 (1)
Здравствуйте, rameel, Вы писали:

R>Обновился с репозитория, ошибка компиляции во второй фазе, эти изменения могут вызвать такую ошибку?


Исправил и залил. За одно обновил корневое сообщение, чтобы оно соответствовало современной действительности.
Код получился еще проще . Удалось избавиться от использования макросв и за одно позволить добавлять автопроперти в макросах, а не только в коде.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: В продолжение беседы
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.10.07 10:57
Оценка: 14 (1)
Здравствуйте, Блудов Павел, Вы писали:

БП>Илья в своём блоге доказывает обратное. Мысли довольно здравые.


Можно, кстати, продумать синтаксис и добавить расширения в Немерле.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Добавил поддержку auto-property (как в C# 3.0)
От: IT Россия linq2db.com
Дата: 11.05.07 16:37
Оценка: 1 (1)
Здравствуйте, VladD2, Вы писали:

IT>>Смысла нет пока тебе это самому не понадобилось. Как понадобится, так сразу и смысл появится.


VD>Смыла нет потому что нет смысла.


Я так и думал

VD>Ты можешь показать хоть какое-то применение для того о чем ты говришь?


Нет. А ты можешь доказать, что такое применение не найдётся в будущем?

Ну да ладно, это в принципе ерунда. Ты мне лучше вот что скажи. Такое поведение можно будет изменить макросами или это теперь прибито гвоздями навсегда?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.05.07 11:04
Оценка: +1
Здравствуйте, IT, Вы писали:

IT>А только getter или только setter можно задать?


Нет. В этом нет смысла. Поле то ведь скрытое.

Вообще спецификацию C# писали разумные люди .
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: _pk_sly  
Дата: 11.05.07 06:38
Оценка: +1
IT>А только getter или только setter можно задать?

да, было бы неплохо...
для тех же read-only и write-only значений
либо когда одно хотелось бы оставить стандартом, а второе поменять.
Re[8]: Добавил поддержку auto-property (как в C# 3.0)
От: Dr.Gigabit  
Дата: 13.05.07 11:28
Оценка: :)
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, VladD2, Вы писали:


IT>>>Смысла нет пока тебе это самому не понадобилось. Как понадобится, так сразу и смысл появится.


VD>>Смыла нет потому что нет смысла.


IT>Я так и думал


Если нет смысла то есть ли хотя бы логика смысла?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.05.07 15:26
Оценка: +1
Здравствуйте, _pk_sly, Вы писали:

__>в дотнет readonly/writeonly надо было бы добавить на основании того, что это — полезная фича, которая НИЧЕГО не стоит разработчикам. ну, слава богу, в дотнете она присутствует, так что о её полезности можно было спор не начинать.


Полезного в ней ничего нет. Для особо упетрых есть возможность прописать свойство с сетерром и без гетера врунчую. Автоматизировать создание этого идиотизма лично я не собираюсь. И всеми силами буду сопротивляться этому.

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

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

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

Попробуй ради хохмы найти в дотнете хотя бы один класс с такими свойствами. Или скажем в компиляторе того же Немерле (там не мало кода).
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Добавил поддержку auto-property (как в C# 3.0)
От: IT Россия linq2db.com
Дата: 09.05.07 10:48
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Добавил поддержку auto-property (как в C# 3.0).


А только getter или только setter можно задать?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: IT Россия linq2db.com
Дата: 09.05.07 17:43
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>А только getter или только setter можно задать?


VD>Нет. В этом нет смысла.


— Ты суслика видишь? — Нет! — А он есть! (c)

VD>Поле то ведь скрытое.


Это детали исключительно твоей реализации. При использовании атрибута Accessor (или как там его) получаемого в результате свойтва тоже не видно. А оно есть!

VD>Вообще спецификацию C# писали разумные люди .


Спецификацию C# на foreach тоже писали разумные люди. Только это не помешало в N сделать его гораздо мощьнее.

Вообще-то, я вот к чему. В bltoolkit можно практически также объявлять свойства даже в C# 1.1. Разница только в том, что эти свойтсва должны быть абстрактные. Для них можно указать только геттер или только сеттер. Абстрактные свойства используется для того, чтобы можно было генерировать реализацию свойств не просто как переменную типа как у свойства, а немного другую. Например, иногда полезно что-то добавить в сеттер, иногда сделать реализацию свойства типа double как EditableValue<double>.

Но проблема с абстрактными классами нам всем хорошо известна. В N это всё можно было бы решить гораздо изящней. Поэтому не хотелось бы получить его сразу в таком ограниченном виде.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.07 09:34
Оценка:
Здравствуйте, IT, Вы писали:

IT>Это детали исключительно твоей реализации.


Нет. Это следствие гигиеничности макросов.

IT> При использовании атрибута Accessor (или как там его) получаемого в результате свойтва тоже не видно. А оно есть!


Предлагаю все же перед обсуждением разобраться в сути проблемы.
Свойство получаемое в результате работы атрибута Accessor видно программисту в лучшем виде. Ты можешь ссылаться на него, "видеть" его в интелесенсе.

Переменна же от автопроперти не видна никак кроме раве что Рефлектором. Система макросов даем ему имя _N_имяПоляXXX где XXX — это каждый раз новое число. Так что при всем желании обратиться к этому полю не выйдет.

IT>Вообще-то, я вот к чему. В bltoolkit можно практически также объявлять свойства даже в C# 1.1. Разница только в том, что эти свойтсва должны быть абстрактные. Для них можно указать только геттер или только сеттер. Абстрактные свойства используется для того, чтобы можно было генерировать реализацию свойств не просто как переменную типа как у свойства, а немного другую. Например, иногда полезно что-то добавить в сеттер, иногда сделать реализацию свойства типа double как EditableValue<double>.


IT>Но проблема с абстрактными классами нам всем хорошо известна. В N это всё можно было бы решить гораздо изящней. Поэтому не хотелось бы получить его сразу в таком ограниченном виде.


Здорово. Только автопроперти тут все же не причем. Если ты что-то будешь делать, то сам сможешь реализовать нужное тебе поведение. А автопроперти всего лишь фича языка позволяющая упроститть ординарный код.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Добавил поддержку auto-property (как в C# 3.0)
От: rameel https://github.com/rsdn/CodeJam
Дата: 10.05.07 10:46
Оценка:
Здравствуйте, VladD2, Вы писали:

Обновился с репозитория, ошибка компиляции во второй фазе, эти изменения могут вызвать такую ошибку?
\Projects\Nemerle\ncc\hierarchy\TypeInfo.n(80,24,80,27): error : interface method cannot have body
\Projects\Nemerle\ncc\hierarchy\TypeInfo.n(80,29,80,32): error : interface method cannot have body
\Projects\Nemerle\ncc\hierarchy\TypeInfo.n(95,28,95,31): error : interface method cannot have body
\Projects\Nemerle\ncc\hierarchy\TypeInfo.n(95,33,95,36): error : interface method cannot have body
\Projects\Nemerle\tools\msbuild-task\Compiler.MSBuild.targets(167,9): error : interface members are not allowed to have any attributes specified, except 'new'
\Projects\Nemerle\tools\msbuild-task\Compiler.MSBuild.targets(167,9): error : fields cannot be defined inside interface
\Projects\Nemerle\tools\msbuild-task\Compiler.MSBuild.targets(167,9): error : interface members are not allowed to have any attributes specified, except 'new'
\Projects\Nemerle\tools\msbuild-task\Compiler.MSBuild.targets(167,9): error : fields cannot be defined inside interface
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.07 11:53
Оценка:
Здравствуйте, rameel, Вы писали:

R>Обновился с репозитория, ошибка компиляции во второй фазе, эти изменения могут вызвать такую ошибку?


Уже знаю. Не учел что пустые методы еще и в интерейсах бывают. Вот думаю как лучше исправить.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Добавил поддержку auto-property (как в C# 3.0)
От: Аноним  
Дата: 10.05.07 12:04
Оценка:
Здравствуйте, rameel, Вы писали:

R>Обновился с репозитория, ошибка компиляции во второй фазе, эти изменения могут вызвать такую ошибку?


Аналогично.
COMPILE [stage2] Nemerle.Compiler.dll
______......................................................
hierarchy/TypeInfo.n:80:24:80:27: ←[01;31merror←[0m: interface method cannot hav
e body
hierarchy/TypeInfo.n:80:29:80:32: ←[01;31merror←[0m: interface method cannot hav
e body
hierarchy/TypeInfo.n:95:28:95:31: ←[01;31merror←[0m: interface method cannot hav
e body
hierarchy/TypeInfo.n:95:33:95:36: ←[01;31merror←[0m: interface method cannot hav
e body
←[01;31merror←[0m: interface members are not allowed to have any attributes spec
ified, except 'new'
←[01;31merror←[0m: fields cannot be defined inside interface
←[01;31merror←[0m: interface members are not allowed to have any attributes spec
ified, except 'new'
←[01;31merror←[0m: fields cannot be defined inside interface
make[3]: *** [out.stage2/Nemerle.Compiler.stage2.dll] Error 1
make[3]: Leaving directory `/work/nemerle/ncc'
make[2]: *** [aux-stage] Error 2
make[2]: Leaving directory `/work/nemerle/ncc'
make[1]: *** [stage2] Error 2
make[1]: Leaving directory `/work/nemerle/ncc'
make: *** [all] Error 2
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.05.07 13:48
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Аналогично.


Это ежу понятно .

Я уже поправил баг, но застрял на сообщениях об ошибках. Я ранее поменял текстовое отображение для свойств и полей и оно теперь вылезло в тестах. Ща поправлю и залью.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Добавил поддержку auto-property (как в C# 3.0)
От: _FRED_ Черногория
Дата: 10.05.07 16:12
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Добавил поддержку auto-property (как в C# 3.0).


Жаль, что для свойств строкового типа, коих в классах, где хотелось бы применить эту фичу, у меня чуть не треть, такой подход неприемлем: в соответствии с guidelines свойства перечислимых типов не должны возвращать null и они у меня описаны так (C#):
get { return field ?? String.Empty; }

Макрос же таким фокусам (без хардкодинга) не научить :о(
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: rameel https://github.com/rsdn/CodeJam
Дата: 10.05.07 16:27
Оценка:
Здравствуйте, VladD2, Вы писали:

О, вот теперь все пучком, я даже заменил несколько мест у себя в проекте, где использовался Accessor на автопроперти
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: Иванков Дмитрий Россия  
Дата: 11.05.07 06:51
Оценка:
Здравствуйте, _pk_sly, Вы писали:

IT>>А только getter или только setter можно задать?


__>да, было бы неплохо...

__>для тех же read-only и write-only значений
__>либо когда одно хотелось бы оставить стандартом, а второе поменять.

Зачем write-only представить не могу, а вот immutable в принципе могу

Примерно так может выглядеть:
[ImmutableProperty]
public Prop1 : int { public get; };


Что должно сгенерировать immutable field и private set, соответственно set только из конструктора будет работать.
Re[4]: Добавил поддержку auto-property (как в C# 3.0)
От: Иванков Дмитрий Россия  
Дата: 11.05.07 07:20
Оценка:
Здравствуйте, Иванков Дмитрий, Вы писали:

ИД>Здравствуйте, _pk_sly, Вы писали:


IT>>>А только getter или только setter можно задать?


__>>да, было бы неплохо...

__>>для тех же read-only и write-only значений
__>>либо когда одно хотелось бы оставить стандартом, а второе поменять.

ИД>Зачем write-only представить не могу, а вот immutable в принципе могу


Хотя зачем это может пригодиться когда можно обойтись public field?
Re[4]: Добавил поддержку auto-property (как в C# 3.0)
От: _pk_sly  
Дата: 11.05.07 07:56
Оценка:
ИД>Зачем write-only представить не могу, а вот immutable в принципе могу :)

а я могу. и пользовался этим.
и разработчики C# тоже, очевидно, могли, если учли это в спецификации.
даже в COM такая возможность присутствует.
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: _FRED_ Черногория
Дата: 11.05.07 09:14
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Только лучше оставить auto-property в покое и доработать макрос Accessor.


Справедливо. Авто-свойствам лучше так, как уже есть.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.07 12:48
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Ну почему, можно доработать напильником примерно до такого вида

БП>
БП>[NullValue("")]
БП>public Foo : string { get; set; } 
БП>

БП>Соответственно если задано NullValue и тип свойства есть ref или nullable, то можно добавить проверку и возвращать подправленное значение.
БП>Только лучше оставить auto-property в покое и доработать макрос Accessor.

На самом деле одно другому не мешает.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.07 12:48
Оценка:
Здравствуйте, Иванков Дмитрий, Вы писали:

ИД>Зачем write-only представить не могу, а вот immutable в принципе могу


ИД>Примерно так может выглядеть:

ИД>
ИД>[ImmutableProperty]
ИД>public Prop1 : int { public get; };
ИД>


ИД>Что должно сгенерировать immutable field и private set, соответственно set только из конструктора будет работать.



Это бесмысленное занятие. Чтобы сделать private сеттер достаточно написать:
public Prop1 : int { get; private set; }

Получат же доступ к полю просто нет смысла.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.07 12:48
Оценка:
Здравствуйте, _pk_sly, Вы писали:

__>а я могу. и пользовался этим.

__>и разработчики C# тоже, очевидно, могли, если учли это в спецификации.
__>даже в COM такая возможность присутствует.

А на основании что в КОМ присутсвуют ГУИД-ы и т.п. не надо все это добавить в дотнет?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Добавил поддержку auto-property (как в C# 3.0)
От: IT Россия linq2db.com
Дата: 11.05.07 13:33
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Получат же доступ к полю просто нет смысла.


Смысла нет пока тебе это самому не понадобилось. Как понадобится, так сразу и смысл появится.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.07 16:25
Оценка:
Здравствуйте, IT, Вы писали:

IT>Смысла нет пока тебе это самому не понадобилось. Как понадобится, так сразу и смысл появится.


Смыла нет потому что нет смысла. Ты можешь показать хоть какое-то применение для того о чем ты говришь?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.07 21:17
Оценка:
Здравствуйте, IT, Вы писали:

VD>>Ты можешь показать хоть какое-то применение для того о чем ты говришь?


IT>Нет. А ты можешь доказать, что такое применение не найдётся в будущем?


Самая большая ошика программистов — это попытки реализовать супер универсальные вещи учитывающие все что может произойти в будущем. Я по этим граблям уже ходил и теперь стараюсь их обходить. Так что когда появятся осмысленные варианты, можно вернуться к этому вопросу и если что поменять код. Он гвоздями не прибит. Мы все же не в Microsoft арботаем.

IT>Ну да ладно, это в принципе ерунда. Ты мне лучше вот что скажи. Такое поведение можно будет изменить макросами или это теперь прибито гвоздями навсегда?


Сейчас код рабоает на стадии создания PropertyBuildero-ов. Собственно из самого кода видно, что он распознает паттерн { get; set; } в свойствах которые не являются абстракными, внешними или свойствами интерфейса. Стало быть если до этого момента кто-то изменит код гетера или сетера, то этот код просто не узнает паттерн. Так что если создать макрос который отработает раньше (на стадии BeforeTypedMembers или BeforeInheritance) и сам проделает похожую работу, то (теоретически) мой код не отработает.

В принципе можно даже создать событие к котому можно было бы подключиться и которое отработало бы при выполнении этого кода, но не уверен, что это нужно. Предпочитаю дождаться наличия такой необходимости, а уже потом думать.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Добавил поддержку auto-property (как в C# 3.0)
От: IT Россия linq2db.com
Дата: 11.05.07 22:32
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Самая большая ошика программистов — это попытки реализовать супер универсальные вещи учитывающие все что может произойти в будущем.


Не учите меня жить, лучше помогите материально (c)

VD>Сейчас код рабоает на стадии создания PropertyBuildero-ов. Собственно из самого кода видно, что он распознает паттерн { get; set; } в свойствах которые не являются абстракными, внешними или свойствами интерфейса. Стало быть если до этого момента кто-то изменит код гетера или сетера, то этот код просто не узнает паттерн. Так что если создать макрос который отработает раньше (на стадии BeforeTypedMembers или BeforeInheritance) и сам проделает похожую работу, то (теоретически) мой код не отработает.


Понятно. Будем надеяться, что проблем не будет.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.05.07 23:59
Оценка:
Здравствуйте, IT, Вы писали:

IT>Не учите меня жить, лучше помогите материально (c)


Сколько вам надо для полного щаться? (с)

IT>Понятно. Будем надеяться, что проблем не будет.


Мне кажется, что проще исправлять проблемы, а не надеяться, что их не будет.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Добавил поддержку auto-property (как в C# 3.0)
От: _pk_sly  
Дата: 13.05.07 14:05
Оценка:
VD>А на основании что в КОМ присутсвуют ГУИД-ы и т.п. не надо все это добавить в дотнет? ;)

ага, можно ещё вспомнить модель памяти huge. или поддержку win16.
только к делу это не относится.

в дотнет readonly/writeonly надо было бы добавить на основании того, что это — полезная фича, которая НИЧЕГО не стоит разработчикам. ну, слава богу, в дотнете она присутствует, так что о её полезности можно было спор не начинать.
Re[8]: Добавил поддержку auto-property (как в C# 3.0)
От: IT Россия linq2db.com
Дата: 13.05.07 17:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Полезного в ней ничего нет. Для особо упетрых есть возможность прописать свойство с сетерром и без гетера врунчую. Автоматизировать создание этого идиотизма лично я не собираюсь. И всеми силами буду сопротивляться этому.


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

VD>Дело в том, что свойство — это публичный интерфейс к состянию объекта.


Свойство — это синтаксический сахар. В джаве свойств нет вообще и без них там прекрасно обходятся. Во многих случаях вместо свойств совершенно спокойно можно использовать публичные поля и никаких проблем не будет. Эта практика в своё время была объявлена кое-кем плохой, но как оказалось, плохого в ней только лишь то, что этот кое-кто криво реализовал TypeDescriptor, который понимает только свойства. Но проблема эта лечится, после чего публичные поля становятся ничем не хуже свойств.

VD>Наличие же свойства доступного только на запись, говорит, что собственно свойства описывающего состояние в общем-то и нет. Смысл такого свойства только в побочном эффекта.


А метод принимающий один параметр и называющийся SetSomething — это нормально или тоже кривой дизайн.

VD>Свойства вообще в идиале не должны менять ничего кроме самих себя


Тогда чем они лучше публичных полей?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.05.07 00:50
Оценка:
Здравствуйте, IT, Вы писали:


IT>Самая большая ошика разработчиков библиотек и прочего инструментария — это попытки решить за других что им будет нужно, а что нет. Особенно, когда сделать чуть гибче и удобнее практически ничего не стоит.


Не. Самая большая ошибка — это делать что-то прозапас. При этом неминуемо получаются кривые и никому не нужные решения в то время как на полезные просто не хватает внемени и сил.

VD>>Свойства вообще в идиале не должны менять ничего кроме самих себя


IT>Тогда чем они лучше публичных полей?


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

ЗЫ

Это последнее мое сообщение в этом обсуждении. Попобую обяснить ситуацию. Автосвойства — это продуманное решение. Продуманное не по одному критерию "ах какая приятная рюшечка", а по массе критериев, от совестимости со старым кодом, до локаничности и безопасности. И самое главно понятно зачем это нужно. Делать же то что "может пригодиться кому-то там" я принципиально не считаю нужным, точнее считаю вредным. С удовольствием изменю свое решение если мне будут предоставлены внятные аргументы.

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

В прочем, они конечно, могут тупо пометить getter как private и получить, что называется, что заслужили.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Вы оба не правы.
От: Блудов Павел Россия  
Дата: 14.05.07 04:21
Оценка:
Здравствуйте, VladD2 & IT

И то, и другое хорошо когда в меру.
Пытаться предусмотреть всё и вся приводит к ASP.Net с его PreInit/Init/PreLoad/Load/PreRender там где за глаза хватит двух методов.
Не делать ничего про запас приведёт к монолиту вроде MFC.

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

Мне вот хочется иметь возможность хранить такие свойства во внешних контейнерах.
Поясню зачем. В том же самом ASP.Net у объектов типа страничка или контрол понятие экземпляра очень короткоживущее.
Фактически объект создаётся каждый раз при получении "GET blablalba HTTP/1.1" и грохается после ответа сервера.

Чтобы это объехать, придуманы три коллекции: ViewState, Session и Application.

И там, где нужно завести на странице свойство, приходится писать что-то вроде
public PageNo : int
{
    get { ViewState["PageNo"] :> (int?) ?? 0; }
    private set { ViewState["PageNo"] = value; }
}


Если нужно десть свойств, то такая фигня копипастится 10 раз. А вообще-то это мусор. И он только затрудняет чтение исходников.
Гораздо проще для понимания вот такое:
[Storage(ViewState), DefaultValue(0)] public PageNo : int { get; private set;}

Тут совершенно ясно, что происходит и лушние детали в глаза не лезут.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re: Вы оба не правы.
От: IT Россия linq2db.com
Дата: 14.05.07 04:41
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Тут совершенно ясно, что происходит и лушние детали в глаза не лезут.


That's what I am talking about!

Речь о внутренней реализации свойств. Но, если я правильно понял Влада, эта проблем вполне разрешима.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re: Вы оба не правы.
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.05.07 05:27
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Гораздо проще для понимания вот такое:

БП>
[Storage(ViewState), DefaultValue(0)] public PageNo : int { get; private set;}

БП>Тут совершенно ясно, что происходит и лушние детали в глаза не лезут.

Это какйо-то странный синтаксис. У тебя проблема предметной области, ну, и нечего придумывать универсальное решение. Сделай макрос ViewState с параметром defaultValue. В нем и добавишь все что тебе нужно. Выгдядеть будет так:
[ViewState(0)] public PageNo : int { get; private set; }

Автосвойства тут вообще не причем. Макрос все должен делать сам.
В общем, потратил 20 минут наклепал этот макрос:
using Nemerle; 
using Nemerle.Compiler;
using Nemerle.Collections;
using Nemerle.Utility;
using Nemerle.Compiler.Parsetree;

using System;

namespace MacroLibrary2
{
  [MacroUsage(MacroPhase.BeforeTypedMembers, MacroTargets.Property, Inherited = true)]
  macro ViewState(_ : TypeBuilder, propertyAst : ParsedProperty, defaulteValue)
  {
    when (!(propertyAst.Attributes %&& (NemerleAttributes.Abstract | NemerleAttributes.Extern)))
      match (propertyAst.get, propertyAst.set)
      {
        | (Some(PT.ClassMember.Function(_, _, FunBody.Abstract) as getr), 
           Some(PT.ClassMember.Function(_, _, FunBody.Abstract) as setr)) =>
          
          def ctx = Nemerle.Macros.ImplicitCTX();
          ctx.Env.Manager.MacroColors.PushUseSiteColor();
          try
          {
            getr.Body = <[
              def val = $("ViewState" : usesite)[$(propertyAst.Name : string)];
              if (val == null) $defaulteValue else (val :> $(propertyAst.ty))
            ]>;
            setr.Body = <[ $("ViewState" : usesite)[$(propertyAst.Name : string)] = value ]>;
          }
          finally { ctx.Env.Manager.MacroColors.PopColor(); }
          
        | _ => Message.Error(propertyAst.Location, "Property should have empty getter and setter!")
      }  
  }
}

Использование:
using System;
using Nemerle.Collections;
using System.Console;
using Nemerle.Utility;
using MacroLibrary2;

public class A
{
  ViewState : System.Collections.Hashtable = System.Collections.Hashtable();
  
  [ViewState(0)]
  public Prop1 : int { get; set; }

  [ViewState("<empty>")]
  public Prop2 : string { get; set; }
}

module Program
{
  Main() : void
  {
    def a = A();
    WriteLine($"a.Prop1=$(a.Prop1)");
    WriteLine($"a.Prop2=$(a.Prop2)");
    a.Prop1 = 123;
    a.Prop2 = "test";
    WriteLine($"a.Prop1=$(a.Prop1)");
    WriteLine($"a.Prop2=$(a.Prop2)");
    
    Write("..."); _ = ReadLine();
  }
}

Вывод:
a.Prop1=0
a.Prop2=<empty>
a.Prop1=123
a.Prop2=test


ЗЫ

Что касается 20 минут. Перед этим конечно пару месяцев нужно потратить на исследование макросистемы, а лушче еще годик на изучение компилятора. Тогда за 20 минут легко такие вещи делаются. Без этих знаний конечно будет не просто. Но думаю, что после того как я допишу цикл статей по макросам — это будет доступно всем кто умеет читать по русски.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Вы оба не правы.
От: Блудов Павел Россия  
Дата: 14.05.07 07:21
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Пока Янус обновлялся, подумал, что переусложнил. Так как используется переключение в цвета области использования (PushUseSiteColor()), то все имена и так будут браться из области использования, так что вместо:

VD>
VD>$("ViewState" : usesite)
VD>

VD>можно просто писать
VD>
VD>ViewState
VD>


Нет, предыдущий макрос был как раз лучше. Осталось только оформить "ViewState" параметром и будет именно то что нужно. А иначе для Session/Application и что там ещё есть придётся новые макросы городить.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[10]: Добавил поддержку auto-property (как в C# 3.0)
От: _pk_sly  
Дата: 14.05.07 08:10
Оценка:
тему уже пора переносить в flame wars ;)

VD>Автосвойства — это продуманное решение. Продуманное не по одному критерию "ах какая приятная рюшечка", а по массе критериев, от совестимости со старым кодом, до локаничности и безопасности.


если бы этот ответ был сразу, никаких споров не возникло бы.
я верю в маудрость разработчиков Nemerle ;) но решать за меня, что мне надо — не стоит.

VD>Пока что я вижу четкую связь между уровнем программиста и желанием налепить решений вроде свойств доступных только для записи


а вот переход на личности с прозначными намёками — это лишнее. (не первый раз уже).
вас (немерлистов) и так слишком мало чтобы вот так из-за эмоций распугивать интересующихся людей.

раз в три года и goto пригождается — поговорим о программистах, которые не предали анафеме goto? :)

за все годы write-only-свойство использовал всего один раз, но там оно было очень кстати.
Re[4]: Вы оба не правы.
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.05.07 15:45
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Нет, предыдущий макрос был как раз лучше. Осталось только оформить "ViewState" параметром и будет именно то что нужно.


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

БП>А иначе для Session/Application и что там ещё есть придётся новые макросы городить.


Декомпозицию еще никто не отменял. Код макроса можно вынести в фукнцию, а имя свойства передавать в качестве параметра. Получится 3 макроса вида:
[MacroUsage(MacroPhase.BeforeTypedMembers, MacroTargets.Property, Inherited = true)]
macro ViewState(_ : TypeBuilder, propertyAst : ParsedProperty, defaulteValue)
{
  Helper.PersistState("ViewState", Nemerle.Macros.ImplicitCTX(), propertyAst, defaulteValue);
}


Не думаю, что создание таких макросов еально напряжет. В прочем ввести еще один параметр проще простого.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.05.07 13:06
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Но language designer-ы — это особые фрукты. От их деятельности зависят (потенциально) тысячи людей. Поэтому они (LD) должны обладать даром предвидения (и чем больше дар, тем лучше) и теоретической базой для создания наиболее общих решений, иначе язык погрязнет в десятках несовместимых версий (или тяжёлом наследии с другой стороны) и кривых воркэраундах. Примеров предостаточно (те же указатели на члены в C++).


Это все оправдывает впихивание фич "на всякий пожарный"?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Добавил поддержку auto-property (как в C# 3.0)
От: IT Россия linq2db.com
Дата: 16.05.07 13:14
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это все оправдывает впихивание фич "на всякий пожарный"?


Главное теперь осталось определить грань между "всяким пожарным" и даром предвидения
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[12]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.05.07 13:30
Оценка:
Здравствуйте, IT, Вы писали:

IT>Главное теперь осталось определить грань между "всяким пожарным" и даром предвидения


Отсуствие внятного обоснования.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Добавил поддержку auto-property (как в C# 3.0)
От: IT Россия linq2db.com
Дата: 16.05.07 22:42
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Главное теперь осталось определить грань между "всяким пожарным" и даром предвидения


VD>Отсуствие внятного обоснования.


Интуиция такая вещь, которую нельзя обосновать. Точнее если её обосновать, то это уже не будет интуицией.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: Добавил поддержку auto-property (как в C# 3.0)
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 17.05.07 06:37
Оценка:
VladD2,

VD>Это все оправдывает впихивание фич "на всякий пожарный"?


Фича уже впихнута. Называется "auto-properties". Предлагается просто чуть-чуть обобщить её поведение, нет? Обобщение слишком сложно в реализации?
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[14]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.05.07 13:00
Оценка:
Здравствуйте, IT, Вы писали:

VD>>Отсуствие внятного обоснования.


IT>Интуиция такая вещь, которую нельзя обосновать. Точнее если её обосновать, то это уже не будет интуицией.


Итересная инженерная технология .
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Добавил поддержку auto-property (как в C# 3.0)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.05.07 13:00
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

VD>>Это все оправдывает впихивание фич "на всякий пожарный"?


LCR>Фича уже впихнута. Называется "auto-properties". Предлагается просто чуть-чуть обобщить её поведение, нет? Обобщение слишком сложно в реализации?


Где предлагается? Предлагается принудить других дуать над какой-то черт знает чем, причем совершенно неизвесно зачем.

Вот действия по такому сценарию и приводят к появлению С++. Хотя ради справедливости надо заметить, Струсруп был все же более разумен.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
В продолжение беседы
От: Блудов Павел Россия  
Дата: 23.10.07 02:09
Оценка:
Здравствуйте, VladD2 & IT, Вы писали:

IT>>А только getter или только setter можно задать?

VD>Нет. В этом нет смысла. Поле то ведь скрытое.
VD>Вообще спецификацию C# писали разумные люди .
Илья в своём блоге доказывает обратное. Мысли довольно здравые.
... << RSDN@Home 1.2.0 alpha rev. 774>>
Re: В продолжение беседы
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.10.07 10:14
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

IT>>>А только getter или только setter можно задать?

VD>>Нет. В этом нет смысла. Поле то ведь скрытое.
VD>>Вообще спецификацию C# писали разумные люди .
БП>Илья в своём блоге доказывает обратное. Мысли довольно здравые.

Ты читал что там написано? Он предлагает разумные расширения. А IT не разумное (точнее бессмысленное).
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Есть один момент
От: Блудов Павел Россия  
Дата: 24.10.07 00:49
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Можно, кстати, продумать синтаксис и добавить расширения в Немерле.

Я думал сегодня ночью об этом и понял, почему нет инициализаторов для автосвойств в C#
public Foo { get; } : Foo = Foo();

можно понимать как
private _foo : Foo = Foo();
public   Foo : Foo { get { _foo; } }

а можно как
private _foo : Foo;
public   Foo : Foo{ get { _foo ?? (_foo = Foo()); } }

Поведение получается разным.
Можно конечно придумать два синтаксиса для обоих случаев, но разработчики C# пошли более простым путём — забили на инициализаторов.
Вобщем чем больше я смотрю на автосвойства, тем они мне меньше нравятся. А макрос Accessor нравится всё больше и больше.
... << RSDN@Home 1.2.0 alpha rev. 774>>
Re: Есть один момент
От: Сергей Туленцев Россия http://software.tulentsev.com
Дата: 24.10.07 06:50
Оценка:
Здравствуйте, Блудов Павел, Вы писали:

БП>Вобщем чем больше я смотрю на автосвойства, тем они мне меньше нравятся. А макрос Accessor нравится всё больше и больше.

Хорошо, когда есть выбор. Record+Accessor, они, конечно, сладкая парочка.
Но кому-то нравится больше писать так

public Foo : int
{ get; private set;}

// нежели так
[Accessor(WantSetter = true)] _foo;


Может, я отстал от жизни и Accessor обзавелся красивой формой, типа Accessor(get; set?
--
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.