Пытаюсь сделать функцию универсальной, но зацикливаюсь - PullRequest
1 голос
/ 11 января 2011

Вот моя проблема. У меня есть переменная в пакете (в данном случае rec), которую нужно установить при вызове из пакета 3, но она приватная. Ранее функция "set_true" только устанавливала rec в true, так что это не имело большого значения. Но у меня есть другой пакет, который выполняет ту же обработку (я привожу простой пример, но мой буквальный регистр более сложный), поэтому я подумал, что я мог бы передать переменную, которую я хочу изменить, и позволить ей измениться. Является ли единственный способ установить «rec» в приведенном ниже макете, чтобы создать вторую функцию в пакете один, которая вызывает set_true с rec в качестве параметра? Я хотел бы избежать создания дополнительных функций для обработки локальных переменных. Я не могу переместить переменную в public (spec), так как я пытаюсь следовать соглашению, и этот «тип» переменной нигде не является публичным, и я не хочу, чтобы кто-либо мог установить его самостоятельно (Я хочу, чтобы функции должны быть установлены). Я не хочу создавать вторую функцию с именем, например, "set_local_true", и создавать перегруженную функцию set_true без параметров, которая вызывает set_true (value => rec), просто кажется обманчивой, есть ли у кого-нибудь лучшие предложения ограничения у меня есть?

Мои два требования:
1. Не могу сделать локальную переменную общедоступной.
2. Уметь использовать функцию для вычисления чего-либо как внутри, так и снаружи.

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;

РЕДАКТИРОВАТЬ: Или, возможно, что было бы лучше соглашение об именовании для функций, чтобы указать, что они изменяют переменную, которая является локальной для этого пакета? Set_Local_True снова является обманчивой причиной, если вы вызываете его из пакета 3, вы не устанавливаете локальное значение true, вы устанавливаете для локального пакета значение true ....

Ответы [ 2 ]

1 голос
/ 15 марта 2011

Если вам нужен доступ к закрытым переменным, вы можете сделать это в дочернем пакете.

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

, а затем

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

Элементы в «закрытой» частиПакет подобен «защищенным» сущностям в C ++ / Java.Истинно закрытые переменные (только в теле пакета) нигде не доступны.

1 голос
/ 11 января 2011

Во-первых, это очень глупый код.Я предполагаю, что это сокращение для чего-то другого.Но, как представлено, я могу заверить вас, что ваши клиенты могут сами устанавливать свои логические значения без написания для вас процедуры.На самом деле, они могут сделать это лучше.В оставшейся части этого ответа я предполагаю, что вы не пишете переменные для установки логических значений для людей, а скорее делаете что-то реальное.Если нет, проигнорируйте оставшуюся часть этого ответа и просто удалите свои глупые подпрограммы.

Во-вторых, если вы создаете подпрограмму с одним параметром out, то, если объект не окажется очень большим, вы, вероятно, должны сделатьэто функция вместо.Это позволит вашим клиентам использовать функциональное программирование, если они захотят.Как у вас есть, бедный кодер должен остановиться и создать специальную переменную просто для вызова вашей подпрограммы, даже если они хотят сделать это только один раз.

В-третьих, вместо использования уникальной подпрограммы для каждогосостояние я вообще предпочитаю переходить в запрашиваемое состояние.

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

Если государство действительно и по-настоящему логические (не возможно третье состояния в будущем), то спорно.Тем не менее, это может быть большим преимуществом для вашего клиента, если ему, возможно, уже придется сохранять состояние в переменной (или проходить через него).

Ваша правка о присвоении имен показывает, что вы на правильном пути.

Здесь вы должны сделать одну из двух вещей.

  1. Найти концепцию более высокого уровня, управляемую этой переменной, и назвать после этого подпрограмму "setter".
  2. Убирайся с дороги и помести переменную flag в спецификацию pacakge.
...