Thanks again for all your help and insights! I think I've got it
now.
I've studied everything you all have written and have to admit
that it has forced me into some introspection! Here I have been
programming for many years, (ahem, since the early '60s), and am
still bumbling along, an unreformed pragmatist. I write just enough
code to get me an answer that works, and then move on to the next
problem. But you guys make a science of it! It's good that the
world's IT systems rely upon people like you instead of like me!
Thanks again for your indulgence,
David
Announcement
Collapse
No announcement yet.
'Procedures': How best to ... ?
Collapse
X
-
With shared:
Code:function DoSomething(a,b,c,d$) AS LONG shared e$ ... end function
Code:function DoSomething(a,b,c,d$[b],e$[/b]) AS LONG ... end function
If you are setting out to make 'DoSomething' a reusable function, it can't require any external variables.
OTOH you can use SHARED variables if you have a collection of functions which will be compiled into a UNIT file; i.e., the SHARED variables are OK... as long as you never intend to use any of those functions except by $LINKing the PBU file.
Bottom line is, you need to invest some time <U>planning</U> your function libraries and #INCLUDE files <U>before</U> you start coding.
MCM
Leave a comment:
-
Originally posted by David Jeppesen:
...were able to solve it without SHARED...
in a unit. Take the following example:
Code:$compile unit function DoSomething(a,b,c,d$) public ... ... ... end function
only 4 variables to be passed. Now suppose, in one particular
program, you need a 5th variable. You could:
Code:$compile unit function DoSomething(a,b,c,d$) public shared e$ ... ... end function
I agree but sometimes, it's unavoidable. In this example, I
personally would copy the 1st file over to a 2nd to keep
compatability.
------------------
Leave a comment:
-
You guys are great!
Mel: I have now successfully employed $INCLUDE, but haven't gotten to
units yet because I am still developing. But I will!
Mike: Thank you for your most extensive reply and for all the time
you spent on it. You make some very good points. It is clear to
me however that your requirements are much more stringent than mine.
For me, this is more of a 'spare-time hobby', so I can tolerate a
few undisciplined screw-ups that wouldn't get by in the professional
world. But I'll bookmark your reply for when I become more prolific!
Michael: As above, re $INCLUDE and units. I am having trouble however
trying to follow your direction, "absolutely positively use no SHARED",
because, by virtue of what they do, all of the procedures must be
called by the main program, at the time of the main program's choosing,
and cannot be called by each other. (However one does use data created
by the others.) If you have encountered something like this before,
and were able to solve it without SHARED, I would be pleased to hear
how you were able to accomplish it.
Thanks again for your insights folks!
Leave a comment:
-
I, too am a fan of $INCLUDE.
THat way you can...
Code:$COMPILE EXE [b]or[/b] $COMPILE UNIT $INCLUDE "proc001.inc" ..
MCM
Leave a comment:
-
My personal preference is to create common units of ranking levels.
Then combine several units in a PB Library of them which is called
forth in each program. By 'ranking levels' I mean the the lowest
level unit contains the most common SUBS that will be needed and can
be CALLED from any code which then becomes an executable.
Right or wrong, the lowest level of these units can also be CALLED
by other units. Thus they are NESTED such CALLS. But the executables
only contain the minimum common code that is ever needed.
That also starts one down the road toward decisions on what to name
one's variables! It focuses one on what can become common named of
common type variable data that is needed from any higher level code
that reaches into these lower level common level SUBS, built into
UNITS and thence into LIBS of them.
For example, my lowest level common code contains generic video and
keyboard I/O operations, for example, for everything else I write.
You might think it crazy to think about what to use for a 'common
name' for the coordinates for screen horizontal and vertical position.
But a million and a quarter lines of PB source later I'm darned glad
I settled on GX% for all vertical line number coordinates and GY%
for all horizontal column number coordinates for all my work.
Yes, virtually every line of my code is commented! But you can only
go so far in that. And MOST IMPORTANT is this. Every comment line
and word your write into your source code may be excluded as to the
number of characters you use up of the 64K generic code space that PB
will allow you. But that is *NOT* true of the bytes required for a
variable name. Sure I could have used, "Cursor_screen_line%" instead
of "GX%" for that variable name. It would have been much clearer for
any subsequent code maintainer to have followed that in my code. But
let's see just what doing really definitive declaration of variable
names would have done to just one of my major executables, OK?
Of the now 114 major code chunks in my suite all done in PB 3.5, there
are 27 UNITS, of which I think the worst nesting levels hit to three
'ranks; deep. And if your work covers a very large playing field for
very complex code action, you'll soon, I think, hit another decision
point in how to create SUBS which have access to a lot more than just
the allowable 16 variables that may be used in a PB SUB operation.
That's been one of the major stumbling blocks I've had to face in
the use of PB at this point. I want to use non-global variables which
are not PUBLIC in nature. But there is simply no way to do this as
I can see this. Take just the action of obtaining a single byte from
the keyboard, for example. Over ten years of this and considering
that a single byte from the keyboard has to integrate into all possible
MENU libraries, as well as being MOUSE related, with timing control,
hidden functions, even screen related array reporting for direct video
overlay work for help and block move/hiding; it takes me thirty-two
calling parameters for every single byte I get from the keyboard in
the suite!
Every single byte I read from the keyboard takes, at this point, 333
discrete lines of code to process properly for suite-wide operations
needed! And I assure you, chuckle, it is at the very lowest core
level as a SUB in the floor level UNIT which is combined into the
lowest best PBL that I can create for use here.
So what to do about the fact that 32 parameters are needed for every
single keystroke I need in every program? Why, yes, all of them are
very carefully thought out as to a meaningful name. I could have used
things like the PB mouse routines for that portion of the work such ]
as the name "Button%", "Row%" or "Column%". You bet things should be
self descriptive. But I can't carry the needed variable names into,
for example, the SUB for just getting a keystroke, and am going to
have to make use of the PUBLIC form of passing parameters into each
time I even get a keystroke. There aren't even close to the needed
number of allowable parameters that can be privately passed as PB is
given to us today. So .. sigh .. I might as well bite the bullet. We
make **ALL* the parameters needed to get a keystroke in the whole
program suite PUBLIC parameters.
There are many reading this who would scream bloody expletives at me
for that .. or for you for doing it. But when a project becomes very
pervasive and has to be server-server related over a huge embedded
system box operation, things get out of hand. I am coming close to
the roughly 2400 allowable variable max in PB's platform in a number
of my executables at this point, sigh. And there is simply no possible
way to break the code down to smaller units because the global operations
issues are simply that huge. Wince.
And then that leads to the next step in making sure you don't start
down the mixup of variables that are type different between SUBS or
FUNCTIONS, but of the same name. So every variable I ever use has to
have the type designator on it! And every variable that is PUBLIC is
read into every program or whatever I create as a master INCLUDE pure
source code chuck common to every program. But wait! There's more!
So far we've talked about just the commonality in getting a keystroke
anywhere in the suite. But what about the commonality of getting a
line of input from anywhere in the suite? Obviously whatever is
involved in getting a keystroke is a lower level part of getting a
line of input data. Getting a line of input data for anything in the
suite has even more common variables which will be needed no matter
what that line input does! And that 'line input' isn't at all the
function pre-made for us by PB called LINE INPUT which has no real
way to handle many of the other needed common level interface
attributes which have to either be calling parameters or PUBLIC data
for optimal use in a large suite like my work.
So .. sigh, the line input SUB for the suite is another one thousand
four hundred and eight lines (1408) of 'common code' that obviously
has to be involved in every program I will ever write. And .. using
the same requirements for 'common variables' that also include handling
every single byte or intervening mouse stroke with it .. we have only
SEVENTY (70) absolutely needed calling parameters for just getting
a single input line of code. After all .. what are the screen width
allowances for the line, the prompt, the color of the I/O, the filter
limitations for the data? Surely you get the idea. Nobody could
ever contemplate over 1700 lines of source code in their programs for
every time they wanted to find out the name of this or that? And
you would waste a horrible amount of time handling cut and paste for
every common task you do. That is what SUBS and FUNCTIONS are all
about, right?
Don't forget about error handling and hard line numbers that are
unique and buried in your nower nested SUBS and so on, though. Not
if you don't want to do things all over and a lot more work when
you start usint EXIT FAR to handle them, grin. So that means, since
we only fave what, about 65,000 possible lines in source code for
PB, your numbering schema better use the highest level line numbers
for marker points in the lowest level SUBS and so on! Say, the
50,000 up line numbers? That's what I did long ago and far away.
And even 80 available calling parameters for a SUB wouldn't get the job
done even for the basic level of I/O work in every program here. So,
sigh, the COMDIMZP.BAS include file which has to be a part of everything
I write in PB only has three hundred (300) PUBLIC variables in it as
reported by Paul Sittler's BASTOOLS utility:
BASTOOLS (v0.0R Mar 25 1991) run 6/1/4 15:39:42. Input File: COMDIMZP.BAS
Variables cross-referenced to 267 physical line numbers.
AA%(: 96 100
AR$(: 130 132
.. (snipped!)
sKey: 177 186
325 Variables cross-referenced to 267 physical line numbers.
BASTOOLS (v0.0R Mar 25 1991) run 6/1/4 15:39:42.
Output File: COMDIMZP.VAR
Elapsed time for run was: 00:00:00
But, sKey doesn't have a type fixed to it? I didn't create that one,
grin. But attaching a variable type to each variable name sure has a
LOT to be said for it when you do an auto-translation for BASIC code
to source code for C/C++ in an emergency! You get to see exactly what
to do with each variable in the auto-translation, grin!
Plus, when I do a similar BASTOOLS run on a major 27,000 line source
code for, say the PRCHANGE.EXE program which edits the proffesional
case files in my suite in:
PRCHANGE EXE 437005 11-16-03 4:55a 27473 Profnl case editor
Of the 27473 lines of total source in PB 3.5 for that 437K executable
which is composed of 4795 MAIN module source code lines we see:
C:\ZLOG>BT/V PRCHANGE.BAS PRCHANGE.VAR
BASTOOLS Version 0.0R dated Mar 25 1991 @ 23:13:21
Copyright 1988, 1989, 1990, 1991 by Paul M. Sittler. All rights reserved.
BASTOOLS (v0.0R Mar 25 1991) run 6/1/4 15:52:47.
Input File: PRCHANGE.BAS
Reading PRCHANGE.BAS and making Variables crossref table.
Line #4795
Writing Variables cross-reference file PRCHANGE.VAR
Line #913, 502 Items
BASTOOLS (v0.0R Mar 25 1991) run 6/1/4 15:52:49. Output File: PRCHANGE.VAR
All done. Elapsed time for run was: 00:00:02
In the file PRCHANGE.VAR generated we'll see that GX% byte input
coordinated variable called in the lines of the MAIN module only!
GX%:
: 303 477 702 711 722 738 774
: 778 781 784 787 790 793 799
: 806 810 813 825 829 832 835
: 838 841 844 848 855 858 861
: 1237 1254 1270 1286 1302 1318 1466
: 1534 1550 1566 1632 1648 1664 1680
: 1697 1713 1733 1780 1796 1812 1828
: 1844 1861 1878 2078 2122 2198 2317
: 2340 2383 2429 2484 2507 2530 2550
: 2570 2590 2610 2631 2915 2923 2927
: 2930 2933 2936 2939 2968 2973 2977
: 3004 3009 3013 3046 3238 3275 3337
: 3395 3492 3626 3708 3726 3808 3814
: 3833 3868 3930 3951 3952 3969 3999
: 4059 4080 4702 4755
And that doesn't include, obviously, every other PBU in every other
PBL and even the INCLUDE files that are specific to this executable
which has the over 27,000 lines of source the PB compiler reports
when it compiles the code.
My best suggestion to anyone starting on this UNIT and LIB journey
is to take a serious look at what you are doing and where you want
to go on a long journey into the future. Consider carefully just
how you intend to input keyboard data and present screen data. That
even goes into MENU work, use of the various screen levels in BASIC
which will let you pop portions of the screen away in memory and paste
in other things such as buttons, help blocks, and I/O areas. Either
take the time to coordinate your own creative work here, including
the variable names that you will find you need that are really PUBLIC
and can be chunked into a common INCLUDE file, or purchase one of
or gain the legitimate free use of some I/O and display operation
someone else has created to help you. If you use somebody else's
code for this, consider adopting their variable names to save you
much time and work.
Sure Bob and crew gave us LOCATE(row, column). But, in my humble
opinion, one had better think about where that belongs in code. And
in my case, though I use the raw function in places, most of the
time it is in a SUB which is called relavent to other things. Yes,
the code may be slower this way. But as time goes in a major effort,
as the years go by working on it common routines made up into UNITS
and into LIB's with the wonderful tools given you are crucial.
The life you save may be your own!
------------------
Mike Luther
[email protected]
Leave a comment:
-
David, it sounds for all the world like you are developing your
own libraries. If this is the case, your best bet would be, indeed,
be to compile your "procedures" into units and then link them to
the main program.
You can also leave them as text source then "$Include" them as
needed.
BTW: You can cut-n-paste with PB/DOS in a manner of speaking.
Use Ctrl K-B and Ctrl K-K to highlight the code then use Ctrl K-W
to write the code to a disk file. In the other program(s), use
Ctrl K-R to read the file into the program you are working on.
Works for me!!
Hope this helps
Cheers
------------------
Leave a comment:
-
'Procedures': How best to ... ?
I am developing several 'Procedures', (not subroutines or functions),
which I would like to call from several different totally unrelated
main programs. Can someone please tell me how is the best way to
accomplish this?
My original plan was to develop these procedures, and then cut-and-
paste them into the calling programs. Then, 1) I found that I cannot
cut-and-paste between programs for some reason; but, more importantly,
after thinking about it, it would be nicer to be able to maintain and
extend these procedures in only one place, rather than in each of the
individual calling programs.
I have read a little about creating 'units', but don't know if this is
the best approach.
BTW, I am using 3.5.
In all cases the main programs will only send data to these procedures.
Thank you very much for any guidance,
David
Tags: None
Leave a comment: