Introduccion a ruby

Fernando Calatayud
Fernando CalatayudRoR developer, webmaster at Rankia
RUBYIntroducción
FERNAN
DO
CALATA
YUDTwitter: @fj2c
Github: @fernan2
Hola, me llamo
Fernando, y soy
programador Ruby
RUBY EN UNA
FRASE➤ Ruby es un lenguaje hecho
para optimizar al programador
“Ruby is designed to make
programmers happy.”
Yukihiro “Matz” Matsumoto
Y POR ESO…
➤ Ruby es un lenguaje hecho
para optimizar al programador
➤ Ruby es un lenguaje
interpretado
Y POR ESO…
➤ Ruby es un lenguaje hecho
para optimizar al programador
➤ Ruby es un lenguaje
interpretado
➤ Ruby es dinámicamente
tipado
“With great power comes great
responsability.”
Uncle Ben
Y POR ESO…
➤ Ruby es un lenguaje hecho
para optimizar al programador
➤ Ruby es un lenguaje
interpretado
➤ Ruby es dinámicamente
tipado
➤ Ruby es (relativamente) lento
¿Y eso importa?
¿AHORRAR 0.08 SEGUNDOS ES
IMPORTANTE EN TU NEGOCIO?
Y POR ESO…
➤ Ruby es un lenguaje hecho
para optimizar al programador
➤ Ruby es un lenguaje
interpretado
➤ Ruby es dinámicamente
tipado
➤ Ruby es (relativamente) lento
➤ Ruby es un lenguaje
Orientado a Objetos
Y POR ESO…
➤ Ruby es un lenguaje hecho
para optimizar al programador
➤ Ruby es un lenguaje
interpretado
➤ Ruby es dinámicamente
tipado
➤ Ruby es (relativamente) lento
➤ Ruby es un lenguaje
Orientado a Objetos
➤ Ruby es muy flexible
“With great power comes great
responsability.” (sí, otra vez!)
¿QUE SIGNIFICA EXACTAMENTE QUE
ES FLEXIBLE?➤ Ruby tiene “formas acortadas” para escribir las cosas
tecleando menos.
¿QUE SIGNIFICA EXACTAMENTE QUE
ES FLEXIBLE?➤ Ruby tiene “formas acortadas” para escribir las cosas
tecleando menos.
➤ Es frecuente tener la versión acortada para usar con trozos de
código pequeños y la “normal” para cuando hay más código.
¿QUE SIGNIFICA EXACTAMENTE QUE
ES FLEXIBLE?➤ Ruby tiene “formas acortadas” para escribir las cosas
tecleando menos.
➤ Curiosamente, el beneficio no es que se escribe menos, sino
que queda más bonito y se lee mejor.
➤ Conviene seguir una “guía de estilo” para asegurar la
consistencia y que no sea un caos:
https://github.com/bbatsov/ruby-style-guide
➤ Es frecuente tener la versión acortada para usar con trozos de
código pequeños y la “normal” para cuando hay más código.
➤ Una especie de “cadena corta” especialmente eficiente porque es
inmutable e internamente funciona como un entero
➤ Además de eficiente… es muy legible, y mola!
:title
SYMBOLS
➤ Una especie de “cadena corta” especialmente eficiente porque es
inmutable e internamente funciona como un entero
➤ Además de eficiente… es muy legible, y mola!
➤ Hay una versión acortada para arrays de symbols
attributes = %i(title author year description)
SYMBOLS
➤ Una especie de “cadena corta” especialmente eficiente porque es
inmutable e internamente funciona como un entero
➤ Además de eficiente… es muy legible, y mola!
➤ Hay una versión acortada para arrays de symbols
➤ Con frecuencia se usa para key de hashes (pares key-value), así
que… también hay una versión acortada para este caso
SYMBOLS
:key => 'My value'
key: 'My value'
➤ El bucle menos rubyish del mundo (pero funciona):
for i in 0..(subscribers.length - 1)
subscribers[i].notify
end
BUCLES
➤ Preferimos trabajar con instancias mejor que índices:
for i in 0..(subscribers.length - 1)
subscribers[i].notify
end
BUCLES
for suscriber in subscribers
subscriber.notify
end
➤ Preferimos trabajar con instancias mejor que índices.
➤ Preferimos “each” en vez de “for” (crea un bloque: scope propio). Lo
que pasa en el “each”, se queda en el “each”:
BUCLES
for suscriber in subscribers
subscriber.notify
end
suscribers.each do |subscriber|
subscriber.notify
end
➤ Preferimos trabajar con instancias mejor que índices.
➤ Preferimos “each” en vez de “for” (crea un bloque: scope propio). Lo
que pasa en el “each”, se queda en el “each”.
➤ Si se va a iterar una línea corta, se puede meter todo en una línea:
BUCLES
suscribers.each { |subscriber| subscriber.notify }
suscribers.each do |subscriber|
subscriber.notify
end
➤ Preferimos trabajar con instancias mejor que índices.
➤ Preferimos “each” en vez de “for” (crea un bloque: scope propio). Lo
que pasa en el “each”, se queda en el “each”.
➤ Si se va a iterar una línea corta, se puede meter todo en una línea.
➤ Si lo único que voy a hacer es llamar un método de la instancia, ni
siquiera necesitaré el bucle:
GREAT!!!!
BUCLES
suscribers.each(&:notify)
suscribers.each { |subscriber| subscriber.notify }
➤ Hay una versión acortada para usar con trozos de código pequeños
if subscriber.valid?
subscriber.notify
end
CONDICIONALES
subscriber.notify if subscriber.valid?
➤ Hay una versión acortada para usar con trozos de código pequeños
➤ Se puede usar en su lugar, sin abusar, el operador ternario
timeout = if is_admin
ADMIN_TIMEOUT
else
USER_TIMEOUT
end
CONDICIONALES
timeout = is_admin ? ADMIN_TIMEOUT : USER_TIMEOUT
➤ Hay una versión acortada para usar con trozos de código pequeños
➤ Se puede usar en su lugar, sin abusar, el operador ternario
➤ Preferimos unless en vez de condiciones negadas (siempre que no
haya else)
CONDICIONALES
if !subscriber.valid?
subscriber.reject
end
unless subscriber.valid?
subscriber.reject
end
➤ Hay una versión acortada para usar con trozos de código pequeños
➤ Se puede usar en su lugar, sin abusar, el operador ternario
➤ Preferimos unless en vez de condiciones negadas (siempre que no
haya else)
➤ Si no se trata de condiciones “normales”, sino de tratamiento de
errores, es más expresivo usar “condiciones de salida” que partir el
flujo en dos ramas con apariencia de similar jerarquía
CONDICIONALES
(Requisito: los métodos deben devolver nil si fallan)
blog = Blog.find(url)
if blog
subscription = subscribe(me, blog)
if subscription
notify_subscription(subscription)
else
subscription_failed
end
else
render_404
end
CONDICIONALES
blog.find(url) or return render_404
subscription = subscribe(me, blog) or return subscription_failed
notify_subscription(subscription)
➤ Similares a otros lenguajes.
➤ Muy enriquecidos con métodos útiles “de fábrica”. Consultar
documentación https://docs.ruby-lang.org/en/2.3.0/String.html
➤ Se usa interpolación "Nombre: #{user.name}" en vez de suma
"Nombre:" + user.name para evitar problemas con nil.
➤ Conversión a entero inteligente: "46-valencia".to_i => 46
➤ Al interpolar un objeto, se llamará a su método .to_s . Definiendo
este método, tendremos un magnífico “default” de cómo se
muestran las instancias de esta clase: "Nombre: #{user}"
(podremos definirlo como nombre+apellidos, o nick, o lo que sea)
STRINGS
➤ Similares a otros lenguajes.
➤ Muy enriquecidos con métodos útiles “de fábrica”. Consultar
documentación https://docs.ruby-lang.org/en/2.3.0/Array.html &
https://docs.ruby-lang.org/en/2.3.0/Enumerable.html
ARRAYS
➤ Pares de key + value, en los que se busca usando la key para
obtener el value asociado
HASHES
{
nil => "No se encuentra",
'A' => "Opción A",
'X' => AMOUNT * RATE
}
(Explicación de informático a jefe de proyecto: correcto pero no muy útil)
¿Para qué sirven los hashes?
➤ Pares de key + value, en los que se busca usando la key para
obtener el value asociado
➤ Útiles para implementar diccionarios de traducción
HASHES
ORDER_TO_BD = {
'cheap' => 'price',
'expensive' => 'price DESC',
'popular' => 'likes_count DESC'
}
order = ORDER_TO_BD[param_order] || 'created_at DESC'
PROVINCIA_API = {
'La Coruña' => 'A Coruña',
'Gerona' => 'Girona'
}
provincia = PROVINCIA_API[provincia_api] || provincia_api
➤ Pares de key + value, en los que se busca usando la key para
obtener el value asociado
➤ Útiles para implementar diccionarios de traducción
➤ O para convención sobre configuración
HASHES
DEFAULT_PAGINATE = {
page: 1,
per_page: 25,
order: 'created_at'
}
def pagination(custom_pagination = {})
options = DEFAULT_PAGINATE.merge(custom_pagination)
first = 1 + (options[:page] - 1) * options[:per_page]
...
end
➤ Pares de key + value, en los que se busca usando la key para
obtener el value asociado
➤ Útiles para implementar diccionarios de traducción
➤ O para convención sobre configuración
➤ Fácil de convertir desde/hacia JSON, YAML, atributos de un
modelo, campos de la tabla en BD…
HASHES
➤ Se pueden enviar llamadas a atributos o métodos de una instancia
componiendo dinámicamente su método
MÉTODOS
DINÁMICOS
user.phone_1 = '963112233'
user.phone_4 = '666111000'
user.phone_2 = '678111000'
phones = (1..4).map do |i|
user.send("phone_#{i}")
end
=> ['963112233', '678111000', nil, '666111000']
➤ Se pueden enviar llamadas a atributos o métodos de una instancia
componiendo dinámicamente su método
➤ Cuidado con la seguridad: si no son constantes, sino parámetros o
valores de la BD, hay que usar whitelists
MÉTODOS
DINÁMICOS
VALID_SECTIONS = %w(banca bolsa fondos)
def filter_by_section(param_section)
return unless param_section.in?(VALID_SECTIONS)
Message.send("in_#{param_section}")
end
➤ Se pueden enviar llamadas a atributos o métodos de una instancia
componiendo dinámicamente su método
➤ Cuidado con la seguridad: si no son constantes, sino parámetros o
valores de la BD, hay que usar whitelists
➤ Útil para manejar items con gran cantidad de campos que siguen
patrones en su nombre o que se comportan igual
MÉTODOS
DINÁMICOS
➤ Se pueden enviar llamadas a atributos o métodos de una instancia
componiendo dinámicamente su método
➤ Cuidado con la seguridad: si no son constantes, sino parámetros o
valores de la BD, hay que usar whitelists
➤ Útil para manejar items con gran cantidad de campos que siguen
patrones en su nombre o que se comportan igual
➤ En ocasiones es un smell: si muchos atributos se comportan de
forma repetitiva, quizá se resuelva mejor usando atributos de tipo
array, o una tabla con una relación 1-n
MÉTODOS
DINÁMICOS
➤ Los métodos en Ruby retornan el valor de la última operación que
se hizo
MÉTODOS
Asignación: el valor asignado a la variable
return unless admin?: nil (default)
return “No way!” unless admin?: “No way!”
Llamada a otro método: el valor de retorno del
otro método
➤ Los métodos en Ruby retornan el valor de la última operación que
se hizo
➤ Se pueden pasar parámetros opcionales (al final) poniendo un
default
MÉTODOS
def pictures(format, order = 'created_at desc', limit = nil)
"Bring #{format} files sort #{order} max #{limit || 'all'}"
end
item.pictures('jpg')
item.pictures('jpg', 'likes_count desc')
item.pictures('jpg', 'created_at desc', 20)
➤ Los métodos en Ruby retornan el valor de la última operación que
se hizo
➤ Se pueden pasar parámetros opcionales (al final) poniendo un
default
➤ Se puede reducir el acoplamiento (Connascence) con named
parameters (aka keyword arguments)
MÉTODOS
def pictures(format:, order: 'created_at desc', limit: nil)
"Bring #{format} files sort #{order} max #{limit || 'all'}"
end
item.pictures(format: 'jpg')
item.pictures(format: 'jpg', order: 'likes_count desc')
item.pictures(format: 'jpg', limit: 20)
1 of 38

Recommended

Exposicion de php by
Exposicion de phpExposicion de php
Exposicion de phpangie barre
2.5K views25 slides
Unidad 2 by
Unidad 2Unidad 2
Unidad 2Tadeo Rmz
501 views10 slides
Unidad 2 by
Unidad 2Unidad 2
Unidad 2Tadeo Rmz
153 views10 slides
Programacion en php by
Programacion en phpProgramacion en php
Programacion en phpAngiie Mortera
3K views69 slides
Anyi amaya by
Anyi amayaAnyi amaya
Anyi amayaanyicitaazulita
344 views13 slides
39 Php. Bucles While by
39 Php. Bucles While39 Php. Bucles While
39 Php. Bucles WhileJosé M. Padilla
482 views2 slides

More Related Content

What's hot

Php by
PhpPhp
PhpConfesorAD
1.3K views34 slides
Php1 by
Php1Php1
Php1Rodrigo Cabrera
633 views41 slides
Php1 by
Php1Php1
Php1Rodrigo Cabrera
156 views46 slides
14 PHP. Variables by
14 PHP. Variables14 PHP. Variables
14 PHP. VariablesJosé M. Padilla
407 views2 slides
VBScript Tutorial by
VBScript TutorialVBScript Tutorial
VBScript TutorialLeminy
8.3K views24 slides
Vb script hx-c-wd by
Vb script hx-c-wdVb script hx-c-wd
Vb script hx-c-wdDiego Caceres
759 views74 slides

Viewers also liked

Estrategias en multigrado by
Estrategias en multigradoEstrategias en multigrado
Estrategias en multigradoJesús Alberto Arvizu Aguilar
1.5K views62 slides
Group2 sec c by
Group2 sec cGroup2 sec c
Group2 sec cSatwik Mohanty
97 views13 slides
укрдузт кафедра електроенегетики by
укрдузт кафедра електроенегетикиукрдузт кафедра електроенегетики
укрдузт кафедра електроенегетикиAndrei Bondarenko
222 views8 slides
Свети Сава by
Свети СаваСвети Сава
Свети СаваSrpska škola u inostranstvu
417 views23 slides
Nuno pacc by
Nuno paccNuno pacc
Nuno paccLina Silva
101 views7 slides
Phrases,clauses and Sentances by
Phrases,clauses and SentancesPhrases,clauses and Sentances
Phrases,clauses and SentancesHENOK SHIHEPO
644 views11 slides

Viewers also liked(16)

укрдузт кафедра електроенегетики by Andrei Bondarenko
укрдузт кафедра електроенегетикиукрдузт кафедра електроенегетики
укрдузт кафедра електроенегетики
Andrei Bondarenko222 views
Phrases,clauses and Sentances by HENOK SHIHEPO
Phrases,clauses and SentancesPhrases,clauses and Sentances
Phrases,clauses and Sentances
HENOK SHIHEPO644 views
開放源碼的ASP.NET Core & ADO.NET (for VS2015) by MIS2000 Lab.
開放源碼的ASP.NET Core & ADO.NET (for VS2015)開放源碼的ASP.NET Core & ADO.NET (for VS2015)
開放源碼的ASP.NET Core & ADO.NET (for VS2015)
MIS2000 Lab. 449 views
Hyperlink (SMCL-Grade7Computer) by jbesin
Hyperlink (SMCL-Grade7Computer)Hyperlink (SMCL-Grade7Computer)
Hyperlink (SMCL-Grade7Computer)
jbesin608 views

Similar to Introduccion a ruby

The linux shell. Shell Scripting desde 0 by
The linux shell. Shell Scripting desde 0The linux shell. Shell Scripting desde 0
The linux shell. Shell Scripting desde 0Remigio Salvador Sánchez
1.8K views44 slides
Anonimo el libro hacker by
Anonimo   el libro hackerAnonimo   el libro hacker
Anonimo el libro hackerGabriel Moreno Cordero Jr.
2.6K views163 slides
Perl1 escalares by
Perl1 escalaresPerl1 escalares
Perl1 escalaresAlfonso Alba
438 views74 slides
Gestión Remota de Equipos con Python by
Gestión Remota de Equipos con PythonGestión Remota de Equipos con Python
Gestión Remota de Equipos con PythonJuan Manuel Rodriguez Burgos
2.7K views75 slides
Curso c++ by
Curso c++Curso c++
Curso c++Jhunior Ramírez Carranza
276 views231 slides
Java Basico Platzi by
Java Basico PlatziJava Basico Platzi
Java Basico PlatziAnahí Salgado
2.1K views148 slides

Similar to Introduccion a ruby(20)

Anon el libro hacker by ssusere4a74e
Anon   el libro hackerAnon   el libro hacker
Anon el libro hacker
ssusere4a74e129 views
Script presentacion by Vanne Napa
Script presentacionScript presentacion
Script presentacion
Vanne Napa5K views
Curso de C++ (2014) by Miriam Ruiz
Curso de C++ (2014)Curso de C++ (2014)
Curso de C++ (2014)
Miriam Ruiz2.5K views
Shell script by uniminuto
Shell scriptShell script
Shell script
uniminuto1.7K views
Manual de hacking basico por taskkill#3 by Brat Stell
Manual de hacking basico por taskkill#3Manual de hacking basico por taskkill#3
Manual de hacking basico por taskkill#3
Brat Stell2.5K views

Recently uploaded

Advanced Persistent Threat ' BugCON 2023 by
Advanced Persistent Threat '  BugCON 2023Advanced Persistent Threat '  BugCON 2023
Advanced Persistent Threat ' BugCON 2023Jonathan Palacios
12 views40 slides
Tecnologia (1).pdf by
Tecnologia (1).pdfTecnologia (1).pdf
Tecnologia (1).pdfnosi6702
9 views13 slides
Seguridad de Windows 11 by
Seguridad de Windows 11Seguridad de Windows 11
Seguridad de Windows 11cesardani28128
6 views7 slides
Seguridad de los Sistema Operativo by
Seguridad de los Sistema OperativoSeguridad de los Sistema Operativo
Seguridad de los Sistema Operativobyshyno19
9 views16 slides
MDE en la industria by
MDE en la industriaMDE en la industria
MDE en la industriaPedro J. Molina
32 views55 slides
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1 by
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1Angel Borroy López
6 views22 slides

Recently uploaded(10)

Tecnologia (1).pdf by nosi6702
Tecnologia (1).pdfTecnologia (1).pdf
Tecnologia (1).pdf
nosi67029 views
Seguridad de los Sistema Operativo by byshyno19
Seguridad de los Sistema OperativoSeguridad de los Sistema Operativo
Seguridad de los Sistema Operativo
byshyno199 views
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1 by Angel Borroy López
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
La Guía Definitiva para una Actualización Exitosa a Alfresco 23.1
Tecnologia (3).pdf by nosi6702
Tecnologia (3).pdfTecnologia (3).pdf
Tecnologia (3).pdf
nosi67028 views
T3. Taller de diseño del informe PRESENTACION.pptx by EmanuelMuoz11
T3. Taller de diseño del informe PRESENTACION.pptxT3. Taller de diseño del informe PRESENTACION.pptx
T3. Taller de diseño del informe PRESENTACION.pptx
EmanuelMuoz117 views
Qué es el rodamiento hacia adelante.docx by FabianCarrillo31
Qué es el rodamiento hacia adelante.docxQué es el rodamiento hacia adelante.docx
Qué es el rodamiento hacia adelante.docx
FabianCarrillo3112 views

Introduccion a ruby

  • 2. FERNAN DO CALATA YUDTwitter: @fj2c Github: @fernan2 Hola, me llamo Fernando, y soy programador Ruby
  • 3. RUBY EN UNA FRASE➤ Ruby es un lenguaje hecho para optimizar al programador “Ruby is designed to make programmers happy.” Yukihiro “Matz” Matsumoto
  • 4. Y POR ESO… ➤ Ruby es un lenguaje hecho para optimizar al programador ➤ Ruby es un lenguaje interpretado
  • 5. Y POR ESO… ➤ Ruby es un lenguaje hecho para optimizar al programador ➤ Ruby es un lenguaje interpretado ➤ Ruby es dinámicamente tipado “With great power comes great responsability.” Uncle Ben
  • 6. Y POR ESO… ➤ Ruby es un lenguaje hecho para optimizar al programador ➤ Ruby es un lenguaje interpretado ➤ Ruby es dinámicamente tipado ➤ Ruby es (relativamente) lento ¿Y eso importa?
  • 7. ¿AHORRAR 0.08 SEGUNDOS ES IMPORTANTE EN TU NEGOCIO?
  • 8. Y POR ESO… ➤ Ruby es un lenguaje hecho para optimizar al programador ➤ Ruby es un lenguaje interpretado ➤ Ruby es dinámicamente tipado ➤ Ruby es (relativamente) lento ➤ Ruby es un lenguaje Orientado a Objetos
  • 9. Y POR ESO… ➤ Ruby es un lenguaje hecho para optimizar al programador ➤ Ruby es un lenguaje interpretado ➤ Ruby es dinámicamente tipado ➤ Ruby es (relativamente) lento ➤ Ruby es un lenguaje Orientado a Objetos ➤ Ruby es muy flexible “With great power comes great responsability.” (sí, otra vez!)
  • 10. ¿QUE SIGNIFICA EXACTAMENTE QUE ES FLEXIBLE?➤ Ruby tiene “formas acortadas” para escribir las cosas tecleando menos.
  • 11. ¿QUE SIGNIFICA EXACTAMENTE QUE ES FLEXIBLE?➤ Ruby tiene “formas acortadas” para escribir las cosas tecleando menos. ➤ Es frecuente tener la versión acortada para usar con trozos de código pequeños y la “normal” para cuando hay más código.
  • 12. ¿QUE SIGNIFICA EXACTAMENTE QUE ES FLEXIBLE?➤ Ruby tiene “formas acortadas” para escribir las cosas tecleando menos. ➤ Curiosamente, el beneficio no es que se escribe menos, sino que queda más bonito y se lee mejor. ➤ Conviene seguir una “guía de estilo” para asegurar la consistencia y que no sea un caos: https://github.com/bbatsov/ruby-style-guide ➤ Es frecuente tener la versión acortada para usar con trozos de código pequeños y la “normal” para cuando hay más código.
  • 13. ➤ Una especie de “cadena corta” especialmente eficiente porque es inmutable e internamente funciona como un entero ➤ Además de eficiente… es muy legible, y mola! :title SYMBOLS
  • 14. ➤ Una especie de “cadena corta” especialmente eficiente porque es inmutable e internamente funciona como un entero ➤ Además de eficiente… es muy legible, y mola! ➤ Hay una versión acortada para arrays de symbols attributes = %i(title author year description) SYMBOLS
  • 15. ➤ Una especie de “cadena corta” especialmente eficiente porque es inmutable e internamente funciona como un entero ➤ Además de eficiente… es muy legible, y mola! ➤ Hay una versión acortada para arrays de symbols ➤ Con frecuencia se usa para key de hashes (pares key-value), así que… también hay una versión acortada para este caso SYMBOLS :key => 'My value' key: 'My value'
  • 16. ➤ El bucle menos rubyish del mundo (pero funciona): for i in 0..(subscribers.length - 1) subscribers[i].notify end BUCLES
  • 17. ➤ Preferimos trabajar con instancias mejor que índices: for i in 0..(subscribers.length - 1) subscribers[i].notify end BUCLES for suscriber in subscribers subscriber.notify end
  • 18. ➤ Preferimos trabajar con instancias mejor que índices. ➤ Preferimos “each” en vez de “for” (crea un bloque: scope propio). Lo que pasa en el “each”, se queda en el “each”: BUCLES for suscriber in subscribers subscriber.notify end suscribers.each do |subscriber| subscriber.notify end
  • 19. ➤ Preferimos trabajar con instancias mejor que índices. ➤ Preferimos “each” en vez de “for” (crea un bloque: scope propio). Lo que pasa en el “each”, se queda en el “each”. ➤ Si se va a iterar una línea corta, se puede meter todo en una línea: BUCLES suscribers.each { |subscriber| subscriber.notify } suscribers.each do |subscriber| subscriber.notify end
  • 20. ➤ Preferimos trabajar con instancias mejor que índices. ➤ Preferimos “each” en vez de “for” (crea un bloque: scope propio). Lo que pasa en el “each”, se queda en el “each”. ➤ Si se va a iterar una línea corta, se puede meter todo en una línea. ➤ Si lo único que voy a hacer es llamar un método de la instancia, ni siquiera necesitaré el bucle: GREAT!!!! BUCLES suscribers.each(&:notify) suscribers.each { |subscriber| subscriber.notify }
  • 21. ➤ Hay una versión acortada para usar con trozos de código pequeños if subscriber.valid? subscriber.notify end CONDICIONALES subscriber.notify if subscriber.valid?
  • 22. ➤ Hay una versión acortada para usar con trozos de código pequeños ➤ Se puede usar en su lugar, sin abusar, el operador ternario timeout = if is_admin ADMIN_TIMEOUT else USER_TIMEOUT end CONDICIONALES timeout = is_admin ? ADMIN_TIMEOUT : USER_TIMEOUT
  • 23. ➤ Hay una versión acortada para usar con trozos de código pequeños ➤ Se puede usar en su lugar, sin abusar, el operador ternario ➤ Preferimos unless en vez de condiciones negadas (siempre que no haya else) CONDICIONALES if !subscriber.valid? subscriber.reject end unless subscriber.valid? subscriber.reject end
  • 24. ➤ Hay una versión acortada para usar con trozos de código pequeños ➤ Se puede usar en su lugar, sin abusar, el operador ternario ➤ Preferimos unless en vez de condiciones negadas (siempre que no haya else) ➤ Si no se trata de condiciones “normales”, sino de tratamiento de errores, es más expresivo usar “condiciones de salida” que partir el flujo en dos ramas con apariencia de similar jerarquía CONDICIONALES (Requisito: los métodos deben devolver nil si fallan)
  • 25. blog = Blog.find(url) if blog subscription = subscribe(me, blog) if subscription notify_subscription(subscription) else subscription_failed end else render_404 end CONDICIONALES blog.find(url) or return render_404 subscription = subscribe(me, blog) or return subscription_failed notify_subscription(subscription)
  • 26. ➤ Similares a otros lenguajes. ➤ Muy enriquecidos con métodos útiles “de fábrica”. Consultar documentación https://docs.ruby-lang.org/en/2.3.0/String.html ➤ Se usa interpolación "Nombre: #{user.name}" en vez de suma "Nombre:" + user.name para evitar problemas con nil. ➤ Conversión a entero inteligente: "46-valencia".to_i => 46 ➤ Al interpolar un objeto, se llamará a su método .to_s . Definiendo este método, tendremos un magnífico “default” de cómo se muestran las instancias de esta clase: "Nombre: #{user}" (podremos definirlo como nombre+apellidos, o nick, o lo que sea) STRINGS
  • 27. ➤ Similares a otros lenguajes. ➤ Muy enriquecidos con métodos útiles “de fábrica”. Consultar documentación https://docs.ruby-lang.org/en/2.3.0/Array.html & https://docs.ruby-lang.org/en/2.3.0/Enumerable.html ARRAYS
  • 28. ➤ Pares de key + value, en los que se busca usando la key para obtener el value asociado HASHES { nil => "No se encuentra", 'A' => "Opción A", 'X' => AMOUNT * RATE } (Explicación de informático a jefe de proyecto: correcto pero no muy útil) ¿Para qué sirven los hashes?
  • 29. ➤ Pares de key + value, en los que se busca usando la key para obtener el value asociado ➤ Útiles para implementar diccionarios de traducción HASHES ORDER_TO_BD = { 'cheap' => 'price', 'expensive' => 'price DESC', 'popular' => 'likes_count DESC' } order = ORDER_TO_BD[param_order] || 'created_at DESC' PROVINCIA_API = { 'La Coruña' => 'A Coruña', 'Gerona' => 'Girona' } provincia = PROVINCIA_API[provincia_api] || provincia_api
  • 30. ➤ Pares de key + value, en los que se busca usando la key para obtener el value asociado ➤ Útiles para implementar diccionarios de traducción ➤ O para convención sobre configuración HASHES DEFAULT_PAGINATE = { page: 1, per_page: 25, order: 'created_at' } def pagination(custom_pagination = {}) options = DEFAULT_PAGINATE.merge(custom_pagination) first = 1 + (options[:page] - 1) * options[:per_page] ... end
  • 31. ➤ Pares de key + value, en los que se busca usando la key para obtener el value asociado ➤ Útiles para implementar diccionarios de traducción ➤ O para convención sobre configuración ➤ Fácil de convertir desde/hacia JSON, YAML, atributos de un modelo, campos de la tabla en BD… HASHES
  • 32. ➤ Se pueden enviar llamadas a atributos o métodos de una instancia componiendo dinámicamente su método MÉTODOS DINÁMICOS user.phone_1 = '963112233' user.phone_4 = '666111000' user.phone_2 = '678111000' phones = (1..4).map do |i| user.send("phone_#{i}") end => ['963112233', '678111000', nil, '666111000']
  • 33. ➤ Se pueden enviar llamadas a atributos o métodos de una instancia componiendo dinámicamente su método ➤ Cuidado con la seguridad: si no son constantes, sino parámetros o valores de la BD, hay que usar whitelists MÉTODOS DINÁMICOS VALID_SECTIONS = %w(banca bolsa fondos) def filter_by_section(param_section) return unless param_section.in?(VALID_SECTIONS) Message.send("in_#{param_section}") end
  • 34. ➤ Se pueden enviar llamadas a atributos o métodos de una instancia componiendo dinámicamente su método ➤ Cuidado con la seguridad: si no son constantes, sino parámetros o valores de la BD, hay que usar whitelists ➤ Útil para manejar items con gran cantidad de campos que siguen patrones en su nombre o que se comportan igual MÉTODOS DINÁMICOS
  • 35. ➤ Se pueden enviar llamadas a atributos o métodos de una instancia componiendo dinámicamente su método ➤ Cuidado con la seguridad: si no son constantes, sino parámetros o valores de la BD, hay que usar whitelists ➤ Útil para manejar items con gran cantidad de campos que siguen patrones en su nombre o que se comportan igual ➤ En ocasiones es un smell: si muchos atributos se comportan de forma repetitiva, quizá se resuelva mejor usando atributos de tipo array, o una tabla con una relación 1-n MÉTODOS DINÁMICOS
  • 36. ➤ Los métodos en Ruby retornan el valor de la última operación que se hizo MÉTODOS Asignación: el valor asignado a la variable return unless admin?: nil (default) return “No way!” unless admin?: “No way!” Llamada a otro método: el valor de retorno del otro método
  • 37. ➤ Los métodos en Ruby retornan el valor de la última operación que se hizo ➤ Se pueden pasar parámetros opcionales (al final) poniendo un default MÉTODOS def pictures(format, order = 'created_at desc', limit = nil) "Bring #{format} files sort #{order} max #{limit || 'all'}" end item.pictures('jpg') item.pictures('jpg', 'likes_count desc') item.pictures('jpg', 'created_at desc', 20)
  • 38. ➤ Los métodos en Ruby retornan el valor de la última operación que se hizo ➤ Se pueden pasar parámetros opcionales (al final) poniendo un default ➤ Se puede reducir el acoplamiento (Connascence) con named parameters (aka keyword arguments) MÉTODOS def pictures(format:, order: 'created_at desc', limit: nil) "Bring #{format} files sort #{order} max #{limit || 'all'}" end item.pictures(format: 'jpg') item.pictures(format: 'jpg', order: 'likes_count desc') item.pictures(format: 'jpg', limit: 20)