Reputation: 8043
I've noticed that TJSONObject.AddPair
functions results Self
instead of the newly created object:
For example, in System.JSON
unit I see the following code:
function TJSONObject.AddPair(const Str: string; const Val: string): TJSONObject;
begin
if (not Str.IsEmpty) and (not Val.IsEmpty) then
AddPair(TJSONPair.Create(Str, Val));
Result := Self;
end;
I was expecting something like that:
function TJSONObject.AddPair(const Str: string; const Val: string): TJSONObject;
begin
if (not Str.IsEmpty) and (not Val.IsEmpty) then
Result := AddPair(TJSONPair.Create(Str, Val));
else
Result := nil;
end;
I find this very unusual, is it a Delphi XE7 bug or is there any technical/practical reason why they did that?
Upvotes: 2
Views: 731
Reputation: 28516
Returning Self
is common coding pattern called fluent interface.
It allows you to continue with calls to the same object, creating chain of methods without the need to reference object variable for every call. That makes code more readable, on the other hand it is harder to debug.
var
Obj: TJSONObject;
begin
Obj := TJSONObject.Create
.AddPair('first', 'abc')
.AddPair('second', '123')
.AddPair('third', 'aaa');
...
end;
would be equivalent of
var
Obj: TJSONObject;
begin
Obj := TJSONObject.Create;
Obj.AddPair('first', 'abc');
Obj.AddPair('second', '123');
Obj.AddPair('third', 'aaa');
...
end;
And the generated JSON object will look like:
{
"first": "abc",
"second": "123",
"third": "aaa"
}
That kind of coding style is more prevalent in languages with automatic memory management, because you don't need to introduce intermediate variables.
For instance, if you need JSON string you would use following construct:
var
s: string;
begin
s := TJSONObject.Create
.AddPair('first', 'abc')
.AddPair('second', '123')
.AddPair('third', 'aaa')
.Format(2);
...
end;
The problem with the above code in Delphi is that it creates memory leak as you don't have ability to release intermediate object. Because of that, it is more common to use fluent interface pattern in combination with reference counted classes where automatic memory management will handle releasing of any intermediary object instances.
Upvotes: 6