MainframeSupports
tip uge 23/2004:

For ISPF programmører (både applikations-, drifts- og systemprogrammører) og diverse software leverandører er LIBDEF funktionen en næsten uundgåelig del af tilværelsen. Desværre volder funktionen mange kvaler. Jeg vil her efter bedste evne prøve at gennemgå de dele af LIBDEF funktionen, som du skal være særligt opmærksom på.

For de uindviede, så kan LIBDEF funktionen allokere ekstra datasets svarende til de forskellige ISPF systemdataset, såsom ISPPLIB, ISPLLIB med flere. De ekstra allokerede datasets kigger ISPF i før de ved opstart af ISPF allokerede datasets. LIBDEF giver altså mulighed for at allokere datasets med paneler, load-moduler med mere, der svarer lige præcis til den applikation, man ønsker at køre. Problemerne med LIBDEF opstår, når man begynder at starte nye funktioner op i samme split screen eller hvis man ikke sørger for at deaktivere LIBDEF. Det hele kompliceres yderligere af, at man i samme split screen kan have flere forskellige application id's. Inden for samme application id vil LIBDEF funktionen overskrive en tidligere LIBDEF af samme type (eksempelvis ISPPLIB).

Nu har jeg ligesom kradset lidt i overfladen af problemerne. Der har længe været hjælp at hente i kraft af LIBDEF funktionen STACK, som jeg sjældent ser anvendt. Herudover findes der faktisk en ISPF kommando kaldet ISPLIBD, som viser de aktuelle LIBDEF definitioner for den split screen og den application id, man befinder sig i. ISPLIBD er en meget simpelt værktøj, men også et ganske rart værktøj, når nu man løber sur i alle de forskellige LIBDEF definitioner.

for at undgå problemer med LIBDEF funktionen skal man efter min mening følge følgende grundregler. For det første skal man huske at deaktivere en tidligere LIBDEF. For det andet skal man altid bruge STACK på sin LIBDEF. For det tredie skal man undgå at benytte LIBRARY eller EXCLLIBR. Her følger et lille REXX eksempel med den ideelle måde at benytte LIBDEF på:

/* REXX: GOODDEF */
ADDRESS ISPEXEC
"LIBDEF ISPPLIB DATASET ID('MY.PANEL.DATASET') STACK"
"DISPLAY PANEL(MYPANEL)"
"LIBDEF ISPPLIB"

Denne GOODDEF REXX vil med sikkerhed vise panelet MYPANEL, hvis det er rigtigt defineret og findes i datasettet MY.PANEL.DATASET. Det vil GOODDEF også gøre, hvis STACK ikke er angivet på den første LIBDEF. Desværre vil en manglende STACK medføre, at en LIBDEF foretaget før GOODDEF bliver kaldt, vil gå tabt og dermed sandsynligvis skabe problemer, når kalderen får kontrollen tilbage. Dette problem forsøgte IBM i første omgang at løse ved at introducere COND. Hvis man i GOODDEF erstatter STACK med COND, så vil man ikke spolere en tidligere LIBDEF i det første LIBDEF kald. Til gengæld vil DISPLAY fejle, hvis MYPANEL kun findes i MY.PANEL.DATASET, da COND kun gennemfører en LIBDEF, hvis der ikke er nogen aktiv LIBDEF i forvejen.

Den afsluttende LIBDEF deaktiverer den seneste foretagne LIBDEF, som i eksemplet er LIBDEF'en af MY.PANEL.DATASET. Hvis der før kaldet af GOODDEF er foretaget en LIBDEF, så bliver den aktiv igen. Hvis COND havde været angivet i stedet for STACK, så var det en LIBDEF foretaget før kaldet af REXX'en, som var blevet deaktiveret, og det er nok ikke nogen god ide.

Lad mig vise endnu et eksempel:

/* REXX: BADDEF */
ADDRESS TSO "ALLOC FI(MYPANELS) DA('MY.PANEL.DATASET') SHR REUSE"
ADDRESS ISPEXEC
"LIBDEF ISPPLIB LIBRARY ID(MYPANELS) STACK"
"DISPLAY PANEL(MYPANEL)"
"LIBDEF ISPPLIB"

I dette eksempel allokerer jeg selv et DD navn, som jeg så lader den første LIBDEF benytte i stedet for at lade LIBDEF lave allokeringen. Der er bare det triste ved BADDEF, at nu står DD navn MYPANELS åbent under DISPLAY af MYPANEL, så hvis man prøver at køre BADDEF fra en anden split screen imens, så vil BADDEF fejle. Det sker ikke med GOODDEF, fordi ISPF selv holder styr på allokeringerne.

Til sidst får du lige et link til LIBDEF i den nyeste version af ISPF.

Forrige danske tip        Last tip in english        Tip oversigten