preparing for const, final, and invariant
Aarti_pl
aarti at interia.pl
Fri May 18 04:02:48 PDT 2007
Daniel Keep pisze:
>
> Aarti_pl wrote:
>> I want to ask about something opposite to above example...
>>
>> Will it be possible to pass ownership of object? I mean that when you
>> pass object by reference to function/class/member variable you can still
>> modify this object from outside of function/class. It breaks
>> encapsulation in program.
>>
>> Example:
>>
>> import std.stdio;
>> public class TestX {
>> char[] value;
>> char[] toString() {
>> return value;
>> }
>> }
>> public class TestMain {
>> TestX x;
>> }
>>
>> void main(char[][] args) {
>> TestX parameter = new TestX();
>> parameter.value = "First assignment";
>>
>> TestMain tmain = new TestMain();
>> tmain.x = parameter;
>>
>> parameter.value = "Second assignment";
>> writefln(tmain.x);
>> }
>>
>> Notice that tmain.x value has changed although I would like just to set
>> once, and have second assignment to parameter illegal... When using
>> setters and getters problem is even more visible....
>>
>> How to achieve proper behavior with new final/const/invariant/scope??
>>
>> Regards
>> Marcin Kuszczak
>> (aarti_pl)
>
> I don't think the new const, final & invariant are going to help you
> any. Basically, you seem to be complaining that reference semantics
> are... well, reference semantics.
>
> That's like complaining that water is wet :P
>
The problem here is that current behavior breaks encapsulation - you can
change already passed value from outside of object, when contract is
that you can set it only with setter. Imagine consequences in
multithreaded application, when in the middle of function your data
suddenly change... But also with single threaded application it can be
real problem when you change referenced object by mistake.
So it is more like complaining that water is dry when it should be wet
in fact :-)
I know that other languages also have same problem, but I think that D
can do better.
> There's a few things I can think of to get the behaviour you want.
>
> 1. Use a write-once setter for 'value'. You can either create a
> nullable template, or use a flag to ensure external code can only set it
> once.
>
Could you please give example? I don't know how to achieve this behavior
with this method...
> 1.a. A "nicer" approach would be to set it in the constructor, and then
> either mark it "final" (with the new final),
> or only write a public getter function.
I think that rather invariant? Final will not disallow changing of
referenced object. And I am afraid that it won't help anyway, it would
be still possible to change value from outside... Using only getter and
passing reference in constructor also doesn't help. You can still also
modify variable from outside...
>
> 2. Use a struct instead; no references, no indirect changes.
>
Ok. I didn't think about it. But it is basically same as below, so
please see comment below. Probably you have also problem when struct has
references inside...
> 3. Take a private copy of the object by writing a .dup method.
>
Yes that is possible solution, but program would be much faster (no
unnecessary copies) with other solution...
> -- Daniel
>
BR
Marcin Kuszczak
(aarti_pl)
More information about the Digitalmars-d-announce
mailing list