Ada使用私有函数的前提条件?

时间:2016-08-18 08:08:47

标签: private encapsulation ada

我是Ada的新手,我真的很困惑在Ada spec文件中私有化。我有一些私人功能需要保持私密,但我想在我的一些非私人程序中将它们用作前/后条件的一部分。当我试着告诉他们时,它说函数是未定义的吗?

我认为将函数设为私有意味着它只能在该包中调用?即.ads和.adb文件?

以下是我的代码。所以我的Lift_Nozzle过程的前/后条件使用私有函数Get_Active_Pump和Get_Pump,但是当我检查语义时它说它们是未定义的(因为它们是私有的?)。有没有解决这个问题?感谢

pump_unit.ads(其中一些):

with Pumps; use Pumps;
with Shared_Types; use Shared_Types;

package Pump_Unit is

   procedure Lift_Nozzle(x: Shared_Types.ID_Value)
     with Pre => Get_Active_Pump = 0 and then
     Get_Pump(x).State = base,
     Post => Get_Pump(x).State = ready and then
     Get_Active_Pump = x;

private

   type Private_Pumps is array (Integer range 1..3) of Pumps.Pump;
   function Get_Pump(x: Shared_Types.ID_Value) return Pumps.Pump;   
   function Get_Active_Pump return Shared_Types.ID_Value;

end Pump_Unit;

pump_unit.abd(其中一些):

with Pumps;
with Shared_Types;

package body Pump_Unit is

   Pump_Array: Private_Pumps;

   --ID of the current pump being used at the pump unit. 0=no pump currently in use.
   Active_Pump: Shared_Types.ID_Value; 

   function Get_Active_Pump return Shared_Types.ID_Value is
   begin -- Get_Active_Pump
      return Active_Pump;
   end Get_Active_Pump;

   function Get_Pump(x: Shared_Types.ID_Value) return Pumps.Pump is
      use type Shared_Types.ID_Value;
   begin -- Get_Pump
      for Index in 1..3 loop
         if Pump_Array(Index).ID = x then
            return Pump_Array(Index);
         end if;
      end loop;
      return Pump_Array(1);
   end Get_Pump;

   procedure Lift_Nozzle(x: Shared_Types.ID_Value) is
      use type Shared_Types.ID_Value;
      pump : Pumps.Pump;
   begin -- Lift_Nozzle
      pump := Get_Pump(x);
      pump.State := Pumps.ready;
      Active_Pump := x;
   end Lift_Nozzle;

begin

   Pump_Array :=
     ((ID => 1, Fuel_Variety => Pumps.Fuel_91, State => Pumps.base, Price => 1.70, Reservoir => 50000, Active => False),
      (ID => 2, Fuel_Variety => Pumps.Fuel_95, State => Pumps.base, Price => 1.90, Reservoir => 100000, Active => False),
      (ID => 3, Fuel_Variety => Pumps.Fuel_Diesel, State => Pumps.base, Price => 1.10, Reservoir => 60000, Active => False));

   Active_Pump:= 0;

end Pump_Unit;

1 个答案:

答案 0 :(得分:7)

一般情况下,您只能调用函数(此规则有一些例外,特别是对于迭代器)。 在您的情况下,似乎您可能想要添加一些公共函数(不公开您的Pump类型)。例如,如何:

function No_Active_Pump return Boolean
   with Inline;
function Is_Active (x : ID_Value) return Boolean
   with Inline;

procedure Lift_Nozzle(x: Shared_Types.ID_Value)
   with Pre => No_Active_Pump and then
           Get_Pump(x).State = base,
        Post => Is_Active (x);

private
    function No_Active_Pump return Boolean
       is (Get_Active_Pump = 0);
    function Is_Active (x : ID_Value) return Boolean
       is (Get_Pump (x).State = ready
           and then Get_Active_Pump = x);

如果他们需要编写自己的pre和post,而不暴露私有类型,那么我们的想法是公开一些可能对你的包用户有用的函数。