With Statements

The with can be used to temporarily introduce new members in the scope. It supports multiple with items seperated by a comma. The main benefit of with over using a regular local var declaration is that with more explicitly limits the scope of the new variables to the statement or block of statements it applies to. The do keyword can be followed by a single statement or a begin/end block grouping multiple statements.

with fb := CalculateFooBar do begin
  writeLn(fb);
end;
// fb is not available here anymore.

Optionally, the matching keyword can be applied to ensure that the object matches a certain type or subtype – symmetrical to how matching works in for loops. The with statement will only be executed if the type matches, otherwise it will be silently skipped. For obvious reasons, an explicit type needs to be specified when using matching.

with matching b: Butotn := GetNextControl do begin
  writeLn($"Ayup, {b} is a button!");
end;

With Statements and Records

When the expression for the with statement is a Record or other value type, the new variable acts as an alias to the original record, and any changes done on the identifier will directly affect the original record.

By contrast, assigning the record to a new local var declaration would create a copy of the record on the stack:

var x: Person;
x.Name := "Peter";

with y := x do  
  y.Name := "Paul";
  
// x.Name is now Paul

Compared to:

var y := x;
y.Name := "Paul";

// x.Name is unchanged, as y is a separate copy

See Also