Está en la página 1de 73

RubyFcil

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

También podría gustarte