I do the following
Address TSO "ALLOC DD(PDSM1) DA('"PDSMSYM"') MOD "
Some code to queue data then
"EXECIO " QUEUED() " DISKW PDSM1A(FINIS "
Each time the MOD acts like OLD. Am I missing something??
Psuedo Process
Do Loop to build control cards to QUEUE
Allocate output file with MOD
EXECIO write out the queued stuff.
This is all done in one self contained section of code. I am not going in
and out of this code. I am not using PUSH or NEWSTACK/DELSTACK.
Thoughts? Suggestions?
Lizette
----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX
Or, if the data are small, you can EXECIO one line at a time.
The stack entails the same hazards as USERKEYCSA, in my
perception. You never know what other code will manipulate
it, not even your own.
</SERMON>
-- gil
/* REXX - MODTEST */
modtest.1 = time(l)
modtest.2 = time(l)
modtest.3 = time(l)
modtest.4 = time(l)
modtest.5 = time(l)
modtest.6 = time(l)
modtest.7 = time(l)
modtest.8 = time(l)
modtest.9 = time(l)
"ALLOC F(MODTEST) DA('OPSROZ.MODTEST') MOD"
"EXECIO * DISKW MODTEST (STEM MODTEST. FINIS"
"EXECIO * DISKR MODTEST (STEM MODTEST. FINIS"
do i=1 to modtest.0
say strip(modtest.i)
end
"FREE F(MODTEST)"
Rob
In a message dated 12/9/2010 5:41:22 P.M. US Mountain Standard Time,
Robz...@aol.com writes:
Look at the code again (line 4)... The DISKR was simply a confirmation
run AFTER the DISKW to make sure the process was actually MODing onto the end
of the file...
> 000001 /* REXX - MODTEST */
> 000002 queue time()
> 000003 "ALLOC F(MODTEST) DA('my.seqdsn') MOD"
> 000004 "EXECIO" queued() "DISKW MODTEST (FINIS"
> 000005 "EXECIO * DISKR MODTEST (STEM MODTEST. FINIS"
> 000006 do i=1 to modtest.0
> 000007 say strip(modtest.i)
> 000008 end
Like Gil, I also prefer STEM's, but tried exactly what you were doing.
Rob
In a message dated 12/9/2010 5:37:22 P.M. US Mountain Standard Time,
star...@MINDSPRING.COM writes:
Rob,
The PDSM is probably misleading. It stand for PDSMAN. The file being used
is a SEQ file and not a PDS.
Your example is using DISKR and I am trying to use DISKW.
So I do the following
ADDRESS TSO "ALLOC DD(OUTSEQ) DA('"PDSMSEQ"') MOD"
Do I = 1 to Stem.0
Queue stem.i
End
" EXECIO " QUEUED() " OUTSEQ (FINIS "
On the first run of this process, it is good. But subsequent runs the MOD
acts like OLD and just replaces the contents rather than adding on to the
end of the file.
I am going to work with pure stems next and see if that behaves better like
Gil offered.
Lizette
> -----Original Message-----
> From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On
> Behalf Of Robert Zenuk
> Sent: Thursday, December 09, 2010 7:28 PM
> To: TSO-...@VM.MARIST.EDU
> Subject: Re: [TSO-REXX] How to MOD a dataset with EXECIO
>
> From your naming convention it looks like you are trying to use a
> PDS(member)... As far as I know, MOD only works with sequential
> files... The
> following works fine with a sequential file...
>
> 000001 /* REXX - MODTEST */
> 000002 queue time()
> 000003 "ALLOC F(MODTEST) DA('my.seqdsn') MOD"
> 000004 "EXECIO" queued() "DISKW MODTEST (FINIS"
> 000005 "EXECIO * DISKR MODTEST (STEM MODTEST. FINIS"
> 000006 do i=1 to modtest.0
> 000007 say strip(modtest.i)
> 000008 end
>
> Executing it multiple times works as expected.
>
> When I tried it with a PDS member, it worked the first time then I got
> a
> B14-04 for all successive attempts. I guess MOD for a PDS member
> attempts
> to STOW the member name at CLOSE time and finds a duplicate name.
>
> Rob
>
>
>
>
> In a message dated 12/9/2010 4:33:49 P.M. US Mountain Standard Time,
> star...@MINDSPRING.COM writes:
>
> Okay, I have been trying to get this one little snippet of code
> working and
> for some reason, it escapes me. If I execute this once per day I am
> good.
> But if done multiple times in a day, the dataset only has the entries
> from
> the last run.
>
>
>
> I do the following
>
>
>
> Address TSO "ALLOC DD(PDSM1) DA('"PDSMSYM"') MOD "
>
>
>
>
> Some code to queue data then
>
>
>
> "EXECIO " QUEUED() " DISKW PDSM1A(FINIS "
>
>
>
> Each time the MOD acts like OLD. Am I missing something??
>
>
>
> Psuedo Process
>
>
>
> Do Loop to build control cards to QUEUE
>
>
>
> Allocate output file with MOD
>
>
>
> EXECIO write out the queued stuff.
>
>
>
> This is all done in one self contained section of code. I am not
> going in
> and out of this code. I am not using PUSH or NEWSTACK/DELSTACK.
>
>
>
> Thoughts? Suggestions?
>
>
>
> Lizette
The initial execution of the REXX is fine. The EXECIO writes out the lines
correctly. However, if I go and execute the rexx later (a min/hr.day) then
it replaces the output dataset rather than mod onto the end.
I am starting to think the EXECIO may have some limitations I am not
familiar with. So I am going with PLAN B. I will create an ISPF SKEL and
then I will get what I want.
Lizette
> -----Original Message-----
> From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On
> Behalf Of Robert Zenuk
> Sent: Thursday, December 09, 2010 7:48 PM
> To: TSO-...@VM.MARIST.EDU
> Subject: Re: [TSO-REXX] How to MOD a dataset with EXECIO
>
> Here is the code modified to use a stem... Line 12 is still DISKW
>
> /* REXX - MODTEST */
> modtest.1 = time(l)
> modtest.2 = time(l)
> modtest.3 = time(l)
> modtest.4 = time(l)
> modtest.5 = time(l)
> modtest.6 = time(l)
> modtest.7 = time(l)
> modtest.8 = time(l)
> modtest.9 = time(l)
> "ALLOC F(MODTEST) DA('OPSROZ.MODTEST') MOD"
> "EXECIO * DISKW MODTEST (STEM MODTEST. FINIS"
> "EXECIO * DISKR MODTEST (STEM MODTEST. FINIS"
> do i=1 to modtest.0
> say strip(modtest.i)
> end
> "FREE F(MODTEST)"
>
>
> Rob
>
>
----------------------------------------------------------------------
> Have you tried:
>
> Â Address TSO "ALLOC DD(PDSM1) DA('"PDSMSYM"') MOD REU Â "
>
> just a shot in the dark.
REUSE has nothing to do with MOD - it applies to the DDNAME - but you
have an interesting point: what if DDNAME PDSM1 was already allocated
to DSNAME PDSMSYM as OLD? Would another ALLOCATE with identical DDNAME
and DSNAME but with MOD do anything at all, or would it consider the
allocation to be satisfied already?
Hmmm... on my system it prompts with "file in use" (i.e. DDNAME in
use), "enter FREE or END". So much for that theory.
Tony H.
On Thu, 2010-12-09 at 19:36 -0500, Lizette Koehler wrote:
> Rob,
> The PDSM is probably misleading. It stand for PDSMAN. The file being used
> is a SEQ file and not a PDS.
>
> Your example is using DISKR and I am trying to use DISKW.
>
> So I do the following
>
> ADDRESS TSO "ALLOC DD(OUTSEQ) DA('"PDSMSEQ"') MOD"
>
> Do I = 1 to Stem.0
> Queue stem.i
> End
> " EXECIO " QUEUED() " OUTSEQ (FINIS "
>
> On the first run of this process, it is good. But subsequent runs the MOD
> acts like OLD and just replaces the contents rather than adding on to the
> end of the file.
>
> I am going to work with pure stems next and see if that behaves better like
> Gil offered.
>
> Lizette
>
>
> > -----Original Message-----
> > From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On
> > Behalf Of Robert Zenuk
> > Sent: Thursday, December 09, 2010 7:28 PM
> > To: TSO-...@VM.MARIST.EDU
> > Subject: Re: [TSO-REXX] How to MOD a dataset with EXECIO
> >
> > Address TSO "ALLOC DD(PDSM1) DA('"PDSMSYM"') MOD "
> >
> >
> >
> >
> > Some code to queue data then
> >
> >
> >
> > "EXECIO " QUEUED() " DISKW PDSM1A(FINIS "
> >
> >
> >
> > Each time the MOD acts like OLD. Am I missing something??
> >
> >
> >
> > Psuedo Process
> >
> >
> >
> > Do Loop to build control cards to QUEUE
> >
> >
> >
> > Allocate output file with MOD
> >
> >
> >
> > EXECIO write out the queued stuff.
> >
> >
> >
> > This is all done in one self contained section of code. I am not
> > going in
> > and out of this code. I am not using PUSH or NEWSTACK/DELSTACK.
> >
> >
> >
> > Thoughts? Suggestions?
> >
> >
> >
> > Lizette
> >
> >
> >
> >
> > ----------------------------------------------------------------------
> > For TSO-REXX subscribe / signoff / archive access instructions,
> > send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX
> >
> >
> > ----------------------------------------------------------------------
> > For TSO-REXX subscribe / signoff / archive access instructions,
> > send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX
>
> ----------------------------------------------------------------------
> For TSO-REXX subscribe / signoff / archive access instructions,
> send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX
--
John McKown
Maranatha! <><
Rob
In a message dated 12/9/2010 7:08:37 P.M. US Mountain Standard Time,
star...@MINDSPRING.COM writes:
Thanks for all the help so far. I have tried various iterations of QUEUE
and STEM and it does not seem to behave the way I want.
The initial execution of the REXX is fine. The EXECIO writes out the
lines
correctly. However, if I go and execute the rexx later (a min/hr.day) then
it replaces the output dataset rather than mod onto the end.
I am starting to think the EXECIO may have some limitations I am not
familiar with. So I am going with PLAN B. I will create an ISPF SKEL and
then I will get what I want.
Lizette
> -----Original Message-----
> From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On
> Behalf Of Robert Zenuk
> Sent: Thursday, December 09, 2010 7:48 PM
> To: TSO-...@VM.MARIST.EDU
> Subject: Re: [TSO-REXX] How to MOD a dataset with EXECIO
>
> Here is the code modified to use a stem... Line 12 is still DISKW
>
> /* REXX - MODTEST */
> modtest.1 = time(l)
> modtest.2 = time(l)
> modtest.3 = time(l)
> modtest.4 = time(l)
> modtest.5 = time(l)
> modtest.6 = time(l)
> modtest.7 = time(l)
> modtest.8 = time(l)
> modtest.9 = time(l)
> "ALLOC F(MODTEST) DA('OPSROZ.MODTEST') MOD"
> "EXECIO * DISKW MODTEST (STEM MODTEST. FINIS"
> "EXECIO * DISKR MODTEST (STEM MODTEST. FINIS"
> do i=1 to modtest.0
> say strip(modtest.i)
> end
> "FREE F(MODTEST)"
>
>
> Rob
>
>
----------------------------------------------------------------------
Ah, well. Just a thought from an airport waiting area.
Too bad.
--
Kind regards,
-Steve Comstock
The Trainer's Friend, Inc.
303-393-8716
http://www.trainersfriend.com
* To get a good Return on your Investment, first make an investment!
+ Training your people is an excellent investment
* Try our new tool for calculating your Return On Investment
for training dollars at
http://www.trainersfriend.com/ROI/roi.html
any suggestions how to avoid the stack and do it smarter? i thought myself
it's more useful than returning endless strings and parse them in the main
program then.
bye,
andi
TSO REXX Discussion List <TSO-...@VM.MARIST.EDU> schrieb am 10.12.2010
01:00:39:
--
Andy Styles
-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf
bye,
andi
Lloyds TSB Bank plc. Registered Office: 25 Gresham Street, London EC2V 7HN. Registered in England and Wales, number 2065. Telephone: 020 7626 1500.
Bank of Scotland plc. Registered Office: The Mound, Edinburgh EH1 1YZ. Registered in Scotland, number 327000. Telephone: 0870 600 5000
Lloyds TSB Scotland plc. Registered Office: Henry Duncan House, 120 George Street, Edinburgh EH2 4LH. Registered in Scotland, number 95237. Telephone: 0131 225 4555.
Cheltenham & Gloucester plc. Registered Office: Barnett Way, Gloucester GL4 3RL. Registered in England and Wales, number 2299428. Telephone: 01452 372372.
Lloyds TSB Bank plc, Lloyds TSB Scotland plc, Bank of Scotland plc and Cheltenham & Gloucester plc are authorised and regulated by the Financial Services Authority.
Halifax is a division of Bank of Scotland plc. Cheltenham & Gloucester Savings is a division of Lloyds TSB Bank plc.
HBOS plc. Registered Office: The Mound, Edinburgh EH1 1YZ. Registered in Scotland, number 218813. Telephone: 0870 600 5000
Lloyds Banking Group plc. Registered Office: The Mound, Edinburgh EH1 1YZ. Registered in Scotland, number 95000. Telephone: 0131 225 4555
This e-mail (including any attachments) is private and confidential and may contain privileged material. If you have received this e-mail in error, please notify the sender and delete it (including any attachments) immediately. You must not copy, distribute, disclose or use any of the information in it or any attachments.
Telephone calls may be monitored or recorded.
______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email
______________________________________________________________________
"ALLOC FI(MQDEF) DA("dsnu") SHR REUSE" /* pds(memname) */
"execio * diskr MQDEF (stem abc. finis" /* read all existing stmts */
j = abc.0
do i = 1 to def.0 /* append all new stmts to end of existing ones */
j = j + 1
abc.j = def.i
abc.0 = j
end
"execio 0 diskw MQDEF (OPEN FINIS" /* empty it! */
"execio * diskw MQDEF (stem abc. finis" /* write all data back */
"FREE FI(MQDEF)"
--
Regards - Grant
=====================================
Note: Any opinion expressed is my own
No trees were killed in the sending of this message, but a large number of
electrons were severely disturbed.
The views I have expressed on this website/service are my own personal
views, and are not endorsed or supported by, and do not necessarily
express or reflect, the views, positions or strategies of my employer.
Lizette Koehler <star...@MINDSPRING.COM>
Sent by: TSO REXX Discussion List <TSO-...@VM.MARIST.EDU>
10/12/2010 02:07
Please respond to
TSO REXX Discussion List <TSO-...@VM.MARIST.EDU>
Lizette
<BR>_____________________________________________________________
<FONT size=2><BR>
DTCC DISCLAIMER: This email and any files transmitted with it are
confidential and intended solely for the use of the individual or
entity to whom they are addressed. If you have received this email
in error, please notify us immediately and delete the email and any
attachments from your system. The recipient should check this email
and any attachments for the presence of viruses. The company
accepts no liability for any damage caused by any virus transmitted
by this email.</FONT>
> Okay, I have been trying to get this one little snippet of code working and
> for some reason, it escapes me. If I execute this once per day I am good.
> But if done multiple times in a day, the dataset only has the entries from
> the last run.
>
My test case:
/* Rexx */ signal on novalue; /*
Doc: Does disp(MOD) really work?
*/
trace Err
RC = SYSCALLS( 'ON' )
C = ' catalog'
do I = 1 to 10
RC = BPXWDYN( 'alloc dd(X) mod'C 'DSN('userid()'.TEMP.MODTEST) reuse msg(WTP)' )
C = ''
L.1 = 'Line:' right( I, 2 ) date() time()
address 'MVS' 'EXECIO 1 DISKW X (finis stem L.'
address 'SYSCALL' 'sleep 1'; end
RC = BPXWDYN( 'free dd(X) msg(WTP)' )
address 'SH' 'set -x; cp "//'''userid()'.TEMP.MODTEST''" /dev/fd/1'
RC = BPXWDYN( 'alloc dd(X) old delete DSN('userid()'.TEMP.MODTEST) reuse msg(WTP)' )
RC = BPXWDYN( 'free dd(X) msg(WTP)' )
return( RC )
... and the output, which does not exhibit the problem:
user@MVS 30$ modtest
/bin/sh 0 + cp //'user.TEMP.MODTEST' /dev/fd/1
Line: 1 10 Dec 2010 08:58:44
Line: 2 10 Dec 2010 08:58:47
Line: 3 10 Dec 2010 08:58:48
Line: 4 10 Dec 2010 08:58:50
Line: 5 10 Dec 2010 08:58:52
Line: 6 10 Dec 2010 08:58:54
Line: 7 10 Dec 2010 08:58:56
Line: 8 10 Dec 2010 08:58:57
Line: 9 10 Dec 2010 08:58:59
Line: 10 10 Dec 2010 08:59:01
-- gil
> just being curious now... i use the stack when calling functions that will
> return an unknown number of elements, example giving, i wrote a function
> that uses the catalog search interface that will queue the matching
> catalog entries in the stack and just return the number of elements in the
> stack. same thing with racf stuff like determing data set profiles or
> connected userids.
>
> any suggestions how to avoid the stack and do it smarter? i thought myself
> it's more useful than returning endless strings and parse them in the main
> program then.
>
Does it not work to use "OUTTRAP STEM." and find the number of
elements in STEM.0?
Where is your FREE command?
Does it still malfunction after a logoff/logon?
From Chicago Soft's * MVS/QuickRef 7.0 *
------------- V=IBM P=TSO/SYSHELP R=V3R11M0 I=ALLOCATE D=M -----
NOTE - DATA SETS ALLOCATED REMAIN ALLOCATED UNTIL LOGOFF OR
FREED BY FREE COMMAND. NO PERMANENT CONNECTION EXISTS
David.Speake
first of all there's no problem at all using the stack - and writing
it to a file is never a problem either - god knows what the people wuo
denigrate it have done
modding a file is no problem either - done it many times; but you must
make sure it actually exists before the exec is run if you're getting
this result - or if you yourself are deleting it in the beginning or
end of the exec - or in another exec.
are you running on-line or in batch? looks like on-line, but in batch
you may have the wrong disp
is the ddname unique? could some other activity allocate the file shr?
> Okay, I have been trying to get this one little snippet of code working
> and for some reason, it escapes me. If I execute this once per day I am
> good. But if done multiple times in a day, the dataset only has the
> entries from the last run.
>
>
>
> I do the following
>
>
>
> Address TSO "ALLOC DD(PDSM1) DA('"PDSMSYM"') MOD "
but you don't appear to check the rc so don't know if it actually gets
allocated...
> Some code to queue data then
>
>
>
> "EXECIO " QUEUED() " DISKW PDSM1A(FINIS "
and what's the rc from this?
And is that trailing "A" on the ddname a typo?
> Each time the MOD acts like OLD. Am I missing something??
Error checking?
--
Jeremy C B Nicoll - my opinions are my own.
First off I do a check to see if the dataset is allocated, i.e for the PDS:
dsnx = Sysdsn("'"jobsdsn"'")
x = Outtrap('al.')
If dsnx = 'OK' Then Do
Say 'CATLOG JOBS dataset' jobsdsn 'already exists'
End
Else Do
'ALLOC FI(JOBS) UNIT(SYSDA) NEW CYLINDERS SPACE(30,30)' ,
'LRECL(80) RECFM(F B) BLKSIZE(6160) DIR(600) DSORG(PO)' ,
'DA('"'"jobsdsn"'"')'
'FREE FI(JOBS)'
End
x = Outtrap('OFF')
And for the sequnetial:
...
'ALLOC FI(REPORT) DA('"'"repdsn"'"')' ,
'NEW CATALOG UNIT(SYSDA) TRACKS' ,
'SPACE(95 95) LRECL(255) RECFM(F B) DSORG(PS)'
'FREE FI(REPORT)'
...
Next up I write out my data. For the PDS I just 'Queue' all the statements:
x = Outtrap('al.')
"ALLOC FI(JOBS) SHR REUSE DA('"jobsdsn"("memname")')"
x = Outtrap('OFF')
...
Queue '//PGM1 EXEC PGM=IDCAMS,COND=(0,NE,STEP1)'
Queue '//SYSPRINT DD SYSOUT=X'
Queue '//SYSIN DD *'
...
x = Outtrap('al.')
'EXECIO * DISKW JOBS (FINIS'
'FREE FI(JOBS)'
'DELSTACK'
x = Outtrap('OFF')
The sequential datasets are slightly different where I use a counter:
...
t = t + 1
text.t = 'Jobs dataset is' jobsdsn
...
'ALLOC FI(REPORT) DA('"'"repdsn"'"') MOD'
'EXECIO' t 'DISKW REPORT (OPEN FINIS STEM TEXT.'
...
x = Outtrap('fre.')
'FREE FI(JOBS)'
'FREE FI(REPORT)'
x = Outtrap('OFF')
Hope that helps in some way...
--
MfG / Best Regards
Sebastian Welton
IBM zSeries Technical Solutions Consultant EMEA
George (x7327)
I guess it saves a couple lines of "IF" logic, but is somewhat obscure...
I would think the following would be easier to read and follow requiring
only 1 more line of code...
if sysdsn("'"DS_Name"'") = 'OK' then
disp = 'MOD'
else
disp = 'NEW'
At first glance, I believe using a non-standard approach like this and
with stems forces support to the most advanced REXX developers to first
interpret what is being done then work on the code. But, I will think about it
some more before I pass judgement. Any other examples out there of using
this technique to help sway my opinion?
My two cents,
Rob
In a message dated 12/14/2010 9:23:47 A.M. US Mountain Standard Time,
That syntax is just assigning a Boolean (logical) value (i.e., 0 or 1) to the leftmost variable on the line. The second "=" is not assignment but comparison, so a meta-description of that code line would be
variable = conditional-expression
Personally, I would code such a line as:
variable = (conditional-expression)
to emphasize the nature of the conditional-expression, but that's just my preference.
I have often used that syntax when "conditional-expression" involves an expensive Rexx operation (like an external function call) and the expression needs to be tested more than once.
For your version, I would keep the line count down by coding it as:
if sysdsn("'"DS_Name"'") = 'OK' then disp = 'MOD'
else disp = 'NEW'
Maybe I qualify as an "expert" (I've never really thought so), but the interpretation of the code as George presented it was obvious to me at first reading. Maybe I've just been coding for too many years to be surprised by "interesting" techniques any more.
Peter
--
This message and any attachments are intended only for the use of the addressee and
may contain information that is privileged and confidential. If the reader of the
message is not the intended recipient or an authorized representative of the
intended recipient, you are hereby notified that any dissemination of this
communication is strictly prohibited. If you have received this communication in
error, please notify us immediately by e-mail and delete the message and any
attachments from your system.
Peter,
You beat me to it by 2 mins. It's a boolean value, but I would have coded
it your way. Easier to read and debug by far, and I would bet more
efficient as well.
Regards,
Tom Conley
DataSetExists = ( SYSDSN("'"DS_Name"'") = "OK" )
Disp = IFF(DataSetExists, "MOD", "NEW")
The arguments to IFF are evaluated before the function is invoked - no
short-circuiting.
Tony
-----Original Message-----
From: Farley, Peter x23353
> if sysdsn("'"DS_Name"'") = 'OK' then
> disp = 'MOD'
> else
> disp = 'NEW'
----------------------------------------------------------------------
----------------------------------------------------------------------
:>You got me on that one, Tony. What exactly is "IFF"?
Probably
IFF: IF ARG(1) THEN RETURN ARG(2) ELSE RETURN ARG(3)
And
Disp = IFF((SYSDSN("'"DS_Name"'") = "OK"), "MOD", "NEW")
is a lot clearer IMHO.
:>-----Original Message-----
--
Binyamin Dissen <bdi...@dissensoftware.com>
http://www.dissensoftware.com
Director, Dissen Software, Bar & Grill - Israel
Should you use the mailblocks package and expect a response from me,
you should preauthorize the dissensoftware.com domain.
I very rarely bother responding to challenge/response systems,
especially those from irresponsible companies.
/* REXX */ IF ARG(1) THEN RETURN ARG(2) ; ELSE RETURN ARG(3)
I like cramming simple external functions onto a single line. =)
-----Original Message-----
From: Mosley, George
You got me on that one, Tony. What exactly is "IFF"?
George
-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf
Of Vitonis, Tony
I use a hand-rolled ternary function for this sort of thing:
DataSetExists = ( SYSDSN("'"DS_Name"'") = "OK" )
Disp = IIF(DataSetExists, "MOD", "NEW") [Edit: Corrected the
function name]
The arguments to IIF are evaluated before the function is invoked - no
You could have the best of both with something like:
Disp = IIF(DataSetExists(DS_Name), "MOD", "SHR")
...
DataSetExists: RETURN ( SYSDSN("'"ARG(1)"'") = "OK" )
As shown, the DataSetExists function is suboptimal. It could be made
more verbose to make its intent more clear; it could be externalized for
use in multiple execs; it could take into account the PREFIX/NOPREFIX
setting in the user's TSO profile; etc.
Anyway, to externalize the check is to hide the details and allow for
reuse, good practices both. If we find later that we want or have to do
the check a different way, we need change it in only one place - of
course, keeping in mind the whole time that premature optimization is
the root of all evil.
Let the religious wars begin.
Tony
If SYSDSN(somedataset) = 'OK' Then
"ALLOC (Fxxx) DA('xxx.zzz.yyy') MOD REU"
Else
"ALLOC (Fxxx) DA('xxx.zzz.yyy') New SomeDsorgIno"
will do for me :)
Mickey
--------------------------------------------------
From: "Vitonis, Tony" <Tony.V...@CA.COM>
Sent: Tuesday, December 14, 2010 1:01 PM
To: <TSO-...@VM.MARIST.EDU>
Subject: Re: [TSO-REXX] How to MOD a dataset with EXECIO
Tony
-----Original Message-----
From: Mickey
Whereas I think a simple
If SYSDSN(somedataset) = 'OK' Then
"ALLOC (Fxxx) DA('xxx.zzz.yyy') MOD REU"
Else
"ALLOC (Fxxx) DA('xxx.zzz.yyy') New SomeDsorgIno"
will do for me :)
--------------------------------------------------
Without a doubt this is personal preference. I don't consider myself an
expert either and I was able to figure it out, but this is not a commonly
used rexx technique. I guess this goes back to the adage of writing good
code versus clever code. When you are writing for personal use, then all bets
are off. I have tons of clever techniques I have tried and decided did
not belong in production code. In production code, the KISS method is most
likely to keep you off 3AM calls when something fails and nobody can
figure out the code. However, I will admit, there are techniques that simply
save too much coding and/or offer extreme performance benefits. The use of
booleans in stems is one of those when dealing with large sparse arrays. As
for the number of lines, I have never been worried about the number of
lines except when performance of those lines becomes an issue. From a coding
style perspective I tend to "stretch" my IF statements across multiple
lines just in case the THEN becomes a THEN DO.. END. I haven't been on a
machine in years where the difference between an IF on 2 lines was more
efficient than an IF on 4 lines. In fact to prove that I just ran a little test...
I also included the boolean alternative. I used the time() function to
keep it an apples to apples comparison.
My opinion is the difference in this is insignificant...
000001 call iftest1 10
000002 call iftest2 10
000003 call boolck0 10
000004 call boolck1 10
000005 call iftest1 100
000006 call iftest2 100
000007 call boolck0 100
000008 call boolck1 100
000009 call iftest1 1000
000010 call iftest2 1000
000011 call boolck0 1000
000012 call boolck1 1000
000013 call iftest1 10000
000014 call iftest2 10000
000015 call boolck0 10000
000016 call boolck1 10000
000017 call iftest1 100000
000018 call iftest2 100000
000019 call boolck0 100000
000020 call boolck1 100000
000021 call iftest1 1000000
000022 call iftest2 1000000
000023 call boolck0 1000000
000024 call boolck1 1000000
000025 exit 0
000026 iftest1: arg count
000027 x = time('r')
000028 do count
000029 if time() > 0 then answer = 'YES'
000030 else answer = 'NO'
000031 end
000032 say '2 line IF' count 'loops:' time('e')
000033 return
000034 iftest2: arg count
000035 x = time('r')
000036 do count
000037 if time() > 0 then
000038 answer = 'YES'
000039 else
000040 answer = 'NO'
000041 end
000042 say '4 line IF' count 'loops:' time('e')
000043 return
000044 boolck0: arg count
000045 x = time('r')
000046 do count
000047 x = time() < 0
000048 answer = x
000049 end
000050 say 'Boolean 0' count 'loops:' time('e')
000051 return
000052 boolck1: arg count
000053 x = time('r')
000054 do count
000055 x = time() > 0
000056 answer = x
000057 end
000058 say 'Boolean 1' count 'loops:' time('e')
000059 return
Results:
2 line IF 10 loops: 0.000039
4 line IF 10 loops: 0.000033
Boolean 0 10 loops: 0.000063
Boolean 1 10 loops: 0.000033
2 line IF 100 loops: 0.000309
4 line IF 100 loops: 0.000549
Boolean 0 100 loops: 0.000594
Boolean 1 100 loops: 0.000428
2 line IF 1000 loops: 0.004488
4 line IF 1000 loops: 0.003112
Boolean 0 1000 loops: 0.003942
Boolean 1 1000 loops: 0.003425
2 line IF 10000 loops: 0.034859
4 line IF 10000 loops: 0.037957
Boolean 0 10000 loops: 0.029135
Boolean 1 10000 loops: 0.050950
2 line IF 100000 loops: 0.356839
4 line IF 100000 loops: 0.377404
Boolean 0 100000 loops: 0.332617
Boolean 1 100000 loops: 0.354190
2 line IF 1000000 loops: 3.343181
4 line IF 1000000 loops: 3.197640
Boolean 0 1000000 loops: 3.325473
Boolean 1 1000000 loops: 3.215539
Here is the actual technique in question...
000001 dsn = my.jcl
000002 call iftest1 10
000003 call iftest2 10
000004 call boolck1 10
000005 call boolck0 10
000006 call iftest1 100
000007 call iftest2 100
000008 call boolck1 100
000009 call boolck0 100
000010 call iftest1 1000
000011 call iftest2 1000
000012 call boolck1 1000
000013 call boolck0 1000
000014 call iftest1 10000
000015 call iftest2 10000
000016 call boolck1 10000
000017 call boolck0 10000
000018 call iftest1 100000
000019 call iftest2 100000
000020 call boolck1 100000
000021 call boolck0 100000
000022 call iftest1 1000000
000023 call iftest2 1000000
000024 call boolck1 1000000
000025 call boolck0 1000000
000026 exit 0
000027 iftest1: arg count
000028 x = time('r')
000029 do count
000030 if sysdsn(dsn) = 'OK' then disp = 'MOD'
000031 else disp = 'NEW'
000032 end
000033 say '2 line IF' count 'loops:' time('e')
000034 return
000035 iftest2: arg count
000036 x = time('r')
000037 do count
000038 if sysdsn(dsn) = 'OK' then
000039 disp = 'MOD'
000040 else
000041 disp = 'NEW'
000042 end
000043 say '4 line IF' count 'loops:' time('e')
000044 return
000045 boolck1: arg count
000046 x = time('r')
000047 do count
000048 disp.0 = 'NEW'
000049 disp.1 = 'MOD'
000050 y = sysdsn(dsn) = 'OK'
000051 disp = disp.y
000052 end
000053 say 'Boolean 1' count 'loops:' time('e')
000054 return
000055 boolck0: arg count
000056 dsn = 'XXX.XXX'
000057 x = time('r')
000058 do count
000059 disp.0 = 'NEW'
000060 disp.1 = 'MOD'
000061 y = sysdsn(dsn) = 'OK'
000062 disp = disp.y
000063 end
000064 say 'Boolean 0' count 'loops:' time('e')
000065 return
I canceled this one after the 10K loops since it was taking so long with
the actual catalog checks...
2 line IF 10 loops: 0.083265
4 line IF 10 loops: 0.070373
Boolean 1 10 loops: 0.068867
Boolean 0 10 loops: 0.067225
2 line IF 100 loops: 0.867322
4 line IF 100 loops: 0.828794
Boolean 1 100 loops: 0.800526
Boolean 0 100 loops: 0.854536
2 line IF 1000 loops: 9.458147
4 line IF 1000 loops: 8.549017
Boolean 1 1000 loops: 9.077987
Boolean 0 1000 loops: 9.576846
2 line IF 10000 loops: 92.039735
4 line IF 10000 loops: 112.807368
Boolean 1 10000 loops: 102.295000
Boolean 0 10000 loops: 97.244225
With the SYSDSN catalog access involved the numbers changed and were
greatly slowed down due to the I/O. The catalogs are using ECS.
I don't think the results of either test prove the technique is more or
less efficient nor is the difference of a 2 line IF versus a 4 line IF... In
my mind we are back to personal preference and best practices coding style
for personal versus production code...
Well, that was a fun diversion... Now I have to get back to work...
Rob
In a message dated 12/14/2010 10:07:39 A.M. US Mountain Standard Tim,
Peter....@BROADRIDGE.COM writes:
> -----Original Message-----
> From: TSO REXX Discussion List [mailto:TSO-...@vm.marist.edu] On Behalf
> Of Robert Zenuk
> Sent: Tuesday, December 14, 2010 11:52 AM
> To: TSO-...@vm.marist.edu
> Subject: Re: How to MOD a dataset with EXECIO
>
> Interesting... I had never seen the "something = functioncall(parms) =
> 'value'" syntax in REXX. I tried a few examples using time and left and
> it
> seems to work. What are the rules? Is it documented?
>
> I guess it saves a couple lines of "IF" logic, but is somewhat
obscure...
> I would think the following would be easier to read and follow requiring
> only 1 more line of code...
>
> if sysdsn("'"DS_Name"'") = 'OK' then
> disp = 'MOD'
> else
> disp = 'NEW'
>
> At first glance, I believe using a non-standard approach like this and
> with stems forces support to the most advanced REXX developers to first
> interpret what is being done then work on the code. But, I will think
> about it some more before I pass judgement. Any other examples out
> there of using this technique to help sway my opinion?
That syntax is just assigning a Boolean (logical) value (i.e., 0 or 1) to
the leftmost variable on the line. The second "=" is not assignment but
comparison, so a meta-description of that code line would be
variable = conditional-expression
Personally, I would code such a line as:
variable = (conditional-expression)
to emphasize the nature of the conditional-expression, but that's just my
preference.
I have often used that syntax when "conditional-expression" involves an
expensive Rexx operation (like an external function call) and the expression
needs to be tested more than once.
For your version, I would keep the line count down by coding it as:
if sysdsn("'"DS_Name"'") = 'OK' then disp = 'MOD'
else disp = 'NEW'
Maybe I qualify as an "expert" (I've never really thought so), but the
interpretation of the code as George presented it was obvious to me at first
reading. Maybe I've just been coding for too many years to be surprised by
"interesting" techniques any more.
Peter
--
This message and any attachments are intended only for the use of the
addressee and
may contain information that is privileged and confidential. If the reader
of the
message is not the intended recipient or an authorized representative of
the
intended recipient, you are hereby notified that any dissemination of this
communication is strictly prohibited. If you have received this
communication in
error, please notify us immediately by e-mail and delete the message and
any
attachments from your system.
----------------------------------------------------------------------
> I use a hand-rolled ternary function for this sort of thing:
>
> DataSetExists = ( SYSDSN("'"DS_Name"'") = "OK" )
It's a side-issue, but you need to be more careful.
You can get return values other than "OK" from SYSDSN for datasets that
exist.
From notes I wrote for myself sometime in the 1990s:
Logic problems can be caused by using SYSDSN badly. It is possible
that a routine expecting OK (ie: member exists) will get some other
value: eg DATASET UNAVAILABLE even if the member does exist. Basing
code on test of (in)equality with "OK" can be wrong!!
When sysdsn is used to enquire about a tape dataset if the dataset is
cataloged you'd normally get "VOLUME NOT ON SYSTEM". If the dataset
is allocated by another job, but not open, you still get this message.
When a job running on another system has opened the dataset you still
get that message. Unfortunately when a job running on the SAME system
has opened it you get: ERROR PROCESSING REQUESTED DATASET.
I asked IBM about this. They said that the ERROR ... message
is coded as a catch-all message for all the bad return codes from SVC
99. If you get this message you cannot tell what the snag is. They
admit that sysdsn is 'quick & dirty' compared, say, with listdsi.
LISTDSI always says retcode 16 (tape not supported) but it also gives
a reason code: 8 is 'not on dasd' while 16 is 'not cataloged'.
--
Jeremy C B Nicoll - my opinions are my own.
----------------------------------------------------------------------
If DataSetExists (or DSEXISTS or whatever) were in a single place, all
of its callers would benefit from a logic change that takes into account
what you've mentioned. They'd all remain exactly as readable, too.
Neither would be the case if SYSDSN("'"DS_Name"'") = "OK" were
explicitly coded everywhere the check was being done.
Tony
"Vitonis, Tony" <Tony.V...@CA.COM> wrote:
----------------------------------------------------------------------
damn you guys like to make life difficult
allocating a dataset "NEW" and checking the return code will tell you
all you need to know - and if it's not supposed to exist then you'll
be satisfied. on the other hand you can allocate "SHR" and check that
return code if it's supposed to already exist; allocating "MOD" will
give you the dataset you want if it exists or create it if it doesn't
- and you'll probably run into space problems if you don't allocate
any.
readdressing the original problem - it's illogical to use apend for
adding to a pds member since the allocation is for the dataset and
append makes no sense for a pds member - so you imo should not be able
to just add lines to a member that way - don't have an assignment
right now so can't test the results
in general it's no big deal to read in a whole member, add lines and
write back - but remember that this kind of access will delete ispf
statistics if there were any and you wanted to keep them - but then
you can use lmxxx commands under ispf instead can't you?
Correct. I like to use x = Sysdsn('dataset_name')
and then I can evaluate x and if not OK either call an error routine or create the dataset depending on what the REXX procedure is meant to be doing.
--
MfG / Best Regards
Sebastian Welton
IBM zSeries Technical Solutions Consultant EMEA
Fon: +49 (0) 6151 307144
Fax: +49 (0) 6151 307144
Mobile: +49 (0) 171 8880522
----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX
If SYSDSN(somedataset) = 'OK' Then opts='MOD REU'
else opts='New SomeDsorgIno'
"ALLOC (Fxxx) DA('xxx.zzz.yyy')" opts
---
Bob Bridges, rhb...@attglobal.net, cell 336 382-7313
work bob.b...@libertymutual.com, 317 581-6487
/* When weeding, the best way to make sure you're removing a weed and not a
valuable plant is to pull on it. If it comes out of the ground easily, it's
a valuable plant. */
-----Original Message-----
From: Mickey
Sent: Tuesday, December 14, 2010 13:21
Whereas I think a simple
If SYSDSN(somedataset) = 'OK' Then
"ALLOC (Fxxx) DA('xxx.zzz.yyy') MOD REU"
Else
"ALLOC (Fxxx) DA('xxx.zzz.yyy') New SomeDsorgIno"
will do for me :)
----------------------------------------------------------------------
/* Is it a DSN? */
fds:
call listdsi dx
sysreason=sysreason+0
if result=16 & wordpos(sysreason,'1 5 25')=0,
then say 'DSDD: FDS' dx result sysreason
return result<16 | sysreason=25
/* Get LISTDSI. Warning: LISTDSI returns RC=16, sysreason=2 both if
DD is missing and if it's allocated to a GDG(+1)! */
fdd:
call listdsi dx 'FILE'
sysreason=sysreason+0
if result=16 & wordpos(sysreason,'1 2 3 27 28')=0,
then say 'DSDD: FDD' dx result sysreason
return result<16 | wordpos(sysreason,'3 27')>0
The SAY statements are just my notification that a new SYSREASON has cropped
up that I haven't encountered before. Otherwise, basically the above says
that a DS exists if RESULT isn't 16, or even if it is if SYSREASON is 25.
For the DD test the SYSREASON exceptions are 3 and 27.
---
Bob Bridges, rhb...@attglobal.net, cell 336 382-7313
work bob.b...@libertymutual.com, 317 581-6487
/* Even when the pop stars of the past moved around, they stuck to movements
that did not require superb physical conditioning, or even a central nervous
system. A good example is a dance called "The Freddie", which was
popularized briefly in 1965 by Freddie and the Dreamers, a British Twit
Invasion band that, when it performed this dance, strongly resembled a group
of men failing a roadside sobriety test. -Dave Barry, 2001 */
-----Original Message-----
From: Jeremy Nicoll - ls tsrx
Sent: Tuesday, December 14, 2010 16:59
It's a side-issue, but you need to be more careful. You can get return
values other than "OK" from SYSDSN for datasets that exist.
----------------------------------------------------------------------
---
Bob Bridges, rhb...@attglobal.net, cell 336 382-7313
work bob.b...@libertymutual.com, 317 581-6487
/* Easy credit terms available. -Satan */
-----Original Message-----
From: Robert Zenuk
Sent: Tuesday, December 14, 2010 11:52
Interesting... I had never seen the "something = functioncall(parms) =
'value'" syntax in REXX. I tried a few examples using time and left and it
seems to work. What are the rules? Is it documented?
I guess it saves a couple lines of "IF" logic, but is somewhat obscure...
I would think the following would be easier to read and follow requiring
only 1 more line of code...
if sysdsn("'"DS_Name"'") = 'OK' then
disp = 'MOD'
else
disp = 'NEW'
--- In a message dated 12/14/2010 9:23:47 A.M. US Mountain Standard Time,
George...@ICBC.COM writes:
tempstat = Sysdsn("'"DS_Name"'") = "OK"
----------------------------------------------------------------------
Thanks,
Rob
In a message dated 12/15/2010 5:58:38 A.M. US Mountain Standard Time,
rhb...@ATTGLOBAL.NET writes:
if result=16 & wordpos(sysreason,'1 5 25')=0,
--------------------------------------------------
From: "Bob Bridges" <rhb...@ATTGLOBAL.NET>
Sent: Wednesday, December 15, 2010 7:58 AM
To: <TSO-...@VM.MARIST.EDU>
Subject: Re: [TSO-REXX] How to MOD a dataset with EXECIO
Come to think of it, though, I could have been doing it this way all along
and saved myself the extra line:
if result=16 & wordpos(sysreason+0,'1 5 25')=0 then....
---
Bob Bridges, rhb...@attglobal.net, cell 336 382-7313
work bob.b...@libertymutual.com, 317 581-6487
/* Wink at small faults; remember thou hast great ones. -Poor Richard */
-----Original Message-----
From: Robert Zenuk
Sent: Wednesday, December 15, 2010 11:22
This is a nice tidbit. While I have used wordpos a gazillion times it
never occurred to me to use it with the multiple sysreasons from LISTDSI.
In my DDCHECK routine I accept/ignore the sysreason values 3, 8, 12, 22 and
27 (tape, SYSOUT, VSAM and VIO) from LISTDSI (with other checks later to
confirm). So, this will nicely streamline my IF statement.
--- In a message dated 12/15/2010 5:58:38 A.M. US Mountain Standard Time,
if result=16 & wordpos((ABS(sysreason),'1 5 25')=0 then
--------------------------------------------------
From: "Bob Bridges" <rhb...@ATTGLOBAL.NET>
Sent: Wednesday, December 15, 2010 8:03 PM
To: <TSO-...@VM.MARIST.EDU>
Subject: Re: [TSO-REXX] How to MOD a dataset with EXECIO
> You're welcome, Rob - but don't forget the previous statement
----------------------------------------------------------------------
:>We have a process wherein a Rexx exec launches a started task by issuing a CONSOLE ACTIVATE, a CONSOLE START jobname and a CONSOLE DEACTIVATE. This Rexx code is executing in a batch job and so there may be multiple instances of the same code executing simultaneously.
:>We had an instance today that involved four of these jobs all executing at approximately the same time. It turned out in this instance that two of the jobs completed successfully and the other two didn't. The two that failed had a message in the job sysout indicating that the CONSOLE ACTIVATE had failed because the CONSOLE was already ACTIVATED.
:>I don't have a lot of experience with this command but was my understanding that code executing in separate address spaces could ACTIVATE CONSOLE without concern for what's going on in other address spaces.
:>Does anyone have experience with this. The manual doesn't provide that level of detail.
Look at the NAME keyword.
--
Binyamin Dissen <bdi...@dissensoftware.com>
http://www.dissensoftware.com
Director, Dissen Software, Bar & Grill - Israel
Should you use the mailblocks package and expect a response from me,
you should preauthorize the dissensoftware.com domain.
I very rarely bother responding to challenge/response systems,
especially those from irresponsible companies.
----------------------------------------------------------------------
- Don Imbriale
On Tue, May 31, 2011 at 5:12 PM, Mosley, George <George...@icbc.com>wrote:
> Hello All.
>
> We have a process wherein a Rexx exec launches a started task by issuing a
> CONSOLE ACTIVATE, a CONSOLE START jobname and a CONSOLE DEACTIVATE. This
> Rexx code is executing in a batch job and so there may be multiple instances
> of the same code executing simultaneously.
>
> We had an instance today that involved four of these jobs all executing at
> approximately the same time. It turned out in this instance that two of the
> jobs completed successfully and the other two didn't. The two that failed
> had a message in the job sysout indicating that the CONSOLE ACTIVATE had
> failed because the CONSOLE was already ACTIVATED.
>
> I don't have a lot of experience with this command but was my understanding
> that code executing in separate address spaces could ACTIVATE CONSOLE
> without concern for what's going on in other address spaces.
>
> Does anyone have experience with this. The manual doesn't provide that
> level of detail.
>
> Thanks.
>
> George Mosley
>
----------------------------------------------------------------------
JOBnnnnn or STCnnnnn or TSUnnnnn
This does a good job of insuring uniqueness.
Here is a little chunk of code to get it...
/* rexx */
tcb = storage(21c,4)
jscb = storage(d2x(c2d(tcb)+180),4)
ssib = storage(d2x(c2d(jscb)+316),4)
jobnum = storage(d2x(c2d(ssib)+12),8)
say mvsvar('SYMDEF',JOBNAME) jobnum
Hope this helps,
Rob
In a message dated 5/31/2011 2:24:36 P.M. US Mountain Standard Time,
Regards,
John K
From: "Mosley, George" <George...@ICBC.COM>
Date: 06/20/2011 12:56 PM
Subject: [TSO-REXX] SLEEP
Hello All.
I'm familiar with the following pause processing technique in Rexx (for 10
seconds, for example):
Call syscalls('ON')
Address syscall "sleep" 10
Call syscalls("OFF")
Does anyone know how to achieve the same thing in Clist code?
Thanks.
George
----------------------------------------------------------------------
- Don Imbriale
On Mon, Jun 20, 2011 at 1:54 PM, Mosley, George <George...@icbc.com>wrote:
> Hello All.
>
> I'm familiar with the following pause processing technique in Rexx (for 10
> seconds, for example):
>
> Call syscalls('ON')
> Address syscall "sleep" 10
> Call syscalls("OFF")
>
> Does anyone know how to achieve the same thing in Clist code?
>
> Thanks.
>
> George
>
----------------------------------------------------------------------