开发者

Trying to make a function generic, but getting hung up

开发者 https://www.devze.com 2023-02-03 10:43 出处:网络
I have a variable in a package (rec in this case) that needs to be set when called from package 3, but it\'s private. Previously the function set_true only set rec to true, so it wasn\'t a big deal. B

I have a variable in a package (rec in this case) that needs to be set when called from package 3, but it's private. Previously the function set_true only set rec to true, so it wasn't a big deal. But I have another package that does the same processing (I'm giving a simple example, but my literal case is more complex), so I thought, well I could pass in the variable I want modified, and let it get changed. Is the only way to set rec in the below layout, to create a second function in package one, that calls set_true with rec as the parameter? I would like to avoid having to keep creating additional functions to handle the local variables. I can't move the variable to public (spec) as I am trying to follow convention and this "type" of variable isn't public anywhere else, and I don't want anyone to be able to just set it on their own (I want functions to have to set). I don't want to have to create a second function named for example set_local_true, and creating an overloaded function set_true, with no parameters, that calls set_true(value => rec) just seems deceptive, does anyone have any better suggestions with the limitations I have?

My two requirements:

  1. Can't make the local variable public.
  2. Be able to use the function to calculate something both externally and internally.
package one is
   procedure set_true(value : out Boolean);
end one;

package body one is
   rec : Boolean;
begin
   procedure set_true(value : out Boolean)
   begin
      value := true;
   end set_true;
end one;

package body two is
   local_rec : Boolean;
begin
   procedure call_function is
   begin
      one.set_true(value => local_rec);
   end call_function;
end two;

package body three is
begin
   procedure call_function is
   begin
      one.set_true(value => <PACKAGE ONE'S REC))
   end call_function;
end three;

EDIT: Or perhaps, what would be a better naming convention for the functions to specify that they are modifying the variable that is loc开发者_StackOverflowal to that package? Set_Local_True again is deceptive cause if you call it from package 3, you're not setting your local true, you're setting package one's local to true....


First off, this is very silly code. I'll assume it is shorthand for something else. But as presented, I can assure you that your clients can set their own booleans themselves without you writing a routine to do it for them. In fact, they can do it better. For the remainder of this answer, I'll assume you aren't acutally writing variables to set booleans for people, but rather doing something of actual use. If not, ignore the rest of this answer and just delete your silly routines.

Secondly, if you are creating a routine with a single out parameter, then unless the object happens to be very large, you should probably make it a function instead. That will allow your clients to use functional programming if they chose. The way you have it, the poor coder has to stop and create a special variable just to call your routine, even if they only want to do it once.

Thirdly, rather than using a unique set routine for each state, I generally prefer to pass in the requested state.

function Set_Frobnost (New_State : boolean := true) return boolean;

If the state is really and truly boolean (no possible third state in the future), then it is debateable. However, it can be a big advantage to your client if they might already have to store the state in a variable (or loop through it).

Your edit about naming shows me you are on the right track.

You should do one of two things here.

  1. Find the higher-level concept controlled by that variable, and name the "setter" routine after that.
  2. Get the hell out of the way and put the flag variable in the pacakge spec.


If you have to access private variables, you might to do it in a child package.

package One is
   procedure Foo (X : Boolean);
private
   One_Private : Boolean;
end One;

and then

package body One.Two is
    procedure Bar is
       One.Foo (One.One_Private);
    end Bar;
end One.Two;

Elements in the "private" part of a package are like "protected" entities in C++/Java. Truly private variables (only in package body) are not accessible from anywhere else.

0

精彩评论

暂无评论...
验证码 换一张
取 消