SlideShare une entreprise Scribd logo
1  sur  38
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)

Contenu connexe

Tendances (20)

Php
PhpPhp
Php
 
Php1
Php1Php1
Php1
 
Php1
Php1Php1
Php1
 
14 PHP. Variables
14 PHP. Variables14 PHP. Variables
14 PHP. Variables
 
VBScript Tutorial
VBScript TutorialVBScript Tutorial
VBScript Tutorial
 
Vb script hx-c-wd
Vb script hx-c-wdVb script hx-c-wd
Vb script hx-c-wd
 
Perl4 io
Perl4 ioPerl4 io
Perl4 io
 
Resumen Java Script
Resumen Java ScriptResumen Java Script
Resumen Java Script
 
Php1
Php1Php1
Php1
 
Php1
Php1Php1
Php1
 
Php1
Php1Php1
Php1
 
Php1
Php1Php1
Php1
 
Php1
Php1Php1
Php1
 
Php curso03
Php   curso03Php   curso03
Php curso03
 
13 PHP. Un Ejemplo Con Constantes
13 PHP. Un Ejemplo Con Constantes13 PHP. Un Ejemplo Con Constantes
13 PHP. Un Ejemplo Con Constantes
 
Librerias de dev c++
Librerias de dev c++Librerias de dev c++
Librerias de dev c++
 
37 Php. Operadores Condicionales
37 Php. Operadores Condicionales37 Php. Operadores Condicionales
37 Php. Operadores Condicionales
 
Proyectos Web 3 Introduccion Php
Proyectos Web   3 Introduccion PhpProyectos Web   3 Introduccion Php
Proyectos Web 3 Introduccion Php
 
Php informacion
Php informacion Php informacion
Php informacion
 
Php basico
Php basicoPhp basico
Php basico
 

En vedette

En vedette (16)

Estrategias en multigrado
Estrategias en multigradoEstrategias en multigrado
Estrategias en multigrado
 
Group2 sec c
Group2 sec cGroup2 sec c
Group2 sec c
 
укрдузт кафедра електроенегетики
укрдузт кафедра електроенегетикиукрдузт кафедра електроенегетики
укрдузт кафедра електроенегетики
 
Свети Сава
Свети СаваСвети Сава
Свети Сава
 
Nuno pacc
Nuno paccNuno pacc
Nuno pacc
 
Phrases,clauses and Sentances
Phrases,clauses and SentancesPhrases,clauses and Sentances
Phrases,clauses and Sentances
 
La amistad
La amistadLa amistad
La amistad
 
Allen thaddaeus ppp
Allen thaddaeus pppAllen thaddaeus ppp
Allen thaddaeus ppp
 
開放源碼的ASP.NET Core & ADO.NET (for VS2015)
開放源碼的ASP.NET Core & ADO.NET (for VS2015)開放源碼的ASP.NET Core & ADO.NET (for VS2015)
開放源碼的ASP.NET Core & ADO.NET (for VS2015)
 
El compañerismo
El compañerismoEl compañerismo
El compañerismo
 
Los valores
Los valoresLos valores
Los valores
 
20170222 商社セミナー 北村
20170222 商社セミナー 北村20170222 商社セミナー 北村
20170222 商社セミナー 北村
 
Hyperlink (SMCL-Grade7Computer)
Hyperlink (SMCL-Grade7Computer)Hyperlink (SMCL-Grade7Computer)
Hyperlink (SMCL-Grade7Computer)
 
Conservacion del medio ambiente
Conservacion del medio ambienteConservacion del medio ambiente
Conservacion del medio ambiente
 
RiskOff - Business Consulting
RiskOff - Business Consulting RiskOff - Business Consulting
RiskOff - Business Consulting
 
Escrito ampliacion de plazo aprolab ii
Escrito ampliacion de plazo  aprolab iiEscrito ampliacion de plazo  aprolab ii
Escrito ampliacion de plazo aprolab ii
 

Similaire à Introduccion a ruby (20)

The linux shell. Shell Scripting desde 0
The linux shell. Shell Scripting desde 0The linux shell. Shell Scripting desde 0
The linux shell. Shell Scripting desde 0
 
Anonimo el libro hacker
Anonimo   el libro hackerAnonimo   el libro hacker
Anonimo el libro hacker
 
Perl1 escalares
Perl1 escalaresPerl1 escalares
Perl1 escalares
 
Gestión Remota de Equipos con Python
Gestión Remota de Equipos con PythonGestión Remota de Equipos con Python
Gestión Remota de Equipos con Python
 
Curso c++
Curso c++Curso c++
Curso c++
 
Java Basico Platzi
Java Basico PlatziJava Basico Platzi
Java Basico Platzi
 
Introduccion a php
Introduccion a phpIntroduccion a php
Introduccion a php
 
Curso php-my sql-clase-4
Curso php-my sql-clase-4Curso php-my sql-clase-4
Curso php-my sql-clase-4
 
Anon el libro hacker
Anon   el libro hackerAnon   el libro hacker
Anon el libro hacker
 
Script presentacion
Script presentacionScript presentacion
Script presentacion
 
Curso de C++ (2014)
Curso de C++ (2014)Curso de C++ (2014)
Curso de C++ (2014)
 
Lenguaje
LenguajeLenguaje
Lenguaje
 
Shell script
Shell scriptShell script
Shell script
 
Php1
Php1Php1
Php1
 
PHP mode on
PHP mode onPHP mode on
PHP mode on
 
Creacion de scripts en linux
Creacion de scripts en linuxCreacion de scripts en linux
Creacion de scripts en linux
 
15 iniciacion gnu_linux
15 iniciacion gnu_linux15 iniciacion gnu_linux
15 iniciacion gnu_linux
 
Aprendizaje de Lenguaje de Programación Python
Aprendizaje de Lenguaje de Programación PythonAprendizaje de Lenguaje de Programación Python
Aprendizaje de Lenguaje de Programación Python
 
Curso Bash 3
Curso Bash 3Curso Bash 3
Curso Bash 3
 
Manual de hacking basico por taskkill#3
Manual de hacking basico por taskkill#3Manual de hacking basico por taskkill#3
Manual de hacking basico por taskkill#3
 

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)