Note that there are some explanatory texts on larger screens.

plurals
  1. POAda: tagged type---inheritance from parent package
    primarykey
    data
    text
    <p>I am trying to understand tagged types and code extensions and reuse. I first create a program <code>conventional_method_number_of_averages</code> which implements one method for doing some calculation. Then I use extension of the tagged type and create a second program <code>alternative_method_number_of_averages</code> which implements a different method for solving the same problem. The difference is that now I have an additional <code>parameter</code>called <code>overlap_fraction</code>. Here is the simple program with the first method <code>conventional_method_number_of_averages</code> that works fine:</p> <ol> <li><p><strong>number_of_averages.ads</strong></p> <pre><code>with Conventional_Method_Number_Of_Averages; package Number_Of_Averages renames Conventional_Method_Number_Of_Averages; </code></pre></li> <li><p><strong>conventional_method_number_of_averages.ads</strong></p> <pre><code>package Conventional_Method_Number_Of_Averages is type First_Method is tagged private; procedure Count_Averages (Any_Method : in out First_Method; Sampling_Frequency, FFT_Size, Time_Recorded: in Float); function Average_Is (Any_Method : in First_Method) return Float; private type First_Method is tagged record Number_Of_Averages : Float :=0.0; end record; end Conventional_Method_Number_Of_Averages; </code></pre></li> <li><p><strong>conventional_method_number_of_averages.adb</strong></p> <pre><code>package body Conventional_Method_Number_Of_Averages is procedure Count_Averages (Any_Method : in out First_Method; Sampling_Frequency, FFT_Size, Time_Recorded: in Float) is begin Any_Method.Number_Of_Averages := (((Sampling_Frequency * Time_Recorded) - FFT_Size)*(2.0/FFT_Size)) + 1.0; end Count_Averages; function Average_Is (Any_Method : in First_Method) return Float is begin return Any_Method.Number_Of_Averages; end; end Conventional_Method_Number_Of_Averages; </code></pre></li> <li><p>and the test file <strong>test_number_of_averages.adb</strong></p> <pre><code>with Ada.Float_Text_IO; with Ada.Text_IO; use Ada.Text_IO; with Number_Of_Averages; with Conventional_Method_Number_Of_Averages; use type Number_Of_Averages.First_Method; procedure Test_Number_Of_Averages is Fs, Time_Duration, NFFT : Float := 0.0; Averages : Float := 0.0; Good_Method : Conventional_Method_Number_Of_Averages.First_Method; begin Ada.Text_IO.Put("Enter the sampling frequency "); Ada.Float_Text_IO.Get (Item =&gt; Fs); Ada.Text_IO.New_Line (1); Ada.Text_IO.Put("Enter the time recorded "); Ada.Float_Text_IO.Get (Item =&gt; Time_Duration); Ada.Text_IO.New_Line (1); Ada.Text_IO.Put("Enter the FFT size "); Ada.Float_Text_IO.Get (Item =&gt; NFFT); Ada.Text_IO.Put_Line (Ada.Text_IO.Get_Line); Ada.Text_IO.New_Line(1); Ada.Text_IO.Put("Number of averages = "); Number_Of_Averages.Count_Averages(Good_Method, Fs, NFFT, Time_Duration); Averages := Conventional_Method_Number_Of_Averages.Average_Is(Good_Method); Ada.Float_Text_IO.Put (Item =&gt; Averages, Fore =&gt; 3, Aft =&gt; 5, Exp =&gt; 0); end Test_Number_Of_Averages; </code></pre></li> </ol> <p>The above works fine as it is.</p> <p>Now if I create an alternative method for the same calculation, I have:</p> <ol> <li><p>its specification <strong>alternative_method_number_of_averages.ads</strong></p> <pre><code>with Conventional_Method_Number_Of_Averages; use Conventional_Method_Number_Of_Averages; package Alternative_Method_Number_Of_Averages is type Second_Method is new First_Method with private; --override this function procedure Count_Averages (Any_Method : in out Second_Method; Sampling_Frequency, FFT_Size, Time_Recorded, Overlap_Fraction: in Float); private type Second_Method is new First_Method with record Overlap_Fraction : Float :=0.5; end record; end Alternative_Method_Number_Of_Averages; </code></pre></li> </ol> <p>and </p> <ol> <li><p>its body <strong>alternative_method_number_of_averages.adb</strong></p> <pre><code>package body Alternative_Method_Number_Of_Averages is --override this function procedure Count_Averages (Any_Method : in out Second_Method; Sampling_Frequency, FFT_Size, Time_Recorded, Overlap_Fraction: in Float) is begin Any_Method.Number_Of_Averages := ((Sampling_Frequency * Time_Recorded) - FFT_Size) / (FFT_Size - Overlap_Fraction * FFT_Size) + 1.0; end Count_Averages; end Alternative_Method_Number_Of_Averages; </code></pre></li> </ol> <p>Then on compiling the specification file, I get the error message:</p> <p>alternative_method_number_of_averages.ads: no selector "number_of_averages" for type "Second_Method" defined at alternative_method_of_averages.ads. The culprit line is:</p> <pre><code> Any_Method.Number_Of_Averages := ((Sampling_Frequency * Time_Recorded) - FFT_Size) / (FFT_Size - Overlap_Fraction * FFT_Size) + 1.0; </code></pre> <p>So how to fix this?</p> <p>In the end I would like to be able to have something like:</p> <pre><code> Number_Of_Averages.Count_Averages(Alternative_Method, Fs, NFFT, Time_Duration, Overlap_fraction); </code></pre> <p>in the test file <strong>test_number_of_averages.adb</strong>, similarly as the working code</p> <pre><code> Number_Of_Averages.Count_Averages(Good_Method, Fs, NFFT, Time_Duration); </code></pre> <p>Thanks a lot...</p> <p><strong>UPDATE</strong></p> <p>So now for the alternative method implementation, I have, renamed <strong>Alternative_Method_Number_Of_Averages.ads/adb</strong> to <strong>Conventional_Method_Number_Of_Averages-Alternative_Method_Number_Of_Averages.ads/adb</strong>. The test file is:</p> <pre><code> with Ada.Float_Text_IO; with Ada.Text_IO; use Ada.Text_IO; with Number_Of_Averages; with Conventional_Method_Number_Of_Averages; use type Number_Of_Averages.First_Method; with Conventional_Method_Number_Of_Averages.Alternative_Method_Number_Of_Averages; procedure Test_Number_Of_Averages is Fs, Time_Duration, NFFT : Float := 0.0; Averages1 : Float := 0.0; Averages2 : Float := 0.0; Good_Method : Conventional_Method_Number_Of_Averages.First_Method; Alternative_Method : Conventional_Method_Number_Of_Averages.Alternative_Method_Number_Of_Averages.Second_Method; begin Ada.Text_IO.Put("Enter the sampling frequency "); Ada.Float_Text_IO.Get (Item =&gt; Fs); Ada.Text_IO.New_Line (1); Ada.Text_IO.Put("Enter the time recorded "); Ada.Float_Text_IO.Get (Item =&gt; Time_Duration); Ada.Text_IO.New_Line (1); Ada.Text_IO.Put("Enter the FFT size "); Ada.Float_Text_IO.Get (Item =&gt; NFFT); Ada.Text_IO.Put_Line (Ada.Text_IO.Get_Line); Ada.Text_IO.New_Line(1); Ada.Text_IO.Put("Number of averages = "); Number_Of_Averages.Count_Averages(Good_Method, Fs, NFFT, Time_Duration); Averages1 := Conventional_Method_Number_Of_Averages.Average_Is(Good_Method); Ada.Float_Text_IO.Put (Item =&gt; Averages1, Fore =&gt; 3, Aft =&gt; 5, Exp =&gt; 0); Ada.Text_IO.New_Line(1); Ada.Text_IO.Put("Number of averages = "); Number_Of_Averages.Alternative_Method_Number_Of_Averages.Count_Averages(Alternative_Method, Fs, NFFT, Time_Duration); Averages2 := Conventional_Method_Number_Of_Averages.Alternative_Method_Number_Of_Averages.Average_Is(Alternative_Method); Ada.Float_Text_IO.Put (Item =&gt; Averages2, Fore =&gt; 3, Aft =&gt; 5, Exp =&gt; 0); end Test_Number_Of_Averages; </code></pre> <p>With Fs = 48000, Time_Duration = 60, NFFT = 8192, both methods are returning 702.125. The second method though is always returning 702.125 irrespective of the <code>Overlap_Fraction</code> parameter. How to specify <code>Overlap_Fraction</code> in the calling function, while still keeping using it private i.e. by having the function use the value of <code>Overlap_Fraction</code> stored in the record.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload