===================
Visibility Limits
===================

-------------------------------------
Parents Do Not Know Their Children!
-------------------------------------

* Children grant themselves access to ancestors' private sections

   - May be created well after parent
   - Parent doesn't know if/when child packages will exist

* Parent body can reference children

  - Typical method of parsing out complex processes

  .. code:: Ada

     with Calculator.Helper;
     package body Calculator is
        function Calculate (Operator    : String;
                            Left, Right : Some_T)
                            return Some_T is
        begin
           if Operator = "+" then
              return Helper.Plus (Left, Right);

----------------------------------------------
Correlation to C++ Class Visibility Controls
----------------------------------------------

.. container:: columns

 .. container:: column

   * Ada private section is visible to child units

     .. code:: Ada

        package P is
          A ...
        private
          B ...
        end P;
        package body P is
          C ...
        end P;

 .. container:: column

   * Thus private section is like the protected part in C++

     .. code:: C++

        class C {
        public:
          A ...
        protected:
          B ...
        private:
          C ...
        };

-------------------
Visibility Limits
-------------------

* Visibility to parent's private section is not open-ended

   - Only visible to private sections and bodies of children
   - As if only private section of child package is nested in parent

* Recall users can only reference exported declarations

   - Child public spec only has access to parent public spec

.. code:: Ada

   package Parent is
      ...
   private
      type Parent_T is ...
   end Parent;

   package Parent.Child is
     -- Parent_T is not visible here!
   private
     -- Parent_T is visible here
   end Parent.Child;

   package body Parent.Child is
    -- Parent_T is visible here
   end Parent.Child;

--------------------------------
Children Can Break Abstraction
--------------------------------

* Could **break** a parent's abstraction

  - Alter a parent package state
  - Alters an ADT object state

* Useful for reset, testing: fault injections...

.. code:: Ada

   package Stack is
      ...
   private
      Values : array (1 .. N) of Foo;
      Top : Natural range 0 .. N := 0;
   end Stack;

   package body Stack.Reset is
      procedure Reset is
      begin
        Top := 0;
      end Reset;
   end Stack.Reset;

--------------------------
Using Children for Debug
--------------------------

* Provide **accessors** to parent's private information
* eg internal metrics...

.. code:: Ada

   package P is
      ...
   private
     Internal_Counter : Integer := 0;
   end P;

.. code:: Ada

   package P.Child is
     function Count return Integer;
   end P.Child;

.. code:: Ada

   package body P.Child is
     function Count return Integer is
     begin
       return Internal_Counter;
     end Count;
   end P.Child;

------
Quiz
------

.. container:: latex_environment scriptsize

 .. container:: columns

  .. container:: column

    .. code:: Ada

       package P is
          Object_A : Integer;
       private
          Object_B : Integer;
          procedure Dummy_For_Body;
       end P;

       package body P is
          Object_C : Integer;
          procedure Dummy_For_Body is null;
       end P;

       package P.Child is
          function X return Integer;
       end P.Child;

  .. container:: column

   Which return statement(s) would be legal in ``P.Child.X?``

      A.  :answermono:`return Object_A;`
      B.  :answermono:`return Object_B;`
      C.  ``return Object_C;``
      D.  None of the above

   .. container:: animate

      Explanations

      A. :ada:`Object_A` is in the public part of :ada:`P` - visible to any unit that :ada:`with`'s :ada:`P`
      B. :ada:`Object_B` is in the private section of :ada:`P` - visible in the private section or body of any descendant of :ada:`P`
      C. :ada:`Object_C` is in the body of :ada:`P`, so it is only visible in the body of :ada:`P`
      D. A and B are both valid completions

