-1

I am working with Delphi 10 Seattle DX Studio. I am devoloping app in which I use ListBox. I want to delete selected items in my ListBox, but I have a problem with this code. When I run this code, I get error "Type of expression must be boolean", despite that my code have correct syntax. Your answers will be appreciated.

procedure TForm1.Button2Click(Sender: TObject);
var
  ii : integer;
begin
    with ListBox1 do
  for ii := -1 + Items.Count downto 0 do
       if Selected[ii] then Items.Delete(ii) ;
end;
end;
Dominikis
  • 52
  • 1
  • 1
  • 9

1 Answers1

3

Your code (which I suspect differs from that in the question) does not have the correct syntax, which is what the compiler is telling you.

The fact that it looks likely that your code differs from the code we see in the question, and that we cannot tell whether you use VCL or FMX, makes this question somewhat dubious. On another day, I would probably vote to close as off-topic, but today, I'm going to plough on regardless, which is probably imprudent. Here goes.

The code in the question is (nearly) valid VCL code. There is an extra end and I can only assume that is a transcription error. Clearly your actual code doesn't look like this because you would not indent like that.

Your code is not valid FMX code, even after the stray end is removed. The compiler objects to Selected[ii] with:

[dcc32 Error]: E2149 Class does not have a default property

That's a different error from the one you reported. The reason for the error is that Selected is a non-indexed property of type TListBoxItem.

I think that what is really going on is that the code in the question differs from the code that you are attempting to compile. And the code that you are attempting to compile is not valid. As a broad rule, when the compiler tells you that your code is invalid, you should believe it, even if you cannot immediately understand it.

Your life will become much easier when you stop using with. Every time you use with, a puppy dies. Furthermore, your namespace is widened with often surprising and unpredictable results, as names from the inner namespace hide those from the outer namespace.

Whilst it is clear that -1 + Items.Count is the same as Items.Count - 1, you will have to search far and wide to find a programmer that would write the former. You could continue doing so, but you will be swimming against the tide. Your code will look different from all other code, and there will be a large impedance for any other readers of your code. I suggest that you go with the flow on this one.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    Those poor, poor puppies :-/ – Jerry Dodge Apr 05 '16 at 18:05
  • *No puppies were harmed in the writing of this code*. :) This is an example where *everything* within the *with* is a direct reference to the inner scope or a simple loop variable. Problems with `with` [sic] arise when referencing both inner *and* wider scopes. Or with the debugger. Bottom line: The use of `with` was entirely irrelevant to the problem in the question. Raising it is pure dogma. Which isn't to say that `with` isn't potentially damaging. There is precious little that is. ;) – Deltics Apr 05 '16 at 20:36
  • Incidentally, I always use `Pred()`, not `'-1`. ime it is much easier to miss a missing *tail-end* `-1` when reading code (a left-to-right activity). A similar reason may inspire this `-1 + ` approach. It places the 0-base adjustment up-front, more prominently, making it (perhaps) more likely to be registered when it's *not* there. I agree that this is unusual tho, But that's not necessarily a bad thing. After all, "Going with the flow" is the fundamental principle that leads to **Cargo Cultism**. – Deltics Apr 05 '16 at 20:43
  • @Deltics `ii` is not in the scope introduced by the `with`. I don't think this is dogma because I have never seen code that is better written using `with`. The only time it is useful is while refactoring a method into another location where a `with Self` can be useful to keep the code working as before while you refactor it. Long term I've never seen code that benefits from `with`. – David Heffernan Apr 05 '16 at 20:44
  • @Deltics Going with the flow doesn't have to lead to cargo cult programming. It's possible for intelligent programmers to both go with the flow, and understand why they are doing so, and be able to judge when it's time to do something different. – David Heffernan Apr 05 '16 at 20:46
  • @David - Ignoring merits of a specific case is dogmatism, by definition. The `ii` is clearly not confused with or by any more complex scope (other object properties etc). `with` avoids the noise of Listbox1 being repeated unnecessarily, reduces the possibility of typo reference errors in repeated refs (eg. ListBox11 vs ListBox1) and makes the intention easier to read. i.e. the case for any number of "better" syntax elements. All of which can be used badly, but not all uses of which are bad. This is *not* a bad use of `with` and has zero bearing on or relevance to the OP's problem. – Deltics Apr 05 '16 at 20:55
  • @Daivd - between `with` and poor object naming standards (Listbox1), the latter poses the far greater risk to code quality and comprehension ime. – Deltics Apr 05 '16 at 20:57
  • @Deltics so the only time you mention to someone that `with` is bad, is when you see a specific egregious misuse? I think that we should be able to see past specifics and offer generic advice. Hence my link. – David Heffernan Apr 05 '16 at 21:01
  • I *never* mention to anyone that "*with is bad*" because *it* isn't. The "with is bad" premise is simply wrong. However, `with` can be *used* badly, and I **would** call out bad *uses*. Similarly, variable names. A named variable is not intrinsically bad (duh!) but variables can be *badly named*. **Listbox1** is an atrocious name, going *entirely unmentioned*. Instead the OP is belittled for (in this case) an entirely reasonable and arguably beneficial use of `with`. If code quality is the issue, why not provide a link to an article on the pitfalls of bad variable names ? – Deltics Apr 05 '16 at 22:12
  • @Deltics I disagree. ListBox1 is fine for a toy program for a question here. It is terrible in a real program. And `with` is bad in my view. You carry on using `with` if you wish, but I won't. – David Heffernan Apr 06 '16 at 06:07
  • @David - Then we agree to disagree. Not that I use `with` either frequently or often. I rationally use it when useful rather than avoiding it *religiously*. By which I mean "*without thinking*" (with thanks to some modern philosopher who's name currently escapes me... Milton Jones maybe ?). :) – Deltics Apr 06 '16 at 22:03
  • @Deltics I've never come across a scenario where `with` was better than the alternative. When I do, I'll use it. But I don't believe I'll ever do so. I suspect that we just judge things differently. The scenarios where you feel `with` is appropriate I would not feel so. Religion doesn't come in to it. Nor does rationality. But thanks for the insults all the same. – David Heffernan Apr 06 '16 at 22:13
  • @David - "better" isn't necessarily the deciding factor. Where two things are equally *valid* then *personal preference* is a perfectly reasonable criteria. "`with` is always bad and not to be used, ever.*" allows no room for this or for merit in any specific case. i.e. No need to think, just apply the rule. There is no insult in pointing out (in what was intended to be a *humorous* fashion) that this removes the need for engaging the brain in any specific case. In fact actively *prohibits* it. Certainly no more insulting than suggesting someone engages in "terrible" practices. :shrug: – Deltics Apr 07 '16 at 00:01
  • @Deltics Equally valid? I've never seen a case where, long term, `with` is not clearly worse than another way not using `with`. Your arguments over the safety of the code here are based on an assumption that the code is never to be changed. I personally am never in a position to make that assumption. Even if you can be confident of safety, where's the benefit? Why force yourself to evaluate that when you don't need to? – David Heffernan Apr 07 '16 at 06:06
  • @Deltics I actually used a `with` yesterday, transiently. It's gone now. I had `TFoo.Method()`. I was refactoring it to reside in a different class. `TBar.Method(Target: TFoo)`. So I wrapped the body in `with Target`, and changed references to `Self` to `Target`. Then I refactored until I was ready to remove the `with`. – David Heffernan Apr 07 '16 at 06:12
  • ...cont You are right that it's important to understand how things work and why we have rules. That allows you to break them when it is appropriate to do so. But we do need the rules otherwise every decision requires thought from first principle. How shall I indent this line of code? You have rules to avoid asking that and so be able to see the bigger picture. – David Heffernan Apr 07 '16 at 06:12