tags:

views:

59

answers:

3

Suppose I have a procedure that I want to only have called by another specific procedure. Is it possible to force restrictions on that procedure so that it can only be referenced by the specified calling procedure? Really what I'm wanting to know, is whether there is another way to write the code so you don't have to nest/embed procedures within procedures, to force a limited scope.

procedure one
   procedure two
   begin
      blah
   end two;
begin
end one;

EDIT: This is for Ada Code btw.

+3  A: 

Well, if you were to put procedure one in a package by itself and put procedure two in its private section, then no other routine would be able to call it (unless written into the package or a child package).

You could also make a tagged type with any data specific to procedure one in it, and put procedure two in its package with an object of that type as a parameter. Then others might call procedure two, but not with procedure one's object.

I'm a little confused as to why you'd want to recreate Ada's scoping behavior without using scoping though. Embrace the language.

T.E.D.
@T.E.D. I guess I just really don't like embedding code a lot, and making additional packages in this case really doesn't work. Putting 3 procedures that are 20 lines each for example, inside a procedure with 50 lines just seems messy...I was hoping for a "cleaner" way to do it, like maybe declare the function inside the elaboration section, and then defining it elsewhere, but it doesn't look like that works
onaclov2000
I've gotten to where I really like it, and am annoyed with other languages that don't allow it. BTW: You haven't lived until you've embedded a **task** inside a subprogram. :-)
T.E.D.
+4  A: 

No (generally speaking).

A public procedure is a public procedure, so it can be invoked by anything that "with's" it (if it's a standalone procedure) or the package in which it is declared.

There are a few ways to constrain its visibility if any of these might fit with your implementation approach:

  • Declare the procedure in the private part of a package, or within the package body. Then only subprograms within that package would have access to it.
  • Declare the supplying package or subprogram as private, then those packages that 'with' it can only reference the supplying unit's contents (including invoking its subprograms) within their private part or package body.
  • "Private with" the supplying package, so that it can only reference the package within its private part/package body.

But like T.E.D. says, work with the language and exploit its capabilities rather than trying to recreate some other language's constructs.

Marc C
+1  A: 

Hi, I have two possible suggestions. The first one is slightly odd and off topic a bit but I wanted to bring it up in case you didn't know since most of the answers have to do with hiding visibility of the code or changing relationships

  1. You could consider using the Ada Tasking features and use the 'Caller Attribute. Normally this is only for tasking and then the "caller" name only denotes the calling task to the receiving task. But once inside the receiving task's entry you can then use the Caller name to quickly end or otherwise flag the caller as wrong or not the caller you expected. This basically puts a "doorman" inside the task entry which could then decide to let them proceed, requeue the caller to a different entry, or do something else. But again this would only really work if you have a task consuming published calls from another task. This is the only thing that I'm aware of in Ada where you can detect who called you and do something about it at runtime.

  2. However your question seemed to want to use scope and so I would agree with what's been said here and only add that in Ada it is a normal have have nested procedures (for readability) but in addition to that you could consider creating child packages and using the hierarchy in reverse. That is expose the chidren to the programmer and make the parent only accessible from the children. Design the parent to be very limited in scope such that the public spec of the parent is totally worthless to any caller that doesn't have the private view of the parent's spec. That way you have your separation and only the chidren can access the functions in the parent and can actually call them because they have a complete view of the parent's types and function definitions.

Good luck with your issue.

Josh