) хотел инициализаторы коллекций, так что я решил поделиться, и обновил реализацию with-макроса в сниппетах. Поддерживаются новые фичи.
H>Макрос переехал в стандартную библиотеку в пространство имен Nemerle.Extensions. H>К сожалению, использовать оригинальное имя "with" в качестве имени оператора не вышло: виртуальный оператор с таким именем, используемый для поддержки PM-а, имеет неподходящие приоритеты. Использована синтетическая штуковина: <-. Пример тут. Как и макра анонимного типа, инициализатор пока не отражен в официальной документации.
Крутая макра!!! НАконецто можно декларативно создавать формочки из немерловского кода.
Если доработать то и поддержка XAMLa будет не нужна.
Чего не хватало в оригинальном макросе -- возмодности присваивать промежуточные результаты глобальной области видимости (те. формочка создаеться макросом и все ее содержымое, но какой-то TextBox также помещается в переменную)
Обратить внимание на места lbl <- Label() и txtBox <- TextBox() то есть помещаем во внешнюю переменную(или поле класса) текущие контролы.
Приимущества:
Весь код формы находиться в одном месте, а не размазан по местам где создаются нужные переменные(и контрольчики)
нужные контрольчики лежат в переменных
Ну мешать эту макру с "<-" не обязательно, просто этот символ для этого действия ажеться логичным(и другого не придумал) а оператор "=" как ихвестно имеет тип возврата void по этому надо как то выкручиваться
Желаю услышать ваши мнения. Если катит то доведу до ума и закомичу ибо ИМХО полезная доработка для этого макроса.
Здравствуйте, BogdanMart, Вы писали:
ВМ>Чего не хватало в оригинальном макросе -- возмодности присваивать промежуточные результаты глобальной области видимости
Так, правда, приходится создавать переменные сверху. Чтобы автоматически добавлять переменные в область видимости (но это уже другой вопрос!), можно добавить оператор as, как в паттерн-матчинге:
def w = Window() <-
{
Content = StackPanel() as pnl <-
{
Children <-
[
TextBox() as this.txtBox <- { blah blah } // если написано this, то генерируется член класса, а не локальная переменная
]
}
}
Преимущество в том, что повторно используется стандартный синтаксис ввода в область видимости. Недостаток в том, что Немерле при этом на шаг приближается к С++, где все выражения вроде int *&, (int*)&, const int *, const * int, * const int позволены и имеют различную семантику. Но это так, философия
Здравствуйте, catbert, Вы писали:
C>Так, правда, приходится создавать переменные сверху. Чтобы автоматически добавлять переменные в область видимости (но это уже другой вопрос!), можно добавить оператор as, как в паттерн-матчинге:
C>
C>def w = Window() <-
C>{
C> Content = StackPanel() as pnl <-
C> {
C> Children <-
C> [
C> TextBox() as this.txtBox <- { blah blah } // если написано this, то генерируется член класса, а не локальная переменная
C> ]
C> }
C>}
C>
Идея хорошая с именами — они позволят записать инициализацию циклических структур:
def x = Node() as n <-
{
Parent = n
};
Фактически это имя можно использовать вместо временного имени, генерируемого компилятором.
C>def w = Window() <-
C>{
C> Content = StackPanel() as pnl <-
C> {
C> Children <-
C> [
C> TextBox() as this.txtBox <- { blah blah } // если написано this, то генерируется член класса, а не локальная переменная
C> ]
C> }
C>}
C>
Выглядит уже симпатично. Не придумал как cделать..
Вот только с введением переменных во внешнюю область видимости могут быть сложности.. Компилятор вроде бы автоматически ставит блок вокруг тела макроса.. значит объявленные переменные будут внутри блока.
Здравствуйте, BogdanMart, Вы писали:
BM>Выглядит уже симпатично. Не придумал как cделать.. BM>Вот только с введением переменных во внешнюю область видимости могут быть сложности.. Компилятор вроде бы автоматически ставит блок вокруг тела макроса.. значит объявленные переменные будут внутри блока.
ставит если макрос из нескольких выражений, попробуй так:
C>mutable pnl : StackPanel;
C>mutable txtBox : TextBox;
C>def w = Window() <-
C>{
C> Content = StackPanel() as pnl <-
C> {
C> Children <-
C> [
C> TextBox() as this.txtBox <- { blah blah } // если написано this, то генерируется член класса, а не локальная переменная
C> ]
C> }
C>}
C>
Из макроса их объявить более глобально -- это куча гемора связанная с доставанием MethodBuilder'a из Typer'a а это уже шаманство.
Проще будет объявить нужную переменную
Не катит, потому что создания переносятся вверх... а если использовать первый способ то намного удобнее. И можно изменять тип контролов по требовании с меньшими затратами (все в одном месте лежит).
Хотя если вы знаете как по хорошему объявить переменную во внешней области.. то попробуйте..
ПС, как мне кажется даже с объявлением полей класса могут возникнуть проблемы, так как другие методы могут быть уже обработаны к этому моменту и не находить соответствующих полей(+ непонятно какую область видимости им давать, или может их свойствами, или вообще DependencyProperty) по этому лучше оставить объявление мест хранения объектиков на откуп пользователю.
H>mutable obj;
H>def x = X() <-
H>{
H> Y = Y() as out obj <-
H> {
H> A = ... // используем инициализированный obj здесь
H> B = ...
H> }
H>}
H>// а также уже после блока
H>
Конкретно именно так работать не будет ввиду специфики разбора out-выражение, но можно поискать решения типа:
mutable obj;
def x = X() <-
{
Y = out Y() as obj <-
{
A = ... // используем инициализированный obj здесь
B = ...
}
}
// а также уже после блока
Здравствуйте, BogdanMart, Вы писали:
BM>Тоесть полюбому не даст(напрямую, кончено можно из Тайпера получить MethodBuilder и потом колдовать, но брррр).
Макросы гигиеничны, переменную надо задавать так: $("var" : usesite).
BM>А еслибы и заработало с одним выражением, так нам надо и проретурнить и присвоить выражению.
Здравствуйте, hardcase, Вы писали:
H>Случай 1: использование имени внутри инициализатора
H>
H>def x = X() as current <-
H>{
H> // используем current для создания циклических структур данных
H>}
H>
public macro @as(obj, ing, initializer) // пробовал public macro @<-(obj, ing, initializer) как было в оригинале, не помогло..syntax( obj, "as", ing, "<-", initializer)
{
WithMacroImpl.Run(obj, initializer);
}
def _w = Window() as temp <- {}
выдает: Error: found pattern expression () inside a raw expression