2012-04-23 1 views

ответ

0

Фактическая проблема заключается в следующем: «У меня есть много процедур, которые вызывают общую процедуру. В одном специальном случае мне нужно, чтобы общая процедура устанавливала специальное значение в вызывающей процедуре, но я не могу изменить все остальные. "

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

Многие люди скажут вам, что это плохой метод кодирования. Они правы. Но вы не просите совета относительно лучших практик.

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

Один из ваших "нормальных" программ:

/* p1.p */ 

message "p1, I'm normal.". 
run common.p. 

Вашей "специальная" Программа:

/* p2.p */ 

define new global shared variable special as character no-undo. 

message "p2, I'm special!". 
run common.p. 
message "special = " special. 

Общей программа:

/* common.p */ 

define new global shared variable special as character no-undo. 
message "common stuff...". 
if program-name(2) = "p2.p" then special = "special value". 
return. 

Вы можете определить НОВУЮ МИРОВУЮ разделяемый переменную столько раз, сколько вам нравится, и вы получаете только одну ее копию. «Новый» не перезаписывает никаких существующих переменных (если вы не используете GLOBAL, он ведет себя по-другому).

Вы не просили об этом, и, возможно, вам это не нужно, но имя программы (2) проверяет заглядывание в стек вызовов, чтобы узнать, был ли common.p вызван p2.p.

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

+0

есть пять различных экранов (5 различных файлов .p), используя кусок кода (6-й .p-файл) во всех них. Мне нужно изменить конкретный «кусок кода», чтобы он имел эффект только на один экран, который мне нужен, а не другой 4. Так что я думал, что использование флага решит проблему. попросив вас сообщить мне возможные пути для достижения этого. Извините, новичок в этой нишевой технологии. я просто пытаюсь воспользоваться всем, что доступно по этому поводу. Еще раз спасибо за вашу помощь –

+0

Если «часть кода» - это еще одна процедура (именно это вы заявляете в своем вопросе), тогда переменная GLOBAL SHARED позволит вам это сделать. Очевидно, я понятия не имею, как выглядит ваш код - но вы должны легко адаптировать приведенную выше концепцию. –

+0

, если я определяю глобально разделяемую переменную, скажем, «флаг» в файле .p, и я использую его в другом .p файле (который я запускаю в первом .p-файле) без определения, будет ли он работать? –

0

Нравится?

define variable i as integer no-undo. /* a variable in the main procedure */ 

procedure internalProcedure: 

    message "Internal Procedure (a):" i. 
    i = 13. 
    message "Internal Procedure (b):" i. 
end. 

/* main block 
*/ 

i = 1. 
message "Main procedure (a):" i. 

run internalProcedure. 

message "Main procedure (b):" i. 

Более сложный вопрос может быть: «Есть ли в любом случае предотвратить глобально переменные из области видимости используются во внутренней процедуре»?

+0

: Спасибо за ваше внимание. Позвольте мне рассказать всю мою проблему, чтобы вы могли дать мне то, что мне нужно. ** _ Я работаю в процессе 4gl и начинаю программист. Я работаю над ситуацией, когда есть пять процедур (.p файлов), которые не связаны друг с другом, разделяя одну процедуру (файл .p). Моя проблема в том, что мне нужно изменить общую процедуру, которая должна влиять только на одну процедуру вызова, а не на остальные четыре. Каковы способы, которыми я могу связать эти две процедуры одновременно, предотвращая последствия для других четырех процедур ._ ** –

+0

еще одна вещь: мне сказали, что передавали флаг из файла с расширением .p в другой .p-файл невозможно . это так, сэр? Если утверждение ложно, оно решит мою проблему. !! Спасибо. –

+0

Итак, ваша проблема фактически не имеет ничего общего с внутренними процедурами и на самом деле связана с передачей параметров между несколькими файлами .p? –

0

Это вы имеете в виду?

Здесь у нас есть общий .p файл с именем ShowTime.p, который будут запускаться и другие .p-файлы. Вы хотите, чтобы он вел себя определенным образом для одного из файлов .p, а другой - для других. По этой причине мы определяем параметр. В этом примере это ЛОГИЧЕСКИЙ параметр, поэтому значение может быть ДА или НЕТ. Как вы можете видеть, процедура ShowTime отображает TIME, если параметр lShowDate равен NO, и он отобразит DATE, если параметр lShowDate равен YES.

/* ShowTime.p */ 
DEFINE INPUT PARAMETER lShowDate AS LOGICAL. 
IF lShowDate = NO THEN 
    MESSAGE STRING(TIME,"HH:MM:SS"). 
ELSE 
    MESSAGE STRING(TODAY,"9999/99/99"). 

Вот один из ваших пяти несвязанных файлов .p. Он запускает процедуру ShowTime.p, передавая ей параметр NO, поэтому ShowTime покажет TIME.

/* p1.p */ 
MESSAGE "P File 1". 
RUN ShowTime(INPUT NO) NO-ERROR. 

Другой, почему бы и нет?

/* p2.p */ 
MESSAGE "P File 2". 
RUN ShowTime(INPUT NO) NO-ERROR. 

Этот файл .p работает ShowTime с параметром lShowDate как YES, это означает, что процедура ShowTime будет вести себя по-разному для этого, показывая ДАТУ вместо времени.

/* p5.p */ 
MESSAGE "P File 5". 
RUN ShowTime(INPUT YES) NO-ERROR. 

Итак, у вас есть одна процедура, ShowTime, которая может сделать одну из двух вещей. Несвязанная процедура, выполняющая эту процедуру, может сообщить ей, что она хочет, передав ей параметр.

Чтобы выразить это с точки зрения вашего вопроса: существует пять процедур (p1.p, p2.p ... p5.p), которые не связаны друг с другом, разделяя одну процедуру (файл ShowTime.p) , Общая процедура модифицируется параметром, так что она может влиять только на одну вызывающую процедуру (та, которая имеет параметр YES), а не на другие четыре (те, у которых параметр NO).

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

/* DoThing.p */ 
IF SOURCE-PROCEDURE:NAME = "p5.p" THEN 
    MESSAGE "Do one thing". 
ELSE 
    MESSAGE "Do something else". 

Это сделало бы одно дело для одной из пяти процедур и что-то еще для остальных четырех.

+0

Да, это то, что мне было нужно, Роберт. Спасибо за вашу помощь. –

+0

Всякий раз, когда я пытаюсь «ЭТОТ ПРОЦЕДУРА: ФАЙЛ-ИМЯ», чтобы отобразить текущий .p-файл, с которым я работаю, результатом я всегда получаю файл .ped. Я хотел бы знать, что такое файл .ped и способы отображения имени файла, которое является именем файла .p в моей программе. –

+0

Когда вы запускаете свою программу непосредственно из исходного кода, Progress будет скомпилировать ее во временном файле и запустить этот временный файл. ЭТА-ПРОЦЕДУРА: FILE-NAME вернет имя временного файла, а не имя файла исходного кода.Но если вы запустите свою программу как скомпилированный код, вы должны получить правильное имя файла. Если у меня есть программа под названием app.p open в редакторе процедур, я получаю «c: \ temp \ p78104_app.cmp» при запуске. Но если я выполню «RUN» app.p ». из редактора процедур он запускает скомпилированный файл, поэтому ЭТА-ПРОЦЕДУРА: FILE-NAME дает мне «C: \ MyProgs \ app.p». – RobertT