Alexander Klenin schrieb:
The answer was that properties are meant to change the value on the object
immediately. Also a property setter can raise an exception, or additional
actions can take place or the value can be substituted....
All this wouldn't happen with a temp variable (or at best deferred).
Therefore the behaviour would not be according to the rules of properties
I thought about that too. There are few counter-arguments here:
Strictly speaking, properties are not *meant* to change anything
neither immediately nor
in any other way. Assigning to a property with the setter is just a
procedure call,
and I do not think there exist any specification requiring the setter
to change anything.
So it is important to understand that we are dealing here with "common
sense" and "usual expectations",
not with any formal requirement.
Now the question is, given the code:
-----
type T = class
...
property P: Integer read GetP write SetP;
end;
procedure MyInc2(var a: Integer); begin a := a + 1; a := a + 1; end;
var obj: T;
begin
MyInc2(obj.P);
end.
-----
what is the *usual expectation* of the number of calls to GetP and SetP?
Using temporary variables, there will be one call to each.
Where would you place such temporary variables, in your sample code?
Into an invisible layer between the caller and MyInc2?
It might be argued that some programmer might expect two calls to each,
but I am really not sure if such programmer exists ;-)
Moreover, if we assume the existence of such a hypothetical programmer,
how could he implement MyInc2 to achieve the behaviour he expects?
The answer is: he could not. It is impossible with or without the
proposed extension.
I could follow your argumentation in an example like
for i := 1 to obj.P do ...
where a C programmer would assume any number of calls to obj.GetP, while
a Pascal programmer would be sure that obj.GetP is invoked only once,
and the returned value is stored in a local variable.
So we must conclude that the possible downside is relatively small.
It must be weighted against the upside:
Components[ComponentIndex].Options :=
Components[ComponentIndex].Options + [myOption];
vs
Include(Components[ComponentIndex].Options, myOption);
is, IMO, a very compelling argument.
Right :-)
But again, a C++ programmer would write a macro
#define Inc2(x) {x += 2;}
and use it like
Inc2(obj.P);
where a Pascal programmer would use the compiler magic
Inc(obj.P,2);
because he cannot write macros, and the compiler should[1] do the job
for him.
Unfortunately FPC did a lousy job in the past, using the field address
(returned by @obj.P) to bypass the setter. Strange enough that FPC
realized that a typed constant cannot be written to - it simply could
have detected the same obstacle for a property. [I didn't realize these
flaws until I did some testing just now]
[1] A quick comparison with Delphi 7 revealed:
Delphi notices that a property cannot be passed as a var parameter.
Delphi also denies Inc(obj.P), so that I have to adjust my opinion about
the cleverness of Inc() :-(
[What does not influence my opinion about the *expected* behaviour of
Inc() :-]
DoDi
--
_______________________________________________
Lazarus mailing list
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus