2011-01-11 3 views
1

Вот моя проблема. У меня есть переменная в пакете (rec в этом случае), которая должна быть установлена ​​при вызове из пакета 3, но она является частной. Раньше функция set_true только возвращала значение true, так что это было неважно. Но у меня есть другой пакет, который выполняет ту же обработку (я даю простой пример, но мой литеральный случай более сложный), поэтому я подумал, что я могу передать переменную, которую я хочу изменить, и пусть она будет изменена. Единственный способ установить «rec» в приведенном ниже макете, создать вторую функцию в пакете 1, которая вызывает 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; 

EDIT: Или, может быть, что было бы лучше именования для функций, чтобы указать, что они изменяют переменную, которая является локальной для этого пакета? Set_Local_True снова является обманчивой причиной, если вы вызываете его из пакета 3, вы не устанавливаете свой местный true, вы устанавливаете локальный пакет в true.

ответ

1

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

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

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

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

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

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

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

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

Я пытался дать простой пример, я не могу опубликовать литеральный код, но я отправлял аналогичную версию, я фактически передаю около 8 переменных в одном случае (знаю, что знаю, 8 переменных .. ..), но это необходимо для ситуации. По сути дела происходит случай, и две из переменных получают определенное значение, а другие не затрагиваются. Мне нравятся ваши предложения! – onaclov2000

+0

Ну, если большинство этих параметров имеют логические значения по умолчанию, поместите их в конец списка параметров со значениями по умолчанию. Если нет, то из них сделайте свой собственный класс (пакет с абстрактным типом данных). Многие параметры указывают на то, что ложная настройка вызова вашей подпрограммы - это сама работа. Программное обеспечение должно выполнять наши обязанности для нас. :-) –

+0

@ T.E.D К сожалению, когда я попытался скомпилировать «выходные» параметры, нельзя по умолчанию не использовать, и все они не соответствуют параметрам. Не могли бы вы привести краткий пример того, что вы подразумеваете под пакетом с абстрактным типом данных? Я имею в виду, что я думал о том, чтобы положить их в массив и просто передать массив, есть ли разница в этой идее и твоей? Кроме того, «по умолчанию» обычно обрабатываются в вызывающем пакете и до того, как они были переданы в процедуру, уже установлены по умолчанию. – onaclov2000

1

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

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. Поистине частные переменные (только в корпусе пакета) недоступны нигде.

Смежные вопросы