Tải bản đầy đủ - 0 (trang)
Chapter 13. Does This Job Require a Reference?

Chapter 13. Does This Job Require a Reference?

Tải bản đầy đủ - 0trang

variablethatactuallyholdsthevalueisunawareofthem.

Asymbolicreferencenamesanothervariableratherthanjust

pointingtoavalue.[2]Typeglobs,variablenamesprecededby*,

areakindofsymbolicreference.Theyarealiases.

[2]



Wall,L.,ProgrammingPerl,O'Reilly&Associates:Sebastopol,CA,1996,p.

244.



Youmayrememberusingtypeglobsinpreviousexamples.In

Chapter11,wediscussedhowtypeglobswereusedintheearly

daysofPerltopassargumentstosubroutinesbyreference.In

Chapter12,typeglobswereusedtoimportsymbolsontothe

symboltableofapackage.Thefollowingstatementuses

typeglobs:



*town=*city;#Anytypecalledcitycanalsobereferenced

Theasteriskrepresentsallofthefunnycharactersthatprefix

variables,includingsubroutines,filehandles,andformats;i.e.,it

"globs"ontoallthesymbolsinthesymboltablethathavethat

name.[3]*townisanaliasfor*city.Itisyourjobtodetermine

whatsymbolyouwantthealiastoreference.Thisisdoneby

prependingthecorrectfunnycharactertothealiasnamewhen

youwanttoaccessitsunderlyingvalue.Forexample:

[3]Thisisnotthesameastheglobbingdoneforfilenamesubstitution,asin



.



Given: *town=*city

Then: $townreferstothescalar$city

@townreferstothearray@city

$town{"mayor"}referstoanelement

ofahash$city{"mayor"}



Example13.1demonstratesanothertypeofsymbolicreference

wherethevalueofonevariablereferencesthenameofanother

variable.

Example13.1.



#!/bin/perl

#Programusingsymbolicreferences

1$animal="dog";

2$dog="Lady";

3print"Yourdogiscalled${$animal}\n";#Symbolicreferenc

4eval"\$$animal='Lassie';";

5print"Whydon'tyoucallher${$animal}?\n";

(Output)

3YourdogiscalledLady

5Whydon'tyoucallherLassie?



Explanation

1. Thescalar$animalisassignedthevalue"dog".Thename

animalisstoredinthesymboltablealongwithareference

toitsvaluedog.

2. Thescalar$dogisassignedthestring"Lady".

3. Thevariable${$animal}evaluatestoLady.Thisisa

symbolicreference.$animal,onevariable,isevaluatedto

dog.Theseconddollarsigncausesanothervariable,$dog,

tobeevaluatedtoitsunderlyingvalue,"Lady".One

variablehasreferencedanother.

4. Theevalfunctionevaluatesthestatementasifina

separatelittlePerlprogram.Thefirstdollarsignis

escaped.$animalwillbeevaluatedtoitsvalue,dog.The

literaldollarsign,prependedtotheresultofthe

evaluation,leaves$dog="Lassie"asthestatement.

5. Aftertheeval,thevalueof${$animal};i.e.,$dogis

"Lassie".Itisprinted.



ThestrictPragma

Toprotectyourselffrominadvertentlyusingsymbolicreferences

inaprogram,usethestrictpragmawiththerefsargument.

ThiscausesPerltocheckthatsymbolicreferencesarenotused

intheprogram.Here,wereexecutethepreviousexampleusing

thestrictpragma.

Example13.2.

#!/bin/perl

#Programusingsymbolicreferences

1usestrict"refs";

2$animal="dog";



3$dog="Lady";

4print"Yourdogiscalled${$animal}\n";

5eval"\$$animal='Lassie';";

6print"Whydon'tyoucallher${$animal}?\n";



(Output)

Can'tusestring("dog")asaSCALARrefwhile"strictrefs"in

symbolic.plxline4.



Explanation

1 Thestrictpragmaensuresthattheprogramuses

onlyhardreferencesand,ifitdoesn't,willabort

duringcompilationandprintanerrormessageas

shownintheoutputofthisscript.

3 Thisislinenumber10inthescript.Theprogram

diedatthispointbecauseofthefirstuseofa

symbolicreference,${$language}.

4 Thislinealsoincludesasymbolicreferencebutis

neverreached,becausetheprogramhadalready

abortedbecausestrictcaughtit.



13.1.2.HardReferences,Pointers

WediscussedpointersinChapter11whenpassingreferencesto

asubroutine.Toreiterate:Ahardreferenceisascalarthat

holdstheaddressofanotherdatatype.Avariablethatis

assignedanaddresscanalsobecalledapointerbecauseit

pointstosomeotheraddressortoanotherreference.Thistype

ofreferencecanpointtoascalar,array,associativearray,ora

subroutine.ThepointerwasintroducedinPerl5togiveyouthe

abilitytocreatecomplexdatatypes,suchasarraysofarrays,

arraysofhashes,hashesofhashes,etc.Inalloftheexamples

wheretypeglobswereused,wecannowoptforpointers

instead.Pointersprovideawaytopassparametersto

subroutinesbyreference.



TheBackslashOperator

Thebackslashunaryoperatorisusedtocreateahard

reference,similartothe&usedinCtogetthe"addressof."In

thefollowingexample,$pisthereference.Itisassignedthe

addressofthescalar$x.



$p=\$x;



AnexampleofhardreferencesfromthePerlmanpageperlref:

$scalarref=\$foo;#referencetoscalar$foo

$arrayref=\@ARGV;#referencetoarray@ARGV

$hashref=\%ENV;#referencetohash%ENV

$coderef=\&handler;#referencetosubroutinehandler

$globref=\*STDOUT;#referencetotypeglobSTDOUT

$reftoref=\$scalarref;#referencetoanotherreference

(pointertopointer,ugh)



DereferencingthePointer

Ifyouprintthevalueofareference(orpointer),youwillseean

address.Ifyouwanttogotothataddressandgetthevalue

storedthere—thatis,dereferencethepointer—thepointermust

beprefacedbytwo"funny"symbols.Thefirstisthedollarsign,

becausethepointeritselfisascalar,andprecedingthatgoes

thefunnysymbolrepresentingthetypeofdatatowhichit

points.Whenusingmorecomplextypes,thearrow(infix)

operatorcanbeused.

Example13.3.

(TheScript)

#!/bin/perl

1$num=5;

2$p=\$num;#$pgetstheaddressof$num

3print'Theaddressassigned$pis',$p,"\n";

4print"Thevaluestoredatthataddressis$$p\n";#

(Output)

3Theaddressassigned$pisSCALAR(0xb057c)

4Thevaluestoredatthataddressis5



Explanation

1. Thescalar$numisassignedthevalue5.

2. Thescalar$pisassignedtheaddressof$num.Thisisthe

functionofthebackslashoperator.$piscalledeithera

referenceorapointer;thetermsareinterchangeable.

3. Theaddressstoredin$pisprinted.Perlalsotellsyouthe

datatypeisSCALAR.

4. Todereference$p,anotherdollarsignisprependedto$p.

ThisdollarsigntellsPerlthatyouarelookingforthevalue

ofthescalarthat$preferences;i.e.,$num.



Example13.4.

CodeView:

#!/bin/perl

1@toys=qw(BarbieElmoThomasBarney);

2$num=@toys;

3%games=("Nintendo"=>"Wii",

"Sony"=>"PlayStation3",

"Microsoft"=>"XBox360",

);

4$ref1=\$num;#Createpointers

5$ref2=\@toys;

6$ref3=\%games;

7print"Thereare$$ref1toys.\n";#dereferencepointers

8print"Theyare:",join(",",@$ref2),".\n";



9print"Jessica'sfavoritetoyis$ref2->[0].\n";

10print"Willie'sfavoritetoyis$ref2->[2].\n";

11while(($key,$value)=each(%$ref3)){

print"$key=>$value\n";

}

12print"Theywaitedinlinefora$ref3->{'Nintendo'}

(Output)

Thereare4toys.

Theyare:Barbie,Elmo,Thomas,Barney.

Jessica'sfavoritetoyisBarbie.

Willie'sfavoritetoyisThomas.

Microsoft=>XBox360

Sony=>PlayStation3

Nintendo=>Wii

TheywaitedinlineforaWii

























Explanation

1. Alistisassignedtothearray@toys.

2. Thearray@toysisassignedtothescalarvariable$num,

returningthenumberofelementsinthearray.

3. Thehash%gamesisassignedkey/valuepairs.

4. Thepointer$ref1isapointer.Itisassignedtheaddressof

thescalar$numbyusingthebackslashoperator.

5. Thepointer$ref2isassignedtheaddressofthearray

@toys.

6. Thepointer$ref3isassignedtheaddressofthehash

%games.

7. Thepointerisdereferenced,meaning:Gototheaddress

that$ref1ispointingtoandprintthevalueofthescalar

storedthere.

8. Thepointerisagaindereferenced,meaning:Gotothe

addressthat$ref2ispointingto,getthearray,andprint

it.

9. The->arrowoperatorisusedtodereferencethepointer

andgetthefirstelementofthearray.(Thiscouldalsobe

writtenas$$ref2[0].)

10. Againthe->arrowoperatorisusedtodereferencethe

pointerandretrievethethirdelementofthearray.

11. Theeachfunctionisusedtoretrievethekeysandvalues

fromthehashviaitspointer.Todereferenceahash,the%

signprecedesthepointervariable.

12. The->arrowoperatorisusedtodereferencethepointer

andgetthevalueofthehashwherethekeyis"Nintendo".

(Thiscouldalsobewrittenas$$ref3{"Nintendo"}.)



13.1.3.ReferencesandAnonymousVariables

Itisnotnecessarytonameavariabletocreateareference

(pointer)toit.Ifavariableorsubroutinehasnoname,itis

calledanonymous.Ifananonymousvariable(orsubroutine)is

assignedtoascalar,thenthescalarisareferencetothat

variable(subroutine).

Thearrowoperator(–>),alsocalledtheinfixoperator,is

usedtodereferencethereferencetoanonymousarraysand

hashes.Althoughnotreallynecessary,thearrowoperator

makestheprogrameasiertoread.



AnonymousArrays

Anonymousarrayelementsareenclosedinsquarebrackets

([]).Thesesquarebracketsarenottobeconfusedwiththe

squarebracketsusedtosubscriptanarray.Heretheyareused

asanexpressiontobeassignedtoascalar.Thebracketswill

notbeinterpolatedifenclosedwithinquotes.Thearrow(infix)

operatorisusedtogettheindividualelementsofthearray.

Example13.5.



(TheScript)

#!/bin/perl

1my$arrayref=['Woody','Buzz','Bo','Mr.PotatoHead']

2print"Thevalueofthereference,\$arrayrefis",

$arrayref,"\n";

#Alloftheseexamplesdereference$arrayref

3print"$arrayref->[3]","\n";

4print$$arrayref[3],"\n";

5print${$arrayref}[3],"\n";

6print"@{$arrayref}","\n";

(Output)

2Thevalueofthereference,$arrayrefisARRAY(0x8a6f134)



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 13. Does This Job Require a Reference?

Tải bản đầy đủ ngay(0 tr)

×