-
Notifications
You must be signed in to change notification settings - Fork 89
Nemerle object modifier
When writing code that interfaces with .NET libraries (or writing imperative code in general), one often needs to edit multiple object properties at once, like this:
def x = Form();
x.Text = "Hello!";
x.BackColor = Color.Red;
x.Width = 300;
This code pattern is so common that mainstream .NET languages, like C# and VB.NET, have developed their own syntax constructs for it, called object initializers (and also With statement in VB.NET).
Nemerle object modifier macro from Nemerle.Extensions namespace is currently in standard library. Its purpose is to consolidate modifying multiple object properties into one expression, both for language brevity, fluency and greater flexibility. It works on general objects, but is also tuned for lists and dictionaries.
Syntax for object modifier macro is next:
objectName <-
{
PropertyName1 = value1;
PropertyName2 = value2;
...
}
or
objectName <-
[
object1,
(Key1, value1), // or this way
Key2 = value2 // or this way
]
Different bracket types switch macro to different modes: object mode and collection mode.
Object mode takes object objectName, assigns specified values to the corresponding properties, and returns the same object:
using Nemerle.Extensions;
def myForm = Form() <- // myForm becomes Form() with specified properties
{
Text = "Hello!";
BackColor = Color.Red;
Width = 300;
}
_ = myForm <- // return value is ignored, but myForms.Text changes
{
Text = "World!";
}
Object mode also supports other operations instead of assignments:
using Nemerle.Extensions;
def myForm = Form() <-
{
Location <- // nested modifiers; meaningless in this case, since Location is of value type Point
{
X = 100;
Y = 200;
};
Location = Point() <- { X = 100; Y = 200 }; // works this way with value types
Controls ::= array[Button(), Label()]; // calls AddRange with specified parameters
Controls <- [ TextBox(), CheckBox() ]; // nested list modifier works all right
Click += OnButtonClick; // adds event
Click -= OnButtonClick; // removes event
Click => WriteLine("wow"); // Mono C#-style shortcut
BringToFront(); // calls a method
}
Collection mode works on lists and dictionaries by calling their Add() methods. The macro doesn't require the modified object to be of any type; it just calls Add() method, so if your type happens to implement it, the macro will work just fine.
using System.Collections.Generic;
using Nemerle.Extensions;
def lst = List() <- [ "hello", "world" ];
def dic = Dictionary() <- [ "question" = 31, "answer" = 42 ];
def dic = Dictionary() <- [ ("question", 31), ("answer", 42) ]; // this (yet) works