Ruby idiomático: escribir código hermoso

Ruby es un hermoso lenguaje de programación.

Según la página web oficial de Ruby, Ruby es un:

Lenguaje de programación dinámico de código abierto con un enfoque en la simplicidad y la productividad. Tiene una sintaxis elegante que es natural de leer y fácil de escribir ".

Ruby fue creado por Yukihiro Matsumoto, un ingeniero de software japonés. Desde 2011, ha sido el diseñador jefe e ingeniero de software de Ruby en Heroku.

Matsumoto ha dicho a menudo que intenta hacer que Ruby sea natural, no simple , de una manera que refleje la vida.

"Ruby es simple en apariencia, pero es muy complejo por dentro, al igual que nuestro cuerpo humano" - Yukihiro Matsumoto

Siento lo mismo por Ruby. Es un lenguaje de programación complejo pero muy natural, con una sintaxis hermosa e intuitiva.

Con un código más intuitivo y rápido, podemos crear un mejor software. En esta publicación, le mostraré cómo expreso mis pensamientos (también conocido como código) con Ruby, mediante el uso de fragmentos de código.

Expresando mis pensamientos con métodos de matriz

Mapa

Utilice el método del mapa para simplificar su código y obtener lo que desea.

El mapa de métodos devuelve una nueva matriz con los resultados de ejecutar un bloque una vez por cada elemento en enum.

Vamos a intentarlo:

an_array.map  element * element 

Simple como eso.

Pero cuando comienza a codificar con Ruby, es fácil usar siempre cada iterador.

La cada iterador como se muestra a continuación

user_ids = [] users.each user

Se puede simplificar con el mapa en una sola hermosa línea de código:

user_ids = users.map  user.id 

O incluso mejor (y más rápido):

user_ids = users.map(&:id)

Seleccione

Y cuando está acostumbrado a codificar con map , a veces su código puede ser así:

even_numbers = [1, 2, 3, 4, 5].map element # [ni, 2, nil, 4, nil] even_numbers = even_numbers.compact # [2, 4]

El uso del mapa para seleccionar solo los números pares devolverá elobjeto nulo también. Utilice el método compacto para eliminar todos los objetos nulos .

Y ta-da, has seleccionado todos los números pares.

Misión cumplida.

¡Vamos, podemos hacerlo mejor que esto! ¿Escuchaste sobre el método select del módulo enumerable?

[1, 2, 3, 4, 5].select  

Solo una línea. Código simple. Fácil de comprender.

Prima

[1, 2, 3, 4, 5].select(&:even?)

Muestra

Imagine que necesita obtener un elemento aleatorio de una matriz. Acabas de empezar a aprender Ruby, así que tu primer pensamiento será "Usemos el método aleatorio ", y eso es lo que sucede:

[1, 2, 3][rand(3)]

Bueno, podemos entender el código, pero no estoy seguro de que sea lo suficientemente bueno. ¿Y si usamos el método aleatorio ?

[1, 2, 3].shuffle.first

Hmm. De hecho, prefiero usar shuffle sobre rand . Pero cuando descubrí el método de muestra , tenía mucho más sentido:

[1, 2, 3].sample

Realmente, realmente simple.

Bastante natural e intuitivo. Pedimos una muestra de una matriz y el método la devuelve. Ahora estoy feliz.

¿Que pasa contigo?

Expresando mis pensamientos con la sintaxis de Ruby

Como mencioné antes, me encanta la forma en que Ruby me permite codificar. Es realmente natural para mí. Mostraré partes de la hermosa sintaxis de Ruby.

Retorno implícito

Cualquier declaración en Ruby devuelve el valor de la última expresión evaluada. Un ejemplo sencillo es el método getter . Llamamos a un método y esperamos algún valor a cambio.

Veamos:

def get_user_ids(users) return users.map(&:id) end

Pero como sabemos, Ruby siempre devuelve la última expresión evaluada. ¿Por qué utilizar la declaración de devolución ?

Después de usar Ruby durante 3 años, me siento genial usando casi todos los métodos sin la declaración de devolución .

def get_user_ids(users) users.map(&:id) end

Varias asignaciones

Ruby me permite asignar múltiples variables al mismo tiempo. Cuando empiece, puede estar codificando así:

def values [1, 2, 3] end one = values[0] two = values[1] three = values[2]

Pero, ¿por qué no asignar varias variables al mismo tiempo?

def values [1, 2, 3] end one, two, three = values

Bastante impresionante.

Métodos que hacen preguntas (también llamados predicados)

One feature that caught my attention when I was learning Ruby was the question mark (?) method, also called the predicates methods. It was weird to see at first, but now it makes so much sense. You can write code like this:

movie.awesome # => true

Ok… nothing wrong with that. But let’s use the question mark:

movie.awesome? # => true

This code is much more expressive, and I expect the method’s answer to return either a true or false value.

A method that I commonly use is any? It’s like asking an array if it has anything inside it.

[].any? # => false [1, 2, 3].any? # => true

Interpolation

For me string interpolation is more intuitive than string concatenation. Period. Let’s see it in action.

An example of a string concatenation:

programming_language = "Ruby" programming_language + " is a beautiful programming_language" # => "Ruby is a beautiful programming_language"

An example of a string interpolation:

programming_language = "Ruby" "#{programming_language} is a beautiful programming_language" # => "Ruby is a beautiful programming_language"

I prefer string interpolation.

What do you think?

The if statement

I like to use the if statement:

def hey_ho? true end puts "let’s go" if hey_ho?

Pretty nice to code like that.

Feels really natural.

The try method (with Rails mode on)

The try method invokes the method identified by the symbol, passing it any arguments and/or the block specified. This is similar to Ruby’s Object#send. Unlike that method, nil will be returned if the receiving object is a nil object or NilClass.

Using if and unless condition statement:

user.id unless user.nil?

Using the try method:

user.try(:id)

Since Ruby 2.3, we can use Ruby’s safe navigation operator (&.) instead of Rails try method.

user&.id

Double pipe equals (||=) / memoization

This feature is so C-O-O-L. It’s like caching a value in a variable.

some_variable ||= 10 puts some_variable # => 10 some_variable ||= 99 puts some_variable # => 10

You don’t need to use the if statement ever. Just use double pipe equals (||=) and it’s done.

Simple and easy.

Class static method

One way I like to write Ruby classes is to define a static method (class method).

GetSearchResult.call(params)

Simple. Beautiful. Intuitive.

What happens in the background?

class GetSearchResult def self.call(params) new(params).call end def initialize(params) @params = params end def call # ... your code here ... end end

The self.call method initializes an instance, and this object calls the call method. Interactor design pattern uses it.

Getters and setters

For the same GetSearchResult class, if we want to use the params, we can use the @params

class GetSearchResult def self.call(params) new(params).call end def initialize(params) @params = params end def call # ... your code here ... @params # do something with @params end end

We define a setter and getter:

class GetSearchResult def self.call(params) new(params).call end def initialize(params) @params = params end def call # ... your code here ... params # do something with params method here end private def params @params end def params=(parameters) @params = parameters end end

Or we can define attr_reader, attr_writer, or attr_accessor

class GetSearchResult attr_reader :param def self.call(params) new(params).call end def initialize(params) @params = params end def call # ... your code here ... params # do something with params method here end end

Nice.

We don’t need to define the getter and setter methods. The code just became simpler, just what we want.

Tap

Imagine you want to define a create_user method. This method will instantiate, set the parameters, and save and return the user.

Let’s do it.

def create_user(params) user = User.new user.id = params[:id] user.name = params[:name] user.email = params[:email] # ... user.save user end

Simple. Nothing wrong here.

So now let’s implement it with the tap method

def create_user(params) User.new.tap do |user| user.id = params[:id] user.name = params[:name] user.email = params[:email] # ... user.save end end

You just need to worry about the user parameters, and the tap method will return the user object for you.

That’s it

We learned I write idiomatic Ruby by coding with

  • array methods
  • syntax

We also learned how Ruby is beautiful and intuitive, and runs even faster.

And that’s it, guys! I will be updating and including more details to my blog. The idea is to share great content, and the community helps to improve this post! ☺

I hope you guys appreciate the content and learned how to program beautiful code (and better software).

If you want a complete Ruby course, learn real-world coding skills and build projects, try One Month Ruby Bootcamp. See you there ☺

This post appeared first here on my Renaissance Developer publication.

Have fun, keep learning, and always keep coding!

My Twitter & Github. ☺