2014-02-19 2 views
3

Я начинаю с RPGLE, и я пытаюсь определить, есть ли способ просто определить параметры для процедур в моей сервисной программе один раз. Я знаю, что могу поместить прототипы внутри члена копии (что я сделал), но тогда мне все равно придется поместить тот же самый код в тело процедуры («интерфейс процедуры»).Разделите определения между прототипом и интерфейсом процедуры

Мой вопрос: есть ли какой-то способ использования прототипа для определения параметров в интерфейсе процедуры (или наоборот)?

В идеале, что-то вроде:

Прототип:

D buildForm  PR 
D formType      10A CONST 
D mode       4A CONST 

Процедура:

P buildForm  B 
D buildForm  PI 
D formType       LIKE(formType) 
D mode        LIKE(mode) 

Ну, идеально я бы просто быть в состоянии сказать «использовать прототип или что-то в теле процедуры, или компилятор найдет это самостоятельно ...


ли я недоразумение как Прототипы и порядок интерфейсы должны быть установлены, или они на самом деле это повторяющиеся, когда все сделано правильно:

Прототип

D buildForm  PR 
D formType      10A CONST 
D mode       4A CONST 

Процедура:

P buildForm  B 
D buildForm  PI 
D formType      10A CONST 
D mode       4A CONST 

Спасибо за чтение.

ответ

4

На 7.1, если вы определяете подпроцедуру в той же программе, которую вы используете, вам не нужен прототип. Вам нужен только прототип, если вы используете подпроцедуру из сервисной программы или связанного модуля (не связывайте модули с программой!)

Я лично не считаю, что прототип обременителен для создания. Я скопировать PI, изменить его PR, поместить его в элемент/копировать и использовать его во многих программах, как это:

/copy buck/qprotosrc,buildform 
    ... 
    buildform(form: mode); 

Единственный раз, когда мне нужно «двойной определить» в сервисной программе, где PI находится. Способ избежать большей части этого - использовать условную компиляцию. Вот пример:

qprotosrc (buildform)

// Build form prototype and start of interface 
    // Service program will complete the interface with P E 
    /if not defined(buildform_proto) 
    /define buildform_proto 
D buildForm  PR 
    /else 
P buildForm  B 
D buildForm  PI 
    /endif 
D formType      10A CONST 
D mode       4A CONST 

qrpglesrc (mysrvpgm)

/copy buck/qprotosrc,buildform 
    ... 
    /copy buck/qprotosrc,buildform 
    // body of buildform here 
    ... 
    return; 
p     e 

Первый раз/копия обрабатывается, он вставляет прототип - это то, что вы хотите для всех ваших потребительских программ. В качестве части обработки он определяет buildform_proto. В вашей сервисной программе вы затем ставите вторую/копию.Поскольку buildform_proto определен, компилятор вставляет спецификации P ... B и D ... PI. Вам нужно будет предоставить тело процедуры и спецификацию P ... E.

+0

Большое спасибо за этот ответ. Правильно ли я полагаю, что наличие нескольких прототипов в копировальной книге потребует вложенных ifs, поэтому вы получите только PI, который вы используете в каждой процедуре? –

+1

Это общая идея. Один ОПРЕДЕЛЕНИЕ для каждой пары PR/PI. –

+0

Хорошее решение. Я думаю, что я адаптирую это для нового синтаксиса свободной формы TR7. B-) – WarrenT

1

Многие магазины решают это, помещая парм в копилку. Затем копия используется сразу же после строки D-spec Prototype (PR) и линии интерфейса процедуры (PI).

+0

Это копия, а затем вставлена ​​в интерфейс процедуры? У меня уже есть прототип в копировальной книге ... –

+1

Мое предпочтение состоит в том, чтобы в вашем собственном экземпляре были пармеры. Вы можете вставить/COPY или/INCLUDE в свой экземпляр прототипа, если хотите. Я хочу, чтобы мои прототипы были всегда совместимы с интерфейсами, особенно если интерфейс изменился. Меня меньше беспокоит, что каждая программа использует одно и то же имя прототипа. – WarrenT

+0

Однако я думаю, что могу принять решение Бака: o) – WarrenT

3

ИМХО, это одна из тех вещей, которая кажется полезной, но не служит реальной цели и на самом деле может привести к другим проблемам.

Это только избавляет вас от необходимости копировать & вставить список парти. Но это на самом деле больше нажатий клавиш. Я большой поклонник «Не повторяй себя», но я не вижу в этом дублирования, но избыточности, которая увеличивает захват ошибок. Компилятор сообщит вам, существует ли несоответствие между PI и PR.

Как я упоминал в своем комментарии к сообщению Bucks, вы можете столкнуться с проблемой с этим. Предполагая, что ваш источник include не просто прототипы, введите другие полезные определения, скорее всего, в какой-то момент вы найдете включенный файл include из нескольких мест. Исправление для того, чтобы просто иметь в верхней части каждого включают

/if defined(MYPROTO_INC) 
/EOF 
/endif 
/define MYPROTO_INC 

Теперь независимо от того, сколько раз он вытащил в компилятор будет видеть только определение раз.

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

Кроме того, рассмотрит шаблонирование вашего Parms ..

d formType_t  S    10a template 
d formMode_t  s    4a template 

D buildForm  PR 
D type        CONST like(formType_t) 
D mode        CONST like(formMode_t) 

P buildForm  B 
D buildForm  PI 
D type        CONST like(formType_t) 
D mode        CONST like(formMode_t) 

Это позволяет вызывающим абонентам легко создать переменный, чтобы использовать для передачи процедуры.

Возможно, у вас могут быть шаблоны в целом другом, например, STDTYPES или APPTYPES.

+0

шаблоны - отличная вещь. Это позволяет более надежное определение и единую точку изменения (любое расширение поля?). – jgriffin

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