From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Path: eternal-september.org!reader02.eternal-september.org!aioe.org!5WHqCw2XxjHb2npjM9GYbw.user.gioia.aioe.org.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: How to check class type ? Date: Wed, 21 Apr 2021 19:40:25 +0200 Organization: Aioe.org NNTP Server Message-ID: References: <60805c0e$0$12690$426a74cc@news.free.fr> NNTP-Posting-Host: 5WHqCw2XxjHb2npjM9GYbw.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.9.1 X-Notice: Filtered by postfilter v. 0.9.2 Content-Language: en-US Xref: reader02.eternal-september.org comp.lang.ada:61890 List-Id: On 2021-04-21 19:08, DrPi wrote: > Hi, > > I have the following declarations (just for the example) : > > type Root is tagged null record; > type Root_Ptr is access all Root'Class; > > type Leaf1 is new Root with null record; > type Leaf1_Ptr is access all Leaf1'Class; > > type Leaf2 is new Root with null record; > type Leaf2_Ptr is access all Leaf2'Class; > > > To check if a variable is of type Leaf1_Ptr or Leaf2_Ptr, I do : That does not make sense, Leaf1_Ptr is not tagged. > if var'Tag = Leaf1'Tag then >   ... > elsif var'Tag = Leaf2'Tag then >   ... > end if; if Var in Leaf1'Class then ... -- Class rooted in Leaf1 elsif Var in Leaf2'Class then ... -- Class rooted in Leaf2 > It works. But is this correct ? Should the test be done differently to > suit Ada coding style ? It depends on the intent. Usually you should never check for the class except two cases: 1. Defensive programming of a downcast: if X in T'Class then declare Y : T'Class renames T'Class (X); begin ... end; Downcasts are by themselves problematic, to be avoided when possible. 2. Emulation of multiple dispatch. In most cases you leave all tag checks to dispatch. This may lead to so-called God-classes when primitive operations migrate to the root. E.g. if you had a primitive Foo on Leaf1, but not in Leaf2 and the purpose of check would be if you could call to Foo, you might move Foo as abstract to Root and override it as raising exception in Leaf2. Then instead of checking for the tag, you would simply dispatch: Var.Foo; -- Will raise if not Leaf1 This would be a God-class case. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de