Author Topic: Clever Library Scope Code  (Read 3920 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Clever Library Scope Code
« on: December 21, 2019, 04:21:56 pm »
As you guys probably know, a lot of the stuff I write, I write it in such a manner than I can use it inside a library later, if I want to.  Here's a little epiphany that occurred to me today, that I thought I'd share, which other library builders might want to make use of:

Code: QB64: [Select]
  1. FUNCTION ProcessMenu$ (k AS LONG, active AS INTEGER)
  2.     'k is for the keyboard
  3.     'active is a return code for which menu we got the result from, in case someone makes multiple menus
  4.     '    with the same options listed in the sub menus, such as PAINT -- Circle as one menu/submenu
  5.     '    and then DRAW -- Circle as another menu/submenu.
  6.     '    Both would just return "Circle" as our final choice, so we'd need to know which menu was active
  7.     '    and where the command came from.
  8.  
  9.     DIM Caption AS STRING
  10.     STATIC oldmouse AS INTEGER 'the old status of our left mouse button (up or down)
  11.     IF mb = 0 THEN resetmb = -1: mb = _MOUSEBUTTON(1) 'shortcut key so I don't have to type _mousebutton(1) multiple times.
  12.     IF mx = 0 THEN resetmx = -1: mx = _MOUSEX
  13.     IF my = 0 THEN resetmy = -1: my = _MOUSEY 'same here.

mb, mx, my are my usual names for simple variables for mousebutton, mousex, and mousey, to help me cut down on a lot of typing.   The problem with using them in code which might be stripped out and tossed into a library is that I also often use them as DIM SHARED variables, which means the local sub values could end up corrupting the global values if I just automatically reread them...

So, my solution here is this one:
    IF mb = 0 THEN resetmb = -1: mb = _MOUSEBUTTON(1) 'shortcut key so I don't have to type _mousebutton(1) multiple times.
    IF mx = 0 THEN resetmx = -1: mx = _MOUSEX
    IF my = 0 THEN resetmy = -1: my = _MOUSEY 'same here.


If they're global variables, they'll pass whatever value they have into the sub, and I won't bother to get them from our mouse functions.  If they're not global variables, there won't be any value to pass, so since they default to 0, I'll get the current values...

Only IF they're global and 0 to begin with, can I have any conflict with using the names inside this sub...

...and that's easily resolved by checking the reset variable and then resetting them to 0 before I exit the sub, if I need to.

Now, I can safely use mb,mx,my inside my sub and not need to worry about if they're local or shared variables.  As long as someone keeps mb, mx, my as representing the mouse buttons, and don't make them represent something else in their code (which I never do, as it's just habit for me to make them mouse, just as k is for keyboard, m is for mem, i and j are for loops...), it now no longer matters if they're shared or local.  The SUB/FUNCTION is now prepared to deal with them either way.  ;)



Anywho...

I just thought I'd share.  I've been writing library code for a long time now, and this simple solution is the first time I've ever considered and thought of something like this, so I thought I'd go ahead and share the concept for others.  If it's useful for you, GREAT!  If not, then...   MuHaHaHaHa!  I wasted a precious 2 minutes of your life that you'll never get back after having read my ramblings!  (Now, if I could only figure out how to add those 2 minutes to my own life span...)  :P
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Clever Library Scope Code
« Reply #1 on: December 21, 2019, 04:39:46 pm »
But mb stands for middle button, not mouse button. Everybody knows that!!!!! :D

I use mouse with keyboard routines as a separate sub in all of my programs. In a sense, that's a library. It saves a ton of duplicate coding, especially in gigantic programs. Just call the mouse/keyboard sub as needed.

Oh crap, I'm finished with this topic, and depending on what your reading speed is, I probably only stole 30-seconds of your time... So now I'm down by a minute and a half. Damn you Steve!!!

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Clever Library Scope Code
« Reply #2 on: December 21, 2019, 06:32:24 pm »
Not to detract or derail, but there's no better place than here to advertise the Unix philosopher's take on DIM SHARED or globals in general: avoid them. You pretty much always can do away with them if you structure things right. CONSTS are just data; treat them as such, and don't let what you name the thing get you into trouble later. Functions have scope for a reason, we use operating systems for a reason. I only bring this representation to the table because I too have a habit of stacking works together, with a dozen bi/bm includes, etc etc. Structure things "right", and whole classes of bugs are existentially avoided.
You're not done when it works, you're done when it's right.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Clever Library Scope Code
« Reply #3 on: December 21, 2019, 06:50:07 pm »
Aye, but sometimes it’s just so much simpler to type DIM SHARED once at the top of a segment of code, than it is to type SHARED variable AS TYPE repeatedly for every SUB/FUNCTION.  Some folks like to limit themselves on certain functionality with their code, in a pursuit to create “the best code style”.  (Never use GOTO.  LET is stupid...  GOSUB has been replaced with SUB... And so on...)

If it works better for them, then I say, “More power to them.”  I’m happy they have the OPTION _EXPLICIT to to code in a style they prefer to code in.  As for me, I simply feel that the “best code style” is whatever ends up compiling and making a runable EXE for the programmer.  I’ll always have an use for that evil GOTO statement, and I’ll always take a shortcut and have DIM SHARED variables in my code.  Knowing this about myself (and I assume there’s others with the same, or almost same, coding “style” as mine), I thought I’d share a nice way around a common global/local variable problem which pops up in my code.

Another simple solution is one I’ve used many times in the past: Rename variables before making them a library.  Go from mb to Menu_Library_mb and chances are, any naming conflicts will go away then as well.

Various solutions to the same issue.  Just choose the one that suits you the best.  (Or even avoid the issue completely, as StxAxTic suggests, by not even having global variables...).

Me personally though, I’m happy to hear any and all options which others use.  You never know when THEIR method might be the best solution to one of MY problems, and I’m certainly not too old to ever learn something new and improved.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Clever Library Scope Code
« Reply #4 on: December 21, 2019, 07:12:31 pm »
Thank you, Steve, Thank you STxAxTIC. Both is very usable for me.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Clever Library Scope Code
« Reply #5 on: December 21, 2019, 07:19:09 pm »
I DIM SHARE the $#%^ out of variables and never get into trouble. 1000 variables no problem! Especially from go ol' QBasic days, when you needed to keep your variable name size restricted, to save space. Mine were never over 3 characters long. How could I remember them all you ask? Simple, I was a stable genius! That's right, Donal J. Trump paid big bucks to learn from me!!! :D Wow, I do miss those days, but I'd be a lying son of a democrat (hey, that's sod for short) if I stated I never got bit in the ascii once in awhile, especially when trying to combine projects or adding modules. I still use DIM SHARED a lot, but I like to prefix  my variables for the main sub they are used in. So if I have a subroutine for a ledger, I use a "ledger-" prefix to all ledger related variables, and with DIM SHARED I can then use them wherever they are needed. I also know they are relating to a ledger function. Besides, have you ever tried to keep straight a $#!^ ton of variables to pass in parentheses? That can be a source of misfires,  too. One trick I used ages back, was to run all my variables I wanted prefixed through a routine to read the code, and add the prefix when it discovered the variable. It's just "parse" for the course.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Clever Library Scope Code
« Reply #6 on: December 21, 2019, 07:24:13 pm »
Quote
One trick I used ages back, was to run all my variables I wanted prefixed through a routine to read the code, and add the prefix when it discovered the variable. It's just "parse" for the course.

Find and Replace in the menu works excellently for this.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Clever Library Scope Code
« Reply #7 on: December 21, 2019, 08:15:58 pm »
Find and Replace in the menu works excellently for this.  ;)

It works for a few variables, but automation is your friend when you want to do a bunch quickly. In other words, let the routine hunt out each variable and change it. It takes about 1 second to run. More time for a Cheetos break for me!!!

Hey, I think you did something cool a couple of years back with something we both do... Start out with short variable names and then lengthen them, so they make since when you pick apart your code a couple of years down the road. Do you remember that message thread?

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Clever Library Scope Code
« Reply #8 on: December 21, 2019, 08:50:04 pm »
I was about to modify but since there have been a handful of responses - I totally agree, sometimes you need globals. I suppose if your names are long and crazy enough you will get away with no bugs for all practical purposes. The desert island physicist in me with an infinite lifespan though still gets antsy about this tactic, because there's no true security in obscurity.

BTW, I'm not the only one with this fantasy: https://xkcd.com/505/
You're not done when it works, you're done when it's right.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Clever Library Scope Code
« Reply #9 on: December 21, 2019, 08:52:43 pm »
It works for a few variables, but automation is your friend when you want to do a bunch quickly. In other words, let the routine hunt out each variable and change it. It takes about 1 second to run. More time for a Cheetos break for me!!!

Hey, I think you did something cool a couple of years back with something we both do... Start out with short variable names and then lengthen them, so they make since when you pick apart your code a couple of years down the road. Do you remember that message thread?

Pete

I do, but I think it was back on the old .net forums and currently lost.  :(

Name and key substitution is something which I do a lot of.  When coding for personal use, I do a lot of things like you do: a, b, c variable names.  (And for the same reasons — memory limits from back in the day.)  Of course, nobody wants a library filled with such generic variables, so they have to be expanded before release to the public...

So if you grab a copy of Steve’s Repo, you see I have what I consider an essential keyword that nobody else seems to like/need: $REPLACE.

Usage is like this:
$REPLACE ?? WITH _PRINTSTRING (

Then when I want to printstring something in my program, all I do is type ?? And those double question marks instantly replace themselves with _PRINTSTRING (

All I do then is finish that statement with the rest of its values.

It lets me type those short codes which me and you are used to, but then it automatically expands them to something readable by others (and the compiler itself).

Somewhere around one of these forums is a simple batch file you can run to add $REPLACE to your version of QB64.  You may find it as useful for you, as I do for me.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!