Is there a way to create an equivalent to C# get/set in Ada ?
I have a type like this (in Ada) :
-- Ada :
type MyType is record
Value : Integer;
end record;
I want to split the value like this
-- Ada :
type MyType is record
ten : Integer;
unit : Integer;
end record;
But I want to keep MyType.Value
(referenced in many readonly files). I want to create an accessor but I did not find how to do in Ada. I know how to do in C# :
// C# :
int Value
{
get
{
return this.ten * 10 + this.unit;
}
set
{
this.unit = value % 10;
this.ten = value / 10;
}
}
What I want to do :
-- ada :
MyType var := MyType'(Value => 15); -- unmodified code
var.Value := 65; -- can be modified like before
Integer ten := var.ten; -- new getter
This is a job for a private type.
package Hidden is
type T is tagged private;
function New_T (Value : Integer) return T;
function Value (Tee : T) return Integer;
function Ten (Tee : T) return Integer;
function Unit (Tee : T) return Integer;
private -- Hidden
type T is tagged record
Ten : Integer;
Unit : Integer;
end record;
...
end Hidden;
Now you can write things like
V : T := New_T (42);
...
Put_Line (Item => V.Value'Image & V.Ten'Image & V.Unit'Image);
V := New_T (23);
As I said in the comment of my answer to your previous question, There's no language construct that does it for you. Depending on your use-case, you could possibly employ controlled types:
type MyTypeView (Data : not null access MyType) is limited
new Ada.Finalization.Limited_Controlled with record
Value: Integer;
end record;
overriding procedure Initialize (Object : in out MyTypeView) is
begin
Object.Value := Object.Data.ten * 10 + Object.Data.unit;
end Initialize;
overriding procedure Finalize (Object : in out MyTypeView) is
begin
Object.Data.ten := Object.Value / 10;
Object.Data.unit := Object.Value mod 10;
end Finalize;
This would allow you to alter the Value in the way you want with the View:
declare
-- assuming MyObj is an object of type MyType
View : MyTypeView (MyObj'Access);
-- Initialize will be called, setting View.Value
begin
-- can access value as "property"
Do_Something (View.Value);
-- can assign value as "property"
View.Value := 123;
-- when View goes out of scope, Finalize will be called, updating MyObj
end;
Note however that as long as View lives, View.Value is detached from the original object, meaning that at the end;
, other modifications of MyObj that happened after View has been created will be discarded. In a single-threaded program, this means that you may not call any subroutines that may instantiate a View of the same object while the current view lives (and may not directly instantiate a second View of this object inside the block).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With