Mi guía de Ruby – Poniendo algo de sentido y sentimiento


Beginning Ruby From Novice to ProfessionalEs primordial, dar sentido a las cosas que vamos haciendo y ponerle sentimiento en cada línea de código que vamos construyendo. Ruby es uno de esos lenguajes que uno debe detenerse a contemplar, para no dejar pasar detalles muy interesantes.

Voy a comenzar hablando de alguno de esos detalles de Ruby a tener en consideración, cómo podemos mejorar algunas de las sentencias que alguna vez ponemos y llevarlas a la práctica para mejorar nuestro código a la vista de los demás.

Vemos algunos de estos detalles de los que estoy comentando y como digo, merecen la pena entrar en los detalles y conocerlos, despés está en nuestra mano el hacerlo para mejorar.

Si lo vemos así sin más UNLESS, no vemos el detalle para lo que se ha puesto en nuestras manos. Vamos a imaginarnos que tenemos las siguientes líneas de código en las que vamos a necesitar preguntar si tenemos ‘reviews’  para mostrar. En ese caso lo podemos hacer con un if ! reviews.empty? y “es correcto” pero si lo piensas, no es buen código y además en este caso, no es muy claro, intenta leerlo……puede llevarnos a confusiones de interpretación. Aquí lo que necesitamos es unless, es mucho mejor utilizar y queda mucho más claro utilizando unless reviews.empty?, veamos ambos casos:

En el caso de uso del if no es el mejor caso, se puede, pero no se debe si tenemos una mejor forma y mucho más clara de hacer las cosas, además hay que aplicarlas con criterio, intentar que quede claro sin necesidad de explicar nada en código. Bien, ahora fíjate en este trozo de código en el que dice si tenemos reviews que los muestre:

if ! reviews.empty?
      puts “Reviews:”
      puts reviews
end

¿Podríamos mejorar la claridad del código anterior? Pues yo creo que si y lo conseguimos mediante la expresión unless que ya hemos comentado anteriormente. Fíjate ahora que el mismo código anterior, lo transformamos en algo más natural de leer y entender. Veamos cómo y qué es lo que hace nuestro código:

unless reviews.empty?

           puts “Reviews:”
           puts reviews
end

¿No crees que es mucho más natural cuando decimos, “si tenemos comentarios (si no están vacios), muéstrame los comentarios”? Piensa que unless es lo contrario del if, el if ejecuta cuando cumple una condición y el unless mientras no se cumpla. Aunque también tenemos la posibilidad de hacer combinaciones de condiciones y aplicar un else a unless, no es lo más adecuado , para eso ya tenemos el if, por ejemplo:

unless !person.present? && !company.present?

            puts “do you even know what you’re doing?”

else

            puts “and now we’re really confused”

end

Entonces, ¿qué podemos extraer de todo esto? ¿qué reglas podríamos aplicarnos?:

  1. Evitar más de una condición lógica unless !person.present? && !company.present?
  2. Evitar la negación unless !person.present?, unless ya es negación
  3. Evitar utilizar else en unless

Cuidado cuando utilizamos nil, por ejemplo

if attachment.file_path != nil
         attachment.post
end

En este caso será mejor hacer lo siguiente, ya que nil es tratado como false, por tanto mejor:

if attachment.file_path 
         attachment.post
end

Si nil es tratado como false, ahora debemos tener sumo cuidado en aquellos aspectos cuando tengamos “”, [] y 0 que son tratados como true, por ejemplo:

unless name.length
     puts “User name required”
end

Si aplicamos esta lógica, lo que nos ocurre es, que nunca nos va a entrar si tenemos algunos de los casos de “”, 0 o []. Cuidado cuando apliquemos criterios, hay que fijarse en estos detalles.

Vemos algunos detalles más interesantes:

if password.length < 8
      puts “Password too short”
end

unless username
    puts “No user name set”
end

Podríamos mejorar nuestro código de la siguiente manera:

         puts “Password too short” if password.length < 8
         puts “No user name set” unless username

Veamos ahora algunas expresiones interesantes:

reviews = timeline.reviews
reviews = [] unless reviews

Para las dos sentencias anteriores lo que podemos mejorar es dejarlo en una única sentencia, es decir, si tenemos nil en los comentarios, entonces por defecto lo dejamos vacío el array

reviews = timeline.reviews || []

Para la asignación condicional, verifica si tenemos algún valor o no y le asignamos uno:

i_was_set = 1
i_was_set ||= 2
puts i_was_set En este caso puedes comprobar que el resultado es 1 ya que inicialmente tenemos un valor asignado de 1.

Asigna el que le pongamos después del ||, si no tenemos ningún valor

i_was_not_set ||= 2
puts i_was_not_set En este caso el valor de asignación será 2 y el resultado es 2, ya que inicialmente no disponemos de valor alguno para la variable i_was_not_set

Para estos otros casos ¿cómo podríamos mejorarlas?:

options[:country] = ‘us’ if options[:country].nil?
options[:privacy] = true if options[:privacy].nil?

pues para mejorarlas, tendríamos que utilizar la asignación condicional:

options[:country] ||= ‘us’
options[:privacy] ||= true

Para la siguiente sentencia, ¿cómo podríamos mejorarla?:

if list_name
        options[:path] = “/#{user_name}/#{list_name}”
else
       options[:path] = “/#{user_name}”
end

podríamos utilizar la asignación de un valor con la condición if:

options[:path] = if list_name
          “/#{user_name}/#{list_name}”
else
          “#{user_name}”
end

Para los valores que se devuelven en un método mediante return:

def list_url(user_name, list_name)
            if list_name
                    url = “https://twitter.com/#{user_name}/#{list_name}”
            else
                     url = “https://twitter.com/#{user_name}”
            end
            url
end

podríamos mejorar este caso haciendo que el método devuelva, en función al cumplimiento de la condición aplicada,  la última sentencia ejecutada del método. Finalmente, devolverá un valor:

def list_url(user_name, list_name)
          if list_name
                   “https://twitter.com/#{user_name}/#{list_name}”
          else
                   “https://twitter.com/#{user_name}”
          end
end

Para los casos de case:

client_url = case client_name
      when “web”
               “http://twitter.com&#8221;
       when “Facebook”
                “http://facebook.com/twitter&#8221;
        else
                 nil
end

Para el caso de range:

popularity = case review.review_count
            when 0..9
                   nil
           when 10..20
                  “trending”
            else
                  “love”
end

Para las expresiones regulares:

review_type = case review.status
           when /\A@\w+/
                           :mention
            when /\Ad\s+\w+/
                           :direct_message
            else
                   :public
end

Y para terminar la expresión when/then:

review_type = case review.status
         when /\A@\w+/     then :mention
         when /\Ad\s+\w+/ then :direct_message
         else :public
end

Bueno, por el momento eso es todo. Seguiremos viendo los aspectos de Ruby en los siguientes post….

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s