4GL Coding Worst Practices

Post on 08-Apr-2022

14 views 1 download

transcript

1

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

4GLCodingWorstPracticesaka:TheKeywordForgetListAccordingtoTom

TomBascom,WhiteStarSoftwaretom@wss.com

AFewWordsabouttheSpeaker

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

–  tom@wss.com

3

4

{disclaimer.i}

•  IdonotworkforProgress…•  …andafterthiswecanbeprettysurethatIneverwill;)

•  Thecontentofthissessionisheavilylacedwithopinion!

5

“Deprecated”=notquite“banned”L

knowledgebase.progress.com/articles/Article/P67734

•  Codewillstill“work”butitisstronglyrecommendedtostartmodifyingyourcode.

•  TechnicalSupportwilldotheirbesttohelp.•  Noescalationswillbeissuedondeprecatedstatementsandclauses.

•  Notguaranteedthatoldcodewithdeprecatedstatementswillstillworkinfuturereleases.

6

Progress’OfficiallyDeprecatedFeatures

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

7

Tom’sList!

8

DOS

•  EvenworsethanWindows!

9

DOS

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

10

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))).

UnquotedFileNames

•  Unfortunately,thiscodeworks:

12

outputtotest.put"hellokitty".

•  IMHOthatshouldbeacompilererror.•  Allowingunquotedfilenamesisabugwaitingtohappen:

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

CALL

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

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

13

DEFINEWORK-TABLE(WORKFILE)

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

14

ACCUMULATEetc.

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

•  Muchlesslikelytobemessedupbyamaintenanceprogrammer.

15

ACCUMULATE

Therearetwowaysofconstructingasoftwaredesign:Onewayistomakeitsosimplethatthereareobviouslynodeficienciesandtheotherwayistomakeitsocomplicatedthattherearenoobviousdeficiencies.

—C.A.R.Hoare,The1980ACMTuringAwardLecture

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

BrianW.KernighanandP.J.PlaugerinTheElementsofProgrammingStyle.

16

VALIDATE

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

•  Ifyouchangeavalidationexpressionthatchangeisn'tnoticedbycodeuntilyourecompile.

•  Validationexpressionsmadegooddemosbackinthedaybuthaveneverreallybeenusefulforrealcode.

•  Theroleofvalidationexpressionsisbetterfilledbya“rulesengine”(suchasCorticon).

17

RELEASE

•  Almostalwaysasignthattheprogrammerisconfusedaboutrecordlockingortransactionscopeanddoesnotreaddocumentationverycarefully.

18

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

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

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

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.

CAN-DO()

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

22

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

CAN-DO…morehistory

•  A*lot*ofcodewascreatedbyaveryearly,verysuccessfulVARusingthistechnique.

•  UnfortunatelyagreatmanyProgressprogrammershavebeenexposedtothatcode.

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

•  Atbestitisa“badhabit”.

23

JustBecauseyouCAN-DO…

…doesn’tmeanthatyouSHOULD-DOUsingasecurityfunctiontoperformstringoperationsismisleading.RatherthanhavingplainEnglishself-documentingcodeyouareabusingafunctiontoachieveapurposethatitwasneverintendedfor.

24

FromtheKbase…

25

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

UsingtheCAN-DOfunctionasasubstitutefortheLOOKUPfunctionconstitutesamisuseoftheCAN-DOfunctionandisstronglydiscouraged.

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

TheCAN-DOfunctionisexplicitlydesignedtomatchuser-idpatterns.Usingitforarbitrarystringcomparisonsisnotintendedandwillprovideundefinedresults.

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…

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.

…aboutthose“wild-cards”

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

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

•  Otherquirkscouldbeaddedatanytime!

28

Andifthatallthatwasn’tBadEnough

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

29

CAN-DO()Summary

•  CAN-DOisasecurityfunction!•  Specialcharactersinthedatawillcauseittoproduceunexpectedresults!(akabugs)

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

30

OF

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

31

USE-INDEX

•  OverridesProgress’optimizer:– Youareprobablynotsmarterthanthecompiler*–  Icertainlyamnot.

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

– MayconflictwithBYphraseandcauseclientsidesorting.

32*Tryingtooutsmartacompilerdefeatsmuchofthepurposeofusingone.—KernighanandPlauger,TheElementsofProgrammingStyle.

USE-INDEX…

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

33

FINDFIRST(andLAST)

•  ReflexiveandautomaticuseoneachandeveryFINDdoesNOTimproveyourcode.

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

•  Yes,Iknowitisallovertheplaceincertaincodebases.

34

UniqueFINDs

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

•  Worse–itconfusesthemaintenanceprogrammerbyimplyingthatthere/should/beanorderedresult-set.

35

UniqueFINDFIRSTperformance•  ItisNOTfaster.•  ItdoesNOT“eliminateacheckforambiguousrecords”.

•  Allofthestatementsabovetakethesametimetorunandhavethesame“logical”impactonthedbengine.

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

•  Feelfreetotestityourself!

36

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

FasterFINDwithFIRST?

•  ButwhatifFIRSTdoesactuallymakeaqueryfaster?– YouhavenotspecifiedUNIQUEcriteria!– YouaremissinganappropriateindextomatchyourWHEREclause.

– MaybeyourWHEREclauseisn’tdoingwhatyouthinkitshouldbedoing?

37

FINDFIRSTSlogan

ReturningtheWrongRecordFaster!

Aprogramthatproducesincorrectresultstwiceasfastisinfinitelyslower.

—JohnOsterhout

38

FINDSECOND?

•  YouusedFINDFIRSTanyway…whatareyoudoingaboutthesecondrecord?

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

39

“ItAlwaysWorks”

•  Thisusuallymeansthattheprogrammerdoesnotwanttodealwith:

MorethanoneCustomerrecordsfoundbyauniqueFIND.(3166)

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

40

MagicFIRSTRecords

•  Recordsthatarespecialbyconvention.•  Nospecificattributeidentifiestheusage.•  AclearviolationofThirdNormalForm.

41

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

FINDFIRSTSummary

•  FINDFIRSTisalmostalwaysasignoflazyprogramming•  Itdoesnotimproveperformance•  Itcancreatebugsandmaskexistingbugs•  Somecodebasesareinfestedwithit–butthereisnoreasontomaketheproblemworsebycontinuingthehabit

FORFIRST(andLAST)

43

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

FORFIRST(continued)

44

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

FORFIRST(results)

•  Sowhatdoes“FIRST”mean?

45

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

FORFIRST(andLAST)

•  GiventhesameWHEREclause:– FINDonlyeverusesoneindex– FORcouldusemultipleindexes

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

46

Summary

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

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

47

Questions?

48

SuggestedAdditions?

49

ThankYou!

50