Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Introduccion a ruby

120 views

Published on

“Ruby is designed to make programmers happy”, en palabras de su creador, Yukihiro “Matz” Matsumoto.

Como programadores, el tema de ser felices trabajando es indudable que tiene su atractivo. Pero… ¿es eso cierto? ¿Qué tiene Ruby de particular? ¿Por qué Ruby “mola”?

Published in: Software
  • Be the first to comment

  • Be the first to like this

Introduccion a ruby

  1. 1. RUBYIntroducción
  2. 2. FERNAN DO CALATA YUDTwitter: @fj2c Github: @fernan2 Hola, me llamo Fernando, y soy programador Ruby
  3. 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. 4. Y POR ESO… ➤ Ruby es un lenguaje hecho para optimizar al programador ➤ Ruby es un lenguaje interpretado
  5. 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. 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. 7. ¿AHORRAR 0.08 SEGUNDOS ES IMPORTANTE EN TU NEGOCIO?
  8. 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. 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. 10. ¿QUE SIGNIFICA EXACTAMENTE QUE ES FLEXIBLE?➤ Ruby tiene “formas acortadas” para escribir las cosas tecleando menos.
  11. 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. 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. 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. 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. 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. 16. ➤ El bucle menos rubyish del mundo (pero funciona): for i in 0..(subscribers.length - 1) subscribers[i].notify end BUCLES
  17. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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)

×