2
votes

I'm kinda new with Ada and recently got an error that I don't seem to know how to solve.

I have the following code:

data.ads

    with Text_IO; use text_io;
with ada.Integer_Text_IO; use ada.Integer_Text_IO;

package data is

type file is private;

   type file_set is array (Integer range <>) of file;
   procedure file_Print (T : in out file); --Not used

private
type file is record
      start, deadline : integer;
end record;

end data;

Main.adb

with ada.Integer_Text_IO; use ada.Integer_Text_IO;


procedure Main is

   Num_files: integer:=3; 
  
   Files:file_set(1..Num_files);
     
begin
   
Files(1):=(2,10); -- Expected private type "file" defined at data.ads

for i in 1..Num_Files loop
      
      Put(integer'Image(i));
      New_Line;
      data.File_Print(Files(i));

But I'm getting this error Expected private type "file" defined at data.ads How can I access the file type and declare a new array of values in main?

1
Note that "access" has a special meaning in Ada, so its use in the title is somewhat misleading. "Manipulate" might be a better choice.Jeffrey R. Carter

1 Answers

5
votes

That's right - you don't get to see or manipulate what's inside a private type. That would be breaking encapsulation. Bugs and security risks follow.

You can only interact with a private type via its methods : functions and procedures declared in the package where it's declared.

Now file_set is NOT a private type (you might consider making it private later, for better encapsulation, but for now ....) you can index it to access a file within it (using one of those procedures).

Files(1):=(2,10);

As you want to create a file here, you need a method to create a file ... a bit similar to a constructor in C++, but really more like the Object Factory design pattern. Add this to the package:

   function new_file(start, deadline : integer) return file;

And implement it in the package body:

package body data is

    function new_file(start, deadline : integer) return file is
    begin
       -- check these values are valid so we can guarantee a proper file
       -- I have NO idea what start, deadline mean, so write your own checks!
       -- also there are better ways, using preconditions in Ada-2012
       -- without writing explicit checks, but this illustrates the idea
       if deadline < NOW or start < 0 then 
          raise Program_Error;
       end if;
       return (start => start, deadline => deadline);
    end new_file;

    procedure file_Print (T : in out file) is ...

end package body;

and that gives the users of your package permission to write

Files(1):= new_file(2,10);
Files(2):= new_file(start => 3, deadline => 15);

but if they attempt to create garbage to exploit your system

Files(3):= new_file(-99,-10);     -- Oh no you don't!

this is the ONLY way to create a file, so they can't bypass your checks.