Escolar Documentos
Profissional Documentos
Cultura Documentos
SEUGUIALIVREPARAPROGRAMAOEMRUBY
DEWWW.SAPPHIRESTEEL.COM
EMASSOCIAOCOMBITWISEMAGAZINE
TraduzidoparaoportugusdoBrasil
porFranciscodeOliveira
SISMICROInformticaLtda.
www.sismicro.com.br
TheLittleBookOfRuby
Copyright2006DarkNeonLtd.
Allrightsreserved.
writtenby
HuwCollingbourne
Downloadsourcecodefrom:
http://www.sapphiresteel.com
Firstedition:June2006
YoumayfreelycopyanddistributethiseBookaslongasyoudonotmodifythetextorremovethis
copyrightnotice.YoumustnotmakeanychargeforthiseBook.
TheLittleBookofRubyisproducedinassociationwithRosedownMillLtd.,makersoftheSteel
IDEforVisualStudio(www.sapphiresteel.com)andBitwiseMagazinetheonlinemagazinefor
developers(www.bitwisemag.com).
Traduo:
SISMICROInformticaLtda
www.sismicro.com.br
Todososdireitosreservados.
Junho/2006
Traduzidoeadaptadoparaalnguaportuguesa(Brasil)porSISMICROInformticaLtda.Voc
podecopiaredistribuirlivrementeestatraduodesdequevocnomodifiqueotextoouremova
esteaviso.Vocnodeveusufruircomercialmentedestatraduo.
Obs:Algumaspalavrase,principalmente,osfontesprogramasforammantidosnalnguaoriginal
consideramosqueestescasosnoprejudicarooentendimentodotexto.
PequenoLivrodoRuby
ndice
BemvindoaoPequenoLivrodoRuby................................................................................................5
AprendaRubyemDezCaptulos....................................................................................................5
OqueRuby?..................................................................................................................................5
OqueRails?..................................................................................................................................5
BaixeoRubymaisumEditordeCdigo........................................................................................6
PegueoCdigoFontedosProgramasExemplo..............................................................................6
RodandoProgramasRuby...............................................................................................................6
Comousarestelivro........................................................................................................................6
Cap.1Stringsemtodos....................................................................................................................8
Strings,Nmeros,MtodoseCondicionais.....................................................................................8
StringseAvaliaoembutida........................................................................................................10
Mtodos.........................................................................................................................................11
Nmeros.........................................................................................................................................14
TestandoumaCondio:ifthen...............................................................................................15
Cap.2ClasseseObjetos..................................................................................................................17
ClasseseObjetos...........................................................................................................................17
InstnciaseVariveisdeInstncia................................................................................................18
Construtoresneweinitialize.......................................................................................................21
InspecionandoObjetos...................................................................................................................23
Cap.3HierarquiadeClasses...........................................................................................................27
Hierarquiadeclasses.....................................................................................................................27
SuperclasseseSubclasses..............................................................................................................30
Cap.4Acessores,Atributos,VariveisdeClasse...........................................................................32
Acessores,AtributoseVariveisdeClasses.............................................................................32
MtodosAcessores........................................................................................................................32
ReaderseWritersdeAtributos......................................................................................................34
AtributosCriamVariveis.............................................................................................................37
Chamandomtodosdeumasuperclasse........................................................................................42
VariveisdeClasse........................................................................................................................43
Cap.5Arrays...................................................................................................................................45
Matrizes(Arrays)...........................................................................................................................45
Usandoarrays................................................................................................................................46
CriandoArrays...............................................................................................................................46
ArraysMultiDimensionais...........................................................................................................49
IterandosobreArrays....................................................................................................................51
IndexandoArrays...........................................................................................................................52
Pg.3
PequenoLivrodoRuby
Cap.6Hashes...................................................................................................................................55
Hashes............................................................................................................................................55
CriandoHashes..............................................................................................................................56
IndexandoemumHash.................................................................................................................58
OperaesHash............................................................................................................................59
Cap.7LaoseIteradores.................................................................................................................61
Laoseiteradores..........................................................................................................................61
LaosFOR.....................................................................................................................................61
Blocos............................................................................................................................................65
LaosWhile...................................................................................................................................65
ModificadoresWhile.....................................................................................................................66
LaosUntil.....................................................................................................................................68
Cap.8DeclaraesCondicionais....................................................................................................69
DeclaraesCondicionais..............................................................................................................69
If..Then..Else................................................................................................................................69
And..Or..Not................................................................................................................................71
If..Elsif..........................................................................................................................................71
Unless.............................................................................................................................................73
ModificadoresIfeUnless..............................................................................................................74
DeclaraesCase...........................................................................................................................75
Cap.9MduloseMixins................................................................................................................77
MduloseMixins..........................................................................................................................77
UmMduloComoUmaClasse..............................................................................................77
MtodosdeMdulo.......................................................................................................................78
MduloscomoNamespaces.........................................................................................................78
MtodosdeInstnciadeMdulos..............................................................................................80
MdulosinclusosouMixins.......................................................................................................81
IncluindoMdulosdeArquivos....................................................................................................84
MduloPredefinidos......................................................................................................................86
Cap.10SalvandoArquivos,Avanando.........................................................................................87
IndoAlm......................................................................................................................................87
Gravandodados.............................................................................................................................87
YAML............................................................................................................................................87
Arquivos.........................................................................................................................................88
Avanando.....................................................................................................................................92
Pg.4
PequenoLivrodoRubyBemvindoaoPequenoLivrodoRuby
O que Ruby?
Rubyumalinguagemdeprogramaointerpretadamultiplataformaquetemmuitas
caractersticasemcomumcomoutraslinguagensdescriptcomoPerlePhyton.Contudoasua
versodeorientaoaobjetosmaiscompletaqueaquelaslinguagense,emmuitosaspectos,o
RubytemmaisemcomumcomobisavdaslinguagensOOP(programaoorientadaaobjetos)
'puras',oSmalltalk.AlinguagemRubyfoicriadaporYukihiroMatsumoto(comumenteconhecido
porMatz)efoiliberadapelaprimeiravezem1995.
O que Rails?
Atualmente,muitodaempolgaoemvoltadoRubypodeseratribudaaoframeworkde
desenvolvimentowebchamadoRailspopularmenteconhecidocomoRubyOnRails.Emborao
Railssejaumframeworkimpressionante,elenoacoisamaisimportantedoRuby.Abemda
verdade,sevocdecidirmergulharfundonodesenvolvimentocomRailssemantesdominaro
Ruby,vocpoderacabarfazendoumaaplicaoquenemvocmesmoentende.Aindaqueeste
PequenoLivrodoRubynoircobrirascaractersticasespeciaisdoRails,elelhedarabase
necessriaparavocentenderocdigodoRailseparaescreversuasprpriasaplicaesRails.
Pg.5
PequenoLivrodoRubyBemvindoaoPequenoLivrodoRuby
Pg.6
PequenoLivrodoRubyBemvindoaoPequenoLivrodoRuby
apenaspequenosprogramasexemploentofcilpulardeumcaptuloparaoutroseassimvoc
acharmelhor.
Tomandoconhecimentodotexto
Nestelivro,qualquercdigofonteRubyestescritocomoeste:
defsaysomething
puts("Hello")
end
Quandoexistirumprogramaexemploacompanhandoocdigo,onomedoprogramasermostrado
emumapequenacaixacomoesta. helloname.rb
Notasexplicativas(asquaisgeralmentefornecemalgumasugesto,dicaouumaexplicao
aprofundadadealgumpontomencionadonotexto)somostradosemumacaixacomoesta:
Estaumanotaexplicativa.Vocpodepullasequisermassevoc
ofizerpoderperderalgointeressante...!
Notadotradutor:Nsoptamospormostrarocdigodosprogramas
exemplodiretamentenotextodolivro,oquenoaconteceunaverso
originalaomenosnodeformaintegra.Esperamosqueissoajudena
compreenso.Emalgunscasospodeocorreraduplicaodecdigo
desdejpedimosdesculpas.
Pg.7
PequenoLivrodoRubyCap.1Stringsemtodos
uppercase.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
puts("helloworld".upcase)
Estedeveseromenorhelloworldprogramadahistriadaprogramao,entovamosavanar
modificandooparapedirqueousuriodigitealgo...
Oprximopasso,ento,'solicitar'aousurioumastring(conjuntodecaracteres).Omtodopara
fazerissoemRubygets.
helloname.rb
#RubySampleprogramfromwww.sapphiresteel.com/
Pg.8
PequenoLivrodoRubyCap.1Stringsemtodos
www.bitwisemag.com
print('Enteryourname:')
name=gets()
puts("Hello#{name}")
Oprogramahelloname.rbperguntaaousuriooseunomevamossuporqueFredeento
mostraumasaudao:HelloFred.
Enquantoissoaindamuitosimples,existemalgunsdetalhesimportantesqueprecisamser
explicados.Primeiro,notequeeuuseiprintemvezdeputsparamostrarapergunta.Istofoifeito
porqueoputsadicionaumanovalinhanofinaleoprintno;nesteexemploeuqueroqueocursor
permaneanamesmalinhadapergunta.
Nalinhaseguinteeuuseiogets()paralerainformaodigitadapelousurioemumastringquando
forpressionadaateclaEnter.Estastringarmazenadanavarivel,name.Eunoprdeclareiesta
varivel,nemespecifiqueiseutipo.EmRubyvocpodecriarvariveiscomoequandoprecisar
delaseoRubydeduzotipocorrespondente.Nestecasoeuatribuiumastringparaavarivelname,
logooRubysabequeotipodenamedeveserumastring.
ObjetoseMtodos
Ruby uma linguagem altamente OOP (Programao Orientada por Objetos). Tudo desde
uminteiroatumastringconsideradoumobjeto.Ecadaobjetoconstitudode'mtodos'os
quaispodemfazermuitascoisas.Parausarummtodo,vocprecisacolocarumpontoapso
objeto, ento adicionar o nome do mtodo. Por exemplo, aqui eu estou usando o mtodo
upcaseparamostrarastringhelloworldemmaisculas:
puts("helloworld".upcase)
Algunsmtodoscomooputseogetsestodisponveisemtodoolugarenonecessitam
serassociadosaumobjetoespecfico.Tecnicamentefalando,estesmtodossofornecidos
pelomduloKerneldoRubyeelesestopresentesemtodososobjetosRuby.Quando
vocrodaumaaplicaoRuby,umobjetochamadomainautomaticamentecriadoeeste
objetoforneceacessoaosmtodosdoKernel.
Nota:ORubysensvelamaisculaseminsculas(caixaalta/baixa).
UmavarivelchamadamyvardiferentedeoutrachamadamyVar.
Umavarivelcomo'name'nonossoexemplodeveiniciarcomuma
letraminscula(emcaixabaixa)
Pg.9
PequenoLivrodoRubyCap.1Stringsemtodos
Osmbolodeparntesesnofinaldegets()opcionalassimcomoosparntesesqueenvolvemas
stringsapsoprinteoputs;ocdigodeveriarodarigualmentesevocremovesseosparnteses.
Contudo,oRubyestmovendosegradualmentenadireodousodosparntesesparticularmente
quandopassaseargumentosparamtodos.Osparntesesajudamaevitarpossveisambigidades
nocdigoe,emalgunscasos,ointerpretadordoRubyiravislosevocomitilos.Enquanto
algunsprogramadoresRubygostamdeomitirosparntesessemprequepossvel,eunosouum
deles;vocir,entretanto,verificarousoliberaldeparntesesnosmeusprogramas.
string_eval.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
defshowname
return"Fred"
end
puts"Hello#{showname}"
puts("\n\t#{(1+2)*3}")
Vejasevocconsegueacertaroqueseriamostradopelocdigoseguinte:
Pg.10
PequenoLivrodoRubyCap.1Stringsemtodos
puts("\n\t#{(1+2)*3}")
Executeoprogramastring_eval.rbparaversevocestcerto.
Comentrios
Linhasquecomeamcomocaracter#sotratadascomocomentrios
(elassoignoradaspelointerpretadorRuby):
#ThisisacommentIstoumcomentrio
Mtodos
Noexemploanterior,eu,sembarulho,introduziummtodoRubysemexplicarprecisamenteoque
easintaxenecessriaparacrilo.Voucorrigiressaomissoagora.
object.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
classMyClass
defsaysomething
puts("Hello")
end
end
ob=MyClass.new
ob.saysomething
Ummtodoassimchamadoporqueeleforneceummtodo(isto,'umaforma')paraumobjeto
responderamensagens.NaterminologiaOOP,vocenviaumamensagemparaumobjetopedindo
queelefaaalgo.Vamosimaginarquevoctemumobjetochamadooboqualpossuiummtodo
chamadosaysomething,estaaformaquevocdeveriaenviarlheumamensagemsaysomething:
ob.saysomething
Vamossuporqueomtodosaysomethingsejaoseguinte:
defsaysomething
Pg.11
PequenoLivrodoRubyCap.1Stringsemtodos
puts("Hello")
end
Quandovocenviaamensagemsaysomethingparaoobjetoobelerespondecomomtodo
saysomethingemostraHello.
OK,estaaformaOOPpuradedescreveresteprocesso.UmaformaOOPnotopurade
descreverissoseriadizerquesaysomethingcomoumafunoqueligadaaoobjetoepodeser
chamadausandoanotaodeponto:
ob.saysomething.
method.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
defshowstring
puts("Hello")
end
defshowname(aName)
puts("Hello#{aName}")
end
defreturn_name(aFirstName,aSecondName)
return"Hello#{aFirstName}#{aSecondName}"
end
defreturn_name2aFirstName,aSecondName
return"Hello#{aFirstName}#{aSecondName}"
end
showstring
showname("Fred")
puts(return_name("MaryMary","QuiteContrary"))
puts(return_name("LittleJack","Horner"))
NoRubyummtododeclaradocomapalavrachavedefseguidadonomedomtodooqual
deveriainiciarcomumaletraminscula,comoeste:
defshowstring
puts("Hello")
Pg.12
PequenoLivrodoRubyCap.1Stringsemtodos
end
Vocpode,opcionalmente,colocarumoumaisargumentos,separadosporvrgula,apsonomedo
mtodo:
defshowname(aName)
puts("Hello#{aName}")
end
defreturn_name(aFirstName,aSecondName)
return"Hello#{aFirstName}#{aSecondName}"
end
Osparntesesemvoltadosargumentossoopcionais.Aseguintesintaxetambmpermitida:
defreturn_name2aFirstName,aSecondName
return"Hello#{aFirstName}#{aSecondName}"
end
Comoexplicadoanteriormente,eusoumaisfavorvelausarosparntesesmasvocpodeomitilos
sequiser.
mainob.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
defshowstring
puts("Hello")
end
defshowname(aName)
puts("Hello#{aName}")
end
defreturn_name(aFirstName,aSecondName)
return"Hello#{aFirstName}#{aSecondName}"
end
defreturn_name2aFirstName,aSecondName
return"Hello#{aFirstName}#{aSecondName}"
end
Pg.13
PequenoLivrodoRubyCap.1Stringsemtodos
#sowhichobjectownsthesemethods,anyhow?
#Thefollowingtestrevealsall...
print("The'freestandingmethods'inthiscodebelongtoan
objectnamed:")
puts(self)
print("whichisaninstanceoftheclass:")
puts(self.class)
#Freestandingmethods(likethoseabovewhicharenotdefined
withina
#specificclass)aremethods(strictlyspeaking,'private'
methods)of
#themainobjectwhichRubycreatesautomtically.Thefollowing
code
#displaysalistofthemainobject'sprivatemethods.Look
carefullyand
#youwillfindshowname,return_nameandreturn_name2inthatlist
puts("Itcontainstheseprivatemethods:")
puts(self.private_methods)
Seosmtodosseligamaosobjetos,qualobjetopossuiosmtodosindependentesquevoc
escrevenoseucdigo?Comomencionadoantes,oRubycriaautomaticamenteumobjetochamado
mainquandovocexecutaumprogramaeaesseobjetoqueosmtodosindependentesse
ligam.
Nmeros
Nmerossotofceisdeusarquantoasstrings.Porexemplo,vamossuporquevocquercalcular
opreodevendaeototalgeraldealgunsitenspartindodosubtotaledataxadeimposto.
Parafazeristovocprecisariamultiplicarosubtotalpelataxadeimpostoeadicionarovalorao
subtotal.Assumindoqueosubtotal$100eataxadeimpostode17.5%,estecdigoRubyfazo
clculoemostraoresultado:
subtotal=100.00
taxrate=0.175
tax=subtotal*taxrate
puts"Taxon$#{subtotal}is$#{tax},sograndtotalis
$#{subtotal+tax}"
Obviamente,seriamaistilsepudssemosefetuaroclculodevriossubtotaisemvezdeficar
Pg.14
PequenoLivrodoRubyCap.1Stringsemtodos
fazendoomesmoclculotodavez.!.
AquiestumaversosimplesdaCalculadoradeImpostosqueperguntaaousurioosubtotal:
taxrate=0.175
print"Enterprice(extax):"
s=gets
subtotal=s.to_f
tax=subtotal*taxrate
puts"Taxon$#{subtotal}is$#{tax},sograndtotalis
$#{subtotal+tax}"
Aquis.to_fummtododaclasseString.Estemtodotentaconverterastringparaumnmerode
pontoflutuante.Porexemplo,astring145.45seriaconvertidaparaonmerodepontoflutuante
145.45.Seastringnopodeserconvertida,0.0retornado.Assim,porexemplo,Hello
world.to_fretornaria0.0.
then
OproblemacomocdigodaCalculadoradeImpostosmostradoacimaqueeleaceitasubtotais
negativosecalculaimpostonegativosobreelesumacoisaqueoGovernonovcombonsolhos!
Eu,poressarazo,precisochecarosvaloresnegativose,quandoencontrlos,zerlos.Esta
minhanovaversodocdigo:
tax_calculator.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
taxrate=0.175
print"Enterprice(extax):"
s=gets
subtotal=s.to_f
if(subtotal<0.0)then
subtotal=0.0
end
tax=subtotal*taxrate
puts"Taxon$#{subtotal}is$#{tax},sograndtotalis
$#{subtotal+tax}"
OtesteRubyifsemelhanteaumtesteifemoutraslinguagensdeprogramao.Notequeos
Pg.15
PequenoLivrodoRubyCap.1Stringsemtodos
parnteses,maisumavez,soopcionais,assimcomoapalavrachavethen.
Entretanto,sevocforescreveroseguinte,semquebradelinhaapsacondiodeteste,othen
obrigatrio:
if(subtotal<0.0)thensubtotal=0.0end
Notequeapalavrachaveendqueterminaoblocoifnoopcional.Esqueadecoloclaeoseu
cdigonoirrodar.
Pg.16
PequenoLivrodoRubyCap.2ClasseseObjetos
Pg.17
PequenoLivrodoRubyCap.2ClasseseObjetos
object_class.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
classMyClass
defsaysomething
puts("Hello")
end
end
ob=MyClass.new
ob.saysomething
Pg.18
PequenoLivrodoRubyCap.2ClasseseObjetos
mydog=Dog.new
yourdog=Dog.new
Nestemomento,estesdoiscachorrosestosemnome.Entoaprximacoisaafazerchamaro
mtodoset_nameparadarnomesaeles:
mydog.set_name('Fido')
yourdog.set_name('Bonzo')
Tendodadonomesaoscachorros,euprecisodealgumaformaparaacharosnomesmaistarde.
Cadacachorroprecisasaberoseuprprionome,entovamoscriarummtodoget_name:
defget_name
return@myname
end
Apalavrachavereturnopcional.MtodosRubysempreretornamaltimaexpressoavaliada.
Paramaiorclareza(etambmparaevitarresultadosinesperadosdemtodosmaiscomplexosque
este!)devemosadquirirohbitoderetornarexplicitamenteovalorparausoposterior.Finalmente,
vamosdaralgumcomportamentoaocachorropedindoparaelefalar(isto:latir).Aquiesta
definiofinaldaclasse:
classDog
defset_name(aName)
@myname=aName
end
defget_name
return@myname
end
deftalk
return'woof!'
end
end
Agora,nspodemoscriarumcachorro,darlheumnome,mostraronomeepedirparaelelatir:
mydog=Dog.new
mydog.set_name('Fido')
puts(mydog.get_name)
puts(mydog.talk)
Pg.19
PequenoLivrodoRubyCap.2ClasseseObjetos
ParamaiorclarezaeparamostrareunoestoucontranossosamigosfelinosEutambm
adicioneiumaclasseCatnomeuprograma,dogs_and_cats.rb.AclasseCatsemelhanteclasse
Dogexcetopelofatoqueomtodotalk,naturalmente,retornaummiaowemvezdewoof.
Esteprogramacontmumerro.Oobjetodenomesomeotherdog
nuncatemumvaloratribuidoparaasuavarivel@name.Porsorte,
oRubynoexplodequandonstentamosmostraronomedocachorro.
EmvezdissooRuby,simplesmente,imprime'nil'.
Nsveremosembreveumaformasimplesdeassegurar
queerroscomoessenoocorramnovamente...
dogs_and_cats.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#Createclassesanduseinstancevariablessuchas@myname
classDog
defset_name(aName)
@myname=aName
end
defget_name
return@myname
end
end
deftalk
return'woof!'
end
classCat
defset_name(aName)
@myname=aName
end
defget_name
return@myname
Pg.20
PequenoLivrodoRubyCap.2ClasseseObjetos
end
end
deftalk
return'miaow!'
end
#Createinstances(objects)oftheDogandCatclasses
mydog=Dog.new
yourdog=Dog.new
mycat=Cat.new
yourcat=Cat.new
someotherdog=Dog.new
#Namethem
mydog.set_name('Fido')
yourdog.set_name('Bonzo')
mycat.set_name('Tiddles')
yourcat.set_name('Flossy')
#Gettheirnamesanddisplaythem
#Dogs
puts(mydog.get_name)
puts(yourdog.get_name)
#hmmm,butwhathappenshereifthedoghasnoname?
puts(someotherdog.get_name)
#Cats
puts(mycat.get_name)
puts(yourcat.get_name)
#Askthemtotalk
puts(mydog.talk)
puts(yourdog.talk)
puts(mycat.talk)
puts(yourcat.talk)
Agora,vamosolharumoutroexemplodeumaclassedefinidapelousurio.Carregueoprograma
treasure.rb.
Pg.21
PequenoLivrodoRubyCap.2ClasseseObjetos
treasure.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#defineaclassandcreatesomeobjects
classThing
defset_name(aName)
@name=aName
end
end
defget_name
return@name
end
classTreasure
definitialize(aName,aDescription)
@name=aName
@description=aDescription
end
defto_s#overridedefaultto_smethod
"The#{@name}Treasureis#{@description}\n"
end
end
thing1=Thing.new
thing1.set_name("AlovelyThing")
putsthing1.get_name
t1=Treasure.new("Sword","anElvishweaponforgedofgold")
t2=Treasure.new("Ring","amagicringofgreatpower")
putst1.to_s
putst2.to_s
#Theinspectmethodletsyoulookinsideanobject
puts"Inspecting1sttreasure:#{t1.inspect}"
Esteumjogodeaventuraemconstruo.Contmduasclasses,ThingeTreasure.AclasseThing
bemsimilarclasseDogvistaanteriormentebem,excetopelofatoqueelanolate('woof').J
aclasseTreasuretemalgunsextrasinteressantes.Primeiramente,elanotemosmtodosget_name
eset_name.Nolugar,elacontmummtodochamadoinitializequerecebedoisargumentoscujos
valoressoatribuidosparaasvariveis@namee@description:
Pg.22
PequenoLivrodoRubyCap.2ClasseseObjetos
definitialize(aName,aDescription)
@name=aName
@description=aDescription
end
Quandoumaclassecontmummtododenomeinitialize,estemtodoautomaticamentechamado
quandoumobjetocriadousandoomtodonew.umaboaidiausarummtodoinitializepara
definirosvaloresdasvariveisdeinstnciadeumobjeto.Istotemdoisbenefciosclarossobre
definirasvariveisusandomtodoscomoset_name.Primeiro,umaclassecomplexapoderconter
numerosasvariveisdeinstncia.Depois,eucrieiummtodochamadoto_soqualservepara
retornarumastringrepresentativadeumobjetodaclasseTreasure.Onomedomtodo,to_s,no
arbitrrio.Omesmonomedemtodousadoextensivamentepelahierarquiadeclassespadrodo
Ruby.Defato,omtodoto_sdefinidoparaaprpriaclasseObjectaqualaltimaancestralde
todasasoutrasclassesemRuby.Redefinindoomtodoto_s,euadicioneiumnovocomportamento
quemaisapropriadoparaaclasseTreasurequeomtodopadro.Emoutraspalavras,ns
sobrescrevemosomtodoto_s.
Nota:Omtodonewcriaumobjetologovocpodevlo
comoumconstrutordeobjetos.Contudo,vocnodeverianormalmente
implementarasuaprpriaversodomtodonew(istopossvel
masno,geralmente,recomendado).Emvezdisso,quandovocquer
executarquaisqueraesdeconfiguraocomodefinirvaloresiniciais
paravariveisinternasdeumobjetovocdeveriafazerissoemum
mtodochamadoinitialize.ORubyexecutaomtodoinitialize
imediatamenteapsumnovoobejtosercriado.
Inspecionando Objetos
NotetambmqueeuolheiinternamenteoobjetoTreasure,t1,usandoomtodoinspect:
t1.inspect
EstemtodoinspectdefinidoparatodososobjetosRuby.Eleretornaumastringcontendouma
Pg.23
PequenoLivrodoRubyCap.2ClasseseObjetos
representaodoobjetolegvelpornshumanos.Nocasoemquesto,mostradoalgoassim:
#<Treasure:0x28962f8@description="anElvishweaponforgedof
gold",@name="Sword">
Comeacomonomedaclasse,Treasure;seguidodeumnmero,oqualpodeserdiferenteda
mostradaacimaesteocdigodeidentificaointernadeumobjetoparticulardoRuby;ento
vemosnomesevaloresdasvariveisdoobjeto.
ORubytambmforneceomtodopqueumatalhoparainspecionaremostrarobjetos:
p(anobject)
p.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
classTreasure
definitialize(aName,aDescription)
@name=aName
@description=aDescription
end
defto_s#overridedefaultto_smethod
"The#{@name}Treasureis#{@description}\n"
end
end
a="hello"
b=123
c=Treasure.new("ring","aglitterygoldthing")
p(a)
p(b)
p(c)
Paravercomoto_spodeserusadocomumavariedadedeobjetoseparatestarcomoumobjeto
Treasureseriaconvertidoparaumastringnaausnciadeumasobrescriodomtodoto_s,testeo
programato_s.rb.
Pg.24
PequenoLivrodoRubyCap.2ClasseseObjetos
to_s.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#Showstringrepresentaionsofvariousobjects
#usingtheto_smethod
classTreasure
definitialize(aName,aDescription)
@name=aName
@description=aDescription
end
#Thistimewewon'toverrideto_ssotheTreasureobject
#willusethedefaultto_smethod...
end
t=Treasure.new("Sword","AlovelyElvishweapon")
print("Class.to_s:")
puts(Class.to_s)
print("Object.to_s:")
puts(Object.to_s)
print("String.to_s:")
puts(String.to_s)
print("100.to_s:")
puts(100.to_s)
print("Treasure.to_s:")
puts(Treasure.to_s)
print("t.to_s:")
puts(t.to_s)
print("t.inspect:")
puts(t.inspect)
Comovocver,classescomoClass,Object,StringeTreasure,simplesmenteretornamseusnomes
quandoomtodoto_schamado.UmobjetocomooobjetoTreasure,t,retornaseuidentificador
queomesmoidentificadorretornadopelomtodoinspect.
Olhandoparaomeuprogramatreasure.rbverificamosqueocdigoumpoucorepetitivo.Almdo
que,porqueterumaclasseThingquecontmumnome(name)eumaclasseTreasurequetambm
contmumnome(avariveldeinstncia@name),cadaqualcodificadaindependentemente?Faria
maissentidoconsiderarTreasurecomumtipodeThing.Seeufordesenvolveresteprograma
Pg.25
PequenoLivrodoRubyCap.2ClasseseObjetos
dentrodeumcompletojogodeaventura,outrosobjetoscomoRoomseWeaponspodemseroutros
tiposdeThing.chegadaahoradecomearatrabalharemumahierarquiadeclassesapropriada.
oqueveremosnaprximalio...
Pg.26
PequenoLivrodoRubyCap.3HierarquiadeClasses
HierarquiasdeClassesAscendenteseDescendentes:Nestelivro,eu
frequentementefalosobreclassesdescendentesherdandocaractersticasdesuas
classesascendentes(ousuperclasses,ouclassespai).Assimestestermos
deliberadamentesugeremumtipoderelacionamentofamiliarentreasclasses
relacionadas.EmRuby,cadaclassepossuisomenteumpai.
Umaclassepode,porm,descenderdeumalongaedistintarvorefamiliar
commuitasgeraesdeavs,bisavseassimpordiante
OcomportamentodeThingsemgeralserocodificadosnaclasseThing.AclasseTreasureir
automaticamente'herdar'todasascaractersticasdaclasseThing,assimnsnotemosquecodificar
tudonovamente.Adicionase,ento,algumascaractersticas,especficasdeTreasures.
Comoregrageral,quandocriarumahierarquiadeclasses,aclassecomocomportamentomais
generalizadomaisaltanahierarquiaqueasclassescomcomportamentomaisespecfico.Assima
classeThingapenascomumnome(name)eumadescrio(description),seriaasuperclassede
umaclasseTreasurequetemumnome,umadescrioe,adicionalmente,umvalor(mtodovalue);
aclasseThingtambmpoderserasuperclassedealgumaoutraclasseespecialistacomouma
Room(sala)quetemumnome,umadescrioetambmsadas(exits)eassimpordiante...
Pg.27
PequenoLivrodoRubyCap.3HierarquiadeClasses
UmPai,muitosFilhos
EstegrficomostraaclasseThingquetemumnameeumadescription
(emumprogramaRuby,estaspodemservariveisinternascomo
@namee@descriptionmaisalgunsmtodosparaacesslas).Asclasses
TreasureeRoomdescendemdaclasseThingassimelasautomati
camenteherdamumnameeumadescription.AclasseTreasure
adicionaumnovoitem:valueassimelaagoratemname,description
evalue;AclasseRoomadicionaexitsassimtemname,
descriptioneexits.
adventure1.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#illustrateshowtocreatedescendentobjects
classThing
definitialize(aName,aDescription)
@name=aName
@description=aDescription
end
defget_name
Pg.28
PequenoLivrodoRubyCap.3HierarquiadeClasses
return@name
end
defset_name(aName)
@name=aName
end
defget_description
return@description
end
defset_description(aDescription)
@description=aDescription
end
end
classTreasure<Thing#TreasuredescendsfromThing
definitialize(aName,aDescription,aValue)
super(aName,aDescription)
@value=aValue
end
defget_value
return@value
end
defset_value(aValue)
@value=aValue
end
end
#Thisiswhereourprogramstarts...
t1=Treasure.new("Sword","anElvishweaponforgedof
gold",800)
t2=Treasure.new("DragonHorde","ahugepileofjewels",550)
puts"Thisistreasure1:#{t1.inspect}"
puts"Thisistreasure2:#{t2.inspect}"
puts"t1name=#{t1.get_name},description=#{t1.get_description},
value=#{t1.get_value}"
t1.set_value(100)
t1.set_description("(nowsomewhattarnished)")
puts"t1(NOW)name=#{t1.get_name},
Pg.29
PequenoLivrodoRubyCap.3HierarquiadeClasses
description=#{t1.get_description},value=#{t1.get_value}"
VamosvercomocriarumaclassedescendenteemRuby.Carregueoprogramaadventure1.rb.Este
comeacomumadefiniodaclasseThingquetemduasvariveisdeinstncia,@namee
@description.Aestasvariveissoatribuidosvaloresnomtodoinitializequandoumnovoobjeto
Thingcriado.
Variveisdeinstnciageralmentenopodem(enodevem)seracessadasdiretamentepelo
mundoexteriordaclassedevidoaoprincpiodoencapsulamento.
Encapsulamentoumtermoquesereferemodularidadedeumobjeto.
Deformasimples,significaquesomenteoprprioobjetopodemexer
comoseuestadointerno.Omundoexternono.Obenefciodisso
queoprogramadorpodermudaraimplementaodosmtodos
semterquesepreocuparcomalgumcdigoexternoquedependadealgum
detalheespecficodaimplementaoanterior.
ParaobterovalordecadavarivelemumobjetoThingnsprecisamosdeummtodogetcomo
get_name;parapassarumnovovalorparaumavarivelnsprecisamosdeummtodosetcomo
set_name:
defget_name
return@name
end
defset_name(aName)
@name=aName
end
Superclasses e Subclasses
AgoraolheaclasseTreasure.Vejacomodeclarada:
classTreasure<Thing
Osinaldemenor,<,indicaqueTreasureumasubclasse,oudescendente,deThingeporisso
elaherdaosdados(variveis)eocomportamento(mtodos)daclasseThing.Comoosmtodos
Pg.30
PequenoLivrodoRubyCap.3HierarquiadeClasses
get_name,set_name,get_descriptioneset_descriptionjexistemnaclasseascendente(Thing)
estesmtodosnoprecisamserrecodificadosnaclassedescendente(Treasure).AclasseTreasure
temumapeaadicionaldedado,seuvalor(@value)eeuescreviacessoresgetesetparaele.
QuandoumnovoobjetoTreasurecriado,seumtodoinitializeautomaticamentechamado.Um
objetoTreasuretemtrsvariveisparainicializar(@name,@descriptione@value),entoseu
mtodoinitializerecebetrsargumentos:
definitialize(aName,aDescription,aValue)
Osprimeirosdoisargumentossopassados,usandoapalavrachavesuper,paraomtodoinitialize
dasuperclasse(Thing)assimomtodoinitializedaclasseThingpodelidarcomelas:
super(aName,aDescription)
Quandousadodentrodeummtodo,apalavrachavesuperchamaomtodocomomesmonome
naclasseascendenteousuperclasse.
OmtodoatualdaclasseTreasurechamadoinitializeassimquandoocdigointernopassaosdois
argumentos(aName,aDescription)parasuperrealmenteestpassandoasparaomtodoinitialize
dasuasuperclasse,Thing.
Seapalavrachavesuperforusada,semqualquerargumento,todososargumentosenviadosao
mtodoatualsopassadosparaomtodoascendente.
Pg.31
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
Mtodos Acessores
Emvezdeacessarovalordavariveldeinstncia@descriptioncomdoismtodosdiferentes,
get_descriptioneset_description,comoaseguir
puts(t1.get_description)
t1.set_description(Somedescription)
seriamuitomaiseleganterecuperareatribuirvaloresdamesmaformaquevocrecuperae
atribuevaloresparavariveissimples,comoaseguir:
puts(t1.description)
t1.description=Somedescription
Parapoderfazerisso,euprecisomodificaradefiniodaclasse.Umaformaseriareescreveros
mtodosacessorespara@descriptioncomosegue:
defdescription
return@description
end
defdescription=(aDescription)
@description=aDescription
end
Euadicioneiacessorescomoosacimanoprogramaaccessors.rb(vejaocdigomaisabaixo).
Existemduasdiferenasdaversoanterior.Primeiro,ambososacessoressochamadosdescription
emvezdeget_descriptioneset_description;segundo,oacessorsetanexaumsinaldeigual(=)ao
nomedomtodo.Agorapossvelatribuirumanovastringpara@descriptionassim:
Pg.32
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
t.description="abitfadedandwornaroundtheedges"
Eagoravocpoderecuperarovalorassim:
puts(t.description)
Nota:Quandovocescreveumacessorsetdestaforma,vocdeve
anexarocaracter=diretamentenonomedomtodo,nomera
mentecolocloemqualquerlugarentreonomedomtodoeseus
argumentos.Logo,istocorreto:
defname=(aName)
Masistoerrado:
defname=(aName)
accessors.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#illustrateshowtoreadandwriteinstancevariables
#usingaccessormethods
classThing
definitialize(aName,aDescription)
@name
=aName
@description
=aDescription
end
#getaccessorfor@name
defname
return@name
end
#setaccessorfor@name
defname=(aName)
@name=aName
end
#getaccessorfor@description
Pg.33
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
defdescription
return@description
end
#setaccessorfor@description
defdescription=(aDescription)
@description=aDescription
end
end
t=Thing.new("TheThing","alovely,glitterywotsit")
print(t.name)
print("is")
puts(t.description)
t.name="ARefurbishedThing"
t.description="abitfadedandwornaroundtheedges"
print("Ithasnowchangeditsnameto")
puts(t.name)
print("Iwoulddescribeitas")
puts(t.description)
Pg.34
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
Smbolos:NoRuby,umsmboloumnomeprecedidopelosinalde
doispontos(:).SymboldefinidanabibliotecadeclassesdoRuby
pararepresentarnomesdentrodointerpretadorRuby.Smbolos
tmalgunsusosespeciais.Porexemplo,quandovocpassa
umoumaissmboloscomoargumentosparaomtodoattr_reader
(podenoserbvio,masattr_reader,defato,ummtododaclasse
Module),oRubycriaumavariveldeinstnciaeummtodoaccessorget
pararetornarovalordavarivel;ambosavariveldeinstnciaeomtodo
acessorteroomesmonomequeosmboloespecificado.
Chamandoattr_readercomumsmbolotmoefeitodecriarumavariveldeinstnciacomo
mesmonomedosmboloeumacessorgetparaaquelavarivel.
Chamandoattr_writer,semelhantementecriaumavariveldeinstnciacomumacessorset.
Aqui,avarivelseriachamadade@description.Variveisdeinstnciasoconsideradascomoos
'atributos'deumobjeto,oqueexplicaporqueosmtodosattr_readereattr_writermethodsso
assimchamados.
accessors2.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#readingandwritingattributes
classThing
attr_reader:description
attr_writer:description
attr_writer:name
definitialize(aName,aDescription)
@name=aName
@description=aDescription
end
#getaccessorfor@name
defname
return@name.capitalize
end
Pg.35
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
#Idon'tneedthisname'set'methodsinceIhaveanattr_writer
forname
#defname=(aName)
#
@name=aName
#end
end
classTreasure<Thing#TreasuredescendsfromThing
attr_accessor:value
definitialize(aName,aDescription)
super(aName,aDescription)
end
end
#Thisiswhereourprogramstarts...
t1=Treasure.new("sword","anElvishweaponforgedofgold")
t1.value=800
t2=Treasure.new("dragonhorde","ahugepileofjewels")
t2.value=500
puts"t1name=#{t1.name},description=#{t1.description},
value=#{t1.value}"
t1.value=100
t1.description<<"(nowsomewhattarnished)"#note<<appends
specifiedstringtoexistingstring
puts"t1name=#{t1.name},description=#{t1.description},
value=#{t1.value}"
puts"Thisistreasure1:#{t1.inspect}"
puts"Thisistreasure2:#{t2.inspect}"
Oprogramaaccessors2.rbcontmalgunsexemplosdereadersewritersdeatributosemao.
PercebaqueaclasseThingdefineaformasimplificadadoacessorset(usandoattr_writermaisum
smbolo)paraavarivel@name:
attr_writer:name
Mastemoacessorgetnaformalongaummtodocodificadointeiramenteparaamesma
varivel:
Pg.36
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
defname
return@name.capitalize
end
Avantagemdeescreverummtodocompletocomoessequedavocaoportunidadedefazer
algumprocessamentoextraemvezdeapenaslereescreverovalordeumatributo.Aquioacessor
getusaomtodocapitalizedaclasseStringpararetornarastring@namecomsuasletrasiniciais
emmaisculas.
Oatributo@descriptionnoprecisadeprocessamentoespecialassimsendoeuuseiambos
attr_readereattr_writerparapegareatribuirovalordavarivel@description.
AtributosouPropriedades?Nosejaconfundidopelaterminologia.No
Ruby,umatributoequivalenteaoquemuitasoutraslinguagensde
programaochamamdepropriedade.
Quandovocquerlereescreverumavarivel,omtodoattr_accessormethodforneceuma
alternativamaiscurtaqueusarambosattr_readereattr_writer.Euuseiissoparaacessarovalordo
atributovaluenaclasseTreasure:
attr_accessor:value
Thisisequivalentto:
attr_reader:value
attr_writer:value
Pg.37
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
definitialize(aName,aDescription)
super(aName,aDescription)
end
end
Anicaindicaoqueumavarivel@valueexisteadefiniodoacessorquedeclaraumatributo
value:
attr_accessor:value
MeucdigonofinaldoarquivofonteatribueovalordecadaobjetoTreasure:
t1.value=800
Oatributovaluenofoiformalmentedeclarado,avarivel@valuerealmentenoexisteens
podemosrecuperaroseuvalornumricousandooacessorget:
t1.value
Paratercertezaqueoacessordoatributorealmentecriou@value,vocpodeinspecionaroobjeto
usandoomtodoinspect.Eufizissonofinaldocdigofontecomasduaslinhasfinaisdo
programa:
puts"Thisistreasure1:#{t1.inspect}"
puts"Thisistreasure2:#{t2.inspect}"
accessors3.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#moreonreadingandwritingattributes
classThing
attr_reader:name,:description
attr_writer(:name,:description)
attr_accessor(:value,:id,:owner)
end
t=Thing.new
Pg.38
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
t.name="AThing"
t.description="Asoft,furrywotsit"
t.value=100
t.id="TH100SFW"
t.owner="Me"
puts("#{t.name}is#{t.description},itisworth$#(t.value)")
puts("it'sidis#{t.id}.Itisownedby#{t.owner}.")
AcessoresdeAtributopodeminicializarmaisqueumatributoporvezsevocenviaraelesuma
listadesmbolosnaformadeargumentosseparadosporvrgulas,comoesteexemplo:
attr_reader:name,:description
attr_writer(:name,:description)
attr_accessor(:value,:id,:owner)
Comosempre,noRuby,osparntesesemvoltadosargumentossoopcionais.
adventure2.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#illustrateshowtocreatingdescendentobjects
#readingandwritingattributes
#object(instance)variables
#classvariables
#Thing
classThing
@@num_things=0#classvariable
attr_reader(:name,:description)
attr_writer(:description)
definitialize(aName,aDescription)
@name=aName
@description=aDescription
@@num_things+=1#increment@@num_things
end
defto_s#overridedefaultto_smethod
return"(Thing.to_s)::The#{@name}Thingis
#{@description}"
Pg.39
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
end
defshow_classvars
return"Thereare#{@@num_things}Thingobjectsinthis
game"
end
end
#Room
classRoom<Thing
#TODO:AddRoomspecificbehaviour
end
#Treasure
classTreasure<Thing
attr_reader:value
attr_writer:value
definitialize(aName,aDescription,aValue)
super(aName,aDescription)
@value=aValue
end
end
#Map
classMap
#@roomswillbeanarrayanorderedlist
#ofRoomobjects
definitialize(someRooms)
@rooms=someRooms
end
#Theto_smethoditeratesoveralltheRoomobjectsin
@rooms
#andprintsinformationoneach.We'llcomebacktolookat
the
#implementationofthismethodlateron
defto_s
@rooms.each{
|a_room|
puts(a_room)
}
end
Pg.40
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
end
#Firstcreateafewobjects
#i)Treasures
t1=Treasure.new("Sword","anElvishweaponforgedof
gold",800)
t2=Treasure.new("DragonHorde","ahugepileofjewels",550)
#ii)Rooms
room1=Room.new("CrystalGrotto","Aglitterycavern")
room2=Room.new("DarkCave","Agloomyholeintherocks")
room3=Room.new("ForestGlade","Averdantclearingfilledwith
shimmeringlight")
#iii)aMapwhichisanarraycontainingtheRoomsjust
created
mymap=Map.new([room1,room2,room3])
#Nowlet'stakealookatwhatwe'vegot...
puts"\nLet'sinspectthetreasures..."
puts"Thisisthetreasure1:#{t1.inspect}"
puts"Thisisthetreasure2:#{t2.inspect}"
puts"\nLet'stryouttheThing.to_smethod..."
puts"Yup,treasure2is#{t2.to_s}"
puts"\nNowlet'sseehowourattributeaccessorswork"
puts"We'llevaluatethis:"
puts't1name=#{t1.name},description=#{t1.description},
value=#{t1.value}'
puts"t1name=#{t1.name},description=#{t1.description},
value=#{t1.value}"
puts"\nNowwe'llassign100tot1.valueandalter
t1.description..."
t1.value=100
t1.description<<"(nowsomewhattarnished)"#note<<appends
specifiedstringtoexistingstring
puts"t1(NOW)name=#{t1.name},description=#{t1.description},
value=#{t1.value}"
puts"\nLet'stakealookatroom1..."
puts"room1name=#{room1.name},
description=#{room1.description}"
puts"\nAndthemap..."
puts"mymap=#{mymap.to_s}"
puts"\nFinally,let'scheckhowmanyThingobjectswe've
created..."
puts(t1.show_classvars)
#Asanexercise,tryaddingaclassvariabletotheMapclassto
Pg.41
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
maintain
#acountofthetotalnumberofroomsthathavebeencreated
Agoravamosvercomocolocarreadersewritersdeatributosparausarnomeujogodeaventura.
Carregueoprogramaadventure2.rb(listagemacima).Vocverqueeucrieidoisatributosna
classeThing:nameedescription.Eutambmfizoatributodescriptionpoderseratribudopelo
programador(attr_writer);porm,eunoplanejomudarosnomesdosobjetoscriadosapartirda
classeThing,porissooatributonametemsomenteoacessorattr_reader.
attr_reader(:name,:description)
attr_writer(:description)
Eucrieiummtodochamadoto_squeretornaastringdescrevendooobjetoTreasure.Lembreque
todaclasseRubytmummtodoto_spadro.Omtodoto_snaclasseThingsobrescreve
(substitui)opadro.Vocpodesobrescrevermtodosexistentesquandovocimplementaum
novocomportamentoapropriadoparaotipoespecficodaclasse.
Pg.42
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
Deoutrolado,aclasseRoom,quetambmdescendedeThing,notemummtodoinitialize;logo
quandoumnovoobjetoRoomcriadooRubyvoltaseparaparaahierarquiadeclasses
ascendentesparaprocuraruminitalize.Oprimeiromtodoinitializequeeleencontraestnaclasse
Thing;assimosatributosnameedescriptiondoobjetoRoomsoinicializadosl.
Variveis de Classe
Existemalgumasoutrascoisasinteressantesnesteprograma.NotopodaclasseThingvocver
isso:
@@num_things=0
Osdoiscaracteres@noinciodonomedavarivel,@@num_things,definemqueessauma
'variveldeclasse'.Asvariveisquensusamosdentrodasclassesatagoraeram'variveisde
instncia',precedidasporumnico@,como@name.
Umavezqueumnovoobjeto(ouinstncia)deumaclasseatribueseusprpriosvaloresparasuas
prpriasvariveisdeinstncia,todososobjetosderivadosdeumaclasseespecficacompartilham
asmesmasvariveisdaclasse.Euatribui0paraavarivel@@num_thingsparaassegurarqueela
tenhaumvalorsignificativoparaoexterior.Aqui,avariveldeclasse@@num_thingsusadapara
manterovalorcorrentedonmerodeobjetosThingnojogo.Istofeitopeloincrementoda
variveldeclasse(usamos+=paraadicionar1aonmerodeobjetos)nomtodoinitializecada
vezqueumnovoobjetocriado:
@@num_things+=1
Sevocolharnapartedebaixodomeucdigo,vocverqueeucrieiumaclasseMapquecontm
umamatrizdesalas(objetosRoom).Incluiumaversodomtodoto_squeimprimeinformao
sobrecadasalanamatriz.NosepreocupecomaimplementaodaclasseMap;nsveremos
arrayseseusmtodosbrevemente.
Pg.43
PequenoLivrodoRubyCap.4Acessores,Atributos,VariveisdeClasse
OdiagramaacimamostraaclasseThing(oretngulo)quecontmuma
variveldeclasse,@@num_thingseumavariveldeinstncia,
@name,Astrsovaisrepresentam'objetosThingisto,instnciasda
classeThing.Quandoumdestesobjetosatribueumvalorparasuavarivel
deinstncia,@name,estevalorafetasomenteavarivel@namenopr
prioobjetoentoaqui,cadaobjetotmumvalordiferentepara@name.
Masquandoumobjetoatribueumvalorparaavariveldeclasse,
@@num_things,aquelevalor'vivedentro'daclasseThingecomparti
lhadoportodasasinstnciasdestaclasse.Aqui@@num_thingsiguala
3equeigualparatodososobjetosThing.
Acheocdigonofinaldoarquivoerodeoprogramaparavercomonscriamoseinicializamos
todososobjetoseusamosavariveldeclasse,@@num_things,paramanteracontagemdetodos
osobjetosThingqueforamcriados.
Pg.44
PequenoLivrodoRubyCap.5Arrays
Cap. 5 - Arrays
Matrizes (Arrays)...
Atagora,nsgeralmentetemosusadosobjetosumdecadavez.Nestecaptulonsveremoscomo
criarumalistadeobjetos.Vamosiniciarvendootipodelistamaiscomumumamatriz(array).
OqueumArray?
Umarrayumacoleosequencialdeitensnaqualcadaitempodeser
indexado.
NoRuby,(diferentedemuitasoutraslinguagens)umnicoArraypode
conteritensdetiposdedadosmisturadoscomostrings,inteirosenmeros
depontoflutuanteoumesmochamadasdemtodosqueretornemalgum
valor:
a1=[1,'two',3.0,array_length(a0)]
Oprimeiroitemdeumarraytmondice0,oquesignificaqueoitemfinal
tmumndiceigualaototaldeitensdoarraymenos1.Dadooarray,a1,
mostradoacima,estaaformadeobterosvaloresdoprimeiroeltimoitens:
a1[0]#returns1stitem(atindex0)
a1[3]#returns4thitem(atindex3)
array0.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
defarray_length(anArray)
returnanArray.length
end
a0=[1,2,3,4,5]
a1=[1,'two',3.0,array_length(a0)]
p(a0)
p(a1)
puts("Itemindex#0ofa1is#{a1[0]},item#3is#{a1[3]}")
Pg.45
PequenoLivrodoRubyCap.5Arrays
Usando arrays
Nsjusamosarraysalgumasvezesporexemplo,noprogramaadventure2.rbnocaptulo4ns
usamosumarrayparaarmazenarummapadesalas(objetosRoom):
mymap=Map.new([room1,room2,room3])
Criando Arrays
Emcomumcommuitasoutraslinguagensdeprogramao,oRubyusaossinaisdecolchetes[]
paradelimitarumarray.Vocpodefacilmentecriarumarray,preenchaocomalgunsvalores
separadosporvrgulaeatribuaosaumavarivel:
arr=['one','two','three','four']
array1.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
arr=['a','b','c']
puts(arr[0])#showsa
puts(arr[1])#showsb
puts(arr[2])#showsc
puts(arr[3])#nil
ComoamaioriadasoutrascoisasnoRuby,arrayssoobjetos.Elessodefinidos,comovocdeve
teradivinhado,porumaclasseArray,assimcomoasstrings,osarrayssoindexadosapartirde0.
Vocpodereferenciarumitememumamatrizcolocandooseundiceentrecolchetes[].Seo
ndiceforinvlido,nilretornado:
arr=['a','b','c']
puts(arr[0])#showsa
puts(arr[1])#showsb
Pg.46
PequenoLivrodoRubyCap.5Arrays
puts(arr[2])#showsc
puts(arr[3])#nil
array2.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
defhello
return"helloworld"
end
x=[1+2,hello,`dir`]
#arraycontaininganexpression,a
methodcallandastring
puts(x.inspect)
#Note:ifyourarenotusingWindows,you
mayneedto
#change`dir`toacommandthatisunderstood
byyour
#operatingsystem
y=%w(thisisanarrayofstrings)
puts(y.inspect)
a=Array.new
puts("Array.new:"<<a.inspect)
a=Array.new(2)
puts("Array.new(2):"<<a.inspect)
a=Array.new(2,"helloworld")
puts(a.inspect)
a=Array.new(2)
a[0]=Array.new(2,'hello')
a[1]=Array.new(2,'world')
puts(a.inspect)
a=[
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]]
puts(a.inspect)
a=Array.new([1,2,3])
Pg.47
PequenoLivrodoRubyCap.5Arrays
puts(a.inspect)
#Note:intheaboveexample,ifyoupassanarraytonew()
without
#puttingitinsoundbrackets,youmustleaveaspacebetween
#'new'andtheopeningsquarebracket.
#Thisworks:
#
a=Array.new[1,2,3]
#Thisdoesn't!
#
a=Array.new[1,2,3]
permitidomisturartiposdedadosemumarrayeatmesmoincluirexpressesqueproduzam
algumvalor.Vamosassumirquevocjcriouestemtodo:
defhello
return"helloworld"
end
Vocpodeagoradeclararestearray:
x=[1+2,hello,`dir`]
Aqui,oprimeiroelementouminteiro,3(1+2),eosegundoumastringhello
world(retornadapelomtodohellocriadoacima).SevocexecutaristonoWindows,oterceiro
elementoserumastringcontendoalistagemdodiretrio.Istodeveseaofatoque`dir`uma
stringcotadaporcrase(`)queexecutadapelosistemaoperacional.Oslotfinaldoarray,por
essarazo,preenchidocomovalorretornadopelocomandodirquemontaastringcomnomesde
arquivos.Sevocestusandoumsistemaoperacionaldiferentevocdevesubstituirocomandodir
pelocomandoapropriadodoseusistemaoperacional(porexemplonoLinuxocomandoo`ls`).
CriandoumArraydeNomesdeArquivos:AlgumasclassesRubypossuem
mtodosqueretornamarrays.Porexemplo,aclasseDir,queusadapara
executaroperaesemdiretriosdedisco,tmomtodoentries.Passeumnomede
diretrioparaomtodoeeleretornaumalistadearquivosemumarray:
Dir.entries('C:\\')#returnsanarrayoffilesinC:\
dir_array.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
Pg.48
PequenoLivrodoRubyCap.5Arrays
p(Dir.entries('C:\\'))
Sevocquercriarumarraydestringsmasnoquerchatearsedigitandotodasasaspasevrgulas,
umatalhocolocartextonocotadoseparadoporespaosentreparntesesprecedidopor%w
comoesteexemplo:
y=%w(thisisanarrayofstrings)
Vocpodetambmcriararrayscomomtodousualdeconstruodeobjetos,new.
Opcionalmente,vocpodepassaruminteiroparacriarumarrayvaziocomumtamanhoespecfico
(noqualcadaelementoserigualanil),ouvocpodepassardoisargumentosoprimeiropara
definirotamanhodoarrayeosegundoparaespecificaroelementoacolocaremcadandice,
assim:
a=Array.new#anemptyarray
a=Array.new(2)#[nil,nil]
a=Array.new(2,"helloworld")#["helloworld","helloworld"]
Arrays Multi-Dimensionais
Paracriararraysmultidimensionais,vocpodecriarumarrayeentoadicionaroutrosarrayspara
os'slots'destearray.Porexemplo,istocriaumarraycontendodoiselementos,cadaqualtambm
umarraydedoiselementos:
a=Array.new(2)
a[0]=Array.new(2,'hello')
a[1]=Array.new(2,'world')
Ouvocpoderiaaninhararraysdentrodeoutrousandooscolchetes.Istocriaumarraydequatro
arrays,cadaqualcontmquatrointeiros:
a=[[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]]
Nocdigoacima,eucoloqueiquatrosubarraysemlinhasseparadas.Istonoobrigatriomas
ajudaatornarclaraaestruturadoarraymultidimensionalmostrandocadasubarraycomosefosse
umalinha,semelhantealinhasemumaplanilhadeclculo.Quandotratardearraysdentrode
Pg.49
PequenoLivrodoRubyCap.5Arrays
arrays,convenientetratarcadaarrayaninhadocomoumalinhadeumarrayexterno.
array_new.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#alltheseareok
arrayob=Array.new([1,2,3])
arrayob=Array.new([1,2,3])
arrayob=Array.new[1,2,3]
#butthisoneisn't
arrayob=Array.new[1,2,3]
p(arrayob)
VoctambmpodecriarumobjetoArraypassandoumarraycomum
argumento para o mtodo new. Seja cuidadoso, contudo. uma
artimanha do Ruby que, mesmo sendo legtimo passar um argumento
array com ou sem os parnteses delimitadores, o Ruby considera um
errodesintaxesevocesquecerdedeixarumespaoentreoneweo
primeiro colchete outra boa razo para criar o firme hbito de usar
parntesesquandopassarargumentos!
Paraalgunsexemplosdousodearraysmultidimensionais,carregueoprogramamulti_array.rb.
Elecomeacriandoumarray,multiarr,contendodoisoutrosarrays.Oprimeirodestesarraysest
nondice0demultiarreosegundoestnondice1:
multiarr=[['one','two','three','four'],[1,2,3,4]]
multi_array.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#createanarraywithtwosubarraysi.e.2'rows'eachwith4
elements
multiarr=[['one','two','three','four'],
#multiarr[0]
[1,2,3,4]]
#multiarr[1]
Pg.50
PequenoLivrodoRubyCap.5Arrays
#iterateovertheelements('rows')ofmultiarr
puts("foriin..(multidimensionalarray)")
foriinmultiarr
puts(i.inspect)
end
puts("\nfora,b,c,din..(multidimensionalarray)")
for(a,b,c,d)inmultiarr
print("a=#{a},b=#{b},c=#{c},d=#{d}\n")
end
Pg.51
PequenoLivrodoRubyCap.5Arrays
puts
#Hereweinspectthechars.Noticethatwecan
#indexintoanarraylikethis...
#
arr[<startindex>,<numberofitems>]
#orspecifyarangelikethis...
#
arr[<startindex>..<endindex>]
#
#Sotheseareequivalent:
p(arr[0,5])
p(arr[0..4])
Iteradoreselaosfor:Ocdigodentrodeumlaoforexecutadoparacadaelementoem
umaexpresso.Asintaxeresumidaassim:
for<umaoumaisvariveis>in<expresso>do
<cdigoparaexecutar>
end
Quando maisdeumavarivelfornecida,elassopassadasparaocdigointernodobloco
for..end da mesma forma que voc passa argumentos para um mtodo. Aqui, por exemplo,
vocpodever(a,b,c,d)comoquatroargumentosquesoinicializados,acadavoltadolaofor,
pelosquatrovaloresdeumalinhademultiarr:
for(a,b,c,d)inmultiarr
print("a=#{a},b=#{b},c=#{c},d=#{d}\n")
end
Indexando Arrays
Vocpodeindexarapartirdofimdeumarrayusandoosinaldemenos(),onde1ondicedo
ltimoelemento;evoctambmpodeusarfaixas(valoresentreumndiceinicialefinalseparados
pordoissinaisdeponto..):
arr=['h','e','l','l','o','','w','o','r','l','d']
print(arr[0,5])#=>hello
print(arr[5,5])#=>world
Pg.52
PequenoLivrodoRubyCap.5Arrays
print(arr[0..4])#=>hello
print(arr[5..1])#=>world
Noteque,comoasstrings,quandofornecidodoisinteirospararetornarumnmerocontguode
itensdeumarray,oprimeirointeiroondiceinicialeosegundonmerodeitens(noum
ndice):
arr[0,5]#returns5chars["h","e","l",
"l","o"]
array_index.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
arr=[]
arr[0]=[0]
arr[1]=["one"]
arr[3]=["a","b","c"]
p(arr)#inspectandprintarr
arr2=['h','e','l','l','o','','w','o','r','l','d']
arr2[0]='H'
arr2[2,3]='L','L'
arr2[4..5]='O','','W'
arr2[4,4]='a','l','d','o'
p(arr2)#inspectandprintarr2
Voctambmpodedesignarndicesdentrodeumarray.Aqui,porexemplo,Euprimeirocrieium
arrayvazioentocoloqueiitensnosndices0,1e3.Oslotvazionondicenmero2ser
preenchidocomumvalornil:
arr=[]
arr[0]=[0]
arr[1]=["one"]
arr[3]=["a","b","c"]
#arrnowcontains:
Pg.53
PequenoLivrodoRubyCap.5Arrays
#[[0],["one"],nil,["a","b","c"]]
Umavezmais,vocpodeusarndicesiniciaisefinais,faixasendicesnegativos:
arr2=['h','e','l','l','o','','w','o','r','l','d']
arr2[0]='H'
arr2[2,3]='L','L'
arr2[4..5]='O','','W'
arr2[4,4]='a','l','d','o'
#arr2nowcontains:
#["H","e","L","L","O","","W","a","l","d","o"]
Pg.54
PequenoLivrodoRubyCap.6Hashes
Cap. 6 - Hashes
Hashes...
Mesmoqueosarraysforneamumaboaformadeindexarumacoleodeitenspornmero,h
situaesqueseriamaisconvenienteindexardealgumaoutraforma.Se,porexemplo,vocfor
criarumacoleodereceitas,seriamaissignificativotercadareceitaindexadapelonometalcomo
BolodeChocolateeSaladaMistaemvezdenmeros:23,87eassimpordiante.
ORubytmumaclassequepermitevocfazerexatamenteisso:ElachamadadeHash.Istoo
equivalenteaoqueoutraslinguagenschamamdeDicionrio(Dictionary).Comoumdicionrio
real,asentradassoindexadasporalgumachavenica(numdicionrio,seriaumapalavra)eum
valor(numdicionrio,seriaadefiniodapalavra).
hash1.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
h1={
'room1'=>'TheTreasureRoom',
'room2'=>'TheThroneRoom',
'loc1'=>'AForestGlade',
'loc2'=>'AMountainStream'}
classX
definitialize(aName)
@name=aName
end
end
x1=X.new('myXobject')
h2=Hash.new("Somekindofring")
h2['treasure1']='Silverring'
h2['treasure2']='Goldring'
h2['treasure3']='Rubyring'
h2['treasure4']='Sapphirering'
h2[x1]='Diamondring'
h3={
'treasure3'=>'Rubyring',
Pg.55
PequenoLivrodoRubyCap.6Hashes
'treasure1'=>'Silverring',
'treasure4'=>'Sapphirering',
'treasure2'=>'Goldring'
}
p(h2)
#inspectHash
puts(h1['room2'])
#getvalueusingakey('TheThrone
Room')
p(h2['treasure1'])
#getvalueusingakey('Silver
ring')
p(h1['unknown_room'])
#returnsdefaultvalue(nil)
p(h2['unknown_treasure'])
#returnsdefaultvalue('Somekind
ofring')
p(h1.default)
#=>nil
p(h2.default)
#=>'Somekindofring'
h1.default='Amysteriousplace'
puts(h1.default)
#=>'Amysteriousplace'
p(h2[x1])
#herekeyisobject,x1;valueis
'Diamondring'
Criando Hashes
VocpodecriarumhashcriandoumanovainstnciadaclasseHash:
h1=Hash.new
h2=Hash.new("Somekindofring")
AmbososexemplosacimacriamumHashvazio.UmobjetoHashsempretmumvalorpadro
isto,umvalorqueretornadoquandonenhumvalorespecficoencontradoemumdadondice.
Nestesdoisexemplos,h2inicializadocomovalorpadro,Somekindofring;h1no
inicializadocomumvalorentoseuvalorpadrosernil.
TendocriadoumobjetoHash,vocpodeadicionaritensaeleusandoumasintaxesemelhantedos
arraysisto,colocandoumndicenoscolcheteseusandoosinaldeigual=paraatribuirum
valor.
Adiferenabviaaquique,comumarray,ondice(achave)deveserumnmerointeiro;com
umHash,elepodeserqualqueritemdedadonico:
h2['treasure1']='Silverring'
h2['treasure2']='Goldring'
Pg.56
PequenoLivrodoRubyCap.6Hashes
h2['treasure3']='Rubyring'
h2['treasure4']='Sapphirering'
Muitasvezes,achavepodeserumnmeroou,comonocdigoacima,umastring.Porprincpio,
umachavepodeserqualquertipodeobjeto.Dadaalgumaclasse,X,aseguinteatribuio
perfeitamentelegal:
x1=X.new('myXobject')
h2[x1]='Diamondring'
ExisteumaformaabreviadadecriarHasheseinicializloscompareschavevalor.Adicionea
chaveseguidapor=>eovalorassociado;cadaparchavevalordeveserseparadoporumavrgula
eolotetodocolocadoentreossinaisdechaves{}:
h1={'room1'=>'TheTreasureRoom',
'room2'=>'TheThroneRoom',
'loc1'=>'AForestGlade',
'loc2'=>'AMountainStream'}
Chavesnicas?TomecuidadoquandoatribuirchavesparaHashes.Se
voc usar a mesma chave duas vezes em um Hash, voc acabar
sobrescrevendo o valor original. a mesma coisa que atribuir duas
vezes um valor para o mesmo ndice de um array. Considere este
exemplo:
h2['treasure1']='Silverring'
h2['treasure2']='Goldring'
h2['treasure3']='Rubyring'
h2['treasure1']='Sapphirering'
Aqui a chave treasure1 foi usada duas vezes. Como conseqncia, o
valor original, Silver ring foi substitudo por Sapphire ring,
resultandonesteHash:
{"treasure1"=>"Sapphire
"treasure2"=>"Goldring",
"treasure3"=>"Rubyring"}
Pg.57
ring",
PequenoLivrodoRubyCap.6Hashes
Indexando em um Hash
Paraacessarumvalor,coloquesuachaveentrecolchetes:
puts(h1['room2'])#=>TheThroneRoom
Sevocespecificarumachavequenoexiste,ovalorpadroretornado.Lembrequensno
especificamosumvalorpadroparah1masofizemosparah2:
p(h1['unknown_room'])#=>nil
p(h2['unknown_treasure'])#=>'Somekindofring'
Useomtododefaultparapegarovalorpadroeomtododefault=paraatribuilo(vejao
Captulo4paramaisinformaessobremtodosgeteset):
p(h1.default)
h1.default='Amysteriousplace'
hash2.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
h1={'key1'=>'val1','key2'=>'val2','key3'=>'val3',
'key4'=>'val4'}
h2={'key1'=>'val1','KEY_TWO'=>'val2','key3'=>'VALUE_3',
'key4'=>'val4'}
p(h1.keys&h2.keys)
p(h1.values&h2.values)
p(h1.keys+h2.keys)
p(h1.valuesh2.values)
p((h1.keys<<h2.keys))
p((h1.keys<<h2.keys).flatten.reverse)
Pg.58
PequenoLivrodoRubyCap.6Hashes
Operaes Hash
OsmtodoskeysevaluesdoHashretornamumarraylogovocpodeusarvriosmtodosArray
methodsparamanipullos.Aquiestounspoucosexemplos(note,osdadosmostradosnos
comentrioscomeandopor#=>mostramosvaloresretornadosquandocadapeadecdigo
executada):
h1={'key1'=>'val1','key2'=>'val2','key3'=>'val3',
'key4'=>'val4'}
h2={'key1'=>'val1','KEY_TWO'=>'val2','key3'=>'VALUE_3',
'key4'=>'val4'}
p(h1.keys&h2.keys)#setintersection(keys)#=>["key1",
"key3","key4"]
p(h1.values&h2.values)#set
intersection(values)
#=>["val1","val2","val4"]
p(h1.keys+h2.keys)#
concatenation
#=>["key1","key2","key3","key4","key1","key3","key4",
"KEY_TWO"]
p(h1.valuesh2.values)#
difference
#=>["val3"]
p((h1.keys<<h2.keys))#append
#=>["key1","key2","key3","key4",["key1","key3","key4",
"KEY_TWO"]]
p((h1.keys<<h2.keys).flatten.reverse)#unnestarraysand
reverse
#=>["KEY_TWO","key4","key3","key1","key4","key3","key2",
"key1"]
Atenoaonotaradiferenaentreconcatenarusando+paraadicionarovalordeumsegundoarray
aoprimeiroarrayeanexarusando<<paraadicionarosegundoarraycomooltimoelementodo
primeiroarray:
a=[1,2,3]
b=[4,5,6]
c=a+b#=>c=[1,2,3,4,5,6]a=[1,
2,3]
a<<b#=>a=[1,2,3,[4,5,6]]
Pg.59
PequenoLivrodoRubyCap.6Hashes
Adicionalmente,<<modificaoprimeiro(orecebedor)arraymaso+retornaumnovoarray
deixandooarrayrecebedorinalterado.Se,apsanexarumarraycom<<vocdecidequegostaria
deadicionaroselementosdoarrayanexadoaorecebedoremvezdeanexaroarraypropriamente
'aninhado'dentrodorecebedor,vocpodefazeristousandoomtodoflatten:
a=[1,2,3,[4,5,6]]
a.flatten#=>[1,2,3,4,5,6]
Pg.60
PequenoLivrodoRubyCap.7LaoseIteradores
Laos FOR
Emmuitaslinguagensdeprogramao,quandovocquerexecutarumpedaodecdigoumcerto
nmerodevezesvocpodefazlocolocandoopedaodecdigodentrodeumlaofor.Na
maioriadaslinguagens,voctemquedaraolaoforumavarivelcomumvalorinicialoqual
incrementadode1acadavoltadolaoatqueseatinjaumvalorfinalespecfico.Quandoovalor
finalatingido,olaoforterminaaexecuo.Aquiestaversodestetipotradicionaldelaofor
escritoemPascal:
#EsteumcdigoPascal,noRuby!
Fori:=1to3do
writeln(i);
for_loop.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
puts('loop#1')
foriin[1,2,3]do
puts(i)
end
puts('loop#3')
#'do'isoptionalwhenforloopis'multiline'
forsin['one','two','three']#do
puts(s)
end
Pg.61
PequenoLivrodoRubyCap.7LaoseIteradores
puts('loop#3')
#'do'isobligatorywhenforloopisonasingleline
forxin[1,"two",[3,4,5]]doputs(x)end
VocpoderevernoCaptulo5(arrays)queolaofordoRubynotrabalhaexatamentedesta
forma!Emvezdefornecerumvalorinicialefinal,nsfornecemosaolaoforumalistadeitense
eleiterasobreeles,umaum,atribuindoovalorparaavariveldolaoatquesechegueaofinal
dalista.
Porexemplo,aquiestumalaoforqueiterasobreseusitensemumamatriz,mostrandoovalora
cadavolta:
#EsteumcdigoRuby...
foriin[1,2,3]do
puts(i)
end
Olaoformaisparecidocomoiterador'foreach'existenteemalgumasoutraslinguagens.O
autordoRubydescreveoforcomoacarsintticoparacadamtodoeachoqual
implementadoportiposcoleodoRubycomoArrays,Sets,HasheseStrings(umaString
sendo,comefeito,umacoleodecaracteres).
Paraefeitodecomparao,esteolaoformostradoacimareescritousandoomtodoeach:
[1,2,3].eachdo|i|
puts(i)
end
Comovocpodever,noexistemuitadiferena.
each_loop.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
puts('loop#1')
[1,2,3].eachdo|i|
puts(i)
end
puts('loop#3')
Pg.62
PequenoLivrodoRubyCap.7LaoseIteradores
['one','two','three'].eachdo|s|
puts(s)
end
puts('loop#3')
[1,"two",[3,4,5]].eachdo|x|puts(x)end
Paraconverterolaoforemumiteradoreach,tudooquefizfoiexcluiroforeoineanexar.each
aoarray.Entoeucoloqueiavariveldoiterador,i,entrepipes(||).
#ii)each
['one','two','three'].eachdo|s|
puts(s)
end
#Example2
#i)for
forxin[1,two,[3,4,5]]doputs(x)end
Notequeapalavrachavedoopcionalemumlaoforqueseextendepormltiplaslinhasmas
obrigatrioquandoeleescritoemumanicalinha:
#Aquiapalavrachave'do'podeseromitida
forsin['one','two','three']
puts(s)
end
#Masaquiobrigatrio
forsin['one','two','three']doputs(s)end
Pg.63
PequenoLivrodoRubyCap.7LaoseIteradores
Comoescreverumlaofor'normal'...
Sevocsentirsaudadesdotipotradicionaldolaofor,vocsemprepode'imitlo'emRuby
usandoumlaoforparaiterarsobreosvaloresdeumafaixa.Porexemplo,vejacomousar
umavarivelparaolaoforparacontarde1at10,mostrandoovaloracadavoltadolao:
foriin(1..10)do
puts(i)
end
Oqualpodeserreescritousandoeach:
(1..10).eachdo|i|
puts(i)
end
Notequeaexpressodafaixa,porexemplo1..3,deveserescritaentreparnteses,(),quando
usadacomomtodoeach,senooRubyassumequevocesttentandousaroeachcomoum
mtododonmerofinaldafaixa(umFixNum)emvezdaexpressointeira(umafaixa).Os
parntesessoopcionaisquandoumafaixausadanolaofor.
Quandoiteramossobreositensusandoeach,oblocodecdigoentreodoeoendchamado
(obviamente)de'blocoiterador'.
Pg.64
PequenoLivrodoRubyCap.7LaoseIteradores
Blocos
ORubytemumasintaxealternativaparadelimitarblocos.Emvezdeusardo..end,comoabaixo..
#do..end
[[1,2,3],[3,4,5],[6,7,8]].eachdo
|a,b,c|
puts(#{a},#{b},#{c})
end
...vocpodeusarchaves{..}assim:
#chaves{..}
[[1,2,3],[3,4,5],[6,7,8]].each{
|a,b,c|
puts(#{a},#{b},#{c})
}
Noimportaqualdelimitadorvocuse,vocdeveassegurarsequeodelimitadordeaberturado
bloco,'{'ou'do',sejacolocadonamesmalinhadomtodoeach.Colocarumaquebradelinha
entreomtodoeacheodelimitadordeaberturadoblocoumerrodesintaxe.
Laos While
Rubytemalgumasoutrasformasdelaos.Estacomofazerumlaowhile:
whiletired
sleep
end
Ou,colocadodeoutraforma:
sleepwhiletired
Emboraasintaxedestesdoisexemplossejamdiferentes,elesdesempenhamamesmafuno.
Noprimeiroexemplo,ocdigoentrewhileeend(umachamadaparaomtodosleep)executa
enquantoacondiolgica(aqual,nestecaso,ovalorretornadopelachamadadomtodotired)
forverdadeira.Comonoslaosforapalavrachavedopode,opcionalmente,sercolocadaentrea
Pg.65
PequenoLivrodoRubyCap.7LaoseIteradores
condiodetesteeocdigoaserexecutadoestiveremlinhasseparadas;apalavrachavedo
obrigatriaquandoacondiodetesteeocdigoaexecutarforemcolocadosnamesmalinha.
Modificadores While
Nosegundaversodolao(sleepwhiletired),ocdigoaserexecutado(sleep)precedea
condiodeteste(whiletired).Estasintaxechamadadeum'modificadorwhile'.Quandovoc
querexecutarmuitasexpressesusandoestasintaxe,vocpodecoloclasentreaspalavraschave
begineend.
begin
sleep
snore
endwhiletired
Esteumexemplomostrandoasvriasalternativasdesintaxe:
$hours_asleep=0
deftired
if$hours_asleep>=8then
$hours_asleep=0
returnfalse
else
$hours_asleep+=1
returntrue
end
end
defsnore
puts('snore...')
end
defsleep
puts(z*$hours_asleep)
end
whiletireddosleepend #laowhileemumanicalinha
whiletired #laowhileemmltiplaslinhas
sleep
end
Pg.66
PequenoLivrodoRubyCap.7LaoseIteradores
sleepwhiletired
linha
begin
sleep
snore
endwhiletired
#modificadorwhileemumanica
#modificadorwhileemmltiplaslinhas
Oltimoexemploacima(modificadorwhileemmltiplaslinhas)mereceumaconsideraomaior
jqueintroduzumnovocomportamento.Quandoumblocodecdigodelimitadoporbegineend
precedeumtestewhile,ocdigosempreexecutapelomenosumavez.Nosoutrostiposdeteste
while,ocdigopodenuncaexecutarseacondiolgicainicialmenteforfalsa.
Assegurandoqueumlaoexecutepelomenosumavez
Usualmente,umlaowhileexecuta0oumaisvezesdesdequeotestelgicoseja
avaliadoantesqueolaoexecute;seotesteretornafalsonoincio,ocdigointernodo
laonoserexecutado.
Porm,quandootestewhilevemdepoisdeumblocodecdigodelimitadoporbegine
end,olaoexecutar1oumaisvezesjqueacondiodetesteavaliadasomenteaps
ocdigointernodolaoexecutar.
Paraverificarasdiferenasdecomportamentodestesdoistiposdelaowhile,rodeo
programawhile2.rb.Estesexemplosdevemajudarnoentendimento:
x=100
#ocdigonestelaonuncaexecuta
while(x<100)doputs('x<100')end
#ocdigonestelaonuncaexecuta
puts('x<100')while(x<100)
#masocdigonestelaoexecutaumavez
beginputs('x<100')endwhile(x<100)
Pg.67
PequenoLivrodoRubyCap.7LaoseIteradores
Laos Until
ORubytambmtemumlaountiloqualpodeserentendidocomoumalao'whilenot'.Sua
sintaxeeopessoasmesmasaplicadasaowhileisto,otesteeocdigoaserexecutado
podemsercolocadosemumanicalinha(nestecasoapalavrachavedoobrigatria)oueles
podemsercolocadosemlinhasseparadas(nestecasoodoopcional).Existetambmum
modificadoruntiloqualpermitevoccolocarocdigoantesdacondiodeteste;eexiste,
tambm,aopodecolocarocdigoentreumbegineendparaassegurarquecdigoexecutepelo
menosumavez.
Aquiestoalgunsexemplossimplesdelaosuntil:
i=10
untili==10doputs(i)end
#nuncaexecuta
untili==10
puts(i)
i+=1
end
#nuncaexecuta
puts(i)untili==10
#nuncaexecuta
begin
puts(i)
enduntili==10
#executaumavez
Ambososlaoswhileeuntilpodem,assimcomoolaofor,serusadosparaiterarsobrematrizes
(arrays)eoutrascolees.Porexemplo,ocdigoabaixomostracomoiterarsobretodosos
elementosdeumamatriz:
whilei<arr.length
puts(arr[i])
i+=1
end
untili==arr.length
puts(arr[i])
i+=1
end
Pg.68
PequenoLivrodoRubyCap.8DeclaraesCondicionais
Pg.69
PequenoLivrodoRubyCap.8DeclaraesCondicionais
deaodiferentesefimdesemana.Vocpodetestarestascondiesadicionandoumaseoelse
apsaseoif,comonoexemploaseguir:
ifaDay=='Saturday'oraDay=='Sunday'
daytype='weekend'
else
daytype='weekday'
end
Acondioifaquidireta.Elatesta2condiespossveis:
1. Seovalordavarivel,aDay,iguala'Saturday'(sbado)ou..
2. SeovalordeaDayiguala'Sunday'(domingo).
Seumadestascondiesforverdadeiraentoocdigodalinhaseguinteserexecutado:
daytype='weekend'
Emtodososdemaiscasos,ocdigodepoisdoelseserexecutado:
daytype='weekday'
Quandoumtesteifeocdigoaserexecutadosocolocadosemlinhasseparadas,apalavra
chavethenopcional.Quandootesteeocdigosocolocadosnamesmalinha,apalavra
chavethen(ousevocpreferirresumirocdigo,osmbolodedoispontos':'),obrigatria.
ifx==1thenputs('ok')end#com'then'
ifx==1:puts('ok')end#com:
ifx==1puts('ok')end#comerrode
sintaxe!
Umtesteifnoestrestritoaavaliarsomenteduascondies.Vamossupor,porexemplo,queseu
cdigonecessitesaberseumdeterminadodiaumdiatilouumferiado.Todososdiasdasemana
sodiasteis(diadetrabalho);todosossbados(Saturday)sodiasdefolgamasosdomingos
(Sunday)somentesodiasdefolgasevocnoestiverfazendohorasextras.
Estaaminhaprimeiratentativadeescreverumtesteparaavaliartodasestascondies:
Pg.70
PequenoLivrodoRubyCap.8DeclaraesCondicionais
working_overtime=true
ifaDay=='Saturday'oraDay=='Sunday'andnotworking_overtime
daytype='holiday'
puts(Hurrah!)
else
daytype='workingday'
end
Infelizmente,istonoteveoefeitoesperado.LembresequeSaturday(sbado)semprediade
folga.Masestecdigoinsisteque'Saturday'umdiatil.IstoocorreporqueoRubyentendeo
testecomo:SeodiaSbadoeeunoestoufazendohorasextras,ouseodiaDomingoeeu
noestoufazendohorasextrasondeeurealmentequeriadizerSeodiaSbado;ouseodia
Domingoeeunoestoufazendohorasextras.
Aformamaissimplesderesolverestaambigidadecolocarparntesesemvoltadequalquer
cdigoquedevaseravaliadocomoumanicaexpresso,assim:
ifaDay=='Saturday'or(aDay=='Sunday'andnot
working_overtime)
If.. Elsif
Nohdvidasquehaverocasiesquevocprecisartomarmltiplasaesbaseadasem
mltiplascondiesalternativas.Umaformadefazerissoavaliarumacondioifseguidadeuma
Pg.71
PequenoLivrodoRubyCap.8DeclaraesCondicionais
sriedeoutrostestescolocadosapsapalavrachaveelseif.Olotetodoentoterminadousandoa
palavrachaveend.
Porexemplo,aquieuestourepetidamentesolicitandoinformaoaousuriodentrodeumlao
while;umacondioiftestaseousuriodigitou'q'(euuseiomtodochomp()pararemovero
'retornodecarro'dodadodigitado);se'q'nofoiinformadooprimeiroelsiftestasefoidigitadoum
nmerointeiro(input.to_i)maiorque800;seotestefalharaprximacondioelsiftestaseo
nmeromenorouiguala800:
whileinput!='q'do
puts(Informeumnmeroentre1e1000(ou'q'parasair))
print(?)
input=gets().chomp()
ifinput=='q'
puts(Tchau...)
elsifinput.to_i>800
puts(Esteumvalormuitoalto!)
elsifinput.to_i<=800
puts(Eunopossogastarisso.)
end
end
Estecdigotemumbug.Elepedeporumnmeroentre1e1000mas
ele aceita outros nmeros, at mesmo palavras e caracteres diversos.
Vejasevocpodeaescreverostestesparaconsertarocdigoacima.
Pg.72
PequenoLivrodoRubyCap.8DeclaraesCondicionais
ORubytambmtemumaformareduzidadenotaoparaoif..then..elsenoqualumpontode
interrogao?Substituiaparteif..theneosinaldedoispontos:atuacomooelse...
<Condiodeteste>?<severdadeirafaaisto>:<senofaa
isto>
Porexemplo:
x==10?puts(Iguala10):puts(Algumoutrovalor)
Quandoacondiodetestecomplexa(seusaandsandors)vocdeveenvolvlapor
parnteses.
Seostesteseoscdigosextendemseporvriaslinhasa?devesercolocadanamesmalinhada
condioprecedenteeo:devesercolocadonamesmalinhadocdigoseguinte?.
Emoutraspalavras,sevoccolocarumanovalinhaantesda?Oudo:istoirgerarumerrode
sintaxe.Vejaabaixoumexemplodeumblocodecdigomultilinhasvlido:
(aDay=='Saturday'oraDay=='Sunday')?
daytype='weekend':
daytype='weekday'
Unless
Rubytambmpodeexecutartestesunless,oqualoopostodotesteif:
unlessaDay=='Saturday'oraDay=='Sunday'
daytype='weekday'
else
daytype='weekend'
end
Pensenounlesscomsendoumaformaalternativadeexpressar'ifnot'.Oexemploabaixo
equivalenteaocdigoacima:
if!(aDay=='Saturday'oraDay=='Sunday')
daytype='weekday'
Pg.73
PequenoLivrodoRubyCap.8DeclaraesCondicionais
else
daytype='weekend'
end
Modificadores If e Unless
VocpodereverasintaxealternativaparaoslaoswhilenoCaptulo7.Emvezdeescreverisso...
whiletireddosleepend
...vocpodeescreverassim:
sleepwhiletired
Estasintaxealternativa,naqualapalavrachavewhilecolocadaentreocdigoaexecutarea
condiodetestechamadode'modificadorwhile'.Dessamesmaforma,Rubytambmpossui
modificadoresifeunless.Aquiestoalgunsexemplos:
sleepiftired
begin
sleep
snore
endiftired
sleepunlessnottired
begin
sleep
snore
endunlessnottired
Aformaresumidadestasintaxetilquando,porexemplo,vocrepetidamenteprecisatomar
algumaaobemdefinidaseumacertacondioverdadeira.
AquiestcomovocpoderiacriticaroseucdigoatravsdedepuraoseumaconstanteDEBUG
verdadeira:
puts(somevar=#{somevar})ifDEBUG
Pg.74
PequenoLivrodoRubyCap.8DeclaraesCondicionais
Declaraes Case
Quandovocprecisatomarumavariedadedediferentesaesbaseadonovalordeumanica
varivel,usarmltiplostestesif..elsifverbosoerepetitivodemais.Umaalternativaelegante
fornecidapeladeclaraocase.Comeasecomapalavracaseseguidodonomedavarivelatestar.
Entovemumasriedeseeswhen,cadaqualespecificaumvalor'gatilho'seguidodealgum
cdigo.Estecdigoexecutasomentequandoovalordavarivelforigualaovalor'gatilho':
case(i)
when1:puts(segunda)
when2:puts(tera)
when3:puts(quarta)
when4:puts(quinta)
when5:puts(sexta)
when(6..7):puts(Oba!fimdesemana!)
elseputs(Noumdiavlido)
end
Noexemploacima,Eusei:parasepararcadatestewhendocdigoaexecutar,alternativamente
vocpoderusarapalavrachavethen.
When1thenputs(segunda)
Osinaldedoispontos:ouothenpodeseromitidoseotesteeocdigoaexecutarestoemlinhas
separadas.DiferentementedasdeclaraescaseemlinguagenssemelhantesaoC,nonecessrio
usarapalavrachavebreaknumaseocujotestedeuverdadeiroparaevitaraexecuodassees
restantes.
EmRuby,umavezqueumtestecasedeuverdadeiroaseocorrespondenteexecutadaeentoa
declaraocaseencerrada.
case(i)
when5:puts(sexta)
puts(...ofimdesemanaestchegando!)
wen6:puts(sbado)
#Ocdigoseguintenuncaexecuta
when5:puts(sextanovamente)
end
Vocpodeincluirmuitaslinhasdecdigoentrecadacondiowhenevocpodeincluirmltiplos
valoresseparadosporvrgulaparadispararumnicoblocowhen,comoeste:
Pg.75
PequenoLivrodoRubyCap.8DeclaraesCondicionais
when(6,7):puts(Oba!fimdesemana!)
Acondioemumadeclaraocasenoestobrigadaaserumavarivelsimples;podeseruma
expressocomoesta:
case(i+1)
Voctambmpodeusartiposnointeiroscomoumastring.
Semltiplosvaloresgatilhossoespecificadosemumaseowhen,elespodemserdetipos
variadosporexemplo,ambosstringeinteiros:
when1,'Monday','Mon':puts(Epa,'#{i}'segundafeira)
Aquiestumexemplomaior,ilustrandoalgunsdoselementossintticosmencionados
recentemente:
case(i)
when1:puts(segunda)
when2:puts(tera)
when3:puts(quarta)
when4:puts(quinta)
when5:puts(sexta)
puts(...ofimdesemanaestchegando!)
when6,7)
puts(sbado)ifi==6
puts(domingo)ifi==7
puts(Oba!fimdesemana!)
#Ocdigoseguintenuncaexecuta
when5:puts(sextanovamente)
elseputs(Noumdiavlido)
end
Pg.76
PequenoLivrodoRubyCap.9MduloseMixins
Pg.77
PequenoLivrodoRubyCap.9MduloseMixins
Paratornaristoemumaclassevocsprecisariasubstituirapalavramodule,nasuadefinio,pela
palavraclasse.
Mtodos de Mdulo
Emadioaosmtodosdeinstnciaummdulotambmpodetermtodosdemduloqueso
precedidospelonomedomdulo:
defMyModule.greet
return"I'm#{BADMOOD}.Howareyou?"
end
Apesardesuassimilaridades,existemduascaractersticasprincipaisqueasclassespossuemmasos
mdulosno:instnciaseherana.Classespodemterinstncias(objetos),superclasses(pais)e
subclasses(filhos);mdulosnopodemternadadisso.Oquelevanosprximaquesto:sevoc
nopodecriarumobjetoapartirdeummdulo,paraqueservemosmdulos?
Estaoutraquestoquepodeserrespondidaemduaspalavras:namespacesemixins.Osmixinsdo
Rubyfornecemnosumaformaparalidarcomopequenoproblemadaheranamltiplaqueeu
mencioneianteriormente.Nsvoltaremosaosmixinsembreve.Antesdisso,vamosdaruma
olhadanosnamespaces.
Pg.78
PequenoLivrodoRubyCap.9MduloseMixins
modules1.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
moduleMyModule
GOODMOOD="happy"
BADMOOD="grumpy"
defgreet
return"I'm#{GOODMOOD}.Howareyou?"
end
end
defMyModule.greet
return"I'm#{BADMOOD}.Howareyou?"
end
puts("MyModule::GOODMOOD")
puts(MyModule::GOODMOOD)
puts("MyModule.greet")
puts(MyModule.greet)
Vamosassumirquenstemosestemdulo:
moduleMyModule
GOODMOOD="happy"
BADMOOD="grumpy"
defgreet
return"I'm#{GOODMOOD}.Howareyou?"
end
defMyModule.greet
return"I'm#{BADMOOD}.Howareyou?"
end
end
Nspodemosacessarasconstantesusandoossinais::assim:
Pg.79
PequenoLivrodoRubyCap.9MduloseMixins
puts(MyModule::GOODMOOD)
Nspodemos,similarmente,acessarmtodosdomdulousandoanotaodepontoisto,
especificandoonomedomduloseguidodoponto.edonomedomtodo.Oseguintedeveria
imprimirI'mgrumpy.Howareyou?(Euestouirritado.Comovocest?):
puts(MyModule.greet)
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
moduleMyModule
GOODMOOD="happy"
BADMOOD="grumpy"
defgreet
return"I'm#{GOODMOOD}.Howareyou?"
end
end
defMyModule.greet
return"I'm#{BADMOOD}.Howareyou?"
end
Pg.80
PequenoLivrodoRubyCap.9MduloseMixins
includeMyModule
puts(greet)
puts(MyModule.greet)
defgreet
return"I'm#{GOODMOOD}.Howareyou?"
end
end
defMyModule.greet
return"I'm#{BADMOOD}.Howareyou?"
end
classMyClass
includeMyModule
Pg.81
PequenoLivrodoRubyCap.9MduloseMixins
defsayHi
puts(greet)
end
defsayHiAgain
puts(MyModule.greet)
end
end
ob=MyClass.new
ob.sayHi
ob.sayHiAgain
puts(ob.greet)
NosomenteosmtodosdestaclasseacessamomtodogreetdeMyModule,mastambm
quaisquerobjetosfilhosdaclassepodemacesslo,comoem:
ob=MyClass.new
ob.sayHi
ob.sayHiAgain
puts(ob.greet)
Emsuma,ento,osmdulospodemserusadoscomummeiodeagrupar,dejuntar,mtodos,
constanteseclassesrelacionadasdentrodeummesmoescopo.Assim,podemosverosmdulos
comounidadesdiscretasdecdigoquepodesimplificaracriaodebibliotecasdecdigoreusvel.
modules4.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
moduleMagicThing
defm_power
return@power
end
end
defm_power=(aPower)
@m_power=aPower
end
Pg.82
PequenoLivrodoRubyCap.9MduloseMixins
moduleTreasure
attr_accessor:value
attr_accessor:insurance_cost
end
classWeapon
attr_accessor:deadliness
attr_accessor:power
end
classSword<Weapon
includeTreasure
includeMagicThing
attr_accessor:name
end
s=Sword.new
s.name="Excalibur"
s.deadliness=10
s.power=20
s.m_power="GlowswhenOrcsAppear"
puts(s.name)
puts(s.deadliness)
puts(s.power)
puts(s.m_power)
Poroutrolado,vocpodeestarmaisinteressadoemusarmduloscomoumaalternativapara
heranamltipla.Retornandoaoexemploqueeumencioneinoinciodocaptulo,vamosassumir
quevoctemumaclasseSword(espada)quenosomenteumtipodeWeapon(arma)mas
tambmumtipodeTreasure(tesouro).PodeserSwordumadescendentedaclasseWeapon(logo
elaherdaseusmtodostaiscomoletalidadeepotncia),maselatambmdevertermtodosda
classeTreasure(taiscomovalorecustodeseguro).Sevocdefineestesmtodosdentrodeum
mduloTreasureemvezdeumaclasseTreasure,aclasseSwordpoderiaincluiromduloTreasure
paraadicionar(misturarmixin)osmtodosdeTreasureaosprpriosmtodosdaclasseSword.
Notequequaisquervariveisquesolocaisparaomdulonopodemseracessadasdeforado
mdulo.Esteocasomesmoseummtododentrodomdulotentasseacessarumavarivellocale
estemtodofossechamadopelocdigodeforadomduloporexemplo,quandoomdulo
misturadoatravsdeincluso.Oprogramamod_vars.rbilustraisso.
Pg.83
PequenoLivrodoRubyCap.9MduloseMixins
mod_vars.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
#localvariablesdeclaredinsideamodulearenot
#accessibleoutsidethemoduleevenwhenthemodule
#ismixedin.
x=1
#localtothisprogram
moduleFoo
x=50
#localtomoduleFoo
#Thiscanbemixedinbutthevariablexwon'tthenbe
visible
defno_bar
returnx
end
defbar
@x=1000
#Youcanmixinmethodswithinstance
variables,however!
return@x
end
puts("InFoo:x=#{x}")#thiscanaccessitslocalx
end
includeFoo
puts(x)
#puts(no_bar)
neededby
puts(bar)
#Thiscan'taccessthemodulelocalvariablex
#theno_barmethod
Atagora,nstemosmisturadosmdulosqueforamtodosdefinidosdentrodeumnicoarquivo
fonte.Freqentementemaistildefinirosmdulosemarquivosseparadoseincluilosquando
necessrio.Aprimeiracoisaquevoctemquefazerparausarocdigodeoutroarquivocarregar
Pg.84
PequenoLivrodoRubyCap.9MduloseMixins
oarquivousandoomtodorequire,destaforma:
requiremodule.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
require("testmod.rb")
puts("MyModule.greet")
puts(MyModule.greet)
puts("MyModule::GOODMOOD")
puts(MyModule::GOODMOOD)
#puts(greet)#=>Thiswon'twork!
includeMyModule#mixinMyModule
puts("greet")
puts(greet) #=>Butnowthisdoeswork!
puts("sayHi")
puts(sayHi)
puts("sayHiAgain")
puts(sayHiAgain)
sing
puts(12346)
testmod.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
moduleMyModule
GOODMOOD="happy"
BADMOOD="grumpy"
defgreet
return"I'm#{GOODMOOD}.Howareyou?"
end
defMyModule.greet
return"I'm#{BADMOOD}.Howareyou?"
end
defsayHi
Pg.85
PequenoLivrodoRubyCap.9MduloseMixins
end
end
returngreet
defsayHiAgain
returnMyModule.greet
end
defsing
puts("Tralalalala....")
end
puts("moduleloaded")
sing
Oarquivorequeridodeveestarnodiretriocorrente,nocaminhodeprocuradosistemaoperacional
(path)ouemumapastalistadanavariveldearraypredefinida$:.Vocpodeadicionarum
diretrioaestearrayusandoomtodo<<destaforma:
$:<<"C:/mydir"
Omtodorequireretornatrueseoarquivoespecificadocarregadocomsucesso;senoele
retornafalse.Emcasodedvida,vocpodesimplesmentemostraroresultado:
puts(require("testmod.rb"))
Mdulo Predefinidos
OsseguintesmdulosestoembutidosnointerpretadordoRuby:Comparable,Enumerable,
FileTest,GC,Kernel,Math,ObjectSpace,Precision,Process,Signal
OmaisimportantedosmdulospredefinidosoKernelque,comojmencionei,fornecemuitos
dosmtodospadrodoRubytaiscomogets,puts,printerequire.Emcomumcommuitasdas
classesdoRuby,omduloKernelescritonalinguagemC.MesmooKernelsendo,defato,
embutidonointerpretadorRuby,conceitualmenteelepodeserconsideradocomoummdulo
misturadoque,comoummixinnormaldoRuby,tornaseusmtodosdiretamentedisponveispara
quaisquerclassesqueosrequeiram;jqueelemisturadonaclasseObject,daqualtodasasoutras
classesdoRubydescendem,osmtodosdomduloKernelsouniversalmenteacessveis.
Pg.86
PequenoLivrodoRubyCap.10SalvandoArquivos,Avanando...
Gravando dados
AgorahoradefinalizarestePequenoLivrodoRuby.Vamosfazeristovendomaisumexemplo
umpequenobancodedadosdeCdsquepermitevoccriarnovosobjetos(umobjetoparacada
discoemsuacoleodeCds),adicionlosaumamatrizeosarmazenlosemdisco.
ParagravarosdadosnodiscoeuuseiabibliotecaYAMLdoRuby:
#savesdatatodiskinYAMLformat
defsaveDB
File.open($fn,'w'){
|f|
f.write($cd_arr.to_yaml)
}
end
YAML
Pg.87
PequenoLivrodoRubyCap.10SalvandoArquivos,Avanando...
YAMLdescreveoformatoparagravardadoscomotextolegvelpornshumanos.Osdados
podemserdepoisrecarregadosdodiscoparaconstruirumamatrizdeobjetosCDnamemriado
computador:
defloadDB
input_data=File.read($fn)
$cd_arr=YAML::load(input_data)
end
Muitodacodificaodestepequenoprogramadeveserfamiliarsooriundosdenossosexemplos
anteriores.Algumascoisasdevemserressaltadas,porm.Primeiro,asvariveisiniciandocomum
sinal$soglobaislogosousadasportodoocdigodoprograma(lembresedasvariveisde
instncia,queiniciamcom@,quesousadassomenteporumobjetoespecfico;enquanto
variveislocais,queiniciamcomumaletraminscula,somentesousadasdentrodeumescopo
bemdefinidocomoummtodoespecfico).
Arquivos
TambmnotequensusamosaclasseFileparaverificarseumarquivoexiste:
ifFile.exist?($fn)
Aqui,exist?um'mtododeclasse'isto,estligadoclasseFileenoaumainstnciada
classeFile.OqueexplicacomonsinvocamosomtododiretamentedeFileemvezdechamlo
deumnovoobjetocriadodeFile.Istodevetlofeitoselembrardosmtodosdemdulos
discutidosnoCaptuloNoveoutroexemplodesemelhanasentremduloseclasses.
data_save.rb
#RubySampleprogramfromwww.sapphiresteel.com/
www.bitwisemag.com
require'yaml'
#arrayforcdobjects
$cd_arr=Array.new
#filenameforsaving/loading
Pg.88
PequenoLivrodoRubyCap.10SalvandoArquivos,Avanando...
$fn='cd_db.yml'
#ancestorgenericCDclass
classCD
#initializevariablesparsedfromarrayargument
#(arr)
definitialize(arr)
@name=arr[0]
@artist=arr[1]
@numtracks=arr[2]
end
#returnanarraycontainingallinstancevariables
#ofaCDobject
defgetdetails
return[@name,@artist,@numtracks]
end
end
#PopCDisa'child'classofCD
classPopCD<CD
#callsupertopassarray,arr,toparent(CD)class
#Thisinitializesthreeinstancevariables.This
#methodtheinitializesonemore:@genre
definitialize(arr)
super(arr)
@genre=arr[3]
end
#callssuptogetarrafromCDclassgetdetails
#method.Thenadds@genretotheendofthearray
#andreturnstheentier4itemarray
defgetdetails
return(super<<@genre)
end
end
classClassicalCD<CD
definitialize(arr)
super(arr)
@conductor=arr[3]
@composer=arr[4]
Pg.89
PequenoLivrodoRubyCap.10SalvandoArquivos,Avanando...
end
defgetdetails
return(super<<@conductor<<@composer)
end
end
#somemethodstogetdatafromtheuser
defotherCD
print("EnterCDname:")
cd_name=gets().chomp()
print("Enterartist'sname:")
a_name=gets().chomp()
print("Enternumberoftracks:")
num_tracks=gets().chomp().to_i
return[cd_name,a_name,num_tracks]
end
defclassicCD
cdInfo=otherCD
print("Enterconductor'sname:")
con_name=gets().chomp()
print("Entercomposer'sname:")
comp_name=gets().chomp()
cdInfo<<con_name<<comp_name
returncdInfo
end
defpopCD
cdInfo=otherCD
print("Entergenreofmusic:")
genre=gets().chomp()
cdInfo<<genre
returncdInfo
end
#addsaCDobjecttothearrayvariable,$cd_arr
defaddCD(aCD)
$cd_arr<<aCD
end
#savesdatatodiskinYAMLformat
#theto_yamlmethodconvertstoYAMLformat
Pg.90
PequenoLivrodoRubyCap.10SalvandoArquivos,Avanando...
defsaveDB
File.open($fn,'w'){
|f|
f.write($cd_arr.to_yaml)
}
end
#loadsdatafromdiskandrecreatesthearrayof
#cdobjects,$cd_arr,fromthedata
defloadDB
input_data=File.read($fn)
$cd_arr=YAML::load(input_data)
end
#printsthedatafromthearraytoscreeninhuman
#readable(YAML)format
defshowData
puts($cd_arr.to_yaml)
end
#StartofProgram
ifFile.exist?($fn)then
loadDB
showData
else
puts("Thefile#{$fn}cannotbefound.")
end
#'main'loop
ans=''
untilans=='q'do
puts("Create(P)opCD(C)lassicalCD,(O)therCD(S)aveor
(Q)uit?")
print(">")
ans=gets[0].chr().downcase()
caseans
when'p'thenaddCD(PopCD.new(popCD()))
when'c'thenaddCD(ClassicalCD.new(classicCD()))
when'o'thenaddCD(CD.new(otherCD()))
when's'thensaveDB
end
Pg.91
PequenoLivrodoRubyCap.10SalvandoArquivos,Avanando...
showData
end
Avanando...
AcomunidadeRubymuitoativaatualmenteenovosprojetosestosurgindoconstantemente.Para
manterseatualizado,nssugerimosquevocvisiteositeSapphireInSteel
(www.sapphiresteel.com)paraencontraroslinksdealgunsdosmaisteisrecursosparaos
programadoresRuby.Nstambmdevemosadicionarmaistutoriaiseprojetosexemploaositepara
continuarnossaexploraodaprogramaoemRuby.
Concluindo,euesperoquevoctenhaaproveitadoestapequenaintroduolinguagemRubyeque
possaserapenasoinciodemuitosanosdeumprazerosoeprodutivodesenvolvimentoemRuby.
Pg.92