50
1 4GL Coding Worst Practices aka: The Keyword Forget List According to Tom Tom Bascom, White Star Software Abstract: Just because you CAN-DO() it doesn't mean that you should do it. Programmers are drawn to bad examples likes moths to flame. No matter how many carefully crafted comments you put around that one usage of a special case some programmer will find it and suddenly propagate it throughout your application. Come to this session to learn why CAN-DO(), FIND FIRST, RELEASE and many, many other coding worst practices should be banned! Or at least learn why you should not continue to use these worst practices just because "everyone else always does it that way".

4GL Coding Worst Practices

  • Upload
    others

  • View
    23

  • Download
    1

Embed Size (px)

Citation preview

Page 1: 4GL Coding Worst Practices

1

4GLCodingWorstPracticesaka:TheKeywordForgetListAccordingtoTomTomBascom,WhiteStarSoftwareAbstract:JustbecauseyouCAN-DO()itdoesn'tmeanthatyoushoulddoit.Programmersaredrawntobadexampleslikesmothstoflame.Nomatterhowmanycarefullycraftedcommentsyouputaroundthatoneusageofaspecialcasesomeprogrammerwillfinditandsuddenlypropagateitthroughoutyourapplication.CometothissessiontolearnwhyCAN-DO(),FINDFIRST,RELEASEandmany,manyothercodingworstpracticesshouldbebanned!Oratleastlearnwhyyoushouldnotcontinuetousetheseworstpracticesjustbecause"everyoneelsealwaysdoesitthatway".

Page 2: 4GL Coding Worst Practices

4GLCodingWorstPracticesaka:TheKeywordForgetListAccordingtoTom

TomBascom,[email protected]

Page 3: 4GL Coding Worst Practices

AFewWordsabouttheSpeaker

•  TomBascom:Progressuser&roamingDBAsince1987•  Partner:WhiteStarSoftware&DBAppraise,LLC– ExpertconsultingservicesrelatedtoallaspectsofProgressandOpenEdge.– RemotedatabasemanagementserviceforOpenEdge.– Authorof:– Simplifyingthejobofmanagingandmonitoringtheworld’sbestbusinessapplications.

–  [email protected]

3

Page 4: 4GL Coding Worst Practices

4

Page 5: 4GL Coding Worst Practices

{disclaimer.i}

•  IdonotworkforProgress…•  …andafterthiswecanbeprettysurethatIneverwill;)

•  Thecontentofthissessionisheavilylacedwithopinion!

5

Page 6: 4GL Coding Worst Practices

“Deprecated”=notquite“banned”L

knowledgebase.progress.com/articles/Article/P67734

•  Codewillstill“work”butitisstronglyrecommendedtostartmodifyingyourcode.

•  TechnicalSupportwilldotheirbesttohelp.•  Noescalationswillbeissuedondeprecatedstatementsandclauses.

•  Notguaranteedthatoldcodewithdeprecatedstatementswillstillworkinfuturereleases.

6

Page 7: 4GL Coding Worst Practices

Progress’OfficiallyDeprecatedFeatures

•  UPDATEEDITING•  GO-PENDING•  CHOOSE•  SCROLL•  PUTSCREEN•  IS-ATTR-SPACE•  GATEWAYS•  SQL(withinthe4gl)

7

Page 8: 4GL Coding Worst Practices

Tom’sList!

8

Page 9: 4GL Coding Worst Practices

DOS

•  EvenworsethanWindows!

9

Page 10: 4GL Coding Worst Practices

DOS

•  EvenworsethanWindows!•  AndUNIXandVMSandBTOSforthatmatter•  ThesestatementsbindyourcodetoaparticularOS.•  Yourcodeislessflexibleandmorebrittle…•  InsteaduseOS-COMMANDVALUE(cmd)– CMDcanbeastoredinaconfigtable.– PerhapsasatemplatethatyouusewithSUBSTITUTE

10

Page 11: 4GL Coding Worst Practices

OS-COMMAND&SUBSTITUTE

11

ifopsys="unix"thendbaCmd="$DLC/bin/proutil&1-Cdbanalys-Bp10>”+“$PROTOP/dbanalys/&2.dba2>&&1&&”.elsedbaCmd="%DLC%~\bin~\proutil&1-Cdbanalys-Bp10>”“%PROTOP%~\dbanalys~\&2.dba2>&&1&&”.os-commandsilentvalue(substitute(dbaCmd,pdbname(1),ldbname(1))).

Page 12: 4GL Coding Worst Practices

UnquotedFileNames

•  Unfortunately,thiscodeworks:

12

outputtotest.put"hellokitty".

•  IMHOthatshouldbeacompilererror.•  Allowingunquotedfilenamesisabugwaitingtohappen:

definevariabletestascharacterno-undo.test="xyzzy".outputtotest.put"hellokitty".

Page 13: 4GL Coding Worst Practices

CALL

•  Thisistheold“HLC”interface.•  Youhavetorelinkyour_progresexecutabletouseit.•  Thecapabilitiesthatitsupportshavebeenreplacedbytheabilitytocallsharedlibraries,evenonUNIX:

http://dbappraise.com/ppt/shlib.pptx

13

Page 14: 4GL Coding Worst Practices

DEFINEWORK-TABLE(WORKFILE)

•  Pre-datestemp-tablesandprodatasets.•  Noindexes-sosearchesareslow•  Nofancy,modernfeatureslikeREAD-JSONetc.•  LimitedbyavailableRAM•  UngracefulfailureswhenyourunoutofRAM– Sessionscrashes– MaybeeventhewholemachineL

14

Page 15: 4GL Coding Worst Practices

ACCUMULATEetc.

•  Aggregatephrases,ingeneral,aretoocomplexandfinicky.•  AVERAGE,TOTAL,etc.•  IMHOitiseasier,andalotclearer,toexplicitlycreatetheintermediatevariablesanddothecalculations.

•  Muchlesslikelytobemessedupbyamaintenanceprogrammer.

15

Page 16: 4GL Coding Worst Practices

ACCUMULATE

Therearetwowaysofconstructingasoftwaredesign:Onewayistomakeitsosimplethatthereareobviouslynodeficienciesandtheotherwayistomakeitsocomplicatedthattherearenoobviousdeficiencies.

—C.A.R.Hoare,The1980ACMTuringAwardLecture

Debuggingistwiceashardaswritingthecodeinthefirstplace.Therefore,ifyouwritethecodeascleverlyaspossible,youare,bydefinition,notsmartenoughtodebugit.

BrianW.KernighanandP.J.PlaugerinTheElementsofProgrammingStyle.

16

Page 17: 4GL Coding Worst Practices

VALIDATE

•  Validationexpressionshavenousefulnessinmoderncode.Theyapplytoolateinthedataentrycycletobeuseful(validationsareperformedjustbeforedataiswrittentothedb).Don'tusethem.You'reonthewrongpath.

•  Ifyouchangeavalidationexpressionthatchangeisn'tnoticedbycodeuntilyourecompile.

•  Validationexpressionsmadegooddemosbackinthedaybuthaveneverreallybeenusefulforrealcode.

•  Theroleofvalidationexpressionsisbetterfilledbya“rulesengine”(suchasCorticon).

17

Page 18: 4GL Coding Worst Practices

RELEASE

•  Almostalwaysasignthattheprogrammerisconfusedaboutrecordlockingortransactionscopeanddoesnotreaddocumentationverycarefully.

18

Page 19: 4GL Coding Worst Practices

RELEASEStatement

Fromthedocumentation:

Verifies that a record complies with mandatory field and unique index definitions. It clears the record from the buffer and unites it to the database if it has been changed.

19

Page 20: 4GL Coding Worst Practices

RELEASEandRecordLocksmessage"beforefind".pause.findcustomerexclusive-lockwherecust-num=2.displaycust-numnamediscount.message"beforeupdate".pause.updatediscount.message"beforereleasecustomer".pause.releasecustomer.message"afterreleasecustomer".pause.

RECIDTableFlagsUsr----------------------------------3862X63862X63862SL6

Page 21: 4GL Coding Worst Practices

RELEASE…

UseproperrecordandtransactionscopingandyouwillneverneedtouseRELEASE:

21

definebufferupd_custforcustomer.foreachcustomerno-lock:ifcustomer.discount>10thendoFORupd_custtransaction:/*strongscopethe“upd_cust"buffer*/findupd_custexclusive-lockwhereupd_cust.custNum=customer.custNum.upd_cust.discount=10.end.end.

Page 22: 4GL Coding Worst Practices

CAN-DO()

•  Along,longtimeago…•  Therewerenolistmanipulationfunctions.•  LOOKUP,ENTRYetc.wasnotinthe4gl…•  SomeonenoticedthatCAN-DOcouldbesubvertedtoperformthiscommontask:

22

displaycan-do("a,b,c","z").

Page 23: 4GL Coding Worst Practices

CAN-DO…morehistory

•  A*lot*ofcodewascreatedbyaveryearly,verysuccessfulVARusingthistechnique.

•  UnfortunatelyagreatmanyProgressprogrammershavebeenexposedtothatcode.

•  Thatdoesnot,however,makeita“bestpractice”orevena“goodidea”.

•  Atbestitisa“badhabit”.

23

Page 24: 4GL Coding Worst Practices

JustBecauseyouCAN-DO…

…doesn’tmeanthatyouSHOULD-DOUsingasecurityfunctiontoperformstringoperationsismisleading.RatherthanhavingplainEnglishself-documentingcodeyouareabusingafunctiontoachieveapurposethatitwasneverintendedfor.

24

Page 25: 4GL Coding Worst Practices

FromtheKbase…

25

http://knowledgebase.progress.com/articles/Article/P100218

UsingtheCAN-DOfunctionasasubstitutefortheLOOKUPfunctionconstitutesamisuseoftheCAN-DOfunctionandisstronglydiscouraged.

http://knowledgebase.progress.com/articles/Article/000041404

TheCAN-DOfunctionisexplicitlydesignedtomatchuser-idpatterns.Usingitforarbitrarystringcomparisonsisnotintendedandwillprovideundefinedresults.

Page 26: 4GL Coding Worst Practices

CAN-DO()alternative

•  Bad:

•  Good:

26

ifcan-do(‘ME,NH,VT,MA,CT,RI’,‘NH’)=truethen…

iflookup(‘NH’,‘ME,NH,VT,MA,CT,RI’)>0then…

Page 27: 4GL Coding Worst Practices

ButCAN-DO()supportswild-cards!

•  99%ofthoseusesarecoveredwithBEGINS,MATCHESorCOMPARE

•  Butifyoureallyneedit:

27

/*credittoKurtGunderson,PEGJuly232015*/functionmyCANDOreturnslogical(inputtaschar,inputsaschar):return((lookup("*",s)<>0orlookup(t,s)<>0)and(notlookup("!"+t,s)<>0)).endfunction.

Page 28: 4GL Coding Worst Practices

…aboutthose“wild-cards”

•  CAN-DO("a,b,#","#”)returnsfalse!•  CAN-DOusessomemagiccharacters:

.:Matchasinglecharacter*:Matchmultiplecharacters!:Negateamatch#:DistinguishGRANTablevs.non-GRANTablepermissionsinSQL89@:Usedtorepresenttheblankuserid(asofoe11)““:Spacesarenotallowed

•  Otherquirkscouldbeaddedatanytime!

28

Page 29: 4GL Coding Worst Practices

Andifthatallthatwasn’tBadEnough

•  CAN-DO()inaWHEREclause*forces*client-sideselectionandsorting.

29

Page 30: 4GL Coding Worst Practices

CAN-DO()Summary

•  CAN-DOisasecurityfunction!•  Specialcharactersinthedatawillcauseittoproduceunexpectedresults!(akabugs)

•  Becauseitisallaboutuseridsitmustbeevaluatedbytheclient.– SoifitisinaWHEREclauseyouwillhaveatablescan!– CAN-DOcannotandwillnotbeevaluatedserver-side.

30

Page 31: 4GL Coding Worst Practices

OF

•  ImpliedWHEREclause•  Usesa”commonnamesthatareindexedimplyJOIN”convention.•  Obscurestablerelationships.•  LikeVALIDATE,OF“makesagooddemo”.•  Butshouldneverbeusedinreallife.

31

Page 32: 4GL Coding Worst Practices

USE-INDEX

•  OverridesProgress’optimizer:– Youareprobablynotsmarterthanthecompiler*–  Icertainlyamnot.

•  Forcesasingleindextobeused.•  WHEREclausemismatcheswillresultinverypoorperformance.•  OnthebrightsideUSE-INDEXprovidesanordering:– Maynotbeclearorobvious–indexnamingconventionscanbemissing,misleadingorwrong.

– MayconflictwithBYphraseandcauseclientsidesorting.

32*Tryingtooutsmartacompilerdefeatsmuchofthepurposeofusingone.—KernighanandPlauger,TheElementsofProgrammingStyle.

Page 33: 4GL Coding Worst Practices

USE-INDEX…

•  Stillthinkyoushoulduseit?– Proveit!– Usingrealisticandmeaningfultestdata.– Providedetailedandreproducibletestcasesinyourcommentssothatfutureprogrammerswillrecognizeandcelebrateyourbrilliance.

33

Page 34: 4GL Coding Worst Practices

FINDFIRST(andLAST)

•  ReflexiveandautomaticuseoneachandeveryFINDdoesNOTimproveyourcode.

•  ItisNOTa“standard”.•  Norisita“bestpractice”.•  Nordoesit“alwayswork”.

•  Yes,Iknowitisallovertheplaceincertaincodebases.

34

Page 35: 4GL Coding Worst Practices

UniqueFINDs

•  FINDisdesignedtoreturnexactlyoneorzerorecords.•  99.44%ofFINDstatementsshouldbeforUNIQUErecords.•  ThisisoneofProgress’bigadvantagesoverSQL.•  IftheWHEREclausespecifiesauniquerecordthenFIRSTaddsnovalue.

•  Worse–itconfusesthemaintenanceprogrammerbyimplyingthatthere/should/beanorderedresult-set.

35

Page 36: 4GL Coding Worst Practices

UniqueFINDFIRSTperformance•  ItisNOTfaster.•  ItdoesNOT“eliminateacheckforambiguousrecords”.

•  Allofthestatementsabovetakethesametimetorunandhavethesame“logical”impactonthedbengine.

•  Allstatementsexecutethesamenumberof“logicalIOops”(ProTop,PROMONorVST“blockaccess”).

•  Feelfreetotestityourself!

36

FINDFIRSTcustomerNO-LOCK.FINDcustomerNO-LOCKWHEREcustNum=1.FINDFIRSTcustomerNO-LOCKWHEREcustNum=1.

Page 37: 4GL Coding Worst Practices

FasterFINDwithFIRST?

•  ButwhatifFIRSTdoesactuallymakeaqueryfaster?– YouhavenotspecifiedUNIQUEcriteria!– YouaremissinganappropriateindextomatchyourWHEREclause.

– MaybeyourWHEREclauseisn’tdoingwhatyouthinkitshouldbedoing?

37

Page 38: 4GL Coding Worst Practices

FINDFIRSTSlogan

ReturningtheWrongRecordFaster!

Aprogramthatproducesincorrectresultstwiceasfastisinfinitelyslower.

—JohnOsterhout

38

Page 39: 4GL Coding Worst Practices

FINDSECOND?

•  YouusedFINDFIRSTanyway…whatareyoudoingaboutthesecondrecord?

•  Ifthereactuallyisasecondrecordandyouareactuallydoingsomethingwithit:– Howdidyouspecifytheordering?–  Ifyoudon’tcareaboutorder–whatdoesFIRSTmean?– AreyoutreatingitexactlythesameastheFIRSTrecordfroma3NFperspective?– Areyouprocessingtheentireresultset?Whydidn’tyouuseFOREACH?

39

Page 40: 4GL Coding Worst Practices

“ItAlwaysWorks”

•  Thisusuallymeansthattheprogrammerdoesnotwanttodealwith:

MorethanoneCustomerrecordsfoundbyauniqueFIND.(3166)

•  AddingFIRSTwill“makeitgoaway”.•  Italsomakesyourresultispotentiallywrong:– Whatifyouforgotacomponentoftheindex?– Ordidn’tknowthatapreviouslyunusedfeaturehasbeenenabledbytheusers?– Ortheuserssuddenlycreateasecondmagicalrecord?

40

Page 41: 4GL Coding Worst Practices

MagicFIRSTRecords

•  Recordsthatarespecialbyconvention.•  Nospecificattributeidentifiestheusage.•  AclearviolationofThirdNormalForm.

41

findfirstcustomerno-lockwherecustNum>0.displaycustNumnamediscount.defaultDiscount=discount.findfirstcustomerno-lockwherename>"".displaycustNumnamediscount.defaultDiscount=discount.

Page 42: 4GL Coding Worst Practices

FINDFIRSTSummary

•  FINDFIRSTisalmostalwaysasignoflazyprogramming•  Itdoesnotimproveperformance•  Itcancreatebugsandmaskexistingbugs•  Somecodebasesareinfestedwithit–butthereisnoreasontomaketheproblemworsebycontinuingthehabit

Page 43: 4GL Coding Worst Practices

FORFIRST(andLAST)

43

forfirstcustomerno-lockwherediscount>10:leave.end.displaycustNumnamediscount.foreachcustomerno-lockwherediscount>10bydiscount:leave.end.displaycustNumnamediscount.forfirstcustomerno-lockbydiscount:leave.end.displaycustNumnamediscount./*continue…*/

Page 44: 4GL Coding Worst Practices

FORFIRST(continued)

44

definevariableminDiscountasdecimalno-undoinitial99999.definevariableminDiscountCustNumasintegerno-undo.foreachcustomerno-lock:ifdiscount<minDiscountthenassignminDiscount=discountminDiscountCustNum=custNum.end.findcustomerno-lockwherecustNum=minDiscountCustNum.displaycustNumnamediscount./*continue…*/

Page 45: 4GL Coding Worst Practices

FORFIRST(results)

•  Sowhatdoes“FIRST”mean?

45

CustNumNameDiscount──────────────────────────────────────────────1LiftTours35%1067ArmadaleFitness15%1LiftTours35%6FanaticalAthletes0%

Page 46: 4GL Coding Worst Practices

FORFIRST(andLAST)

•  GiventhesameWHEREclause:– FINDonlyeverusesoneindex– FORcouldusemultipleindexes

•  Sortingoccursafterselection.– FIRSTandLASTproduceasinglerecord(thusthereisnothingtosort).– Basedonwhateverindexwaschosen.– BYisanindexselectiontie-breaker–itisnottheprimaryoptimization.– Selectionmightnotmatchyourhopedfororder.

46

Page 47: 4GL Coding Worst Practices

Summary

•  DOSetal•  UnquotedFileNames•  CALL•  DEFINEWORKFILE•  ACCUMULATE&AggregatePhrases•  VALIDATE

•  RELEASE•  CAN-DO•  OF•  USE-INDEX•  FINDFIRST•  FORFIRST

47

Page 48: 4GL Coding Worst Practices

Questions?

48

Page 49: 4GL Coding Worst Practices

SuggestedAdditions?

49

Page 50: 4GL Coding Worst Practices

ThankYou!

50