In addition to strings, like what many have already shown, you can do this with arrays too.
For example:
type My_Array is array (Positive range <>) of Integer;
You can have a function return an arbitrary length record by doing:
function Gen_Array (Length : Positive) return My_Array is
Result : constant My_Array (1 .. Length) :=
[for I in 1 .. Length => I];
begin
return Result;
end Gen_Array;
Or you can simply create a new array of arbitrary size at runtime; for example, I get a number from the user with Input : constant String := Get_Line;
, I can then allocate the array later on using N : My_Array (1 .. Positive'Value (Input));
Here’s a fully working program to give you an idea of what I mean:
pragma Ada_2022;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Characters.Handling; use Ada.Characters.Handling;
procedure Test_Dynamic is
type My_Array is array (Positive range <>) of Integer;
-- Dynamically generate an array of a given type.
function Gen_Array (Length : Positive) return My_Array is
Result : constant My_Array (1 .. Length) :=
[for I in 1 .. Length => I];
begin
return Result;
end Gen_Array;
begin
loop
Put_Line ("Enter a positive number for array or Q to exit.");
declare
-- This string is dynamically generated from user input
-- It is the exact size of the input needed.
Input : constant String := Get_Line;
begin
exit when To_Lower (Input) = "q";
declare
-- Create the dynamic array by passing in the length
M : My_Array := Gen_Array (Positive'Value (Input));
-- This also works
N : My_Array (1 .. Positive'Value (Input));
begin
N := M;
for X of M loop
Put (X'Image);
end loop;
for X of N loop
Put (X'Image);
end loop;
New_Line;
end;
exception
when others =>
-- Conversion failed, let user know.
Put_Line ("Invalid number.");
end;
end loop;
end Test_Dynamic;