[fpc-pascal] Read-only global references
Marcos Douglas
md at delfire.net
Sun Mar 6 00:15:51 CET 2011
On Sat, Mar 5, 2011 at 7:05 PM, Mark Morgan Lloyd
<markMLl.fpc-pascal at telemetry.co.uk> wrote:
> Marcos Douglas wrote:
>>
>> On Sat, Mar 5, 2011 at 8:24 AM, Mark Morgan Lloyd
>> <markMLl.fpc-pascal at telemetry.co.uk> wrote:
>>>
>>> Where a unit exports an instance of an object, what's best practice for
>>> making this read-only? I'm referring to the object reference itself here,
>>> not properties of the object.
>>>
>>> Where I've done this in the past I've used a function:
>>>
>>> interface
>>>
>>> function InitText: TFormattedString;
>>>
>>> implementation
>>>
>>> var xInitText: TFormattedString= nil;
>>>
>>> function InitText: TFormattedString;
>>>
>>> begin
>>> result := xInitText
>>> end { InitText } ;
>>>
>>> Is there a better way using e.g. global properties that doesn't
>>> necessitate
>>> both a property and an explicit function?
>>>
>>> property InitText: TFormattedString read xInitText;
>>>
>>> The obvious problem here is that xInitText is a forward reference to an
>>> unexported variable.
>>
>> Make a function to return a global variable does not make it read only.
>> If I use your function like this:
>> o := InitText;
>> o := nil; //this is the same xInitText = nil
>
> Disagree. You are changing the value of o, not of xInitText. xInitText is
> initialised once somewhere in the unit exporting it, subsequently its
> properties etc. can be used elsewhere e.g. InitText.AppendFormatted(...).
You right... but not TOTALY.
I made a little program to explain that, but now I'm confusing, see:
program ref;
{$mode objfpc}{$H+}
uses
sysutils;
type
TObj = class
public
i: integer;
end;
var
o1: TObj = nil;
o2: TObj = nil;
function getobj: TObj;
begin
if not Assigned(o1) then
o1 := TObj.Create;
o1.i := 1;
result := o1;
end;
begin
o1 := getobj;
o2 := o1;
writeln('o1.i: ', o1.i);
writeln('o2.i: ', o2.i);
writeln('o2.i change to 2');
o2.i := 2;
writeln('o1.i = 2 too?": ', o1.i = 2);
writeln('Destroy o2');
o2.Free;
writeln('o1.i still exists?: ', Assigned(o1), ' so, write o1.i: ', o1.i);
writeln('o1.i change to 3');
o1.i := 3;
writeln('o1.i: ', o1.i);
try
o1.Free;
except
on e: Exception do
writeln(e.Message);
end;
readln;
end.
The o1 variable still exists, even after o2 was destroed! But o2 point to o1...
The variable o1 exists, but I can't destroy it! Why??
I test on Lazarus and Delphi 7.
The only diference is in this line:
writeln('o1.i still exists?: ', Assigned(o1), ' so, write o1.i: ', o1.i);
In Lazarus, the result is:
TRUE | 0
In Delphi, the result is:
TRUE | 2
Again... Why??
Marcos Douglas
More information about the fpc-pascal
mailing list