38
RUBY Introducción

Introduccion a ruby

Embed Size (px)

Citation preview

Page 1: Introduccion a ruby

RUBYIntroducción

Page 2: Introduccion a ruby

FERNANDO

CALATAYUD

Twitter: @fj2cGithub: @fernan2

Hola, me llamo Fernando, y soy programador Ruby

Page 3: Introduccion a ruby

RUBY EN UNA FRASE➤ Ruby es un lenguaje hecho

para optimizar al programador

“Ruby is designed to make programmers happy.”Yukihiro “Matz” Matsumoto

Page 4: Introduccion a ruby

Y POR ESO…➤ Ruby es un lenguaje hecho

para optimizar al programador

➤ Ruby es un lenguaje interpretado

Page 5: Introduccion a ruby

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

Page 6: Introduccion a ruby

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?

Page 7: Introduccion a ruby

¿AHORRAR 0.08 SEGUNDOS ES IMPORTANTE EN TU NEGOCIO?

Page 8: Introduccion a ruby

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

Page 9: Introduccion a ruby

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!)

Page 10: Introduccion a ruby

¿QUE SIGNIFICA EXACTAMENTE QUE ES FLEXIBLE?➤ Ruby tiene “formas acortadas” para escribir las cosas

tecleando menos.

Page 11: Introduccion a ruby

¿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.

Page 12: Introduccion a ruby

¿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.

Page 13: Introduccion a ruby

➤ 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

Page 14: Introduccion a ruby

➤ 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

Page 15: Introduccion a ruby

➤ 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'

Page 16: Introduccion a ruby

➤ El bucle menos rubyish del mundo (pero funciona):

for i in 0..(subscribers.length - 1) subscribers[i].notifyend

BUCLES

Page 17: Introduccion a ruby

➤ Preferimos trabajar con instancias mejor que índices:

for i in 0..(subscribers.length - 1) subscribers[i].notifyend

BUCLES

for suscriber in subscribers subscriber.notifyend

Page 18: Introduccion a ruby

➤ 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.notifyend

suscribers.each do |subscriber| subscriber.notifyend

Page 19: Introduccion a ruby

➤ 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.notifyend

Page 20: Introduccion a ruby

➤ 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 }

Page 21: Introduccion a ruby

➤ Hay una versión acortada para usar con trozos de código pequeños

if subscriber.valid? subscriber.notifyend

CONDICIONALES

subscriber.notify if subscriber.valid?

Page 22: Introduccion a ruby

➤ 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

Page 23: Introduccion a ruby

➤ 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.rejectend

unless subscriber.valid? subscriber.rejectend

Page 24: Introduccion a ruby

➤ 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)

Page 25: Introduccion a ruby

blog = Blog.find(url)if blog subscription = subscribe(me, blog) if subscription notify_subscription(subscription) else subscription_failed endelse render_404end

CONDICIONALES

blog.find(url) or return render_404subscription = subscribe(me, blog) or return subscription_failednotify_subscription(subscription)

Page 26: Introduccion a ruby

➤ 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

Page 27: Introduccion a ruby

➤ 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

Page 28: Introduccion a ruby

➤ 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?

Page 29: Introduccion a ruby

➤ 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

Page 30: Introduccion a ruby

➤ 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

Page 31: Introduccion a ruby

➤ 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

Page 32: Introduccion a ruby

➤ 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']

Page 33: Introduccion a ruby

➤ 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

Page 34: Introduccion a ruby

➤ 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

Page 35: Introduccion a ruby

➤ 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

Page 36: Introduccion a ruby

➤ 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 variablereturn unless admin?: nil (default)return “No way!” unless admin?: “No way!”Llamada a otro método: el valor de retorno del otro método

Page 37: Introduccion a ruby

➤ 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)

Page 38: Introduccion a ruby

➤ 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)