PatternsforbuildingexcellentexamplesIssue3.2
Patternsforbuildingexcellentexamples
PracticingRubyIssue3.2::PublishedbyGregoryBrownonJanuary10,2012
GoodcodeexamplesarethesecretsaucethatmakesPracticingRubyahighqualitylearningresource.
Thatsaid,theartofbuildingexcellentexamplesisonethatIthinkallprogrammersshouldpractice,
notjustthosefolksouttheretryingtoteachforaliving.Theabilitytoexpressideasclearlythrough
wellfocusedsnippetsofcodeiskeytowritinggoodtests,documentation,bugreports,codereviews,
demonstrations,andawholelotofotherstuff,too.
Inthisarticle,I'veidentifiedfivepatternsIuseforexpressingideasthroughcodeexamples.These
techniquesrunthegamutfrombuildingcontrived"HelloWorld"programstocraftingfullscale
sampleapplicationsusingaliterateprogrammingstyle.Eachtechniquehasitsownstrengthsand
weaknesses,andI'vedonewhatIcouldtooutlinethemwherepossible.
Althoughthisisn'tnecessarilyacomprehensivelist,itcanhelpyoustarttoimprovethewayyouwrite
yourexamplesandalsoservesasagoodjumpingoffpointforfurtherdiscussiononthetopic.
Contrivedexamples
Foranygivenprogramminglanguageorsoftwarelibrary,theoddsareprettygoodthatthefirst
exampleyou'llrunisacontrived"HelloWorld"program.Thefollowingexampleistakenfromthe
Sinatrawebframeworkbutissimilarinspirittoprettymucheveryother"HelloWorld"application
outthere:
Thiskindofexampleseemsquiteuselessonthesurfaceandisneitherinterestingnoreducational.As
itturnsout,thesecharacteristicsarepreciselywhatmakethis"HelloWorld"programperfect!The
contrivednatureoftheexampleallowsittoserveasasimplesanitycheckforsomeonewhoistrying
outSinatraforthefirsttime.
Ifyoutrytorunthisexampleandfindthatitdoesn'tworkcorrectly,thereareonlyafewpossible
pointsoffailure.Inmostcases,notevengettinga"HelloWorld"programtoruncorrectlycanbe
blamedononeofthreethings:outofdatedocumentation,issueswithyourenvironment,orusererror.
Thefactthatthereareveryfewmovingpartsmakesitmucheasierforyoutodeterminethesourceof
https://practicingruby.com/articles/patternsforbuildingexcellentexamples
1/9
12/14/2015
PatternsforbuildingexcellentexamplesIssue3.2
yourproblemthanitwouldbeiftheexampleweresignificantlymorecomplex.Thiseaseof
debuggingispreciselywhymostintroductorytutorialsstartoffwitha"HelloWorld"programrather
thansomethingmoreexciting.
Althoughthemostcommonusecaseforcontrivedexamplesistoconstruct"HelloWorld"
applications,thereareotherusecasesforthistechniqueaswell.Inparticular,contrivedexamplesare
agoodfitfordiscussionsaboutsyntacticorstructuraldifferencesbetweentwopiecesofcode.Asan
example,considerashorttutorialthatexplainswhyausermightwanttouseRuby's
functionality.Itcouldstartbyshowingaclassthatimplementsaccessorsexplicitly:
Afollowupexamplecouldthenbeprovidedtoshowhowtosimplifythecodevia:
Thisscenarioisverysimplisticwhencomparedtotheclassdefinitionswewriteinrealprojects,but
theabsenceofcomplicatedfunctionalitymakesiteasierforthereadertofocusonthesyntactic
differencesbetweenthetwoexamples.ItalsoallowsthenoviceRubyprogrammertothinkofthe
differencebetweenexplicitlydefiningaccessorsandusingasasimplestructural
transformationratherthansomethingwithcomplexsemanticdifferences.Althoughthismentalmodel
isnot100percentaccurate,itemphasizesthebigpicture,whichiswhatactuallymattersforanovice
programmer.Thesimplicityoftheseexamplesmakesthegeneralpatternmucheasiertoremember,
whichjustifieshidingafewthingsbehindthecurtaintoberevealedlater.
Unfortunately,theabilityofcontrivedexamplestohidethesemanticsofourprogrammingconstructs
isjustasoftenadrawbackasitisanasset.Themorecomplexaconceptis,themoredangerousitisto
presentsimplisticexamplesratherthanworkingthroughmorerealisticscenarios.Forexample,itis
commonforobjectorientedprogrammingtutorialstouserealworldobjectsandhierarchiesto
explainhowclassinheritanceworks,butthedisconnectbetweenthesemodelsandthekindsthatreal
softwareprojectsimplementissogreatthatthisapproachcompletelyobfuscatestherealpowerand
purposeofobjectorientedprogramming.Bychoosingascenariothatmayfeelnaturaltothereader
butdoesnotfitnaturallywiththeunderlyingprogrammingconstructs,thissortoftutorialfailsto
emphasizetherightdetailsandleavesthedooropenforawiderangeofmisconceptions.These
incorrectassumptionsendupgettinginthewayoflearningrealobjectorientedprogramming
techniquesratherthanhelpingdevelopanunderstandingofthem.
Icouldeasilyrantonthistopic,butsomeoneelsediditformebywritingagreatmailinglistpost
https://practicingruby.com/articles/patternsforbuildingexcellentexamples
2/9
12/14/2015
PatternsforbuildingexcellentexamplesIssue3.2
entitledGoodbye,shittyCarextendsVehicleobjectorientationtutorial.Despitethesomewhat
inflammatorytitle,itisaveryinsightfulpost,andIstronglyrecommendreadingitifyouwanttosee
astrongargumentforthelimitationsofcontrivedexamplesasteachingtools.
Figuringoutwheretodrawthelinebetweenwhenitisappropriatetouseacontrivedexampleand
whentouseonethatisbasedonapracticalapplicationistricky.Ingeneral,Itrytokeepinmindthat
thepurposeofacontrivedexampleisspecificallytoremovecontextfromthepicture.Outsideof
"HelloWorld"programsandsimplesyntactictransformations,alackofcontexthurtsmorethanit
helps,andsoItrytoavoidcontrivedexamplesasmuchasIcanforprettymucheveryotherusecase.
Cheapcounterfeits
Oneofmyfavoritetechniquesforteachingprogrammingconceptsistoconstructcheapcounterfeits
thatemulatethesurfacelevelbehaviorofamorecomplicatedstructure.These"poorman's
implementations"aresimilartocontrivedexamplesinthattheycanhideasmuchcomplexityasthey'd
likefromthereaderbut,becausetheyaregroundedbysomerealisticscenario,donotsufferfrom
beingtotallydisconnectedfrompracticalapplications.
IhaveusedthistechniqueextensivelythroughoutPracticingRubyandmyotherwrittenworks,andit
almostalwaysworksoutwell.Infact,theissueonImplementingEnumerableandEnumeratorin
RubywasentirelybasedonthisstrategyandturnedouttobeoneofthemostpopulararticlesI've
writtenforthisjournal.Althoughyouareprobablyalreadyveryfamiliarwiththispatternasa
PracticingRubyreader,Icanstillprovideabitofextrainsightbydecomposingitforyou.
Thepurposeofbuildingacheapcounterfeitisnottogainadeepunderstandingofhowacertain
constructactuallyworks.Instead,thepurposeofacounterfeitistoteachpeoplehowtostealideas
fromotherinterestingbitsofcodefortheirownneeds.Forexample,taketheprevious
example:
Thisisagreatfeature,becauseitreplacestediousboilerplatemethodswithaconcisedeclarative
statement.Butwithoutsomesortofexplanationastohowitworks,feelsprettymagical
andmightbeperceivedasaspecialcasethattheRubyinternalsareresponsibleforhandling.This
misconceptioncaneasilybeclearedupbyshowinghowtoimplementacheapcounterfeitversionof
inapplicationcode:
https://practicingruby.com/articles/patternsforbuildingexcellentexamples
3/9
12/14/2015
PatternsforbuildingexcellentexamplesIssue3.2
Ifteachingprogrammershowtouseisliketreatingthemtoanicefishdinner,teaching
themhowtoimplementitislikegivingthemafishingpoleandshowingthemhowtocatchtheirown
meals.Seeingapracticaluseofopensthedoorsforahugerangeofotherapplications,
allofwhichhingeonthesimpleconceptofdynamicmethoddefinition.Forexample,asimilar
techniquecouldbeusedtoconverthideousmethodnameslike
intotheelegantsyntaxshownhere:
Therearecountlessotherapplicationsofdynamicmethoddefinition,manyofwhichIexpect
PracticingRubyreadersarealreadyfamiliarwith.Thepointhereisthatasingleexamplethat
demystifiesacertaintechniquecanmakeahugedifferenceinwhatpossibilitiessomeoneseesina
givensystem.Thispayoffiswhatmakescheapcounterfeitssuchatremendouslygoodteachingtool.
Animportantthingtokeepinmind,however,isthatthistechniqueisusefulmostlyforteaching
concepts,asopposedtoshowingsomeonehowafeatureisreallyimplemented.Ifyouactuallylook
intotheimplementationof,you'llfindanumberofedgecasesthatthischeapcounterfeit
exampledoesnottakeintoconsideration.Althoughthesesubtletiesarenotespeciallyrelevantif
you'rejusttryingtogiveacontextualizedexampleofhowcanbeused,theywouldbe
importanttopointoutifyouweretryingtowriteaspecificationforhowismeantto
work,whichiswhycheapcounterfeitsarenotasubstituteforcasestudiesofrealcodebutinstead
serveadifferentpurposeentirely.
Simplifiedexamples
Diggingdirectlyintothesourcecodeofaprojectisthemostdirectwaytounderstandhowitsfeatures
areimplemented,butitcanbeasomewhatdisorientingprocess.Productioncodeinallbutthemost
trivialprojectstendstoaccumulateedgecases,errorcheckingcode,andotherbitsofcruftthatmake
ithardertoseewhatthecoreideasare.Whengivingatalkabouthowsomethingisimplementedor
writingdocumentationforpotentialcontributors,itissometimeshelpfultoprovidesimplified
examplesthatdemonstratethekeyfunctionalitywhileminimizingdistractions.
SupposeIwanttodoalightningtalkabouthowMiniTestisimplemented,withthegoalofattracting
newcontributorstotheproject.Inatalklikethat,I'ddefinitelyneedtodiscussabitabouthow
assertionswork.Alogicalplacetostartmightbethemethod:
TheimplementationofissimpleenoughthatIcouldprobablyshowitasiswithoutlosingmy
audience.ButifIkeepinmindthatthiscodeisgoingtobeshownonaslideforjustafewseconds,I
mightshowthefollowingsimplifiedexampleinstead:
https://practicingruby.com/articles/patternsforbuildingexcellentexamples
4/9
12/14/2015
PatternsforbuildingexcellentexamplesIssue3.2
Thiscodeomitssomeimplementationdetails,butitpreservesthemainidea,whichisthatMiniTest's
assertionsworkbyraisinganexceptionwhenatestfails.Thefactthatiswherethenumberof
assertionsiscountedisfairlyobviousandonlyaddsnoisewhenyouwanttogetaroughideaforhow
thecodeworksataglance.Likewise,thefactthatamessagecanbepassedinasaobjectrather
thanastringisaninterestingbutobscureedgecasethatdoesnotneedtobeemphasized.Byremoving
thesetwostatementsfromthemethoddefinition,thecorebehavioriseasiertonotice.
Theprocessofcreatingasimplifiedexamplestartswithlookingattheoriginalsourcecodeandthen
determiningwhichdetailsareessentialtoexpressingtheideayouwanttoexpressandwhichdetails
canbeconsideredbackgroundnoise.Thenextstepistoconstructanexamplethatservesasa
functionalsubsetoftheoriginalimplementationwhenusedwithinacertaincontext.Youdon'twantto
deviatetoomuchfromtheoriginalidea,butyoucancleanupthesyntaxabitwhereappropriateto
maketheexampleeasiertounderstand.Fromthere,youcantreattheexampleasasubstituteforthe
realimplementationforthepurposesofdemonstrationyoujustneedtomakesuretopointoutthat
youhavesimplifiedthingsabit.
WiththisMiniTestexample,thesimplifiedversionofthecodeisonlyslightlylesscomplicatedthan
theoriginal,sothebenefitsofusingthistechniqueareabitsubdued.Inpractice,you'remuchmore
likelytorunintosituationsinwhichtherearedozensoflinesofimplementationcodebutonlya
handfulofthemarecentraltotheideathatyouaretryingtoexpress.Inthosesituations,thispatternis
especiallyeffectiveatcuttingthroughthecrufttogetattherealmeatoftheproblemyouwantto
focuson.However,it'sworthkeepinginmindthatevenrelativelysmallandeasytounderstand
chunksofcodecanbesimplifiediftheyhappentoincludestatementsthatarenotdirectlyrelevantto
thepointyouaretryingtomake.
Reducedexamples
Areducedexampleisonethatreproducesacertainbehaviorinthemostsimplepossibleway.This
techniqueismostcommonlyusedforputtingtogetherbugreportsandisoneofthemostimportant
skillsyoucanhaveasasoftwaredeveloper.
IntheRubyBestPracticesbook,ItoldastoryaboutabugthatwasspottedinPrawnandhowwe
reducedtheoriginalreporttosomethingmuchmoresimpleinordertodiscovertherootcauseofthe
problem.BecausethisisstillthebestexampleI'vefoundofthisprocessinaction,I'llsummarizethat
storyhereratherthantellinganewone.
Adevelopersentusthefollowingbugreporttodemonstratethatourcodeforgeneratingfixedwidth
columnsoftexthadaproblemthatwascausingpagebreakstobeinsertedunnecessarily:
https://practicingruby.com/articles/patternsforbuildingexcellentexamples
5/9
12/14/2015
PatternsforbuildingexcellentexamplesIssue3.2
Inthisexample,heexpectedallofhistexttoberenderedononepageandwastryingtoshowthat
eachtimeheusedtheconstruct,anunnecessarypagebreakwascreated.Heshowedthatthiswas
thecasebothwithinthedefaultpageboundariesandwithinamanuallyspecifiedboundingbox.As
farasuserreportsgo,thisexamplewasprettygood,becauseitwasspecificallydesignedtoshowthe
problemhewashavingandwasclearlynotjustsomebrokenproductioncodethathewantedhelp
with.
Thathavingbeensaid,anunderstandingofhowPrawnworksunderthehoodmadeitpossibleto
simplifythisexamplequiteabit,evenbeforeinvestigatingfurther.Becausethedefaultpage
boundariesinPrawnareimplementedintermsofboundingboxesandthemethodjust
temporarilyswapsthosedimensionswithnewones,thesecondpartofthisreportwassuperfluous.
Removingitgotthereproduciblesampledowntotheexampleshownhere:
Inmakingthisreduction,Ialsodidsomeotherminorcleanupchoressuchasreworkingthetexttobe
selfdocumentingandremovingtheoptionfor,becauseitdidn'taffectthe
outcome.Atthispoint,evensomeonewithoutexperienceinhowPrawnworkswouldbeabletomore
easilyspottheproblemintheexample.
Althoughisnotatrivialconstruct,ithadonlytwopossiblepointsoffailure:the
methodandthemethod.Becauseisfundamentaltoprettymucheverything
Prawndoesandwehadplentyofevidencethatitwasworkingasexpected,weturnedourattentionto
.
Thepurposeofistoexecutethecontentsofablockwhileignoringalldocumentmarginsand
boundingboxesinplace,essentiallyconvertingeverythingtoabsolutecoordinatesonthepage.After
theblockisexecuted,itissupposedtokeepthetextpointerwhereveritleftoff,whichmeansthatit
shouldnottriggerapagebreakunlessthetextflowsbeyondthebottomofthepage.Totestthis
behavior,wecodedupthefollowingexample:
Afterrunningthisexample,wenoticedthatitexhibitedthesamedefectthatwesawintheuser'sbug
report.BecausethismethodisalmostasdeepdownthePrawncallchainasyoucango,itbecame
clearthatatthispointwehadourreducedexample.Thebenefitofdrillingdownlikethisbecame
apparentwhenweconvertedoursamplecodeintoaregressiontest:
https://practicingruby.com/articles/patternsforbuildingexcellentexamples
6/9
12/14/2015
PatternsforbuildingexcellentexamplesIssue3.2
Afterseeingthistestfailandapplyingaquickpatchthatgotittogogreen,wewentbackandranthe
originalbugreporttheuserprovideduswith.Aspredicted,thebadbehaviorwentawayandthings
wereonceagainworkingasexpected.
Thebenefitsofreducingtheexamplebeforewritingaregressiontestweretremendous.Notonlywas
thetesteasiertowrite,butitalsoendedupcapturingtheproblematamuchlowerlevelthanitwould
haveifweimmediatelysetinwithcodifyingthebugreportasaunittest.Inadditiontothesebenefits,
thereductionprocessitselfgreatlysimplifiedthedebuggingprocess,asitallowedustoproceed
methodicallytofindtherootoftheproblem.
I'vemostlyusedthisreductiontechniquewhiledebugging,butitcanalsobeausefulwaytofindyour
wayaroundacomplexcodebase.Bystartingwithapracticalexamplethatexercisesthesystemfrom
theoutermostlayer,youcandrilldownintothecodeandtraceyourwaythroughthecallchainsto
findhowsomeparticularaspectofthesoftwareworks.Althoughthisisalessdirectapproachthan
justreadingthedocumentation,itwillgiveyouabetterfundamentalunderstandingofhowthesystem
hangstogether,andit'safunwaytopracticecodereading.
Whetheryouareexploringanewcodebaseortrackingdownabug,thereductionprocesslimitsthe
scopeofthethingsyouneedtothinkabout,allowingyoutodedicateyourattentioninamorefocused
way.Thiseffectissomewhatsimilartowhatwefindwhenwemakeuseofsimplifiedexamplesbutis
moreofadrillingdownprocessthanitisapruningprocess.Bothhavetheirmerits,andtheycaneven
beusedincombinationattimes.
Sampleapplications
AlthoughallofthetechniquesI'vediscussedsofarcanbequiteusefulforstudying,investigating,and
teachingaboutspecificissues,noneofthemareparticularlysuitablefordemonstratingbigpicture
topics.Whenyouwanttoemphasizehowthingscometogether,asopposedtohoweachindividual
partworks,nothingbeatsthecombinationofasampleapplicationwithagoodwalkthroughtutorial.
SeveralissuesfromPracticingRubyVolume2madeuseofthisformatandwereverywellreceived
bythereadershere.
InLearningnewthingsstepbystep,Ibuiltasmallgameforthepurposeofdemonstratinghowto
developsoftwareintinybitesizedchunks.Thenicethingaboutthisapproachisthatitallowsthe
readertofollowalongathome(eithermentallyorbyliterallyrunningthecodethemselves),while
proceedingattheirownpace.Ihopeitalsoencouragesfolkstoexperimentanddrawtheirown
conclusionsratherthanjustrigidlyfollowingapredefinedscript.
InBuildingUnixstylecommandlineapplications,ItackledthecreationofaRubycloneoftheUnix
utilitybyfocusingondistinctareasoffunctionality,oneatatime.Thisisaslightlylesslinear
formatthanthestepbystepapproachofthegamedevelopmentarticle,butitallowsreaderstolookat
thecompleteapplicationfromseveraldifferentangles,dependingonthetopicsthatinterestedthem
most.
Finally,inDesigningbusinessreportingapplications,Itotallybreakawayfromlinearitybypresenting
https://practicingruby.com/articles/patternsforbuildingexcellentexamples
7/9
12/14/2015
PatternsforbuildingexcellentexamplesIssue3.2
thesourcecodeofafullapplicationinliterateprogrammingstyle.Thisapproachallowsreadersto
studytherealimplementationcodeandmycommentarysidebysideandtobouncearoundastheysee
fit.Thislackofexplicitstructureencouragesreaderstoexploreinafreeformfashionratherthan
focusingonsomepredefinedareasofinterests.
AlthoughthesearticlesweresomeofthemostsuccessfulonesthatI'vepublishedhereatPracticing
Ruby,theywerealsoamongthemostchallengingtowrite.Ihadtoapplyamuchhigherstandardof
writingclearandconcisecodethanIwouldifIweresimplytryingtomakeaprojecteasyenoughfor
metomaintainonmyown.Theprosewastrickytoorganize,becauseit'shardtodecidewhichareas
toemphasizeandwhichtoglossoverinacompleteapplication.Forthesereasons,sample
applicationscanbeacumbersomeandtimeconsuminglearningresourcetoproduce.However,the
investmentseemstobewellworthitintheend.
Reflections
Writinggoodexamplescanbeseriouslyhardwork.Thisiswhyalltoooftenweseepeopleoverusing
contrivedexamplesorsimplyattemptingtopassoffunrefinedsnippetsofproductioncodeaslearning
materials.However,codeexamplesinalloftheirmyriadformslaythefoundationforhowwe
communicateourideasassoftwaredevelopers.
Animportantthingtorememberwhenwritingcodeexamplesisthattheprocessisinmanyways
similartowritingprose.Ifwesimplyspitoutabraindumpwithoutthinkingabouthowitwillbe
interpretedandunderstoodbyothers,wewillendupwithcrappyresults.Butifwerememberthatthe
maingoalofwritingourexamplesistocommunicateanideatoourfellowprogrammers,wenaturally
begintoaskthequestionsthatleadustoimproveourwork.
Ihopethatbysharingthesefewpatternswithyou,I'vegivenyousomeusefulideasforhowto
improveyourcodecommunicationskills.FollowingthepatternsI'veoutlinedherewillleadyouto
writingbetterexamplesforyourdocumentation,bugreports,unittests,tutorials,andquiteafewother
thingsaswell.
ThoughthetechniquesI'veshownhereareonesthatworkwellinawiderangeofcontexts,Iamsure
thereareotherapproachesworthlearningabout.Ifyou'veseenanoveluseofcodeexamplesinthe
wild,pleaseletmeknow!I'dalsobehappytohearanyotherthoughtsyouhaveonthistopic,andI
wouldn'tmindhelpingafewfolkscomeupwithgoodexamplesfortheprojectsthey'reworkingon.If
you'vegotsomethingyouwantmetotakealookat,justleaveacommentandI'llbesuretogetback
toyou.
Follow@practicingdev
https://practicingruby.com/articles/patternsforbuildingexcellentexamples
Tweet
8/9
12/14/2015
PatternsforbuildingexcellentexamplesIssue3.2
https://practicingruby.com/articles/patternsforbuildingexcellentexamples
9/9