Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
To iif or not to iif = .t.
Message
From
01/06/2001 21:17:47
 
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00513276
Message ID:
00514109
Views:
16
>>>SNIP
>>>>
>>>>I think George Tasker hit the nail on the head in an earlier message: that he considers them the equivalent of GOTO in Basic - with all the problems that causes.
>>>>
>>>C'mon Al, it's nothing of the sort.
>>>
>>>Goto can end up anywhere while LOOP goes to only one place and EXIT goes *only* to the place that you are going to go to anyways. There's a HUGE difference.
>>>I'm not arguing against your personal standard, just the justification you (and George) use for this particular one.
>>
>>Whoa there, bucko. First, you do know where a GOTO will end up: either at the line number or line label. Second, the objection to it and EXIT and LOOP is exactly the same. It leads to un-structured code that's more difficult to both read and maintain.
>
>George,
>
>How would you program the following piece of code? Requirements:
>
>1) If user hits ESC, question is asked (this is procedure of oValid object) and if he/she answers "Yes", code should stop.
>
>2) It table could not be opened exclusively, it should be written in the log and proceed with the next.
>
>
>* support user Escapes for interrupting the main loop
>lcOldOnEsc = on('escape')                    && save previous Escape handler
>lcOldSetEscape = set('escape')               && previous Escape enablement state
>set escape on                                   && enable escape handling
>on escape oValid.StopProcess("Are you sure you want to stop Modify Process?")     && Allows for stopping of the process.
>do while oValid.lContinue && Till termination
>     for lnI=1 to m.tnCount     && loop for all selected databases
>          if not oValid.lContinue
>               exit
>          endif
>          if not file(forceext(taDBC[m.lnI],'DBC'))
>               =messagebox("Database "+taDBC[m.lnI]+" is not found!",48,"File does not exist")
>               loop
>          endif
>          llDBCExist=.t.
>          if GetDBC(alltrim(taDBC[m.lnI])) && Opens the database for possible changes && should be in the path
>               lcDBCPath=addbs(justpath(fullpath(alltrim(taDBC[m.lnI]))))
>               if !empty(m.lcWholeLogStr) && Separate Databases
>                    lcWholeLogStr=m.lcWholeLogStr+CR+replicate("*",65)+CR
>               else
>                    lcWholeLogStr=upper("Starting checking "+ m.tcAction+" at ")+ttoc(m.lnStartTime)+CR
>               endif
>               lcWholeLogStr= m.lcWholeLogStr+ttoc(datetime())+" Database: "+alltrim(taDBC[m.lnI])
>               release laTables
>               lnTables=adbobjects(laTables, "TABLE")  && Create list of all tables in Database
>               =asort(laTables)
>               for lnK=1 to m.lnTables
>                    if not oValid.lContinue
>                         exit
>                    endif
>                    lcTableName=upper(alltrim(laTables[m.lnK]))
>                    lnMinSize=3*(GetFileSize(m.lcDBCPath+m.lcTableName+".DBF")+ ;
>                         GetFileSize(m.lcDBCPath+m.lcTableName+".FPT") + ;
>                         GetFileSize(m.lcDBCPath+m.lcTableName+".CDX"))
>                    if vartype(m.pcTempDrive)"C"
>                         pcTempDrive=justdrive(sys(2023))
>                    endif
>                    if GetFreeSpace(m.pcTempDrive, m.llFirstTime)                         =messagebox("Could not check and possibly alter "+m.lcTableName+" because it's not enough free space!"+CR + ;
>                              "Free space, then repeat the process!",48,"Not enough space")
>                         llStop=.t.
>                         exit
>                    else
>                         llTableOpened=.f.
>                         if m.lcTableName"NEXTID"
>                              if OpenTble(m.lcTableName,'WorkFile','exclusive') && Open Table excl with alias WorkFile
>                                   lcWholeLogStr= m.lcWholeLogStr+CR+"Table: "+ m.lcTableName+ ;
>                                        " starting checking "+m.tcAction+" at "+ttoc(datetime())+CR
>                                   llTableOpened=.t.
>                                   if m.tcAction='Structure'
>                                        =Modify_Structure(m.lcTableName, alltrim(taDBC[m.lnI]), @lcWholeLogStr)
>                                   endif   && Structure changes only
>                                   lcWholeLogStr= m.lcWholeLogStr+CR+"Table: "+m.lcTableName+ ;
>                                        " starting checking indexes at "+ttoc(datetime())+CR
>                                   =Modify_Indexes(m.lcTableName, alltrim(taDBC[m.lnI]), @lcWholeLogStr)
>                                   use     in select('WorkFile')
>                                   flush
>                              else && Table was not opened
>                                   lcWholeLogStr= m.lcWholeLogStr+  ;
>                                        ttoc(datetime())+" Table "+ m.lcTableName+ ;
>                                        " was opened by another user and therefore was not checked..."+ ;
>                                        +CR+replicate("_",65)+CR
>
>                              endif
>                         endif
>                         llFirstTime=.f.
>                    endif
>               endfor      && End loop for all tables within Database
>               if oValid.lContinue
>                    lcWholeLogStr= m.lcWholeLogStr+  ;
>                         ttoc(datetime())+" Finished checking all tables in "+alltrim(taDBC[m.lni])+CR
>               endif
>               close database
>               lcDBCPath=addbs(justpath(fullpath(forceext(taDBC[lni],'DBC'))))
>               erase (m.lcDBCPath+'*.bak')
>               erase (m.lcDBCPath+'*.tbk')
>          endif
>     endfor     &&   End loop for all selected databases
>     exit
>enddo
>
>Thanks in advance.

Hitting someone with 100 lines of dense code isn't nice :-) Could you rephrase the logic with pseudocode?

IMO, ON ESCAPE should be used only to set a flag (e.g. llUserPressedEscape set to .T.), not branch to another bunch of processing. Doing that has the same effect as EXIT, LOOP or a GOTO.

In complex logic, the action that must be taken on an ESCAPE-type event often differs depending on exactly what was going on at the time. Trying to support that with a global oValid.StopProcess can make it quite complex and hard to debug for all situations.
Regards. Al

"Violence is the last refuge of the incompetent." -- Isaac Asimov
"Never let your sense of morals prevent you from doing what is right." -- Isaac Asimov

Neither a despot, nor a doormat, be

Every app wants to be a database app when it grows up
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform