Documentos de Académico
Documentos de Profesional
Documentos de Cultura
RubyFacil 071105
RubyFacil 071105
RubyFcil
porDiegoFGuilln
Noviembre,2007
DerechosReservados2007
RubyFcil
Contenido
Parte0...................................................................................................................................................4
BreveHistoria..................................................................................................................................4
Audiencia........................................................................................................................................4
Motivacin.......................................................................................................................................4
CmoInstalarRubyenWindows....................................................................................................5
CmoInstalarRubyenLinux..........................................................................................................5
ParteI....................................................................................................................................................6
Leccin1.RubyInteractivo.............................................................................................................7
Leccin2.Nmeros.........................................................................................................................9
Leccin3.Funcionesmtematicaspredefinidas..........................................................................11
Leccin4.CadenasdeCaracteres..................................................................................................13
Leccin5.Arrays...........................................................................................................................15
Leccin6.FechasyHoras.............................................................................................................16
Leccin7.Hash..............................................................................................................................17
Leccin8.EachyBloques.............................................................................................................18
Leccin9.ContadoresyAcumuladores........................................................................................20
Leccin10.ExpresionesCondicionales........................................................................................22
ParteII................................................................................................................................................23
CmousarSciTE...........................................................................................................................23
Leccin11.LgicaCondicional....................................................................................................25
Leccin12.CiclosRepetitivos......................................................................................................26
Leccin13.CondicionesMltiples(Case)....................................................................................29
Leccin14.Funciones....................................................................................................................31
Leccin15.Clases.........................................................................................................................34
Leccin16.AtributosdeClases.....................................................................................................37
Leccin17.ControldeAccesoalaClase......................................................................................39
Leccin18.HerenciayTaxonomas..............................................................................................40
Leccin19.ExpresionesRegulares................................................................................................41
Leccin20.Archivos.....................................................................................................................43
Leccin21.Directorios..................................................................................................................46
Leccin22.Entrada/Salida,CorrientesyTubos............................................................................47
Leccin23.Formatosdesalida.....................................................................................................49
Bibliografa.........................................................................................................................................64
LibrosImpresos.............................................................................................................................64
EnlacesenInternet.........................................................................................................................65
CuriosidadesMatemticas.............................................................................................................66
DerechosReservados2007
RubyFcil
BibliotecasGrficasparaRuby......................................................................................................67
ApndiceA.ElCdigoASCII...........................................................................................................68
ApndiceB.ComusarSciTE...........................................................................................................69
B.1PrimerpasoEdicin.............................................................................................................69
B.2SegundopasoGuardareltrabajo........................................................................................70
B.3TercerpasoEjecutarelprograma.........................................................................................71
SobreelAutor.....................................................................................................................................73
DerechosReservados2007
RubyFcil
Parte0
BreveHistoria
EllenguajeRubyfueinventadoporYukihiroMatzMatsumoto,enJapn,en1995.Siguiendola
tradicindeloslenguajesdeprogramacinquehansidodesarrolladosrecientemente,yquegozan
depopularidad,Rubyesunlenguajeinterpretado,gratuito(OpenSource),yorientadoporobjeto.
MatzadmitequeseinspirenloslenguajesPerlyPython,peroRubyesmuchomsorientadopor
objeto;dehecho,todoenRubysonobjetos.
EnJapn,estelenguajegozadeunapopularidadmayorqueladellenguajePython,quetambines
muypopularenelmundoentero.
Rubyesunlenguajegenricoquesepuedeutilizarenmuchoscampos:desdeprocesamientode
textoyprogramacinwebconCGI,hastaingeniera,gentica,yprogramacincomercialagran
escala.
LacomunidadRubysiguecreciendomundialmente,yahoraquetambinhasalidolaplataforma
RubyonRailsparaprogramaraplicacionesWeb,estelenguajecobracadadamsseguidores.
Audiencia
Estelibrohasidoescritoprincipalmenteparanovatos,peroesperamosquelosprofesionalesen
sistemastambinloencuentrentil.
Enlos1980s,cuandopasamosporlauniversidad,saberprogramaruncomputadoreraunacosa
esotrica,ylagenteloconsiderabacosadebrujos.Hoyendaestatecnologaseencuentraen
todaspartes,yhastalosestudiantesdelasescuelasprimariasestnaprendiendoaprogramar.
Asqueestelibroesparalagentecuriosa,quetieneaccesoaInternet,yquetieneintersensaber
cmofuncionanlascosas.Elnicoprerequisitoestenerunconocimientodematemticasbsicas
(lgebraytrigonometra),parapoderhacerlosejercicios.
Motivacin
Siguiendolaevolucindeestelenguajedesdeelprincipio,nosdamoscuentadequesuacogidaha
sidotremendaenlosltimosdosaos.Nosbastaraconverlacantidaddelibrosquehansalido
DerechosReservados2007
RubyFcil
sobreeltema.Comovanlascosas,muyprontoelconocimientodeRubysernecesariopara
conseguirunempleoenelreadesistemasycomputadores.
Alescribirestelibro,elobjetivonoerareemplazarnisuperaralosotrostextosexistentessobre
Ruby,sinomsbienayudarademistificareltemadelaprogramacinyhacerloaccesiblealas
masas.Yqumejorquehacerloconunlenguajemodernoybonito,comoloesRuby.
Enunapocaenqueloscomputadoressehacencadavezmspoderosos,loslenguajesde
programacinyanotienenporquserorientadossolamentehacialamquina;debenserorientados
hacialossereshumanosquelovanausar.Rubyhasidodiseadoconelprogramadorencuenta;
comodiceMatz:Rubyhasidodiseadobajoelprincipiodemenorsorpresa,esdecir,entre
menosnossorprenda,mejor.Hasidodiseadoparasereshumanos.
Rubyesunlenguajefcil,eleganteyentretenido.AprendamosaprogramarenRuby!
CmoInstalarRubyenWindows
ParaWindows,bajaraRubydesdeelsiguientesitio:
http://www.rubylang.org/en/downloads/
ElinstaladordeRubysellama:
Ruby_x.y.z_OneClick_Installer
(dondex.y.zsonnmerosdeversin;
alescribirestedocumento,estosnmeroseran1.8.6)
Despusdequehayabajado,correrlo,aceptartodoslosdefaults,hastaverelbotnde[Finish].
Asumimosquequedainstaladoeneldirectorio:c:\ruby
CmoInstalarRubyenLinux
ParainstalarRubyconUbuntu(oDebian),lasdistribucindeLinuxmspopular,laformamsfcil
esescogerloeinstalarloconelinstaladorSynaptic:
System>Administration>SynapticPackageManager.
Alternativamente,ejecutarelsiguientecomandodesdeunaconsola:
sudoaptgetinstallrubyirbrdoc
DerechosReservados2007
RubyFcil
ParteI
Paralosejerciciosdeestaseccin,seasumelosiguiente:
1. QueRubyyahasidoinstaladopropiamente,y,
2. quevamosausarelcomandodeRubyInteractivo,irb.
Enesteconjuntodeleccionesvamosaexaminarelusodevariablesyestructurasdedatosprimitivas
(sencillas)enRuby,asaber:
nmeros(enteros,yreales),
elmduloMath,
arreglos(arrays),
hashes,
fechasyhoras,y
cadenasdecaracteres(strings).
DerechosReservados2007
RubyFcil
Leccin1.RubyInteractivo
ParaempezaraRubyinteractivo,hacerlosiguiente:
EnWindows,abrirunaventanadecomando:
[Inicio]Ejecutar...cmd[Enter]
ElcomandoparacorrerRubyinteractivoes:irb[Enter]
EnLinux,abrirunaconsolayescribir:irb
Seabreunapantalla,comoenlaFigura1.
$irb
irb(main):001:0>a=5#esteesuncomentarioparaexplicarelcodigo;
5#loquesaledespuesdeeselresultado
irb(main):002:0>b=7#hechoporRuby
7
irb(main):003:0>a+b
12
irb(main):004:0>ab
2
irb(main):005:0>a*b
35
irb(main):006:0>a**b
78125
irb(main):007:0>quit
$
Figura1.UnasesinconRubyinteractivo(irb)
Paraterminarlaejecucindeirb,escribir:quitoexit.
DerechosReservados2007
RubyFcil
Rubyesunlenguajedeprogramacinmoderno.Ensta,yenlasleccionesquesiguen,veremos
cmocobranvidalasmatemticasconRuby.
Empezamosconunaasignacinaunavariable:
a=5
Asseguardaelvalor5enunavariable'a'.Elsigno"="seusaenlasasignaciones,peronotieneel
mismosignificadoque"igualdad"enmatemticas,sinomsbienescomodecir:"guardeel
resultadodelaexpresindeladerechaenlavariabledelaizquierda".Esdecir,seescribe"a=5",
peroesmsbiencomodecir"a5".Estoesimportanterecordarlo,paramsadelantecuando
estudiemosigualdadyhagamoscomparaciones.
Porconvencin,enRubyusamospalabrasqueempiezenconletrasminsculas,paradesignar
variables.Lossiguientessonalgunosnombresaceptablesparavariables:
laCaja,unBanco,voltaje.
Tambin,porconvencin,usaremospalabrasenmaysculasparadesignarconstantes.Porejemplo:
PI=3.14159
Ejercicio1.1:Ensayarlasoperacionesbsicas:+(suma),(resta),*(multiplicacin),/(divisin),
**(potencia).Entrarunaasignacinporlnea.Lasasignacionespuedensercomplejasyse
puedenusarparntesis;talescomoenesteejemplo:(8*7)**2+(48/3).Laexpresin
complejadebeestaraladerechaylavariablesolaenlaizquierda(delsigno=).
Tomarencuentaquelaaritmticadenmerosenterosesdiferentequelaaritmticadenmeros
reales.Esdecir,lassiguientesdosasignacionesdanresultadosdiferentes:
a=3/2
b=3.0/2.0
1
1.5
Tambinsepuedenhacerasignacionesconpalabras,ocadenasdecaracteres,comoselesconoce
enellenguajetcnico:
nombre="AugustusCaesar"
saludos=Salut,+nombre
Enestecaso,eloperador"+"funcionacomoconcatenador(pegaunacadenadeletrasconotra),
produciendo:
saludos=Salut,AugustusCaesar
Elcomando"puts"(putstring)imprimeunmensaje,oelresultadodeunacomputacin:
putssaludos
Salut,AugustusCaesar
Conestobsico,yapodemosempezaraexplorarellenguajeRuby.
DerechosReservados2007
RubyFcil
Leccin2.Nmeros
Rubymanejadostiposdenmeros:enterosyreales.
Delaleccinanterior,recordemosquelaaritmticadenmerosenterosesdiferentealadenmeros
reales.Esdecir,lassiguientesdosasignacionesdanresultadosdiferentes:
a=3/21#divisionenteraignoraelsobrante
b=3.0/2.01.5
Losnmerosenterosseexpresancomounacadenadedgitosnumricos,precedidos,ono,porun
signo.Ejemplo:15,0,3000.
Otrasformasdeexpresarnmerosenterossonlassiguientes:
123_456
0377
0xff
0b1011
#equivalea123456;elunderscore_facilitalalectura
#octales(base8)empiezanconcero
#hexadecimales(base16)empiezancon0x
#binarios(base2)empiezancon0b
Losnmerosreales,tambinllamadosnmerosdepuntoflotante,incluyenunpuntodecimal
entrevariosdgitosnumricos.Ejemplo:32.68,4500.651
Otrasformasdeexpresarnmerosdepuntoflotantesonlassiguientes:
1.0e6
4e20
#equivalea1.0*10**6;notacioncientifica
#equivalea4*10**20;omiteelpuntodecimalycero
LaverdadesqueRubymanejacadanmerocomosifueraunobjeto,demaneraqueselepuede
aplicarunafuncinqueactasobreesetipodenmero.
Algunasdelasfuncionesqueactansobrelosnmerosenterossonlassiguientes:
i=5
i.to_s
i.to_f
i.next
j=7
i==j
"5"
5.0
6
7
false
j%5
#definamosunentero
#convierteacadena(string)
#convierteareal(floating)
#sucesor(n+1)
#definamosotroentero
#comparacionporigualdad(doblesigno=)
#comparaelcontenidodeiconj
#divisionpormodulo;retornaelsobrante
Algunasdelasfuncionesqueactansobrelosnmerosrealessonlassiguientes:
r=3.14
DerechosReservados2007
3.14
RubyFcil
r.to_i
r.to_s
r.abs
s=3.14
r==s
r.ceil
r.floor
r.round
(r/0.0).finite?
(r/0.0).infinite?
(0/r).zero?
r%3.0
3
"3.14"
3.14
3.14
true
3
4
3
false
true
true
0.14
#convierteanumeroentero(integer)
#convierteacadena(string)
#retornaelvalorabsoluto
0==0.0
true
#comoesdeesperarse
#comparacionporigualdad
#elenteroinmediatosuperiorar(ceiling)
#elenteroinmediatoinferiorar(floor)
#redondeoalmasproximoentero
#pruebasilaoperacionesfinita
#pruebasilaoperacionesinfinita
#pruebasilaoperaciondaceroono
#divisionpormodulo;retornaelsobrante
LosnmerosenterossepuedenusarparagenerarletrasdelcdigoASCII:
65.chr
"A"
Ejercicio2.1:Verificartodaslasoperacionesanteriores.
Ejercicio2.2:Calculemospi()porvariosmtodosnumricos:
Paraesteejercicio,queinvolucranmerosreales,debemosescribirporlomenosunodelos
nmerosenformareal(decimal).
Ejercicio2.2.1:HiparcocalculenelsigloIIACcomo377/120.Ensayarloconirb.
Ejercicio2.2.2:ArqumedesdeSiracusapredijoqueestabaentre310/71y31/7,considerandoun
polgonode96lados.Expresarestosnmerosconirb.
Ejercicio2.2.3:EnChina,LiuHui(263DC)predijoqueestabacercade355/113.
Ejercicio2.2.4:Fibonacci(LeonardodePisa)calculcomo864/275.
Ejercicio2.3:EscribirunaecuacinqueconviertatemperaturadeFarenheitaCentgrados.
Ejercicio2.4:EscribirunaecuacinqueconviertatemperaturadeCentrgradosaFarenheit.
Ejercicio2.5:Escribirunaecuacinqueconviertadegradosaradianes.
Ayuda:2radianesequivalea360grados.
Ejercicio2.6:Escribirunaecuacinqueconviertaderadianesagrados.
[Algunassolucionesalosejerciciosestnalfinaldeltexto]
DerechosReservados2007
10
RubyFcil
Leccin3.Funcionesmtematicaspredefinidas
Lasfuncionesmatemticasseencuentranagrupadasenun"mdulo"separadollamado"Math".Por
eso,parainvocarlas,hayqueprecederelnombredelafuncinconelnombreMath,yponerun
puntoentreambas:
Math.sqrt(25)
#resultado
Ejercicio3.1:Ensayarlassiguientesfuncioneselementales:
sin(),cos(),tan(),exp(),log(),log10().
Ejercicio3.2:CalcularlahipotenusadeuntringulorectngulousandolafuncinMath.hypot(x,y).
Ejercicio3.3:Laecuacinalgebraica ax 2bx c=0 tienesoluciones
x=
b b24ac
.Calcularxconirb,cuandoa=3,b=6,y,c=2.
2a
Ejercicio3.4:Ensayarlasfuncionestrigonomtricasinversas:
acos(),asin(),atan().
Ejercicio3.5:Ensayarlasfuncioneshiperblicas:
sinh(),cosh(),tanh().
Ejercicio3.6:Eulerusestasfrmulasparacalcular(expresarlasyevaluarlasenirb):
/4=5arctan(1/7)+2arctan(3/79)
/4=2arctan(1/3)+arctan(1/7)
Ejercicio3.7:En1961,WrenchyShanksdeIBMcalcularona100,200dgitosusandolasiguiente
frmula(lestom8horasenuncomputadorIBM7090delapoca):
=24arctan(1/8)+8arctan(1/57)+4arctan(1/239)
Ejercicio3.8:ConfirmarquelaconstantedeRuby,expresadacomoMath::PI,tieneunvalorque
correspondeavariasdelasfrmulasanteriores.Acules?
OtrovalortambindefinidoenelmduloMatheseldelaconstanteexponenciale(tienemuchos
usoseningenierayenmatemticas,pueseslabasedeloslogaritmosnaturales)
e=Math::E
DerechosReservados2007
2.71828182845905
11
RubyFcil
DerechosReservados2007
12
RubyFcil
Leccin4.CadenasdeCaracteres
Otraestructuradedatosimportanteenprogramacinsonlascadenasdecaracteres,oStrings,en
ingls.Confrecuenciaseusalapalabracadenassimplemente.Lascadenasseusanpara
representarpalabrasygruposdepalabras.
Lascadenasseescribenentrecomillas,simplesodobles:
cadena1="estaesunacadenadecaracteres\n"
cadena2='yestaesotra'
Ladiferenciaesquelascadenasqueusancomillasdoblespuedenincluircaracteresespecialestales
como\t(tab),\n(carriagereturn),ynmerosendiferentesrepresentaciones(octales,\061,
hexadecimal,etc).
Comosevioenlaleccinanterior,losenterosylosrealestambinsepuedenconvertiracadenas:
i=5
i.to_s
r=3.14
r.to_s
5
"5"
3.14
"3.14"
#valorentero
#cadena
#valorreal
#cadena
Alternativamente,lascadenassepuedenconvertiranmeros:
"123".oct
"0x0a".hex
"123.45e1".to_f
"1234.5".to_i
"0a".to_i(16)
"1100101".to_i(2)
83
10
1234.5
1234
10
101
#cadenaoctalaentero
#cadenahexadecimalaentero
#convierteareal
#convierteaentero
#conviertedesdehexadecimal
#conviertedesdebinario
Lanotacinespecial#{}reemplazaelvalordeunavariabledentrodeunacadena:
edad=25
"Laedades#{edad}"
"Laedades25"
"Laedades"+edad.to_s
#expresinequivalente
Algunasdelasfuncionesqueaplicanacadenassonlassiguientes:
s="ja"
s*3
s+"ji"
"ja"
"jajaja"
"jaji"
#unacadenacontrescopiasconcatenadas
#elsigno+seusaparaconcatenarcadenas
z="za"
z==s
"za"
false
#elcontenidodelascadenasesdistinto
y="ab"
y<<"cde"
y.length
"ab"
"abcde"
5
#append:concatenaalfinaldelacadena
#elnmerodecaracteresenlacadena
DerechosReservados2007
13
RubyFcil
Funcionesrelacionadasconletrasminsculasymaysculas:
y.upcase
"MN".downcase
"Az".swapcase
"sam".capitalize
"ABCDE"
"mn"
"aZ"
"Sam"
Lasletrasdelacadenasepuedenaccesarindividualmenteponiendounndiceentreparntesis
rectangulares[idx]:(elprimerelementotienendicecero)
y[0]
y[1]
97
98
#retornaelcdigodelcaracterenlaposicin0,"a"
#retornaelcdigodelcaracterenlaposicin1,"b"
Alasignarunvaloraunacadenaconndice,secambiaelcaracterenesaposicin:
y[0]="z"
y
"z"
"zbcde"
Parainsertaryborrarletrasdelacadena:
y.delete("z")
y.insert(2,"x")
y.reverse
"bcde"
"zbxcde"
"edcbz"
Ejercicio4.1:VerificartodaslasoperacionesanterioresconRubyinteractivo.
DerechosReservados2007
14
RubyFcil
Leccin5.Arrays
Elconceptodearrayseningls,ovectores,oarreglos,consisteunconjuntodedatosdiscretos
(nmerosopalabras),todosbajoelnombredeunavariable,demaneraquepuedandespus
accesarseporndice.
a=["Jairo","y","Orfa","se","quedan","en","casa"]
a.size
7
#elnmerodeelementosenlalista
a[i]nosretornael(i1)simoelementodelalista.Poresodecimosquetienebase0(elprimer
elementotienendice0,elsegundo1,etc).
a[2]
"Orfa"
Paraalterarunalista,podemosaadirelementosalfinal:
b="viendolatelevision".split#parteelstringenarraydepalabras
a.concat(b)
["Jairo","y","Orfa","se","quedan","en","casa",
"viendo","la","television"]
Otrasfuncionesprcticasconarreglos:
a.first
a.last
a.empty?
"Jairo"
"television"
false
#accesaelprimero
#accesaelultimo
#preguntasiestavacia
Unarreglocomplejopuedetenerotrosarreglosadentro:
c=[1,2,3,[4,5,[6,7,8],9],10]
Paraaplanarlousarlafuncinflatten:
c.flatten
[1,2,3,4,5,6,7,8,9,10]
Parainsertarelementosseusalafuncininsert(ndice,valor):
c.insert(3,99)
[1,2,3,99,4,5,6,7,8,9,10]
Parainvertirelordendeunarreglo,seusalafuncinreverse:
["a","b","c"].reverse
["c","b","a"]
Paraordenarunarreglo,usarlafuncinsort:
["p","z","b","m"].sort
["b","m","p","z"]
Popypush,remuevenyaaden(respectivamente)elementoshaciaelfinaldelarreglo:
d=["Mozart","Liszt","Monk"]
d.pop
"Monk"
d
["Mozart","Liszt"]
d.push("Bach")
["Mozart","Liszt","Bach"]
d.unshift("Beethoven")
["Beethoven","Mozart","Liszt","Bach"]
Paraconcatenarloselementosdeunarregloproduciendounacadena:
["p","z","b"].join(",")
"p,z,b"
Ejercicio5.1:VerificartodoloanteriorconRubyinteractivo.
DerechosReservados2007
15
RubyFcil
Leccin6.FechasyHoras
Todosloslenguajesdeprogramacintienenunaformaespecialdemanipularfechas,puesestaes
unadelastareascotidianasenlasoficinas.
RubytieneunmdulollamadoTimeparamanipularfechasyhoras.
Lafechayhoracorrienteseobtienenconlafuncinnow:
t=Time.now
"MonSep1023:11:06+10002007"
Elresultadoesunacadenadeletrasynmeros,quesepuedendespusaccesarindividualmentecon
otrasfuncionesadicionales:
t.day
t.month
t.year
t.hour
t.min
t.sec
t.wday
t.yday
t.strftime("%B")
t.strftime("%b")
t.strftime("%A")
t.strftime("%a")
t.strftime("%p")
10
9
2007
23
11
6
1
253
"September"
"Sep"
"Monday"
"Mon"
"PM"
#primerdadelasemana
#dadelao
#nombredelmescompleto
#idemabreviado
#nombredeldadelasemana
#idem,abreviado
#AMoPM
Unaaplicacionprctica,comunmenteusada,escreardosvariablesdetiempoaintervalos
diferentes,yluegosacarladiferencia,paravercuntotiemposehademoradolaejecucindeun
programa.
Ejercicio6.1:VerificartodaslasoperacionesanterioresconRubyinteractivo.
DerechosReservados2007
16
RubyFcil
Leccin7.Hash
ExisteotraestructuradedatosbastanteconvenientellamadoelHash.
Consisteenunarregloquepermitealmacenarvaloresindexadosporpalabras(adiferenciadel
Array,queindexalosvalorespornmerosnaturales).
Asseusaraunhashqueempiezavaco,ypocoapocoselevanaadiendoelementos:
genios=Hash.new
genios["matematicas"]="Gauss"
genios["violin"]="Paganini"
#declaraunhashnuevo,lavariablegenios
#"matematicas"indice,y"Gauss"elvalor
Normalmenteseusaunhashparaalmacenarparesdecosasrelacionadasentres,talescomolas
palabrasdeundiccionarioysusdefiniciones,olasvecesqueocurrecadapalabraenuntexto,por
ejemplo.
Unhashsepuedeinicializarcontodoslosvaloresdesdeelprincipio:
lang={
'Perl'=>'Larry',
'Python'=>'Guido',
'Ruby'=>'Matz'
}
#declaraunhash,lavariablelang
#relacionalenguajesconsusautores
#elsigno=>separallavedevalor
lang['Ruby']
lang.has_key?('Fortran')
lang.has_value?('Napoleon')
lang.sort
lang.values_at('Python','Ruby')
lang.values
lang.keys
Matz
#accesaunvalor
false
#preguntasiexistellave
false
#preguntasiexistevalor
#ordenaporordendellave(key)
['Guido','Matz']
['Larry','Guido','Matz']
['Perl','Python','Ruby']
Parareemplazarparesexistentes,convaloresnuevos,simplementehacerasignacionesconndicey
valor:
lang['Ruby']='Matsumoto'
#reemplaza'Matz'con'Matsumoto'
Paraeliminarparesqueyanosenecesitan,usarlafuncindelete:
lang.delete('Perl')
#eliminaelpar'Perl'=>'Larry'
Ejercicio7.1:VerificartodaslasoperacionesanterioresconRubyinteractivo.
DerechosReservados2007
17
RubyFcil
Leccin8.EachyBloques
Antesdeseguirconcosasmscomplicadas,aprendamoscmoiterarovisitarloselementosde
unArrayounHash,unoporuno,parahaceralgoconellos.
Hayunafuncinllamadaeach(cadauno),quesepuedeaplicaraunArrayoaunHash,oaun
stringdevariaslneas,paraiterarsobresuselementos.Lasintaxises:
variable.each{bloque}
Elresultadoeselsiguiente:Lasinstruccionesqueseencuentrandentrodelbloque,sevanaaplicar
acadaunodeloselementosdelavariable.Esdecir,seproduceunciclorepetitivodondeencada
pasada,oiteracindelciclo,seevalaunodeloselementosdelarray(ohash),enformasucesiva,
empezandoconelprimero,luegoelsegundo,etc,hastallegaralltimo.
VeamosunejemploconunArraynumrico:
a=[2,4,13,8]
a.each{|i|putsi}
2
4
13
8
#empecemosconesteArray
#porcadaelemento|i|de'a',imprimirlo:
#dentrodelbloque,i2yluegoputs2
#sigueconi4yluegoputs4
#etc
AhoraveamoscmoseaplicaelmismoconceptoaunHash.RecordemosqueelHashalmacena
paresdeelementos:{llave=>valor}.
b={'sol'=>'dia','luna'=>'noche'}#empecemosconunhash
b.each{|k,v|putsk+":"+v}#paracadapar|k,v|de'b'
sol:dia
#k'sol',v'dia',eimprimeel1erpar
luna:noche
#k'luna',v'noche',eimprimeel2dopar
Enlugardelasllaves{}deleach,sepuedenusarlaspalabrasdoyend,yexpresarelbloqueentre
variaslneas.Estoesconvenientecuandoloquevadentrodelbloquepuedetenerunalgicaun
pocomselaboradaquenocabeenunasolalnea.
DerechosReservados2007
18
RubyFcil
Veamosunejemploaplicadoaunacadenadevariaslneas.Elsiguienteprogramaprocesaycuenta
laslneasdeuncuento,unalneaalavez:
lineas="Eraseunavez\nenunlugarlejano...\nFin\n"
num=0
lineas.eachdo|linea|
#usalapalabradoalprincipiodelbloque
num+=1
#elcontenidodelbloquevadepormedio
print"Line#{num}:#{linea}"#ysepuedeextendersobrevariaslineas
end
#usalapalabraendalfinaldelbloque
Elsignificadodelaexpresinnum+=1loestudiaremosenlaleccinsiguiente.
Ejercicio8.1.Verificarloqueocurreconlasexpresioneslistadasenestaleccin.Cambiarlos
valoresdelarraya,hashbocadenalines,hastaasegurarsecmofuncionaesalgica.
Ejercicio8.2.UsarRubyinteractivoparacalcularloscuadradosylarazcuadradadelosnmeros
deunArray.
Ejercicio8.3.UsarRubyinteractivoparacalcularlalongituddelaspalabrasalmacenadasenun
Array.
DerechosReservados2007
19
RubyFcil
Leccin9.ContadoresyAcumuladores
Otrotematileselde"contadores"y"acumuladores".Setratadevariablesqueseutilizanpara
llevarcuentas,talescomosumas,oparacontarelnmerodevecesqueocurrenlasiteraciones.
Elprimertipodevariableesel"contador".Laexpresincontadorasiguienteesbastantecomn:
cuenta+=1
Estoesequivalenteadecir:
cuenta=cuenta+1
Recordemossetratadeunaasignacin,nodeunaigualdad.Asquequieredecirlosiguiente,
leyendodederechaaizquierda:
1.primero,secomputa:cuenta+1,
2.yluegoseasignaelresultadoa:cuenta.
3.elefectofinalesquesucontenidosehaincrementadoen1.
[Recordemosunconceptofundamental:queenunaasignacin,siemprelaexpresindelaizquierda
estasola,esdecir,eselnombredelavariablequerecibeelresultadodelaexpresinquesecalcula
aladerechadelsigno"="]
Elcontadorseusaparallevarlacuentadentrodeunciclo.
Porejemplo,siqueremossabercuntoselementostieneunarreglo'a':
cuenta=0
a.each{cuenta+=1}
puts"tiene#{cuenta}elementos"
#hayqueiniciarelcontadoren0
#cuentadentrodelciclo
#eimprimimoselresultado
Elejemploanterioressolamenteparailustrarelusodelcontador,
pues,comoyavimosenunaleccinanterior,enRubybastaraconhacera.sizeparasaberel
nmerodeelementosdeunarray.
Demanerasimilarsepodrapensarenuncontadorquecontarahaciaabajo:
count=1
Otraexpresinrelacionada,parecidaaun"contador",esun"acumulador".Esunavariableque
sumacantidadesarbitrarias.Laexpresinausareslasiguiente:
DerechosReservados2007
20
RubyFcil
suma+=cantidad
#equivaleasumasuma+cantidad
Habrnnotadoqueesparecidaalcontador,exceptoqueenlugardesumar1,sumaciertas
cantidadesarbitrariasqueseleasignandesdeladerecha.
Veamosunejemploparasumarloselementosdeunarreglo'a':
a=[13,17,19,29]
suma=0
a.each{|i|suma+=i}
puts"eltotales#{suma}"
#iniciaunarrayconnumeros
#inicialasumaen0
#cadaelementoiseacumulaenlavariablesuma
#produceelresultado
Ejercicio9.1:Verificarlasexpresionescitadas.
DerechosReservados2007
21
RubyFcil
Leccin10.ExpresionesCondicionales
CiertasexpresionesenRubyresultanenvaloresdeverdad:
true(verdadero)ofalse(falso).
Porejemplo,lassiguientesexpresiones(enformadecomparacin)evalanaunvalordeverdad:
a==b,x<=z,Math.sqrt(b)>c
Losoperadorespuedenserlossiguientes:
==(igualdad),<(menor),>(mayor),
<=(menoroigual),>=(mayoroigual).
Eloperadorespecial,<=>,resultaen1,0,1,dependiendodesieloperandodelaizquierdaes
menor,igual,omayorqueeldeladerecha,respectivamente:
5<=>7
13<=>13
7<=>3
1
0
1
Alternativamente,elresultadodelaevaluacindeunafuncinpuederesultarenunvalordeverdad.
Ejemplos:
h.empty?,(r/q).finite?
Hayocasionesenlasqueestasexpresionespuedenllegarasercompuestas:expr1orexpr2,expr1
andexpr2.Lassiguientestablasmuestranlosvaloresdeverdadenestoscasos:
nilandtrue
falseandtrue
99andfalse
99andnil
trueandtrue
falseornil
nilorfalse
99orfalse
trueorfalse
nottrue
notfalse
nil
false
false
nil
true
nil
false
99
true
false
true
#falsoycualquiercosa,dafalso
#andesciertocuandoambossonciertos
#oresciertocuandoalgunoescierto
Ejercicio10.1:Verificarlasexpresionescitadas.
Ejercicio10.2:Inventarseyevaluarexpresionesqueresultenenvaloresdeverdad.
DerechosReservados2007
22
RubyFcil
ParteII
Paralosejerciciosdelassiguientesleccionesesnecesariousaruneditordetextoparaguardarlos
programasquevamosaescribir,yguardarenarchivos.
SibienesposibleusareditoressencilloscomoelNotepaddeWindows,esmejorusareditores
especializadosparaprogramadores,puesestostienenfuncionesespecialesqueayudanaescribir
programas,talescomoindentacinautomtica,macros,ysintaxisdecolores.Todoestoleayudaa
unoaescribirprogramasmsrpidamenteyconmenoserrores.
Recomiendamosusar[unode]lossiguienteseditores:
vim(VIimproved):permiteeditarmuchosarchivosalmismotiempo,ytienesintaxisde
coloresparamsde100lenguajesdeprogramacin.EsmuypopularenLinux,perosu
dificultadradicaenaprenderausarloscomandosinternos,quesonunacombinacinde
teclas,puestratadehacertodoconelteclado,envezdeusarmensgrficos.
http://www.vim.org/
RDE(RubyDevelopmentEnvironment):editorintegradodeRubyquepermitehacer
debuggingyejecutarlosprogramasdirectamente.
http://homepage2.nifty.com/sakazuki/rde_en/
SciTE(SCIntillabasedTextEditor):vieneincludoconRubyenlainstalacinpara
Windows.Puedereconocermsde60lenguajespopulares,incluyendoRuby,Python,
HTML,XML,Tcl/Tk,Scheme,SQL,etc.EnWindows,SciTEseencuentraeneldirectorio:
c:\ruby\scite.
http://www.scintilla.org/
Porconveniencia,tambinvamosaasumirquetodoslosprogramaslosvamosaguardarbajoel
directoriosiguiente:
c:\code\ruby
YsiestisusandoLinux,eldirectorioes~/code/ruby.
[Tambinasumimosqueellectorsabecmocrearestosdirectorios,sinoexisten]
CmousarSciTE
SciTEessuficientementefcileintuitivo,asqueparaestecursovamosarecomendarlo.
Paraguardarunprogramaenunarchivo,hacer:File>Save.
Paraejecutarunprograma,hacer:Tools>Go[opresionarF5].
DerechosReservados2007
23
RubyFcil
SciTEnormalmentenoimprimeresultadosparciales;paraexaminarelestadodeuna
variable,imprimirlaconputsoprint.
ParamsinformacinsobreelusodeSciTE,favorreferirsealapndiceB,alfinaldellibro.
DerechosReservados2007
24
RubyFcil
Leccin11.LgicaCondicional
Todosloslenguajesdeprogramacintienenunaformasimilardecontrolarelflujodelprograma
pormediodecondiciones.EnRuby,estoselograconlaestructuradecontrolif/elsif/else/end.
Estatienelasiguienteformagenrica:
ifexpr1then
bloque1
elsifexpr2then
bloque2
else
bloque3
end
silaexpresinexpr1esverdadera,
entoncesseevalaelbloque1;
alternativamente,siexpr2escierta,
entoncesseevalaelbloque2;
alternativamente,
seevalaelbloque3.
Enlaexpresinanterior,solamenteunodelosbloques:bloque1,bloque2obloque3,seejecutan,
dependiendodelosvaloresdeverdaddeexpr1yexpr2,respectivamente.
Laspalabrasthensepuedenomitir,yenvezdeesaspalabrassepuedenusardospuntos,:,
aunquetambinsonopcionales.
Laexpresinelsifexpr2...bloque2esopcional.
Laexpresinelsebloque3tambinesopcional.
Veamosalgunosejemplosqueilustranusosespecficosdeestaestructuralgica.
Paracomparardosnmeros,ayb,escribiramoslosiguiente:
ifa>b
puts"aesmayorqueb"
elsifa==b
puts"aesigualab"
else
puts"besmayorquea"
end
#casoa>b
#casoa==b
#casoa<b
Haytambinotrasformascompactasdeexpresarcondicionessencillas:
x=a>b?1:0#retornax=1sia>b;alternativamenteretornax=0.
puts"aesmayorqueb"ifa>b
printtotalunlesstotal.zero?
Ejercicio11.1:Escribaunprogramaquecomparetresnmeros:a,b,c.
Ejercicio11.2:Escribaunprogramaquesaqueelmnimo,yelmximodelosnmerosdeun
arreglo.
Ejercicio11.3:Imprimalosnmerosparesqueseencuentrenenunarreglo.Ayuda:usarladivisin
pormdulo(%).
DerechosReservados2007
25
RubyFcil
Leccin12.CiclosRepetitivos
Elsiguientepasolgicoesestudiarlasdiferentesformasderepetirbloquesdecdigo.Enlaleccin
8estudiamosuncasoespecial,queeseldelafuncineach,paraiterarsobreloselementosdeun
array:
a=["a","b","c"]
a.each{|v|putsv}
#resultaena,b,cencadalineaseparada
Otramaneradeconseguirelmismoresultadoesconlaexpresinfor/in:
foreina
putse
end
#porcadaelementoedea,haga
#imprimaelvalordee
#findelciclo
Cuandoqueremosrepetirunciclociertonmerodeveces,usamosunrango,dondeescribimoslos
lmitesdelaiteracinseparadospordospuntos,as:
foriin5..10
#repetidamentevaaasignarvalores
putsi#desdei5hastai10ylosvaaimprimir
end
Cuandousamostrespuntos,excluyeelltimovalordelrango.Estoestilparaiterarsobrelos
valoresdeunarray(cuyoltimondiceesn1):
a=["a","b","c"]
foriin0...a.size
#size=3,asiquevaaasignarvaloresientre0..2
puts"#{i}:#{a[i]}"#evaluadesdea[0]hastaa[2]ylosimprime
end
#resultaimprimiendo0:a,1:b,2:c(unparporlinea)
Cuandosabemosexactamenteelnmeroderepeticiones,podemosusartimes,queesmsfcil:
5.timesdo
puts"hola"
end
Otramanera,usandolafuncinupto()sobrelosenteros:
1.upto(5)do
puts"Hola"
end
Tambinexistelafuncincorrespondientedownto()sobrelosenteros:
5.downto(1)do|i|
puts#{i}:Hola
end
DerechosReservados2007
#resultaen5:Hola,4:Hola,etcporcadalinea
26
RubyFcil
Unacuentaqueincrementepornmerosdiferentesde1sepuedehacerconlafuncinstep():
2.step(10,2)do|i|
putsi
end
#desde2hasta10,incrementandodea2
#imprimei:2,4,6,8,10
Aunqueparezcaincreble,lafuncinstep()tambinfuncionasobrelosreales,conincrementos
fraccionarios:
2.step(10,0.5)do|r|
putsr
end
#desde2hasta10,incrementandodea0.5
#imprimer:2.0,2.5,3.0,3.5,etc
Otraformaalternativadehacerciclosrepetitivosesconlainstruccinwhile.Estaevalauna
expresinqueresultaenunvalordeverdad,yrepiteelciclotantasvecescomolaexpresin
evaluadaseacierta.Veamosunejemplo:
cuenta=0
while(cuenta<5)do
putscuenta
cuenta+=1
end
#imprimedesde0hasta4
Laltimavezquerepiteelciclo,cuenta5,ylacomparacin(5<5)esfalsa,asqueyanorepiteel
bloquems.
Lainstruccinuntil,essimilaralwhile,exceptoquelaexpresinevaluadatieneunalgica
negativa:elbloqueserepitemientrasquelacondicinseafalsa.
cuenta=0
untilcuenta>=5do
putscuenta
#imprimedesde0hasta4
cuenta+=1
end
Otrainstruccin,loop,creaunciclopotencialmenteinfinito.Parasalirsedelcicloseusala
instruccinbreak,juntoconunacondicin.Elcicloanteriorseexpresaradelasiguientemanera:
cuenta=0
loop
breakifcuenta>=5
putscuenta
cuenta+=1
end
DerechosReservados2007
#imprimedesde0hasta4
27
RubyFcil
Ejercicio12.1:Verificartodaslasexpresionesdeestaleccin.
Ejercicio12.2:Escribaunprogramaquesumelosnmerosdel1al100.Compararelresultadocon
lafrmula(n+1)*n/2.Dicelaleyenda,queCarlFriedrichGaussinventestafrmulaalaedadde
7aos,cuandoenelcolegiosuprofesorlesdioesatarea:eselresultadodesumar50veces101.
Ejercicio12.3:Escribirunprogramaquecalculeelfactorialdeunnmero,usandounciclode
multiplicaciones.Elfactorialsedefinecomo:
n!=n*(n1)*...*1
Ejercicio12.4:Escribirunprogramaquenosdigacuantasiteracionesdebemoshacerparacalcular
econ3decimalesdeprecisin,usandolafrmuladelaseriedeTaylor,dadaporlaecuacin
siguiente:
x
e =lim 1
n
x x2 x 3
xn
...
1! 2! 3!
n!
Ejercicio12.5:Escribirunprogramaqueimprimalatabladelafuncinf(x)=sin(x)paravaloresde
xentre0y360grados,enincrementosde5grados.
Ejercicio12.6:Escribirunprogramaquenosdigacuntasiteracionessonnecesariasparaacercarse
1 x
aecon3decimalesdeprecisin,usandolafrmulasiguiente: e=lim 1
x
x
Ejercicio12.7:Escribirunprogramaquesumedosmatrices.
LasumadedosmatricesbidimensionalesAyB,sedefinecomo:
C=A+B,dondec(i,j)=a(i,j)+b(i,j),con0<i<m1,0<j<n1,
dondemeselnmerodefilas,yneselnmerodecolumnas.
Ayuda:paradefinirunamatrizusarunarreglodecolumnasyencadaunodesuselementos,definir
unarreglodefilas.
1 32 0 05 1 37
Ensayarloparaproducirlasiguientesuma: 1 00 7 50 = 8 50
1 22 2 11 3 33
[ ][ ][ ]
DerechosReservados2007
28
RubyFcil
Leccin13.CondicionesMltiples(Case)
Comovimosenlaleccin11sobrecondiciones,Rubytieneunaformaespecialdecontrolarelflujo
delprograma,dependiendodecondiciones;estoes,conlainstruccinif/elsif/else.
Uncasoespecial,escuandoqueremoscompararunavariablecontraunacantidaddevalores.Por
ejemplo,siunsemforotieneundeterminadoestado(color),queremosqueunautotomediversas
acciones.Paraeso,Rubytienedefinidalainstruccincase,cuyasintaxisescomosigue:
casevariable#examinalavariable
whenvalor1#cuandovalor1==variable
bloque1#ejecutaelbloque1
whenvalor2#cuandovalor2==variable
bloque2#ejecutaelbloque2
else#encualquierotrocaso
bloque3#ejecutaelbloque3
end
Cuandolavariabletieneunvalorigualaalgunodelosexaminados,entoncesseejecutaesebloque
solamente,ysedescartanlosotros.Enelcasodequelavariablenocoincidaconningunodelos
valoresexaminados,entoncesseejecutalaseccinelseyelbloque3(esteltimocasoes
convenienteparaatrapardatosqueestnfueradelosrangosesperados).Encualquiercaso,
solamenteunodelosbloquesesejecutado,ylosotrossondescartados.
Enlaexpresindesintaxisanterior,losbloqueswhenyelsesonopcionales;losbloqueswhen
puedehaberporlomenosunodeellos,ytantoscomosenecesiten.
Silosvalorescomparadossonnumricos,laexpresinwhenpuedetenervalorespuntuales
(discretos),orangos,oexpresionesregulares(queestudiaremosenotraslecciones).
Unejemplonumrico:
i=8
casei
when1,2..5#evalua(1==i),yluego(2..5==i)
print"iestaentre1..5"
when6..10#evalua(6..10==i)
print"iestaentre6..10"
else
print"Error,datofueraderango"#atrapaerrores
end
DerechosReservados2007
29
RubyFcil
Unejemploconcadenas:
s="abcde"
cases
when"aaa","bbb"#evalua("aaa"==s)o("bbb"==s)
print"sesaob"
when/c?e/#buscaelpatron(expresionregular)"c?e"
print"scontieneelpatron"
else
print"Noescomparable"
end
Elcasodelasexpresionesregulares,seestudiarenotraleccin.
Ejercicio13.1:Escribirunprogramaque,dadaunalistadecalificacionesdeestudiantes(enun
array),convaloresentre0y100,cadauno,determineculessonexcelentes(nota>=90),culesson
buenos(80<=nota<90),culesregulares(60<=nota<80),yculesnopasan(<60).
Ejercicio13.2:Escribirunprogramaque,dadaunalistaqueincludenombresdecompositores
repetidasveces,noscuentelasvecesqueoccurrecadaunodelossiguientesnombres:Mozart,
Haydn,Bach.Ensayarloconlasiguientelista:[MOZART,haydn,mozart,bach,BACH,
Liszt,Palestrina]
DerechosReservados2007
30
RubyFcil
Leccin14.Funciones
Elconceptodefuncionestieneelpropsitodeencapsularcdigoquesevaanecesitarpara
ejecutarlovariasveces.Esunaformaparaescribircdigounasolavezyreusarlovariasveces.
Unafuncinsedefineconlapalabraclavedef,definicin,seguidadesunombre,ycualquier
nmerodeparmetros,ovariables,atravsdelascualesselepasanvaloresalaparteinternadela
funcin.
defmiNombre(s)#estafuncinsellamamiNombre
return"Minombrees#{s}"#recibeelparametros,formalafrase
end#yretornaelvalordelafrasenueva
s1=miNombre("Antares")#imprime"MinombreesAntares"
s2=miNombre("Aldebaran")#imprime"MinombreesAldebaran"
Paraquelafuncinretorneunvalorcalculado,seusalainstruccinreturn.Enrealidad,lapalabra
returnestambinopcional.
Hayfuncionesquenoretornannada,peroquetienenefectossecundarios,talescomoimprimir,o
alterarvaloresdevariablesexternas.
Lasvariablesqueseusandentrodeunafuncinnosonvisiblesporelcdigoexistenteafueradela
funcin,ydejandeexistirunavezquelafuncinhayaterminadosuejecucin.Esdecir,podemos
pensarenunafuncincomounacajanegraquetieneentradasysalidas.Paraqueunavariable
externaseavisibledentrodeunafuncin,sepuedepasarcomoparmetro,osepuededeclararesa
variablecomoglobal,precedindoladeunsigno$.
Veamosunejemploconcomentarios:
a=[1,2,3]#declaramosunavariableexterna
$b=7#declaramosunavariableglobal,precedidapor$
deff(x)#declaramosunafuncion
putsa#estalineadaerror,porqueanoesvisibledentrodef()
puts$b#estalineaaccesalavariableglobal$b,esvalido
putsx#estalineaaccesaelparametroxdelafuncion,esvalido
c=99#declaramosunavariablelocalc,internaalafuncion
end#alterminar,lafuncion,ysusvariableslocalesdesaparecen
putsc#estalineadaerrorporquecnoexistefueradef()
Cuandounafuncinsedefineentrminosdesmisma,decimosqueesrecursiva.Porejemplo,la
funcinmatemtica,factorialden,sedefineparalosnmerosnaturalescomo:
fact(0)=1
fact(n)=n*fact(n1),cuandon>0,para
DerechosReservados2007
n
31
RubyFcil
EnRubyseexpresaradelasiguientemanera:
deffact(n)
if0==n
return1
else
returnn*fact(n1)
end
end
fact(15)
#importanteevaluarelpuntolimiteprimero,
#paradecidircuandoterminar
#lallamadarecursivavienedespues
#produce1307674368000
Siemprequesedefinanfuncionesrecursivas,esmuyimportanteevaluarprimerolacondicinde
terminacin,antesdeinvocarlallamadarecursiva,paraevitarqueseproduzcaunloopinfinito.Por
esarazn,eninglssehabladetailrecursion.
Ejercicio14.1:EscribirunprogramaquecalculelaseriedeFibonacciconunafuncin.Estaserie
fuedescubiertaenoccidenteenelsigloXIIIporLeonardodePisa,(yaseconocadesdeelsigloVI
enlaIndia)ysedefineas:
fib(0)=1
fib(1)=1
fib(n)=fib(n1)+fib(n2),paran>1,
Ejercicio14.2:Lafuncinrecursivaanteriorsehacelentaporque,cadaqueselainvoca,tieneque
calcularunayotraveztodoslosvaloresanteriores.Paraoptimizarla,escribaunprogramaque
recuerdecadaunodelosvalorescalculados,ylosalmaceneenunarreglo,demaneraquepueda
responderrpidamentecuandoseuseconsecutivamente.Ayuda:usarunarregloglobal.
Ejercicio14.3:Demostrar,pormediodeunprogramaqueuselafuncinFibonaccianterior,queel
cocientededosnmerossucesivosdeFibonacci,tiendehaciaelcocienteureo(GoldenRatio):
[demostradoporKepler]
Fibn1
1 5
lim
==
Fibn
2
n
Ejercicio14.4:EscribirunprogramaqueproduzcaunamatrizconeltringulodePascalusandouna
funcinquerecibacomoparmetroelnmerodefilasdeseadas.Cadaelementodeltringulode
Pascaltienelasiguienterelacin:a(i,j)=a(i1,j)+a(i1,j1),conunosenlaprimeracolumna,yen
ladiagonal:1
121
1331
etc
RecordemosquelafilandeltringulodePascalproduceloscoeficientesdelaexpansindela
potenciabinomial:(x+y)n.
DerechosReservados2007
32
RubyFcil
Ejercicio14.5:Escribirunprogramaqueuseunafuncinquenosdelnombredepolgonosden
lados,connentre1y99.Ayuda:ConsultarelenlacesobrepolgonoscitadoenlaseccinTemas
paraCuriosos,alfinaldellibro.
Ejercicio14:6:Escribirunprogramaconfuncionesparacalcularloscoeficientesbinomialesdela
potenciabinomial:(x+y)n
n
n!
x y n= n x nk y k , donde n =
k k !nk !
k=0 k
DerechosReservados2007
33
RubyFcil
Leccin15.Clases
Pormuchosaos,seusaronlenguajesdeprogramacinbasadosenvariablesyfunciones(comoC,y
Pascal).Cuandolosprogramassehacencomplejos,(demilesdelneas)estoresultaencdigo
difcildeentenderymodificar.
Pocoapocosefueroninventandootroslenguajes(comoC++,ySmalltalk)quetenanlacapacidad
deabstraeryconceptualizarelmundoquenosrodeaentrminosdeclases,ocategoras.Estoes
msintuitivo,ypermiteescribircdigomscomprensible.Larazndeestoesquedentrode
nuestrocerebropensamosencategoras(taxonomas),ytenemoslatendenciaaabstraeryagrupar
todoloqueconocemos.
Podemosestartranquilos,pueselconceptodeclasesnoesnadaespecial.Hastaahora,yahemos
manipuladovariablesenRubyquesonobjetos,oinstanciasdedeterminadasclasespredefinidas,
talescomocadenas(Strings),nmeros(Integer,oFloat),arreglos(Array),yhashes(Hash).Enesta
leccinvamosaaprenderadefinirclasesyadarleelcomportamientoquequeramos.
Paraempezar,podemospensarenunaclase,comounacoleccindefunciones,ydevariables,que
describenundeterminadoconcepto.Enpseudocdigo,podramospensarenalgoas:
[ojo,estotodavanoesRuby]
classMiClase
variable1,variable2,etc
funcion1,funcion2,etc
end
Parausarlaclase,primerohayquecrearunobjeto,oinstancia,delaclase.Yasabemoshaceresto
conlafuncinnew:
h=Hash.new#creaunobjetodelaclaseHash
a=Array.new#creaunobjetodelaclaseArray
m=MiClase.new#creaunobjetodelaclaseMiClase
Tambinyahemosusadoantespropiedadesyfuncionesdeunobjeto:
n=a.size#eltamanodeunarrayesunapropiedad
h.sort#sort()esunafunciondelaclase
Algunasdelasvariablesyfuncionesdelaclase,solamenteseusarndentrodelaclase,paraayudar
ahacercomputacionesinternas,mientrasqueotrassernvisiblesdesdeafuera.
Alasvariablesinternaslesllamaremosvariablesdelaclase(classvariables),ypara
distinguirlas,lasprecedemosconunsignodearroba.
Ejemplos:@temperatura.
DerechosReservados2007
34
RubyFcil
Alasvariablesvisiblesdesdeafuera,lesllamaremosatributos,comosifueranuna
propiedaddelobjetoquesepuedeleery/ocambiar.Normalmente,losatributosson
sustantivos,ysusvaloressonadjetivos,onmeros.
Ejemplos:perro.color,planeta.gravedad,motor.cilindros,paciente.edad.
Alasfuncionesdelaclaselellamaremosmtodosynormalmenteusamosverbospara
describirlasaccionesquevanadesempear.
Ejemplos:perro.ladrar,motor.arrancar,paciente.crear.
Ahoraveamosunejemplocompleto.Vamosamodelarelconceptodeunperroquetienenombre,
ysabeladrar.EnRuby,escribimos:
classPerro#nombredelaclase
definitialize(nombre)#metodoparainicializar
@nombre=nombre#@nombrevariableinterna
@ladrido="guau"#@ladridovariableinterna
end
defto_s#representaciontextual
"#{@nombre}:#{@ladrido}"#reportavalorde@nombrey@ladrido
end
defnombre#exportanombrecomopropiedadpublica
@nombre#retornaelvalorde@nombre
end
def<=>(perro)#operadordecomparacionparaordenar
@nombre<=>perro.nombre#comparapornombre
end
defladrar#hacerloladrar
@ladrido#produceelladrido
end
end
Enladefinicinanterior,valelapenanotarlosiguiente:
Porconvencin,elnombredelaclasesiempreempiezaenmayscula.
Lasvariablesquesedeclarandentrodelaclasetienenalcancelocal,pordefault,(esdecir,
nosonvisiblesdesdeafueradelaclase),ysonprecedidasporelsignodearroba:@.
Elmtodoinitialize()seconocecomoelconstructor,porqueeselprimermtodoquese
ejecutacuandocreamosunavariabledetipodelaclase.Elconstructoresopcional,perosi
lodefinimos,lousamosparainicializarlasvariablesdentrodelaclase.Estemtodose
ejecutaautomticamente(nuncaseinvocaexplcitamente)alcrearunavariabledeestaclase
conelmtodonew.
Esconvenientetambindefinirelmtodoto_sdondeexpresamosquhacercuandonos
pidenlarepresentacintextualdelaclase.Estoresultatilcuandoqueremosexaminarel
contenidointerno(oestado)deunaclase.
Elmtododecomparacin<=>sedefineparahacerquelaclaseseacomparable,esdecir,
queselepuedanaplicaroperacionestalescomosort(),etc.Consisteendeclararquvariable
DerechosReservados2007
35
RubyFcil
internavamosausarparahacercomparaciones.Enestecaso,lovamosahacerpornombre.
Elmtodonombre()nospermiteexaminar(leer)elnombredelobjetodesdeafuera.
Elmtodoladrar()hacequeelperroladre(simplementeretornaelvalorde@ladrido).
Ahora,paracrearunobjetodetipoPerro,comoyasabemos,usamoselnombredelaclase,seguido
delapalabranew,seguidodelosargumentosquelevamosapasaralmtodoinitialize():
f=Perro.new("fifi")#creamoselperrofifi,enlavariablef
m=Perro.new("milu")#creamoselperromilu,enlavariablem
putsf.ladrar#loshacemosladrar
putsm.ladrar
putsf.to_s#losexpresamostextualmente
putsm.to_s
m<=>f1#comparapornombre
Enelejemploanterior,Perroeslaclase,yfymsoninstanciasdeclasePerro.Esimportante
distinguirentreestosdosconceptos:
laclase(queconsisteenladefinicin),y,
losobjetos,oinstancias,quesonvariablesdeltipodelaclase.
Ejercicio15.1:ModificarlaclasePerroanteriorparaqueincluyapropiedadestalescomoelcolor,la
edad,yelsexo.
Ejercicio15.2:Ensayarqupasacuandosehacemilu.ladrido="wanwan".
Sepuedeaccesarestavariableinterna?
Ejercicio15.3:Redefinirelmtododecomparacin,demaneraquecompareporedad,envezde
pornombre.
Ejercicio15.4:Escribirunprogramaquepongaunacoleccindeperrosenunarreglo,queexamine
suspropiedades,queloshagaladraratodos,yquelosordeneporedad.
DerechosReservados2007
36
RubyFcil
Leccin16.AtributosdeClases
Enlaleccinanteriormencionamosquelasvariablesdeunaclase,pordefault,tienenvisibilidad
local,esdecir,solamentesonvisiblesparalosmtodosdelaclase(ymsadelanteveremoscmo
afectaestoalassubclases).
AsqueenlaclasePerro,delaleccinanterior,nosepuedeaccesarelladridodirectamente:
fifi.ladrido
#produceunerror
Ahora,paraexportarunatributo,talcomoelnombre,tenemoslaopcindehacerlolegibley/o
escribible.Parahacerlolegible,(esdecirquesepuedaaccesarparaleerdesdeafuera)como
hicimosenlaleccinanterior,declaramosunmtodoqueretornesuvalor:
classPerro#nombredelaclase
definitialize(nombre)#metodoparainicializar
@nombre=nombre#asignarelnombre
...
end
defnombre#propiedadpublicalegible
@nombre#retornaelnombre
end
...
end
f=Perro.new("fifi")
f.nombre"fifi"#retornaelvalorsinproducirerror
Parahacerloescribible,aadimosunmtodoquemodifiquesuvalor:
classPerro
...
defnombre=(nombreNuevo)#metodoparahacerloescribible
@nombre=nombreNuevo#modificaelnombre
end
end
f=Perro.new("fifi")
f.nombre="fifirucho"#invocaelmetodoescribible
Rubynospermitehacerestodeotramaneramsfcil.Siqueremosdeclararatributoslegibles,los
podemosdeclararusandolapalabraclaveattr_reader:
classPerro
attr_reader:nombre,:edad,:color#atributoslegibles
...
end
DerechosReservados2007
37
RubyFcil
Ahora,hayquemodificarelconstructorparaqueaceptevaloresiniciales:
classPerro
...
definitialize(nombre,edad,color)#metodoconstructor
@nombre=nombre#@nombre
@edad=edad#@edad
@color=color#@color...variablesinternas
end
...
end
Loanteriorpermitehacerusodelaspropiedadesnuevasas:
f=Perro.new("fifi",5,"gris")
f.color
"gris"
Parahacerunatributoescribible(modificable),hayqueaadirlasiguientedeclaracin:
classPerro
attr_writer:edad#atributoescribible
...
end
Estopermitecambiarleelvalordesdeafuera,comosifueraunapropiedad,as:
f=Perro.new("fifi",5,"gris")
f.edad=7
Ejercicio16.1:ModificarlaclasePerroanteriorparaqueincluyalassiguientespropiedadeslegibles
yescribibles:color,edad,ysexo.
DerechosReservados2007
38
RubyFcil
Leccin17.ControldeAccesoalaClase
Elaccesoalosmtodosdelaclasesepuederestringirusandotresdiferentesnivelesdeproteccin:
Mtodospblicos:sonlosmtodosquesepuedenaccesarporcualquiera,sinrestringirsu
acceso.Pordefault,losmtodossonpblicos.
Mtodosprotegidos:solamentesepuedenaccesarporobjetosdelaclasequelosdefine,y
sussubclases;esdecir,elaccesoquedaentrelafamilia.
Mtodosprivados:solamentesepuedenaccesardentrodelaclasequelosdefine.
Paraponerestasrestriccionesenefecto,seusanlaspalabrasclaves:public,protected,yprivate.
Haydosformasdeusarlas.Laprimeraformaesescribirestaspalabrasentrelosmtodosdela
clase:
classMiClase
defmetodo1#pblicopordefecto
end
protected
defmetodo2#protegido
end
private
defmetodo3#privado
end
public
defmetodo4#pblico
end
end
Lasegundaformaesunaalternativaparaexpresarlomismo,yconsisteendefinirlosmtodos
primero,ydespuscualificarlosdelasiguientemanera:
classMiClase
defmetodo1
end
defmetodo2
end
defmetodo3
end
defmetodo4
end
public:metodo1,:metodo4
protected:metodo2
private:metodo3
end
Ejercicio17.1:DefinirlaclasePajaroCantorqueusemtodosprivadosparaproducirdiferentes
cantos.Usartambinlafuncinrand(),paraproducircantosaleatorios.
DerechosReservados2007
39
RubyFcil
Leccin18.HerenciayTaxonomas
Taxonomaeselartedeclasificarcosasenunaestructurajerrquica,demaneraquequedenenuna
relacinpadrehijo,osuperclasesubclase.
Porejemplo,paraunaaplicacingrficadeobjetostridimensionales,podramospensarenuna
superclasegenricadecajas,conpropiedadestalescomocolor.
classCaja#Cajaesunobjetogenerico
definitialize(color)
@color=color#guardaelvalorenunavariablelocal
end
end
DespuspodemospensarenotrosobjetosqueconsideramossubclasesdeCaja,talescomo:
cilindro,cubo,esfera,cuyosvolmenesvienendadosporfrmulasdistintas.Decimosquelas
subclasesheredanciertaspropiedadesdelassuperclases,comocolor,etc.Tambindecimosque
lassubclasesseespecializanmsenelobjetoquerepresentan.Deestamanera,vamosmodelando,
oconceptualizandoelproblemaquetratamosderesolver.
Rubypermiteexpresarrelacionesdetaxonoma,aldefinirclases.UsandolasintaxisSubClase<
SuperClase,podemosdefinirclasesas:
classCilindro<Caja#CilindroesunasubclasedeCaja
attr_reader:radio,:lado,:volumen
definitialize(color,radio,lado)
super(color)#invocaelconstructordelasuperclase
@radio,@lado=radio,lado
@volumen=2*Math::PI*radio*lado
end
end
Laventajadeusartaxonomas,esquepodemosirdesarrollandounaaplicacindondelassubclases
heredandelassuperclases,yelcdigoestorganizadodeunamaneralgica,incrementaly
extensible,evitandoduplicacinyminimizandoesfuerzo.
Ejercicio18.1:Completarelejemplodeestaleccinescribiendolasclasesparacuboyesfera.
Ayuda:volumendelaesfera=4/3**r3
Crearuntubo,undado,yunapelota,conradiosylados=2,yreportarsusrespectivosvolmenes.
DerechosReservados2007
40
RubyFcil
Leccin19.ExpresionesRegulares
Lasexpresionesregularesconstituyenunminilenguajecuyopropsitoescrearpatronesgenricos
queluegosebuscandentrodeunacadenadecaracteres.Latablasiguienteexplicaalgunosdelos
caracteresespecialesusadosenexpresionesregulares:
Caracter
Significado
Caracteresespeciales:\t,\n,\s(espacio),\d(digito),\007(octal),\x7f(hex),\|(lineavertical)
cualquiercaracter,excepto\n
elprincipiodeunacadena
elfinaldeunacadena
elelementoanteriorocurre0omasveces
elelementoanteriorocurre1omasveces
elelementoanteriorocurre0o1veces
{}
especificaunrangodeelementos
[]
unaclasedecaracterescontenidosdentrodelosparentesis
()
agrupaexpresionesregulares
expresionesalternativas
Ejemplos:
Enlatablasiguiente,elpatrndelacolumnaizquierdahacejuegoconlascadenasdeladerecha:
ExprRegular
Ejemplo
/\d\d:\d\d:\d\d/
"12:34:56"
/\w+/
unaomaspalabras
/\s+/
unoomasespacios
/a.c/
"xabcz","xamcz","xa9cz",...
(cualquiercaracterentreayc)
/Jair(o|ito)/
"Jairo","Jairito"
/[Ee]lla/
"Ella","ella"
/^Salud/
"Saludando"(cadenaqueempiececonesapalabra)
/Salud$/
"ParasuSalud"(cadenaquetermineconesapalabra)
/ab*c/
"xacz","xabcz","xabbbbcz",...
(ceroomasocurrenciasdeb,precedidaspora,y
seguidasporc)
/ab+c/
"xabcz","xabbbbbcz",...
(unaomasocurrenciasdeb,precedidasporayseguidas
porc)
DerechosReservados2007
41
RubyFcil
/a?c/
"xcz","xacz"
(ceroounaocurrenciadea,seguidadec)
/[09]/
cualquiernumerodeundigito
/[azAZ]/
cualquierpalabradeunaletra
/tu|yo|el|ella/
cualquieradelascuatropalabrasentre//
Paraevaluarelvalordeverdaddeunaexpresinregular,seusaeloperador=~.Sepuedeutilizaren
expresionesif,ywhile.Ejemplo:
if"xabcz"=~/abc/#buscaelpatronabcenlacadenaxabcz
puts"siesta"#imprimesiesta
end
Sepuedenusarexpresionesregularesconlosmtodosdesustitucinenlascadenas,sub()ygsub():
s="nonono"
s.sub(/no/,"si")#produce"sinono",reemplazalaprimeraocurrencia
s.gsub(/no/,"si")#produce"sisisi",reemplazatodaslasocurrencias
Elmtodoscan()delascadenasdecaracteres,tomaunaexpresinregularcomoparmetro.El
efectoesqueiterasobrelacadenabuscandoesepatrn,yretornaunarregloconelresultado:
s="HassunaSamarraHalaf"
s.scan(/\w+/)["Hassuna","Samarra","Halaf"]#separapalabras
Elmtodosplit()delascadenasdecaracteres,tambinpuedetomarunaexpresinregularcomo
parmetro.Entalcaso,usaelpatrndadocomoseparadorparaquebrarlacadena,yretornaun
arregloconelresultado:
s="Aldebaran,Regulus,Antares,Fomalhaut"
s.split(/,\s*/)["Aldebaran","Regulus","Antares","Fomalhaut"]
#laexpresionregularanteriorbuscacomas,seguidasdeceroomasespacios
Ejercicio19.1:Confirmarlasexpresionesregularesexplicadasenestaleccin.
Ejercicio19.2:Escribirunainstruccinqueseparelaspalabrasdelasiguientecadena:
"Paris|Roma|Madrid|Estambul|Damasco"
Ejercicio19.3:Escribirunprogramaquesepareloselementosdelasiguientecadena:
"http://sitioweb.net?var1=1&var2=2&var3=3"
DerechosReservados2007
42
RubyFcil
Leccin20.Archivos
Losarchivosseusanparaalmacenardatosdeformapermanente.Todosloslenguajesde
programacinofrecenlamaneradeaccesararchivosparacrearlos,leerlos,escribirlos,cerrarlos,y
borrarlos.
Rubytienedosclasesrelacionadasparaestepropsito,FileyIO(Input/Output).Fileesuna
subclasedeIOyheredamuchosdesusmtodos.
Veamosprimerocmoabrirunarchivoexistente,ycmoleersucontenido:
archivo="datos.txt"#elnombreenunavariablesilousamosvariasveces
ifFile.exists?(archivo)#nosaseguramosdequeexista
f=File.open(archivo)#abrimoselarchivodatos.txt
f.eachdo|linea|#procesamoscadalineacomounarreglo
puts"#{f.lineno}:#{linea}"#imprimimosnumeroylinea
end
f.close#locerramosalfinaldelproceso
else
puts"#{archivo}noexiste"#reportamosunerrorsinoexiste
end
Enelprogramaanterior,sehubierapodidopasarelparmetroralmtodoFile.open(),as:
File.open(archivo,"r"),paraindicarquelovamosaleer(read),peroesteeseldefault,as
quepodemosomitiresteparmetro.
RecordemosqueRubyfuediseadoparaserfcilyentretenido,asqueofrecemuchasformasde
hacerlomismo.Porejemplo,elmtodoIO.eachessinnimodeIO.each_lines.
Otraalternativaesleertodoelcontenidodelarchivoyguardarloenunarreglo,conelmtodo
IO.readlines():
archivo="datos.txt"#nombredelarchivo
ifFile.exists?(archivo)#nosaseguramosdequeexista
f=File.open(archivo)#abrimoselarchivodatos.txt
a=f.readlines(archivo)#loleemosyasignamosaunarreglo
f.close#unavezleido,yalopodemoscerrar
a.eachdo|linea|#ahoraprocesamoscadalineadelarreglo
puts"#{linea}"#imprimimoslalinea
end
else
puts"#{archivo}noexiste"#reportamosunerrorsinoexiste
end
Estasegundaalternativaofrecevariasventajas:
DerechosReservados2007
43
RubyFcil
usasolamenteunainstruccinparaaccesarelarchivoyleerlo;
procesadirectayrpidamenteenmemoria.
Laposibledesventajaesquesielarchivoesbastantegrande(delordendeMegabytes),puede
ocuparmuchamemoria.
Siqueremosleerunalneaalavez,usamoselmtodoIO.read():
linea=f.read(archivo)
Paraleerunalneaenparticular,podemosusarlapropiedadIO.lineno:
f.lineno=1000#vaalalinea1000
linea=f.gets#laleeyasignaaunavariable
Ahora,vamosacrearunarchivo,leescribimosdatos,ylocerramos:
archivo2="nuevosdatos.txt"#nombreenvariableparausofrecuente
f=File.new(archivo2,"w")#abrimoselarchivonuevosdatos.txt
f.puts("lineacontexto")#escribeunalineadetextoalarchivo
pi=Math::PI
f.print("piaproximado",pi,"\n")#otraformadeescribiralarchivo
e=Math::E
f.write("evale"+e.to_s+"\n")#otraformadeescribiralarchivo
f.close
Comomuestraelejemploanterior,elmtodoFile.new()permitecreararchivos.Elprimer
parmetroeselnombredelarchivo,yelsegundoparmetroeselmododeapertura.Latabla
siguientemuestralosmodosdeaperturadisponibles:
Modo
Significado
Sololectura;comienzadesdeelprincipiodelarchivo(default).
r+
Lectura/Escritura:comienzadesdeelprincipiodelarchivo.
Soloescritura:truncaelarchivosiexiste,ocreaunonuevoparaescritura.
w+
Lectura/Escritura:truncaelarchivosiexiste,ocreaunonuevoparalectura/escritura.
Soloescritura:comienzadesdeelfinaldelarchivosiexiste,olocreanuevoparaescritura.
a+
Lectura/Escritura:comienzadesdeelfinaldelarchivosiexiste,olocreanuevoparalectura/escritura.
(SoloenWindows).Modobinario,ysepuedecombinarconcualquieradelasletrasanteriores.
Ejercicio20.1:Verificarlosprogramasdeestaleccin.
DerechosReservados2007
44
RubyFcil
Ejercicio20.2:Escribirunprogramaqueleaunarchivodetexto,yquecuentelasvecesqueocurre
cadapalabradeltexto.
Ejercicio20.3:Escribirunprogramaqueleauntextodeunarchivo,quereemplaceciertaspalabras,
yescribaeltextonuevoenotroarchivo.
Ejercicio20.4:UnarchivocontieneunasecuenciadeletrasquerepresentanunacadenadeARN
(cidoribonucleico):Adenina(A),Citosina(C),Guanina(G),yUracil(U).Escribirunprograma
queleaelarchivo,yque,utilizandoelcdigogentico,produzcaotroarchivoconlasecuenciade
protenasquesegeneraapartirdelARNdado.
Ayuda:SeleeelARNengruposdetresnucletidos(llamadoscodones)ysetraducenconlatabla
paraproducirunaprotena.Ejemplo:UGGproduceTriptofn(Trp/P).Verificarloscdigosde
iniciacinyterminacindelacadena.
DerechosReservados2007
45
RubyFcil
Leccin21.Directorios
LaclaseDirseusapararepresentarymanipulardirectorios.
Algunosdelosmtodosquesoportasonlossiguientes:
Dir.chdir("c:/code/ruby")#cambiaeldirectoriocorriente
Dir.pwd#nombredeldirectoriocorriente
Dir.getwd#sinonimodeDir.pwd
Dir.delete("c:/code/old")#borraundirectorio
Dir.mkdir("c:/code/ruby/new")#creaundirectorio
Rubyofrecevariasformasdeprocesarlalistadearchivosenundirectorio:
Podemos,porejemplo,crearunarregloconlalistadearchivos:
a=Dir.entries("c:/code/ruby")#arregloconlistadearchivosendirectorio
Alternativamente,podemositerarsobrelalistadirectamente,conforeach:
Dir.foreach("c:/code/ruby"){|x|putsx}#iteracionsobrelistadearchivos
Otraformaalternativaconeach:
d=Dir.open("c:/code/ruby")#usaunobjetoDirenunavariable
d.each{|x|putsx}#iteracionsobrelistadearchivos
d.close
Conelmtodoglob()sepuedefiltrarlalistadearchivosconunaexpresinregular:
a=Dir.glob("*.rb")#listadearchivosconterminacionrb
Tambinesposibleleerundirectoriocond.posyd.read:
d=Dir.new("c:/code/ruby")#sinonimodeDir.open
d.pos=1#seposicionaenel1erelementodelalista
s=d.read#leeeldirectorio
putss#reportaloqueleyo
d.close
Ejercicio21.1:Verificarelcdigodeestaleccin.
DerechosReservados2007
46
RubyFcil
Leccin22.Entrada/Salida,CorrientesyTubos
Avecesdeseamospoderpasardatoshaciaunprogramadesdeafuera,digamos,desdelalneade
comando,yverlosresultadosahmismo.Estoesbastanteconvenienteparaconectarunprograma
conotro,usandoelconceptodepipes,otubos.Laideaesqueciertosprogramassondiseadosde
maneraquesepuedeninvocarsecuencialmente:lasalidadelprimeroeslaentradaalsegundo,etc.
comoconectandountubodetrsdeotro.
Figura22.1Conectandoprogramas
Desdelaconsoladecomandos,estoseinvocaradelasiguientemanera:
c:\code\ruby>rubyProgramaA.rb<archivo1.txt|ProgramaB.rb>archivo2.txt
Parahacerestoposible,Ruby(igualquemuchosotroslenguajes)tienepredefinidaslasconstantes
globalesSTDIN,STDOUT,ySTDERR,detipoIO,quesirvenparapasarstreams,ocorrientes
dedatoshaciadentroyhaciaafueradelprograma.STDINseusaparaleerdatoshaciaadentro,
STDOUTparaescribirresultadoshaciaafuera,ySTDERRparareportarerrores.
Figura22.2STDIN,STDOUT,STDERR
Estascorrientesestnsiempredisponibles(abiertas)asquenohaynecesidaddeabrirlasnide
cerrarlas.
ParaleerunalneadedatosporSTDIN:
DerechosReservados2007
47
RubyFcil
s=STDIN.gets
Tambinexisteunavariable$stdin,quenormalmentetieneelvalorSTDIN,perosepuederedefinir
paraleerdatosdesdediferentesfuentes:
s=$stdin.gets#leedeSTDIN
archi=File.new("misdatos.txt","r")
$stdin=archi#reasignaelvalorde$stdin
s=$stdin.gets#ahoraleelineadesdearchivoarchi
archi.close
$stdin=STDIN#reasignaaldefault
s=$stdin.gets#leedesdeSTDIN
STDOUTsepuedeusardelasiguientemanera:
STDOUT.puts("Lasconstantesson:")#escribetextohaciaafuera
pi=Math::PI
STDOUT.print("piaproximado",pi,"\n")#otraformadeescribiraSTDOUT
e=Math::E
STDOUT.write("e="+e.to_s+"\n")#otraformadeescribiraSTDOUT
Tambinexistelavariable$stdout,quenormalmentetieneelvalorSTDOUT,perosepuede
redefinirparaenviarresultadoshaciaunarchivo.
archi=File.new("misresultados.txt","w")
puts"Hola..."#escribeaSTDOUT
$stdout=archi
puts"Adios!"#escribealarchivoarchi
archi.close
$stdout=STDOUT#reasignaaldefault
puts"Esoestodo."#escribeaSTDOUT
Deigualmanera,existelavariable$stderr,convalorSTDERR,ysepuederedefinir.Suusoes
similaralde$stdout,ySTDOUT,respectivamente.STDERRseusapararedireccionarmensajesde
error.
STDIN,STDOUT,ySTDERRseportancomoarchivos,porquetambinsondescendientesdeIO.
Asquelosiguienteesvlido:
$stdin.each { |linea| $stdout.puts linea }
Ejercicio22.1:VerificarelcdigosobreSTDIN,STDOUTySTDERR,deestaleccin.
Ayuda:ParaensayarSTDIN,escribirunprogramasencilloeinvocarlodirectamenteconRubydesde
lalneadecomandohaciendo:
rubyprograma.rb
DerechosReservados2007
48
RubyFcil
Leccin23.Formatosdesalida
Hastaahorahemosestadousandolasfuncionesputs()yprint()paraimprimirresultadosdeuna
manerasencilla.
Queremos,deahoraenadelante,poderformatearcualquierdatodemaneraqueaparezcacomo
deseemos.Porejemplo,datostextualessuelenseralineadosalaizquierda,derecha,ocentrados,
mientrasquedatosnumricossuelensertruncadosaciertonmerodedecimales.
Rubytienelafuncinsprintf()(heredadadellenguajeC),conlasiguienteformagenrica:
sprintf(formato,var1,var2,...)
Latablasiguientemuestralasletrasaceptadas:
Formato
Descripcin
binario
entero
decimal
real(puntoflotante)
cadenadecaracteres
usarepresentacincientfica(exponencial)
similarae,perousalaletramayuscula
similarae,perodefaulta4decimales,omenos.
convierteaoctal
cadenaalfanumrica
trataelargumentocomodecimalsinsigno
convierteahexadecimalusandoletrasmayusculas
convierteahexadecimal
Elformatoparanmerosesunacadenadelaforma%n[.m]xdonde:
xesunaletradelatablaanterior,
neselnmerototaldedgitosqueocupa(incluyendoelcero),y,
meselnmerodedecimales[solamenteenelcasodenmerosdepuntoflotante].
Ejemplos:
sprintf("%12.9f",Math::PI)
"3.141592654"#picon9decimales
sprintf("%4i",557)
"557"#enteroa4cifras
sprintf("%1.1e",1230000)
"1.2e+06"
sprintf("%1g",1230000)
"1.23e+06"
sprintf("%b%o%x",127,127,127) "11111111777f"#binario,octal,hex.
DerechosReservados2007
49
RubyFcil
Elformatoparacadenasdecaracterestienelaforma%nsdonde:
neselnmerodecaracteresamostrar(truncasiesmenorquelalongituddelacadenaenla
variable)
Siseusaunsignonegativo(),lacadenaesjustificadahacialaizquierda;deotramanera,se
justificaaladerecha.
Ejemplos:
sprintf("%10s","hola")
sprintf("%10s","hola")
"hola"
"hola"
Ejercicio23.1:Verificarelcdigodeestaleccin.
Ejercicio23.2:Escribirunaexpresinqueimprimaunatabladelafuncinseno(x),convaloresde
xdesde0hasta3.14,enincrementosde0.02.Debeimprimirelvalordex,adosdecimales,yel
valordeseno(x),atresdecimales.
DerechosReservados2007
50
RubyFcil
SolucionesaEjerciciosSelectos
2.2.1:piHiparco=377.0/120
3.14166666666667
Nota:conqueunodelostrminosenlaexpresinseaexpresadocomo
nmeroreal,elresultadoserreal.
2.2.2:piArquimedes1=3+10.0/713.14084507042254
piArquimedes2=3+1.0/7 3.14285714285714
2.2.3:piLiuHui=355.0/113
3.14159292035398
2.2.4:piFibonacci=864.0/275
3.14181818181818
2.3:farenheit=(celcius*9/5)+32
2.4:celcius=(farenheit32)/1.8
2.5:radianes=grados*2*Math.PI/360.0
2.6:grados=radianes*360.0/(2*Math.PI)
3.3:a,b,c=3,6,2
x1=b+Math.sqrt(b**24*a*c)/(2*a)#daerrorcuandob**2<4ac
x2=bMath.sqrt(b**24*a*c)/(2*a)
3.6:piEuler1=4*(5*Math.atan(1.0/7)+2*Math.atan(3.0/79))
3.14159265358979
piEuler2=4*(2*Math.atan(1.0/3)+Math.atan(1.0/7))
3.14159265358979
Nota:dentrodelasfuncionestrigonomtricashayqueusarnmerosreales.
3.7:piWrenchShanks=24*Math.atan(1.0/8)+8*Math.atan(1.0/57)+
4*Math.atan(1.0/239)
3.14159265358979
3.8:piRuby=Math::PI
3.14159265358979
#tieneelmismovalorquepiEuler1,piEuler2,ypiWrenchShanks.
8.2:a=[1,2,3,4,5]
a.each{|i|putsi.to_s+","+(i**2).to_s+","+Math.sqrt(i).to_s}
8.3:a=["estas","son","algunas","palabras"]
a.eachdo|p|
putsp+":tiene#{p.length}letras."
end
9.1:a=[1,2,3,4,5]
total=0
a.each{|n|total+=n}
#equivaleadecir:total=total+n
#acumulalasumaenlavariabletotal
puts"Lasumaes:"+total.to_s
DerechosReservados2007
51
RubyFcil
11.1:
#asignarvaloresalasvariables,a,b,c
a,b,c=5,3,7
#fijensecomohayqueconsiderartodosloscasos,unoporuno
#laindentacionseusaparahacerelprogramamasfacildeleer
#ponercomentarioslibrementeparaayudaraseguirlalogicadelprograma
if(a>b)
if(a>c)
if(b>c)
puts"a=#{a}>b=#{b}>c=#{c}"
elsif(b==c)
puts"a=#{a}>b=#{b}=c=#{c}"
else#esteesuncomentario:(a>c>b)
puts"a=#{a}>c=#{c}>b=#{b}"
end
elsif(a==c)
puts"a=#{a}=c=#{c}>b=#{b}"
else#otrocomentario:(c>a>b)
puts"c=#{c}>a=#{a}>b=#{b}"
end
elsif(a==b)
if(a>c)
puts"a=#{a}=b=#{b}>c=#{c}"
elsif(a==c)
puts"a=#{a}=b=#{b}=c=#{c}"
else#(c>a=b)
puts"c=#{c}>a=#{a}=b=#{b}"
end
else#(b>a)
if(b>c)
if(a>c)
puts"b=#{b}>a=#{a}>c=#{c}"
elsif(a==c)
puts"b=#{b}>a=#{a}=c=#{c}"
else#(b>c>a)
puts"b=#{b}>c=#{c}>a=#{a}"
end
elsif(b==c)
puts"b=#{b}=c=#{c}>a=#{a}"
else#(c>b>a)
puts"c=#{c}>b=#{b}>a=#{a}"
end
end
DerechosReservados2007
52
RubyFcil
11.2:
a=[2,8,4,7,1]
min=9999
max=9999
a.eachdo|v|
ifv<min
min=v#asigneunnuevominimo
end
ifv>max
max=v#asigneunnuevomaximo
end
end
puts"Elminimoes:#{min}"
puts"Elmaximoes:#{max}"
11.3:
a=[1,2,3,4,5,6]
a.eachdo|i|
if(i%2==0)#siladivisionmodulo2dacero,espar
puts"#{i}espar."
else
puts"#{i}esimpar."
end
end
12.2:
n=100
1.upto(n){|i|s+=i}
putss
s2=(n+1)*n/2
5050
5050
12.3:
n=5
fact_n=1
1.upto(n)do|i|
fact_n*=i
#equivaleafact_n=fact_n*i
end
puts"fact(#{n})=#{fact_n}"
DerechosReservados2007
53
RubyFcil
12.4:
#exp(1)=1+1/1!+1/2!+...+1/n!
e1=Math::E
#2.71828182845905
#Queremoscalcularhastaqueobtengamoselvalor2.718;estoes:
e2=(e1*1000).to_i/1000.0#metodoparatruncara3decimales:2.718
s=1
#sllevalasumadelaserie
i=1#icuentalasiteracionesdelciclo
whiles<e2#elcicloserepitemientrasques<e2
fact_n=1
1.upto(i){|j|fact_n*=j}#aquicalculamoselfactorial
s+=1.0/fact_n#yaquiloacumulamosas
i+=1#contamoslasiteracioneseni
puts"#{i}:#{s}"#imprimimosresultadosparciales
end
puts"Serequieren#{i}iteraciones"#imprimimoselresultadofinal
#Dehecho,laserieconvergerapidamente.
#Serequiren7iteracionesparallegarae2(3decimalesdeprecision)
#yserequieren15iteracionesparallegarae1(14decimales)
12.5:
0.step(360,5)do|i|
#desde0hasta360,incrementandodea5
rad=i*2.0*Math::PI/360
#conversiongradosaradianes
putsi.to_s+":"+Math.sin(rad).to_s #imprimei:sin(i)
end
12.6:
e1=Math::E#e1=2.71828182845905
e2=(e1*1000).to_i/1000.0#e2=2.718
x=1#xesuncontadoryempiezaen1
loopdo#empiezaelciclo
f=(1+1.0/x)**x#calculaf
puts"#{x}:#{f}"#imprimeelresultadoparcial
breakiff>e2#examinayterminaelciclo
x+=1
#incrementaelcontador
end#repiteelciclodesdeaqui
#estaformularequiere4,822repeticionesparaacercarseae2;
#requiere67,095,913ciclosparaacercarseae1;
#diriamosqueconvergelentamentehaciae.
DerechosReservados2007
54
RubyFcil
12.7:#sumadedosmatrices
a=[[1,3,2],[1,0,0],[1,2,2]]#matriza
b=[[0,0,5],[7,5,0],[2,1,1]]#matrizb
c=Array.new#matrizdefilasc
m,n=a.size,a[1].size#m:filas,n:columnas
foriin0...mdo#iteradorsobrefilas
c[i]=Array.new#la2dadimension(columnas)dec
forjin0...ndo#iteradorsobrecolumnas
c[i][j]=0#lasiniciamosen0
end
end
foriin0...mdo#volvemosaiterarsobrelasfilas
forjin0...ndo#porcadafila,iteramoscolumnas
c[i][j]=a[i][j]+b[i][j]#ycalculamoslasuma
end
end
c.eachdo|fila|#porcadafila
putsfila.join("")#imprimeelresultado
end
13.1:
calificaciones=[20,55,61,70,98,48,87,120,3]
resultados=Array.new
fornotaincalificacionesdo
casenota
when0..59#valoresposiblesquedancubiertos
resultados.push("malo")#prepararlistanueva
when60..79
resultados.push("regular")
when80..89
resultados.push("bueno")
when90.100
resultados.push("excelente")
else
resultados.push("error")
end
end
printresultados.join(",")
#imprimelalistaconlosresultados
13.2:
lista=["MOZART","haydn","mozart","bach","BACH","Liszt","Palestrina"]
cuenta={"Mozart"=>0,"Haydn"=>0,"Bach"=>0,"otros"=>0}
lista.eachdo|nombre|
nombre=nombre.downcase.capitalize#aseguraunformatocomparable
casenombre
when"Mozart"
cuenta["Mozart"]+=1#acumulacuentaenhash
when"Haydn"
cuenta["Haydn"]+=1
when"Bach"
cuenta["Bach"]+=1
else
cuenta["otros"]+=1
end
end
cuenta.each{|k,v|puts"#{k}:#{v}"}
#imprimelacuentadecadauno
DerechosReservados2007
55
RubyFcil
14.1:
deffib(n)
casen
when1,2
return1
else
returnfib(n1)+fib(n2)
end
end
fib(20)
6765
fib(30)
832040
#calculorecursivoylento
#sehacelentoparanumerosgrandes
14.2:#AlgoritmoFibonaccioptimizado:
$f=[1,1]
deffibm(n)
if$f[n]
return$f[n]
else
$f[n]=fibm(n1)+fibm(n2)
return$f[n]
end
end
fibm(100)
#declaraunarrayglobal
#siyatieneelvalor
#lodevuelve
#sino
#localcularecursivamente
#ylodevuelve
#efectosecundario,$fcrece
354224848179261915075
14.3:
deflimgolden(n)
phi=(1+Math.sqrt(5))/2.0
#1.61803398874989
phi2=(phi*10**n).to_i/(10.0**n)
#precisionandecimales
i=1
loopdo
m=1.0*fibm(i+1)/fibm(i)#calculaelcocienteaureo
m=(m*10**n).to_i/(10.0**n)
#aproximaandecimales
puts"#{i}:#{m}"
#imprimeresultadoparcial
breakif(m==phi2)
#precisiondeseada?
i+=1
#contadordeiteraciones
end
print"#{n}decimalestoma#{i}iteraciones"
end
limgolden(3)
3decimalestoma10iteraciones
limgolden(6)
6decimalestoma17iteraciones
limgolden(14)
14decimalestoma36iteraciones
#podemosconcluirqueconvergerapidamenteaphi
DerechosReservados2007
56
RubyFcil
14.4:
defpascal(n)
m=Array.new#crealamatriz,deunadimension
#vamosaconsiderar:ifilas,yjcolumnas
foriin0..ndo#porcadafila
m[i]=Array.new#crealasegundadimension
m[i].fill(0,0..n)#inicialafilaenceros
m[i][0]=1#inicialaprimeracolumnaenunos
m[i][i]=1#inicialadiagonalenunos
end
foriin0..ndo#porcadafila
forjin0...ido#porcadacolumna,hastaladiagonal,excl.
m[i][j]=m[i1][j]+m[i1][j1]#calculalosnumerosinternos
end
putsm[i].join("")#imprimelafila
end
end
14.5:
$prefijos0={1=>"hena",2=>"di",3=>"tri",4=>"tetra",5=>"penta",6=>"hexa",
7=>"hepta",8=>"octa",9=>"enea",10=>"deca",20=>"icosa"}#+sufijogono
$prefijos10={1=>"hen",2=>"dode",3=>"tri",4=>"tetra",5=>"penta",6=>"hexa",
7=>"hepta",8=>"octa",9=>"enea"}#+sufijodecagono
$prefijos100={2=>"icosi",3=>"triaconta",4=>"tetraconta",5=>"pentaconta",
6=>"hexaconta",7=>"heptaconta",8=>"octaconta",9=>"eneaconta"}#+kai+
prefijo0(1..9)+gono
defpoligono(n)
if(n<1)or(n>99)
return"error:#{n}estafueradelimites"
elsif(n<11)or(20==n)
return$prefijos0[n]+"gono"
elsif(n>10)and(n<20)
m=n10
return$prefijos10[m]+"decagono"
elsif(n>20)
decenas=n/10
unidades=n(decena*10)
if(unidades>0)
return$prefijos100[decenas]+"kai"+$prefijos0[unidades]+"gono"
else
return$prefijos100[decenas]+"gono"
end
end
end
#ahoraalgunosejemplosparaensayarlo:
poligono(0)"error:0estafueradelimites"
poligono(5)"pentagono"
poligono(13)"tridecagono"
poligono(20)"icosagono"
poligono(30)"triacontagono"
poligono(54)"pentacontakaitetragono"
DerechosReservados2007
57
RubyFcil
14.6:
deffact(x)#calculamosfact(x)recursivamente
if(0==x)or(1==x)
1
else
x*fact(x1)
end
end
defcoef(n,k)#definimoscoef(n,k)enterminosdefact()
fact(n)/(fact(k)*fact(nk))
end
defbinom(n)
a=Array.new#unarrayparaguardarlasexpresionesparciales
forkin0..n#lasumatoriaimplicaquevaahaberunciclo
c=coef(n,k)#calculamoselcoeficientepara(n,k)
m=nk#guardamoselvalordenk
a[k]="#{c}*x^#{m}*y^#{k}"#calculamoslaexpresionparcial
end
putsa.join("+")#concatenamostodoconelsigno+
end
binom(3)#produceelsiguienteresultado:
1*x^3*y^0+3*x^2*y^1+3*x^1*y^2+1*x^0*y^3
15.1,15.3:
classPerro
definitialize(nombre,color,edad,sexo)#constructor
@nombre=nombre
@color=color
@edad=edad
@sexo=sexo
@ladrido="guau"
end
defto_s#representaciontextual
"Nombre=#@nombre,Ladrido=#@ladrido,"+
"Color=#@color,Edad=#@edad,Sexo=#@sexo"
end
defnombre
@nombre
end
defcolor
@color
end
defedad
@edad
end
defsexo
@sexo
end
def<=>(perro)#15.3permiteordenarloporedad
@edad<=>perro.edad
end
#(continua...)
DerechosReservados2007
58
RubyFcil
defladra
@ladrido
end
end
15.4
a=Array.new
a[0]=Perro.new("fifi","negro",3,"femenino")
a[1]=Perro.new("milu","blanco",5,"masculino")
a[2]=Perro.new("goofy","cafe",7,"masculino")
a.eachdo|p|
putsp.to_s#examinalaspropiedadesdecadauno
putsp.ladra#lohaceladrar
end
a.sort#losordenaporedad
16.1:
classPerro
attr_reader:nombre,:color,:edad,:sexo#estoacortaelprograma
attr_writer:nombre,:color,:edad,:sexo
definitialize(nombre,color,edad,sexo)#constructor
@nombre=nombre
@color=color
@edad=edad
@sexo=sexo
@ladrido="guau"
end
defto_s#representaciontextual
"Nombre=#@nombre,Ladrido=#@ladrido,"+
"Color=#@color,Edad=#@edad,Sexo=#@sexo"
end
def<=>(perro)#permiteordenarloporedad
@edad<=>perro.edad
end
defladra
@ladrido
end
end
DerechosReservados2007
59
RubyFcil
18.1:
classCaja#Cajaessuperclasedetodas
attr_reader:color
definitialize(color)
@color=color
end
end
classCilindro<Caja#CilindroessubclasedeCaja
attr_reader:radio,:lado,:volumen
definitialize(color,radio,lado)
super(color)#pideasuperclasequeguardecolor
@radio,@lado=radio,lado
@volumen=2*Math::PI*radio*lado
end
end
classCubo<Caja#CuboessubclasedeCaja
attr_reader:lado,:volumen
definitialize(color,lado)
super(color)#pideasuperclasequeguardecolor
@lado=lado
@volumen=lado*lado*lado
end
end
classEsfera<Caja#EsferaessubclasedeCaja
attr_reader:radio,:volumen
definitialize(color,radio)
super(color)#pideasuperclasequeguardecolor
@radio=radio
@volumen=(4.0/3.0)*Math::PI*(radio**3)
end
end
tubo=Cilindro.new("gris",2,2)
puts"tubo:#{tubo.volumen}"25.1327412287183
dado=Cubo.new("rojo",2)
puts"dado:#{dado.volumen}"8
pelota=Esfera.new("azul",2)
puts"pelota:#{pelota.volumen}"33.5103216382911
19.2:
s="Paris|Roma|Madrid|Estambul|Damasco"
s.split(/\|/)["Paris","Roma","Madrid","Estambul","Damasco"]
19.3:
s="http://sitioweb.net?var1=1&var2=2&var3=3"
url,vars=s.split(/\?/)
v=vars.split(/\&/)
h=Hash.new
h["url"]=url
v.eachdo|par|
izq,der=par.split(\&)#separacadapardelaforma"izq&der"
h[izq]=der
end
#produce
h=[url=>http://sitioweb.net,var1=>1,var2=>2,var3=>3]
DerechosReservados2007
60
RubyFcil
20.2:
archivo="datos.txt"#archivoaleer
ifFile.exists?(archivo)#loprocesamossiexiste
f=File.open(archivo)
a=f.readlines(archivo)#loleemos
f.close#locerramos
dic=Hash.new#contaremospalabrasenundiccionario
a.eachdo|linea|#ahoraprocesamoscadalineadelarreglo
palabras=linea.downcase.split([\.,'"!;:\s])#separarlaspalabras
palabras.eachdo|palabra|#procesarcadaunadelaspalabras
ifdic[palabra]#siestaeneldiccionario
dic[palabra]+=1#aumentarelcontador
else#sinoestaeneldiccionario
dic[palabra]=1#anadirlaycontarla
end
end
end
sa=dic.sort#ordenayproducearreglodearreglos
sa.eachdo|par|#paracadaelemento
puts"#{par[0]}:#{par[1]}"#imprimeelpar:palabra,cuenta
end
else
puts"#{archivo}noexiste"#reportamosunerrorsinoexiste
end
20.3:
archivo="datos2.txt"#archivoaleer
ifFile.exists?(archivo)#loprocesamossiexiste
f=File.open(archivo)
a=f.readlines(archivo)#loleemos
f.close#locerramos
dic={"@nombre@"=>"Cesar","@mensaje@"=>"vencimos"}#palabrasareemplazar
a.eachdo|linea|#procesamoscadalinea
dic.eachdo|w1,w2|
linea.gsub!(w1,w2)#reemplazaenlinea
end
end
f=File.new("resultados.txt","w")
a.each{|linea|f.puts"#{linea}"}#imprimeenelarchivo
f.close
else
puts"#{archivo}noexiste"#reportamosunerrorsinoexiste
end
Datos2.txt:
Esteesunmensajepara@nombre@:@mensaje@;quedesetranquilo.
EstimadoSr@nombre@,sustropasdicen:"@mensaje@,@mensaje@,@mensaje@".
Resultados.txt:
EsteesunmensajeparaCesar:vencimos;quedesetranquilo.
EstimadoSrCesar,sustropasdicen:"vencimos,vencimos,vencimos".
DerechosReservados2007
61
RubyFcil
20.4:
defesComienzo(codon)#verificasielcodoneselcodigodecomienzo
return("AUG"==codon)
end
defesFinal(codon)#verificasielcodonesuncodigodeterminacion
return(("UAG"==codon)or("UGA"==codon)or("UAA"==codon))
end
#elsiguienteHashtienetodoslosdatosparatraducirdecodonaproteina
$codigoGenetico={"UUU"=>"F","UUC"=>"F","UUA"=>"L","UUG"=>"L",
"UCU"=>"S","UCC"=>"S","UCA"=>"S","UCG"=>"S","UAU"=>"Y",
"UAC"=>"Y","UAA"=>"[stop]","UAG"=>"[stop]","UGU"=>"C",
"UGC"=>"C","UGA"=>"[stop]","UGG"=>"W","CUU"=>"L","CUC"=>"L",
"CUA"=>"L","CUG"=>"L","CCU"=>"P","CCC"=>"P","CCA"=>"P",
"CCG"=>"P","CAU"=>"H","CAC"=>"H","CAA"=>"Q","CAG"=>"Q",
"CGU"=>"A","CGC"=>"A","CGA"=>"A","CGG"=>"A","AUU"=>"I",
"AUC"=>"I","AUA"=>"I","AUG"=>"M","ACU"=>"T","ACC"=>"T",
"ACA"=>"T","ACG"=>"T","AAU"=>"N","AAC"=>"N","AAA"=>"K",
"AAG"=>"K","AGU"=>"S","AGC"=>"S","AGA"=>"R","AGG"=>"R",
"GUU"=>"V","GUC"=>"V","GUA"=>"V","GUG"=>"V","GCU"=>"A",
"GCC"=>"A","GCA"=>"A","GCG"=>"A","GAU"=>"D","GAC"=>"D",
"GAA"=>"E","GAG"=>"E","GGU"=>"G","GGC"=>"G","GGA"=>"G",
"GGG"=>"G"}
deftoRNA(linea)#conviertecadenalargaaarraydecodones
returnlinea.scan(/.../)#partecadatresletras
end
defestaBienConstruida(codons)#funcionparaverificarcomienzoyfinal
returnesComienzo(codons[0])andesFinal(codons[1])
end
archivo="arn.txt"#archivoaleer
ifFile.exists?(archivo)#loprocesamossiexiste
f=File.open(archivo)
a=f.readlines(archivo)#loleemos
f.close#locerramos
result=Array.new#nuevoarregloconresultados
a.eachdo|linea|#procesamoscadalinea
linea.lstrip!#remueveespaciosalaizquierda
linea.rstrip!#remueveespaciosaladerecha
linea.chomp!#remueve\nalfinal
ifnotlinea.empty?
linea.upcase!#convierteamayusculas
codons=toRNA(linea)#conviertecadenaaarraydecodones
ifestaBienConstruida(codons)
proteina=String.new#preparacadenaparaelresultado
codons.eachdo|codon|
proteina+=$codigoGenetico[codon]#reemplazacodonconproteina
end
result.push(proteina)
else
result.push("Error:cadenanocomienzaoterminabien")
end
result.push(proteina)#anadelanuevacadenaalarreglo
end
end
(continua...)
DerechosReservados2007
62
RubyFcil
(...continua)
f=File.new("proteinas.txt","w")
result.each{|linea|f.puts"#{linea}"}#imprimeenelarchivo
f.close
else
puts"#{archivo}noexiste"#reportamosunerrorsinoexiste
end
arn.txt:
AUGGCACUCGCGGAGGCCGACGACGGCGCGGUGGUCUUCGGCGAGGAGCAGUGA
resultado:proteinas.txt:
MALAEADDGAVVFGEEQ[stop]
23.2:
0.step(3.14,0.02){|x|putssprintf("%3.2f%5.3f",x,Math.sin(x))}
DerechosReservados2007
63
RubyFcil
Bibliografa
LibrosImpresos
ProgrammingRuby:ThePragmaticProgrammer'sGuide,DaveThomas
(ThePragmaticProgrammer,2005),ISBN0974514055.
RubyCookbook,LeonardRichardson;LucasCarlson(O'Reilly,2006)
ISBN0596523696.
RubyDeveloper'sGuide,RobertFeldt,LyleJohnson,MichaelNeumann
(SyngressPublishing2002),ISBN1928994644.
RubyinaNutshell,KatzMatsumoto(O'Reilly,2001),
ISBN0596002149.
TheRubyWay,HalFulton(AddisonWesley,2006),
ISBN0672328844.
DerechosReservados2007
64
RubyFcil
EnlacesenInternet
RubyProgrammingLanguage
http://www.rubylang.org/en/
Versinenlneadellibro:ProgrammingRuby
http://www.rubycentral.com/pickaxe/
RubyonRailsTutorial
http://wiki.rubyonrails.org/rails/pages/Tutorial
LearntoProgram
http://pine.fm/LearnToProgram/
LearnRuby
http://www.math.umd.edu/~dcarrera/ruby/0.3/
Rubypedia:fuentederecursosRuby
http://www.rubypedia.com/
RubyMatters:msrecursossobreRuby
http://www.rubymatters.com/
DescripcindeRubyenlawikipedia
http://en.wikipedia.org/wiki/Ruby_%28programming_language%29
DerechosReservados2007
65
RubyFcil
CuriosidadesMatemticas
Algunosdelosejercicioshacenreferenciaatemas,ensumayora,matemticos,conlosquequizs
ellectornoestfamiliarizado.Lossiguientesenlacesofrecenmsinformacinsobreestostemas.
ElcocienteAureo
http://en.wikipedia.org/wiki/Golden_ratio
CoeficienteBinomial
http://en.wikipedia.org/wiki/Binomial_coefficient
ElnmerodeEuler,e
http://en.wikipedia.org/wiki/E_%28mathematical_constant%29
LaseriedeFibonacci
http://en.wikipedia.org/wiki/Fibonacci_number#Limit_of_consecutive_quotients
CarlFriedrichGauss
http://en.wikipedia.org/wiki/Carl_Friedrich_Gauss
Lmites
http://en.wikipedia.org/wiki/Limit_%28mathematics%29
Matrices
http://en.wikipedia.org/wiki/Matrix_%28mathematics%29
SeriesdeTaylor
http://en.wikipedia.org/wiki/Taylor_series
TringulodePascal
http://en.wikipedia.org/wiki/Pascal%27s_triangle
Pi
http://en.wikipedia.org/wiki/Pi
Polgonos
http://en.wikipedia.org/wiki/Polygon
ElCdigoGentico
http://en.wikipedia.org/wiki/Genetic_code
DerechosReservados2007
66
RubyFcil
BibliotecasGrficasparaRuby
Tk:ParaLinuxyWindows.ParaWindows,requiereActiveTcl:
http://www.activestate.com/Products/activetcl/
Ruby/Qt2:basadoenOpenGL,disponibleparaLinux.
http://sfns.ushizuokaken.ac.jp/geneng/horie_hp/ruby/index.html#Ruby/Qt2
fxRuby:paraLinux
http://www.fxruby.org/
DerechosReservados2007
67
RubyFcil
ApndiceA.ElCdigoASCII
ElcdigoASCII,AmericanStandardCodeforInformationInterchange,(CdigoEstndar
AmericanoparaIntercambiodeInformacin)fuedefinidoen1960parateletipos(mquinasque
mandabanmensajeselctricosporcable),yesuncdigode7bits(de0a127)paraloscaracteres
impresosdelingls.
Estecdigotuvomuchaslimitaciones:porejemplo,nosepodanhacerloscaracteresespecialesdel
espaol(),asqueluegotuvoqueserextendidoa8bits.Perotampocosepodanhacerlos
caracteresdeotrosidiomas,asquehubonecesidaddedesarrollarotroscdigos,talescomo
UnicodeyUTF,quesonlosqueactualmenteseusan,de2bytes,yquecubrentodoslosidiomasdel
mundo,incluyendosmbolosespecialesdematemticas,financieros,etc.
ElcdigoASCIIsepuedegenerarfcilmenteconuncicloqueiteresobrelafuncinchr:[del0al
31,yel127,seomitenporsercaracteresdecontrol]
32.upto(126){|c|putsc.chr}
32:(espacio)
33:!
34:"
35:#
36:$
37:%
38:&
39:'
40:(
41:)
42:*
43:+
44:,
45:
46:.
47:/
48:0
49:1
50:2
51:3
52:4
53:5
54:6
55:7
56:8
57:9
58::
59:;
60:<
61:=
62:>
63:?
64:@
65:A
66:B
67:C
68:D
69:E
70:F
71:G
72:H
73:I
74:J
75:K
76:L
77:M
78:N
79:O
80:P
81:Q
82:R
83:S
84:T
85:U
86:V
87:W
88:X
89:Y
90:Z
91:[
92:\
93:]
94:^
95:_
96:`
97:a
98:b
99:c
100:d
101:e
102:f
103:g
104:h
105:i
106:j
107:k
108:l
109:m
110:n
111:o
112:p
113:q
114:r
115:s
116:t
117:u
118:v
119:w
120:x
121:y
122:z
123:{
124:|
125:}
126:~
TabladelcdigoASCII(de32a126)
MsinformacinsobreelcdigoASCII:
http://en.wikipedia.org/wiki/ASCII
DerechosReservados2007
68
RubyFcil
ApndiceB.ComusarSciTE
SciTEeseleditordetextousadoparaprogramarenRuby.Permiteescribirprogramas,guardarlos,
corregirlos,yejecutarlos.
EnestapequeaguavamosademostrarcmoseusaSciTE.
B.1PrimerpasoEdicin
EmpezamosporejecutarScite,queseconsiguesiguiendolossiguientesmensdeWindows:
[Comienzo]>Programas>Ruby18625>SciTE
Seguidamente,escribimoselprogramaenelespacioenblancodeleditor.Podemosnotar,comoen
lafigura1,quecadalneadelprogramaobtieneautomticamenteunnmerosequencial,quese
muestraenlacolumnadelaizquierda.Estoestilcuandonossalenerrores,parasaberquelineair
acorregir.
Tambinpodemosobservarqueelcdigotienecolores.Otraventaja,sonlaslneasverticalesque
aparecenindicandolaindentacin,osubordinacinrelativadelcdigo.Todoestoesparafacilitar
leerloyescribirlocorrectamente.
DerechosReservados2007
69
RubyFcil
FiguraB.1.EditandoprogramasRubyenSciTE
B.2SegundopasoGuardareltrabajo
Unavezquehayamosterminadodeescribirelprograma,loguardamoseneldiscoparamantener
unacopiapermanentedeeste.Deestamanera,podemosvolverotrodayseguirmodificando
nuestrotrabajo.Elcomandoparaguardarloeselmensiguiente,comomuestralafigura2:
File>Save
FiguraB.2.GuardarelprogramaconFile>SaveAs...
Apareceunaventanadondeledamosunnombrealprograma.Laterminacindelnombrede
programasRuby,porconvencin,esrb.Lafigura3ilustraesto.
FiguraB.3.Guardarelprograma
DerechosReservados2007
70
RubyFcil
B.3TercerpasoEjecutarelprograma
Unavezqueelprogramahasidoguardado,entoncessepuedeejecutarparaprobarlo.
ElcomandoparaejecutarunprogramadesdeSciTEeselmensiguiente(figura4):
Tools>Go
FiguraB.4.Ejecutarelprograma
Elequivalenteespresionarlatecla[F5]queseencuentraencimadelasteclasnumricas,enel
tecladoalfanumrico.VerFigura5.
FiguraB.5.[F5]eneltecladoalfanumrico
DerechosReservados2007
71
RubyFcil
Finalmente,losresultadosaparecenenunaventananueva,aladerecha,comosemuestraenla
figura6.
Sihayerrores,estossereportandondesalenlosresultados,aladerecha.Despushayque
corregirlosenlaventanadelaizquierda,volveraguardar,yvolveracorrerelprograma.Estose
repitetantasvecescuantasseannecesariashastagarantizarqueelprogramafuncione
correctamente.
FiguraB.6.Examinarlosresultados
Enlaventanadelaizquierda,lossignos+/delasegundacolumnapermitencolapsaryexpandirel
cdigoparafacilitarsulecturayentenderlomejor.
DerechosReservados2007
72
RubyFcil
SobreelAutor
DiegoFGuillnNakamuratieneunBSdelaUniversidaddeLosAndes(Bogot,Colombia),yun
MSdelaUniversidaddeSofa(Tokyo,Japn).Diegollevaejerciendosuprofesinmsde25aos,
duranteelcualhausadomsde15lenguajesdeprogramacin.Actualmente,Diegotrabajaenel
readesoftwareparaunamultinacionaljaponesa,yviveenGoldCoast,Australia.Susintereses
acadmicosestnenlasreasdematemticas,bioinformtica,ylenguajesdeprogramacin.Ensus
ratoslibresDiegodisfrutadelasarmonassofisticadasdelamsicachoroybossanovadeBrazilen
laguitarra.
DerechosReservados2007
73