Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2006-08

Reading empty collection from stream

7 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Vincent Snijders

Hi,

I am investigating Lazarus issue 7305. The TSynEdit class has a KeyStrokes property of the type TSynEditKeyStrokes, which is a TCollection descendant. The TSynEdit constructor fills the collection with some default items. If I remove the items and stream the TSynEdit, the following line is shown in the lfm:
Keystrokes =

If I read this lfm, I don't get a empty KeyStrokes collection, but one filled with the default value.

I suspect the following lines in TReader.ReadCollection cause this
behaviour:
     if not EndOfList then
       Collection.Clear;

Is this a bug or by design? How do I load an empty collection from a stream, if the collection has a default value?

Note, if I remove the 'Keystrokes = ' line from the lfm, I will get the default collection too, so I wonder why there are two ways to get the default collection.

Vincent

Reply by email

Marc Weustink
to Vincent Snijders
Vincent Snijders wrote 19 lines
Hi, I am investigating Lazarus issue 7305. The TSynEdit class has a KeyStrokes property of the type TSynEditKeyStrokes, which is a TCollection descendant. The TSynEdit constructor fills the collection with some default items. If I remove the items and stream the TSynEdit, the following line is shown in the lfm: Keystrokes = If I read this lfm, I don't get a empty KeyStrokes collection, but one filled with the default value. I suspect the following lines in TReader.ReadCollection cause this behaviour: if not EndOfList then Collection.Clear; Is this a bug or by design? How do I load an empty collection from a stream, if the collection has a default value?

Delphi has the same construction, which is IMO a design flaw. IMO when a collection is "default" is shouldn't be streamed, so there would be nothing written.
I don't know why it is there, since when a "default" collection is written, all elements are written. So it never will be .

Note, if I remove the 'Keystrokes = ' line from the lfm, I will get the default collection too, so I wonder why there are two ways to get the default collection.

I propose to remove the "if not EndOfList then Collection.Clear;" line.

Marc

Reply by email

Flávio Etrusco
to Marc Weustink

Agreed, this is one of the weird Delphi misfeatures...

In later SynEdit versions I implemented custom streameing functions which only store the "diff" from default keystrokes (i.e. the removed and added keystrokes compared to the default list).

-Flávio

Marc Weustink wrote 40 lines
Vincent Snijders wrote: > Hi, > > I am investigating Lazarus issue 7305. The TSynEdit class has a > KeyStrokes property of the type TSynEditKeyStrokes, which is a > TCollection descendant. The TSynEdit constructor fills the collection > with some default items. If I remove the items and stream the TSynEdit, > the following line is shown in the lfm: > Keystrokes = > > If I read this lfm, I don't get a empty KeyStrokes collection, but one > filled with the default value. > > I suspect the following lines in TReader.ReadCollection cause this > behaviour: > if not EndOfList then > Collection.Clear; > > Is this a bug or by design? How do I load an empty collection from a > stream, if the collection has a default value? Delphi has the same construction, which is IMO a design flaw. IMO when a collection is "default" is shouldn't be streamed, so there would be nothing written. I don't know why it is there, since when a "default" collection is written, all elements are written. So it never will be . > Note, if I remove the 'Keystrokes = ' line from the lfm, I will get > the default collection too, so I wonder why there are two ways to get > the default collection. I propose to remove the "if not EndOfList then Collection.Clear;" line. Marc _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Michael Van Canneyt
to Marc Weustink: Delphi has the same construction, which is IMO a design flaw. IMO when a collection is…
Marc Weustink wrote 20 lines
Vincent Snijders wrote: > Hi, > > I am investigating Lazarus issue 7305. The TSynEdit class has a KeyStrokes > property of the type TSynEditKeyStrokes, which is a TCollection descendant. > The TSynEdit constructor fills the collection with some default items. If I > remove the items and stream the TSynEdit, the following line is shown in > the lfm: > Keystrokes = > > If I read this lfm, I don't get a empty KeyStrokes collection, but one > filled with the default value. > > I suspect the following lines in TReader.ReadCollection cause this > behaviour: > if not EndOfList then > Collection.Clear; > > Is this a bug or by design? How do I load an empty collection from a > stream, if the collection has a default value?

You can't.

Delphi has the same construction, which is IMO a design flaw. IMO when a collection is "default" is shouldn't be streamed, so there would be nothing written.

There is no way to know whether the collection is default or not, since that would imply keeping a copy of the collection as it was just after creation.

Show quoted text 8 lines
I don't know why it is there, since when a "default" collection is written, all elements are written. So it never will be . > Note, if I remove the 'Keystrokes = ' line from the lfm, I will get the > default collection too, so I wonder why there are two ways to get the > default collection. I propose to remove the "if not EndOfList then Collection.Clear;" line.

You may not, because then inherited form streaming will be broken: a collection of "" means: don't touch, keep the collection of the parent form.

Michael.

Reply by email

Marc Weustink
to Michael Van Canneyt
Michael Van Canneyt wrote 45 lines
On Thu, 7 Sep 2006, Marc Weustink wrote: > Vincent Snijders wrote: >> Hi, >> >> I am investigating Lazarus issue 7305. The TSynEdit class has a >> KeyStrokes property of the type TSynEditKeyStrokes, which is a >> TCollection descendant. The TSynEdit constructor fills the collection >> with some default items. If I remove the items and stream the >> TSynEdit, the following line is shown in the lfm: >> Keystrokes = >> >> If I read this lfm, I don't get a empty KeyStrokes collection, but >> one filled with the default value. >> >> I suspect the following lines in TReader.ReadCollection cause this >> behaviour: >> if not EndOfList then >> Collection.Clear; >> >> Is this a bug or by design? How do I load an empty collection from a >> stream, if the collection has a default value? You can't. > Delphi has the same construction, which is IMO a design flaw. > IMO when a collection is "default" is shouldn't be streamed, so there > would be nothing written. There is no way to know whether the collection is default or not, since that would imply keeping a copy of the collection as it was just after creation. > I don't know why it is there, since when a "default" collection is > written, all elements are written. So it never will be . > >> Note, if I remove the 'Keystrokes = ' line from the lfm, I will get >> the default collection too, so I wonder why there are two ways to get >> the default collection. > > I propose to remove the "if not EndOfList then Collection.Clear;" line. You may not,

I always can propose ;-)

because then inherited form streaming will be broken: a collection of "" means: don't touch, keep the collection of the parent form.

There you have a point. Didn't think of that.

And indeed, a collection itself doesn't know if it is default or not. The owning class usually knows this.
To solve this problem, I think the owning class needs to know when it is loading or not, so that it can add the defaults when it is not loaded, but created.
I think the cleanest way is to introduce a Loading virtual method as counterpart of the Loaded method. This way the owning class can decide that when loading, the collection should be cleared. AFAIK, there is no other way a component knows on creation if it gets loaded in the future or not.

Marc

Reply by email

Marc Weustink
to Marc Weustink
Marc Weustink wrote 65 lines
Michael Van Canneyt wrote: > > > On Thu, 7 Sep 2006, Marc Weustink wrote: > >> Vincent Snijders wrote: >>> Hi, >>> >>> I am investigating Lazarus issue 7305. The TSynEdit class has a >>> KeyStrokes property of the type TSynEditKeyStrokes, which is a >>> TCollection descendant. The TSynEdit constructor fills the >>> collection with some default items. If I remove the items and stream >>> the TSynEdit, the following line is shown in the lfm: >>> Keystrokes = >>> >>> If I read this lfm, I don't get a empty KeyStrokes collection, but >>> one filled with the default value. >>> >>> I suspect the following lines in TReader.ReadCollection cause this >>> behaviour: >>> if not EndOfList then >>> Collection.Clear; >>> >>> Is this a bug or by design? How do I load an empty collection from a >>> stream, if the collection has a default value? > > You can't. > >> Delphi has the same construction, which is IMO a design flaw. >> IMO when a collection is "default" is shouldn't be streamed, so there >> would be nothing written. > > There is no way to know whether the collection is default or not, > since that would imply keeping a copy of the collection as it was just > after creation. > >> I don't know why it is there, since when a "default" collection is >> written, all elements are written. So it never will be . >> >>> Note, if I remove the 'Keystrokes = ' line from the lfm, I will >>> get the default collection too, so I wonder why there are two ways >>> to get the default collection. >> >> I propose to remove the "if not EndOfList then Collection.Clear;" line. > > You may not, I always can propose ;-) > because then inherited form streaming will be broken: a collection of > "" means: don't touch, keep the collection of > the parent form. There you have a point. Didn't think of that. And indeed, a collection itself doesn't know if it is default or not. The owning class usually knows this. To solve this problem, I think the owning class needs to know when it is loading or not, so that it can add the defaults when it is not loaded, but created. I think the cleanest way is to introduce a Loading virtual method as counterpart of the Loaded method. This way the owning class can decide that when loading, the collection should be cleared. AFAIK, there is no other way a component knows on creation if it gets loaded in the future or not.

Just thought of another option:

in the owning class, in defineProperties, define a property 'CollectionIsEmpty' and write it only when the collection is empty. THen wen read from stream, clear the collection.

Marc

Reply by email

Micha Nelissen
to Michael Van Canneyt: You can't. There is no way to know whether the collection is default or not, since that…
Michael Van Canneyt wrote 9 lines
>> Note, if I remove the 'Keystrokes = ' line from the lfm, I will get >> the default collection too, so I wonder why there are two ways to get >> the default collection. > > I propose to remove the "if not EndOfList then Collection.Clear;" line. You may not, because then inherited form streaming will be broken: a collection of "" means: don't touch, keep the collection of the parent form.

I don't understand: why does it mean that ?

Micha

Reply by email