HyperWork 2024 -二次开发-Tcl语言-Namespaces(10/12)
NamespacesprovideameansoforganizingproceduresandvariablesinTcl.Anamespacebasicallycreatesauniquelocalscope.Withineachuniquescope,variablesandprocedurescreatedinthatscopeareisolatedfromboththeglobalscopeandfromotherscopes.Thisallowsthedeveloperameanstosegregateproceduresandvariablesinanorganizedmanner.Namespacescanbenested,andproceduresandvariablescanbeimportedto,exportedfrom,andreferencedinothernamespacesortheglobalscope.Thefollowingdiagramshowsavisualrepresentationoftheglobalscopeandseveraldifferentnamespaces,includingvariablesandproceduresdefinedineach.AglobalprocedureactsjustlikeanyfunctionwithinTcl.Aglobalprocedurecanbecalledfromanamespacewithoutanyneedtoimportorotherwiselocalizetheprocedure.Aprocedurewithinanamespaceislocaltothenamespaceunlessitisexplicitlycalledortheprocedureisexportedfromthenamespace.Theglobalscopeisalsodesignedsuchthatanyvariablesdefinedoutsideofaprocedureoranamespaceareautomaticallyintheglobalscope.Toaccessaglobalvariableinalocalscope,suchasaprocedureornamespace,youwillneedtousetheglobalcommand.Asascriptgrowsandasthenumberofscriptsrunningsimultaneouslyincreases,theabilityofthedevelopertoavoidconflictbetweenthenamesofproceduresandvariablesdefinedintheglobalscopedecreases.ThefollowingTclcodedemonstrateshowtheglobalcommandpermitsaccesstoglobalvariablesinalocalscope.setf"Thisisaglobalvariable";#Thisprocedurecannotaccesstheglobalvariablef.proctestproc1{}{catch{puts$f}val;puts$val;}#Thisprocedurecanaccesstheglobalvariablefusingtheglobalcommand.proctestproc2{}{globalf;catch{puts$f}val;puts$val;}testproc1;can'tread"f":nosuchvariabletestproc2;ThisisaglobalvariableLikewise,anyvariabledeclaredasglobalfromwithintheprocedurewherethevariableisdefinedisalsoincludedintheglobalscope,oncetheprocedurehasbeenrun.Anyattempttoaccessthevariablebeforerunningtheprocedurewillcauseanerror.Theupvarcommandcanbeusedtochangetheavailabilityofavariablebyprovidingapointertothesourcevariable’scontents.Namespacesaddanotherlevelofsyntaxtoprocedureandvariablenames.Adoublecolon::istheseparatorbetweennamespacenamesandprocedure/variablenames.Anexampleofanamespacecalledmy_namespacewouldbe::my_namespace.Theglobalnamespaceindicatorisjustthedoublecolon.Thismeansthatinsteadofusingtheglobalcommand,itisalsopossibletoreferenceglobalvariablesinsideproceduresusingtheglobalnamespaceindicator.set::element_list"12345";proc::element_info{}{puts$::element_list;set::node_list"10203040";puts$::node_list;}element_info;1234510203040puts$::element_list;12345puts$::node_list;10203040However,usingglobalvariablesisriskybecausetheymayconflictwithvariablesorproceduresdefinedintheglobalscopeofotherTclscripts.Instead,user-definednamespacesarerecommended.Thefollowingtablecontainssomecommonlyusednamespacecommandsandasummaryoftheirusage.Formorein-depthexplanationsandacompletelisting,referredtohttp://www.tcl.tk/man/ortoaTcl/Tkhandbook.namespaceevalnameUsedtodefineanamespaceortoruncommandsinsideanamespace.namespacecurrentReturnsthequalifiednameofthecurrentnamespace.namespacedeleteDeletesandexistingnamespace.namespaceexistsCheckfortheexistenceofanamespace.variableUsedtodefine,andoptionallyassignavalueto,avariablewithinanamespace.ThevariablecommandcanbeusedtosharevariablesbetweenproceduresandthemainbodyoftheTclscript.namespaceeval::my_namespace{variableelement_list"12345";}proc::my_namespace::element_info{}{variableelement_list;puts$element_list;variablenode_list"10203040";puts$::node_list;}::my_namespace::element_info;1234510203040puts$::my_namespace::element_list;12345puts$::my_namespace::node_list;10203040Thefollowingcodegivesexamplesofhowvariablesandprocedurescanbemanipulatedfromnamespaces,procedures,andtheglobalscope.#Scriptbegins.#Defineavariableintheglobalscope.setf"Thisisaglobalvariable";#Thisglobalprocedurewillgenerateanerrorbecausethe#globalvariablefisnotinthescope.proctestproc1{}{catch{puts$f}g;puts$g;}#Thisprocedurewillnotgenerateanerrorbecausethe#globalvariablefislocalizedwiththeglobalcommand.proctestproc2{}{globalf;catch{puts$f}g;puts$g;}#Acalltodeletethenamespaceclearsvariableswithin#thatnamespace.catch{namespacedelete::testspace};#Thenamespaceevalcommandcreatesanewnamespace.namespaceeval::testspace{variablefg"Thisisanamespacevariable";#Exportasingleprocedureforuselater.namespaceexporttproc3}#Procedurescanbeorganizedintonamespaces.proc::testspace::tproc1{}{#Globalproceduresdonotrequireanamespaceindicator.testproc1;testproc2;#Procedureswithinthesamescopedonotrequirea#namespaceindicator.tproc2;tproc3;#Proceduresfromothernamespacesmustbeexplicitlydeclared#unlessanamespaceimportisused.catch{oproc1}ds;puts$ds;::otherspace::oproc1;}#Thisnamespaceprocedurewillgenerateanerrorbecausethe#namespacevariableisnotinthescope.proc::testspace::tproc2{}{#Thecatchcommandisusedtopreventthescriptfrom#exitingwithanerror.catch{puts$fg}g;puts$g;}#Thisnamespaceprocedurewillnotgenerateanerrorbecausethe#namespacevariableislocalized.proc::testspace::tproc3{}{#Thevariablecommand,ifreferringtoanexisting#namespacevariableandnotmakinganassignment,#allowslocalaccesstothevariable.variablefg;catch{puts$fg}g;puts$g;}#Acalltodeletethenamespaceclearsvariableswithin#thatnamespace.catch{namespacedelete::otherspace};#Creatingasecondnamespace.namespaceeval::otherspace{variablefh"Thisisadifferentnamespacevariable";}proc::otherspace::oproc1{}{#Thenamespaceimportcommandcanbeusedto#localizeprocedures.namespaceimport::testspace::tproc3;variablefh;catch{puts$fh}h;puts$h;tproc3;#namespaceoriginreturnsoriginalnamespaceoftheproc.puts[namespaceorigintproc3];}#Runtheprimaryprocedure::testspace::tproc1Runningthesecommandsgeneratesthefollowingoutput.Someproceduresarecalledmorethanonce,sopaycloseattentiontowheretheprocedurecallismade.can'tread"f":nosuchvariableThisisaglobalvariablecan'tread"fg":nosuchvariableThisisanamespacevariableinvalidcommandname"oproc1"ThisisadifferentnamespacevariableThisisanamespacevariable::testspace::tproc3来源:TodayCAEer