Announcement

Collapse
No announcement yet.

Globals vs Locals again

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Globals vs Locals again

    This is in 2 parts involving the best declaration and FreeFile.

    A while back a bit of a debate came out about which is better? Using global variables, or local to the function you are in.

    I have long been a proponent of using globals...I can see the use in Globals because you declare once and then use as needed, but lately I can also see at some point perhaps you have 2 globals with the same name, or where do you declare the global?, the larger the program, the more globals, the harder it is to track down "Where did I declare it"? when you have not used it in a while.

    In my VB past, for a while I used locals, and if something I needed global to several functions, I stored the value in the control that was displaying the current value. (but that slowed down response time, and eventually grew to many more lines of code for each function etc.) And storing the value in the control, is the same as having a global that gets changed when you change the control, right? (most cases that is)

    MCM has been known to be a proponent for keeping variables local to the function they are being used in, and he ALMOST had me thinking storing the value in the control is worthwhile again since it is easy to find the variable (its right in your function) and the speed of PB (I see no discernible penalty with each function asking the current value, unlike what I saw in VB)

    The one problem I saw was how to determine the current value from opening a file using freefile unless I stuck the value in a control (but I see no use for the filenumber in some control in this case, so wondered if a way to find the current value?)

    The other part is:

    Nevermind, I deleted it, the more I re-read to post my question the more obvious it became as to the answer.
    but it involved MCM's explanation to why passing a file handle to a file, and then close the handle does not close the file.

    Anyways, I guess the overall question is if I can get the file, or its handle without storing it in a control of a global so that the function that did not open it, can still use it?

    (does any of this make any sense?)
    Engineer's Motto: If it aint broke take it apart and fix it

    "If at 1st you don't succeed... call it version 1.0"

    "Half of Programming is coding"....."The other 90% is DEBUGGING"

    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

  • #2
    What you are ASKING make sense, but what you are DOING is up for debate.

    The only reason you would need to retain the value of a file handle across calls (User actions resulting in a call to your window/dialog procedure) is because you are keeping the file open across calls, which is something I absolutely recommend you do NOT do.

    When the user gives you a request requiring file access... get a handle (FREEFILE), open the file, get your data, close the file and you don't have to worry about retaining a file handle value.

    But if you have your heart set on keeping the file open, you could always assign your own buffer numbers using equates to keep the values straight...

    Code:
    %FILENO_CUSTOMER = 12
    $FILE_CUSTOMER      = "customer.dat"
    %FILENO_INVENTORY =  8 
    $FILE_INVENTORY      = "inventory.dat"
    
    ..
    OPEN $FILE_CUSTOMER for RANDOM  AS %FILENO_CUSTOMER ...
    OPEN $FILE_INVENTORY for BINARY   AS %FILENO_INVENTORY...
    ....
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      In my case, I guess "File" is a bad use of words, but really serial port, which in turn makes sense that once I open..stay open till done with it.
      (I would think the same of any external device that could be opened via "CreateFile" or some similar context)

      Opening and closing within the physical computer is good and I can see why locals would be better, but once you physically leave the computer to some connected device would slow things down dramatically.

      Thank you MCM...for what I can figure, in some cases such as this the answer is "It depends" again

      or more to the point, almost like threads...it depends on the point of detrimental return.

      I had to ask in the case there was another way. (But when have I NOT tried to think out of the box and see if there was or was not another way?)
      Engineer's Motto: If it aint broke take it apart and fix it

      "If at 1st you don't succeed... call it version 1.0"

      "Half of Programming is coding"....."The other 90% is DEBUGGING"

      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

      Comment


      • #4
        Make it so one function does all the COMM SENDs, and another one function does all the COMM RECV, the COMM # can be STATIC within those two functions. The comm port can stay open, and the # isn't global.

        I don't see the need to be religiously against globals, and COMM # is one of the more justifiable places to use a global. (IMO of course)
        Dale

        Comment


        • #5
          Your choice of GLOBAL or STATIC or LOCAL variables is really a function of your style and the application at hand.

          My dislike of GLOBALs is almost 100% due to an almost maniacal passion that any procedures I create be instantly (i.e., "cut and paste") re-useable in another program and also be easy to relocate to a support DLL - neither of which is true if that procedure relies on GLOBAL variables.

          The other 50% (!) of my dislike is that I forget the global variable names if they are not right in front of me on the current screen.
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            I've occasionally found it useful to pass file handles obtained either through PowerBASIC's 'Open' verb or through CreateFile() Api calls through function parameters. I commonly have apps where if a button is pressed a great deal of processing must take place involving many procedures being called. In such a scenerio it makes sence to me to open the file in the immediate procedure that handles the button click, then pass the file handle to all those procedures that need it. Finally, close the handle at the end of the immediate procedure where it was opened.

            If you need to keep the file open across function calls or for the run of a program, why not store the file handle in the cbWndExtra bytes? Then it will only take a simple GetWindowLong(hWnd,iOffset) to retrieve it.
            Fred
            "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

            Comment


            • #7
              commonly have apps where if a button is pressed a great deal of processing must take place
              .. but if this is something like...
              Code:
                 SELECT CASE AS LONG LOWRD(wParam) OR CBCTL
                     CASE %ID_BUTTON
                       hFile = FREEFILE
                       OPEN ...       AS  hFile
                       CALL FirstOfManyProcedures (hFile....)
                       CLOSE hFile
                      ...
              .. then you are not holding the file open across user actions, are you?

              I's suggesting that doing this...
              Code:
                STATIC/GLOBAL H1 AS LONG,  H2 AS LONG
                ---OR-----
                H1, H2 stored in a DIALOG/CONTROL SET USER value 
                 or a SetWindowLong (GWL_USER or DWL_USERDATA) slot
              
                 CASE %WM_CREATE OR %WM_INITDIALOG
                      H1    = FREEFILE
                      OPEN .... AS H1
                      H2 =  FREEFILE
                      OPEN ...  AS H2 
                 CASE  %WM_CLOSE or %WM_DESTROY
                     CLOSE h1, h2
              
                 CASE %WM_COMMAND
                   IF LOWRD(wParam) = %ID_BUTTON THEN 
                        CALL FirstofMany (h1, h2, ....)
                  ......
              .. is to be avoided.

              MCM
              Last edited by Michael Mattias; 24 Oct 2007, 09:13 AM.
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                In the early part of my programming career (all DOS) I opened files when the program started, kept them open all the while when a user was using them, and only closed them at termination. I can't say this ever caused any problems.

                In Windows now I tend to follow your example Michael (except with debug log files, and even there I sometimes open/close in a transaction), because it just seems 'cleaner'. The only down side seems to be some extra work, and sometimes the necessity of using mutexes or something like that if the app wasn't designed for multiple instances of the same app accessing a file.
                Fred
                "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

                Comment


                • #9
                  >except with debug log files

                  With debug files it's even more important.

                  When you write to a file, it is not necessarily immediately put on disk (it's cached), so if the program goes belly-up your log may be missing the last couple of entries and so you don't really know where your program died.

                  Much better I think to create a little function..
                  Code:
                  FUNCTION WriteDebugLog (text$) AS LONG
                    LOCAL h AS LONG
                    h          = FREEFILE
                    OPEN       $DEBUG_FILE FOR APPEND AS h
                    PRINT      #h, Text$
                    CLOSE      h
                  END FUNCTION 
                  
                  ... WriteDebugLog  "Entered procedure B"
                  MCM
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    "When you write to a file, it is not necessarily immediately put on disk (it's cached), so if the program goes belly-up your log may be missing the last couple of entries and so you don't really know where your program died."

                    FLUSH # ???
                    Dale

                    Comment


                    • #11
                      >FLUSH

                      By golly, I think you are correct. I need to RTFM again, 'cuz I forgot that existed.
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        Hey Michael you forgot to include:

                        Last edited by Sean Roe; 25 Oct 2007, 02:57 PM.

                        Comment


                        • #13
                          Flush

                          Actually, Flush didn't exist within the QuickBasic language I had used for my early PC programming in the 80's. At that time I couldn't seem to get my assembler code working right to take care of it (my deficiencies, really), and found that Microsoft's SmartDrv disk caching program had some obscure command line switches that allowed for immediate flushing of file buffers. When I discovered PowerBASIC 3.5 that was one of the really important issues that so impressed me with PowerBASIC, and when I converted my programs to PB, I used Flush instead of SmartDrv. I discovered it by RTFM!
                          Fred
                          "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

                          Comment


                          • #14
                            The GLOBAL versus LOCAL topic seems to come and go on a regular basis yet the answer remains the same, neither is better or worse than the other, you just use whichever suits the scope you require.

                            Using a LOCAL when all you need is LOCAL scope makes variable naming simple, you can use VAR in every procedure in safety without conflicts where with global variables, every name must be unique.

                            At the other end if you need to have a variable visible across every function/sub in the app, you save yourself some rediculous archipeligo of stack parameters by using a variable of GLOBAL scope.

                            'orses 4 korses, pikk wot yoo need !
                            hutch at movsd dot com
                            The MASM Forum - SLL Modules and PB Libraries

                            http://www.masm32.com/board/index.php?board=69.0

                            Comment

                            Working...
                            X