Fields default values, anonymous records

Recent additions to DWScript… as well as for next Smart MS version 😉

Fields default values

Record and class fields can now have default values, and can be type-inferenced.

The same syntax works both in record declarations and class declarations, and you can use ‘=’ or ‘:=’ for the assignment, for instance

type
   TMyClass = class
      Field1 := 'hello';
      Field2 : Integer = 123;
   end;

Will specify that all new instances of TMyClass will have Field1 set to ‘hello‘ by default (instead of an empty string), and Field2 will be initialized to 123.

As a reminder, unlike in Delphi, all variables in DWScript are always initialized, even local stack-based ones, so the facility above thus applies to local variables of record type as well.

Anonymous records

This is a feature initially targeted at SmartMS, to allow declaring arbitrary inline JS objects, but it’s also available script-side, though I’ve not found an immediate purpose for it there, some might find creative use with language extensions, custom functions or the RTTI connectors 🙂

var v : Variant;
...
v.rec :=  record
   // type-inferenced
   Field = 'hello';
   // explicitly typed and initialized with a dynamic value
   Value : Integer = someVar+someFuncCall(anotherVar);
   // you can use strings for the field names
   'dotted.weird$name' := #"
       Lorem ipsum
       dolor sit amet"
end;

The above would be expressed in JSON as

{
   "Field" : "hello",
   "Value" : someVar+someFuncCall(anotherVar),
   "dotted.weird$name" : "Lorem ipsum\ndolor sit amet"
}

So as you can see the verbosity “overhead” is limited to “record” vs “{” and “end” vs “}”.

Note that type-inference works on anonymous records too, so f.i. it’s possible to declare multiple variables of an anonymous record type with it.

Anonymous classes aren’t yet supported, though when needs and uses will arise, they’ll likely by. The difference between an anonymous record and an anonymous class would be that the record is a value type (an assignment clones the record) while a class is a reference type (an assignment copies the reference/pointer).

Other changes

  • Defined() when used in code is now known as ConditionalDefined(), as Defined() was re-tasked to check if a variable or expression is defined, rather than a conditional directive was defined at the end of the compilation. The meaning of Defined() in conditional directives is unchanged.
  • operator overloading is now scoped and supported in units too (previously was active only in a script’s main program).
  • helper methods are now accepted for operator overloading.
  • helper properties are now active (they were parsed and syntax-checked, but weren’t active).
  • dynamic array’s Add() now accepts static arrays too.
  • fix: alias symbols now have a caption in TdwsSuggestions.
  • fix: external classes no longer inherit from TObject.