├── .gitattributes
├── CONTRIBUTING.md
├── README-esLA.md
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.md whitespace=trailing-space,tab-in-indent
2 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | * [Fork](https://help.github.com/articles/fork-a-repo) the project on GitHub.
2 | * Make your feature addition or bug fix in a feature branch. (Include a description of your changes)
3 | * Push your feature branch to GitHub.
4 | * Send a [Pull Request](https://help.github.com/articles/using-pull-requests).
--------------------------------------------------------------------------------
/README-esLA.md:
--------------------------------------------------------------------------------
1 | # Preludio
2 |
3 | > Los modelos a seguir son importantes.
4 | > -- Officer Alex J. Murphy / RoboCop
5 |
6 | Una cosa siempre me ha molestado como desarrollador Ruby - los
7 | desarrolladores Python tienen una gran referencia de estilo de
8 | programación ([PEP-8](http://www.python.org/dev/peps/pep-0008/)) y
9 | nosotros nunca tuvimos una guía oficial, documentando estilos de
10 | codificación y mejores prácticas de Ruby. Y yo creo que los estilos
11 | importan. También creo que una gran comunidad de hackers, tales como
12 | tiene Ruby, debería ser muy capaz de producir este codiciado documento.
13 |
14 | Esta guía comenzó su vida como nuestra guía interna de codificación de
15 | Ruby para nuestra compañía (escrito por su servidor). En algún momento
16 | decidí que el trabajo que estaba haciendo podría ser interesante para los
17 | miembros de la comunidad Ruby en general y que el mundo no tenía la
18 | necesidad de otra guía interna de una empresa. Pero sin duda el mundo
19 | podría beneficiarse de un conjunto de prácticas, lenguajes y estilos para
20 | la programación de Ruby dirigido por la comunidad y sancionado por la
21 | comunidad.
22 |
23 | Desde el inicio de la guía he recibido un montón de comentarios de los
24 | miembros de la excepcional comunidad Ruby alrededor de todo el mundo.
25 | ¡Gracias por todas las sugerencias y el apoyo! Juntos podemos hacer un
26 | recurso beneficioso para todos y cada uno de los desarrolladores Ruby.
27 |
28 | Por cierto, si estás interesado en Rails es posible que desees ver la [Guía
29 | de Estilos de Ruby on Rails 3](https://github.com/bbatsov/rails-style-guide)
30 | complementaria.
31 |
32 | # La Guía de Estilos de Ruby
33 |
34 | Esta guía de estilo de Ruby recomienda las mejores prácticas a fin de que
35 | los programadores Ruby del mundo real pueden escribir código que pueda ser
36 | mantenido por otros programadores Ruby del mundo real. Una guía de estilo que
37 | refleje los usos del mundo real es utilizada, y una guía de estilo que se aferra
38 | a un ideal que ha sido rechazado por las personas supone que lo mejor es no
39 | utilizarla para nada – no importa lo bueno que sea.
40 |
41 | La guía está dividida en varias secciones de de reglas relacionadas. Intenté
42 | agregar la racionalización de las normas (si está omitido asumí que es bastante
43 | obvio).
44 |
45 | No inventé todas las reglas desde la nada misma - ellas se basan sobre todo en
46 | mi extensa carrera como ingeniero de software profesional, junto con los
47 | comentarios y sugerencias de los miembros de la comunidad Ruby y diversos recursos
48 | conocidos de programación de Ruby, como
49 | ["Programming Ruby 1.9"](http://pragprog.com/book/ruby4/programming-ruby-1-9-2-0)
50 | y ["The Ruby Programming Language"](http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177).
51 |
52 | La guía todavía es un trabajo en progreso - a algunas reglas le faltan ejemplos, y
53 | algunas reglas no tienen ejemplos que ilustren con la suficiente claridad. En su
54 | debido tiempo se abordarán estos temas - sólo ténganlos en cuenta por ahora.
55 |
56 | Podés generar un PDF o una versión HTML de esta guía usando
57 | [Transmuter](https://github.com/TechnoGate/transmuter).
58 |
59 | [RuboCop](https://github.com/bbatsov/rubocop) es un validador de código, basado en
60 | esta guía de estilo.
61 |
62 | Traducciones de esta guía están disponibles en los siguientes idiomas:
63 |
64 | * [Árabe egipto](https://github.com/HassanTC/ruby-style-guide/blob/master/README-EgAr.md)
65 | * [Chino Simplificado](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhCN.md)
66 | * [Chino Tradicional](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhTW.md)
67 | * [Coreano](https://github.com/dalzony/ruby-style-guide/blob/master/README-koKR.md)
68 | * [Francés](https://github.com/porecreat/ruby-style-guide/blob/master/README-frFR.md)
69 | * [Inglés](https://github.com/bbatsov/ruby-style-guide/blob/master/README.md) (versión original)
70 | * [Japonés](https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md)
71 | * [Portugués (pt-BR)](https://github.com/rubensmabueno/ruby-style-guide/blob/master/README-PT-BR.md)
72 | * [Ruso](https://github.com/arbox/ruby-style-guide/blob/master/README-ruRU.md)
73 | * [Vietnamita](https://github.com/CQBinh/ruby-style-guide/blob/master/README-viVN.md)
74 |
75 |
76 | ## Tabla de Contenidos
77 |
78 | * [Estructura del Código Fuente](#estructura-del-c%C3%B3digo-fuente)
79 | * [Sintaxis](#sintaxis)
80 | * [Nombres](#nombres)
81 | * [Comentarios](#comentarios)
82 | * [Apuntes de Comentarios](#apuntes-de-comentarios)
83 | + [Comentarios mágicos](#comentarios-mágicos-magic-comments)
84 | * [Clases](#clases-y-m%C3%B3dulos)
85 | * [Excepciones](#excepciones)
86 | * [Colecciones](#colecciones)
87 | * [Números](#números)
88 | * [Strings](#strings)
89 | * [Date & Time](#date--time)
90 | * [Expresiones Regulares](#expresiones-regulares)
91 | * [Porcentajes Literales](#porcentajes-literales)
92 | * [Metaprogramación](#metaprogramaci%C3%B3n)
93 | * [Varios](#varios)
94 | * [Herramientas](#herramientas)
95 |
96 | ## Estructura del Código Fuente
97 |
98 | > Casi todo el mundo está convencido de que todos los estilos
99 | > excepto los propios son feos e ilegibles. Deja de lado el
100 | > "excepto los propios", y probablemente tengan razón...
101 | > -- Jerry Coffin (sobre indentación)
102 |
103 | * Usa `UTF-8` como la codificación del archivo fuente.
104 | * Usa dos **espacios** por cada nivel de identación. No tabs.
105 |
106 | ```ruby
107 | # mal - cuatro espacios
108 | def some_method
109 | do_something
110 | end
111 |
112 | # bien
113 | def some_method
114 | do_something
115 | end
116 | ```
117 |
118 | * Usa finales de línea estilo Unix. (*por defecto los usuarios BSD/Solaris/Linux/OSX
119 | están protegidos, los usuarios de Windows tienen que tener mucho cuidado.)
120 | * Si estás usando Git es posible que quieras agregar la siguiente
121 | configuración para proteger tu proyecto de los finales de línea
122 | de Windows para que no aparezcan solos:
123 |
124 | ```bash
125 | $ git config --global core.autocrlf true
126 | ```
127 |
128 | * No uses `;` para separar declaraciones y expresiones.
129 | Por convención - usá una expresión por línea.
130 |
131 | ```ruby
132 | # mal
133 | puts 'foobar'; # superfluous semicolon
134 |
135 | puts 'foo'; puts 'bar' # dos expresiones en la misma línea
136 |
137 | # bien
138 | puts 'foobar'
139 |
140 | puts 'foo'
141 | puts 'bar'
142 |
143 | puts 'foo', 'bar' # esto aplica a puts en particular
144 | ```
145 |
146 | * Prefiere un formato de única línea por cada definición de clase
147 | sin cuerpo.
148 |
149 | ```ruby
150 | # mal
151 | class FooError < StandardError
152 | end
153 |
154 | # casi bien
155 | class FooError < StandardError; end
156 |
157 | # bien
158 | FooError = Class.new(StandardError)
159 | ```
160 |
161 | * Evita métodos de una sola línea. Aunque son algo popular, hay
162 | algunas particularidades sobre su sintaxis para definirlos que
163 | hacen que su uso indeseable. En cualquier caso - no debe
164 | existir más de una expresión en un método de una sola línea.
165 |
166 | ```ruby
167 | # mal
168 | def too_much; something; something_else; end
169 |
170 | # casi bien - el primer ; es necesario
171 | def no_braces_method; body end
172 |
173 | # casi bien - el segundo ; es opcional
174 | def no_braces_method; body; end
175 |
176 | # casi bien - la sintaxis es válida, pero al no usar ; hace que sea un poco difícil de leer
177 | def some_method() body end
178 |
179 | # bien
180 | def some_method
181 | body
182 | end
183 | ```
184 |
185 | Una excepción a la regla son los métodos vacíos.
186 |
187 | ```ruby
188 | # bien
189 | def no_op; end
190 | ```
191 |
192 | * Usa espacios entre operadores, después de las comas, dos puntos y puntos
193 | y comas, luego de `{` y antes de `}`. Los espacios en blanco pueden (en
194 | su mayoría) irrelevantes para el intérprete de Ruby, pero su uso adecuado
195 | es la clave para escribir código fácil de leer.
196 |
197 | ```ruby
198 | sum = 1 + 2
199 | a, b = 1, 2
200 | 1 > 2 ? true : false; puts 'Hi'
201 | [1, 2, 3].each { |e| puts e }
202 | ```
203 |
204 | Hay algunas excepciones, con respecto a los operadores, uno es el operador exponente:
205 |
206 | ```ruby
207 | # mal
208 | e = M * c ** 2
209 |
210 | # bien
211 | e = M * c**2
212 | ```
213 |
214 |
215 | Otra excepción es el operador slash en los numeros racionales:
216 |
217 | ```ruby
218 | # mal
219 | o_scale = 1 / 48r
220 |
221 | # bien
222 | o_scale = 1/48r
223 | ```
224 |
225 | Otra excepción es el operador de navegación segura :
226 | ```ruby
227 | # mal
228 | foo &. bar
229 | foo &.bar
230 | foo&. bar
231 |
232 | # bien
233 | foo&.bar
234 | ```
235 |
236 | *
237 | No uses espacios después de `(`, `[` o antes de `]`, `)`.
238 | Usa espacios despues de `{` and antes de `}`.
239 |
240 | ```ruby
241 | # mal
242 | some( arg ).other
243 | [ 1, 2, 3 ].each{|e| puts e}
244 |
245 | # bien
246 | some(arg).other
247 | [1, 2, 3].each { |e| puts e }
248 | ```
249 |
250 | `{` y `}` merecen una aclaración especial, ya que se utilizan
251 | para bloques y hash literales, así como las expresiones
252 | embebidas en strings. Dos estilos se consideran aceptables
253 | para los hash literales.
254 |
255 | ```ruby
256 | # bien - espacio luego de { y antes de }
257 | { one: 1, two: 2 }
258 |
259 | # bien - sin espacio luego de { y antes de }
260 | {one: 1, two: 2}
261 | ```
262 |
263 | La primera variante es un poco más fácil de leer (y posiblemente
264 | más popular en la comunidad de Ruby en general). La segunda
265 | variante tiene la ventaja de tener diferenciación visual entre
266 | los bloques y los hash literales. Cualquiera que elijas -
267 | usalo de forma consistente.
268 |
269 | En cuanto a las expresiones embebidas, también hay dos formas
270 | aceptables:
271 |
272 | ```ruby
273 | # bien - sin espacios
274 | "string#{expr}"
275 |
276 | # ok - podría decirse que es más legible
277 | "string#{ expr }"
278 | ```
279 |
280 | * Sin espacios luego de `!`.
281 |
282 | ```ruby
283 | # mal
284 | ! something
285 |
286 | # bien
287 | !something
288 | ```
289 |
290 | * Indenta `when` al mismo nivel que `case`.
291 | Sé que muchos no estarán de acuerdo con esto, pero es el estilo establecido tanto en
292 | "The Ruby Programming Language" y "Programming Ruby".
293 |
294 | ```ruby
295 | # mal
296 | case
297 | when song.name == 'Misty'
298 | puts 'Not again!'
299 | when song.duration > 120
300 | puts 'Too long!'
301 | when Time.now.hour > 21
302 | puts "It's too late"
303 | else
304 | song.play
305 | end
306 |
307 | # bien
308 | case
309 | when song.name == 'Misty'
310 | puts 'Not again!'
311 | when song.duration > 120
312 | puts 'Too long!'
313 | when Time.now.hour > 21
314 | puts "It's too late"
315 | else
316 | song.play
317 | end
318 | ```
319 |
320 | * Al asignar el resultado de una expresión condicional a una variable, conservá la alineación de su ramificación.
321 |
322 | ```ruby
323 | # mal - bastante complejo
324 | kind = case year
325 | when 1850..1889 then 'Blues'
326 | when 1890..1909 then 'Ragtime'
327 | when 1910..1929 then 'New Orleans Jazz'
328 | when 1930..1939 then 'Swing'
329 | when 1940..1950 then 'Bebop'
330 | else 'Jazz'
331 | end
332 |
333 | result = if some_cond
334 | calc_something
335 | else
336 | calc_something_else
337 | end
338 |
339 | # bien - es aparente lo qué está pasando
340 | kind = case year
341 | when 1850..1889 then 'Blues'
342 | when 1890..1909 then 'Ragtime'
343 | when 1910..1929 then 'New Orleans Jazz'
344 | when 1930..1939 then 'Swing'
345 | when 1940..1950 then 'Bebop'
346 | else 'Jazz'
347 | end
348 |
349 | result = if some_cond
350 | calc_something
351 | else
352 | calc_something_else
353 | end
354 |
355 | # bien (y con un espacio más eficiente)
356 | kind =
357 | case year
358 | when 1850..1889 then 'Blues'
359 | when 1890..1909 then 'Ragtime'
360 | when 1910..1929 then 'New Orleans Jazz'
361 | when 1930..1939 then 'Swing'
362 | when 1940..1950 then 'Bebop'
363 | else 'Jazz'
364 | end
365 |
366 | result =
367 | if some_cond
368 | calc_something
369 | else
370 | calc_something_else
371 | end
372 | ```
373 |
374 | * Usa líneas vacías entre definiciones de métodos y también para romper un método en
375 | párrafos lógicos internos.
376 |
377 | ```ruby
378 | def some_method
379 | data = initialize(options)
380 |
381 | data.manipulate!
382 |
383 | data.result
384 | end
385 |
386 | def some_method
387 | result
388 | end
389 | ```
390 |
391 | *
392 | No uses mas de una linea vacia seguida.
393 |
394 | ```ruby
395 | # mal - hay dos lineas vacias seguidas.
396 | some_method
397 |
398 |
399 | some_method
400 |
401 | # bien
402 | some_method
403 |
404 | some_method
405 | ```
406 | *
407 | Usa lineas vacias alrededor de los modificadores de accesibilidad.
408 |
409 | ```ruby
410 | # mal
411 | class Foo
412 | attr_reader :foo
413 | def foo
414 | # do something...
415 | end
416 | end
417 |
418 | # bien
419 | class Foo
420 | attr_reader :foo
421 |
422 | def foo
423 | # do something...
424 | end
425 | end
426 | ```
427 |
428 | *
429 | No uses lineas vacias alrededor de métodos, clases, módulos y bloques.
430 |
431 | ```ruby
432 | # mal
433 | class Foo
434 |
435 | def foo
436 |
437 | begin
438 |
439 | do_something do
440 |
441 | something
442 |
443 | end
444 |
445 | rescue
446 |
447 | something
448 |
449 | end
450 |
451 | end
452 |
453 | end
454 |
455 | # bien
456 | class Foo
457 | def foo
458 | begin
459 | do_something do
460 | something
461 | end
462 | rescue
463 | something
464 | end
465 | end
466 | end
467 | ```
468 |
469 | *
470 | Evita las comas en el último parametro al llamar un método.
471 | Especialmente si los parametros no estan separados por lineas
472 |
473 | ```ruby
474 | # mal - Es facil mover, eliminar o agregar parametros, pero aún asi no es recomendado
475 | some_method(
476 | size,
477 | count,
478 | color,
479 | )
480 |
481 | # mal
482 | some_method(size, count, color, )
483 |
484 | # bien
485 | some_method(size, count, color)
486 | ```
487 |
488 | * Usa espacios alrededor del operador `=` cuando asignes valores predeterminados a los
489 | parámetros del método:
490 |
491 | ```ruby
492 | # mal
493 | def some_method(arg1=:default, arg2=nil, arg3=[])
494 | # do something...
495 | end
496 |
497 | # bien
498 | def some_method(arg1 = :default, arg2 = nil, arg3 = [])
499 | # do something...
500 | end
501 | ```
502 |
503 | Mientras que varios libros de Ruby sugieren el primer estilo, el segundo es mucho
504 | más utilizado en la práctica (y hasta se podría decir que es más fácil de leer).
505 |
506 | * Evita usar la contínuación de línea con '\' cuando no sea necesario. En la práctica, evita el uso de continuación de línea en cualquier caso, excepto para la concatenación de strings.
507 |
508 | ```ruby
509 | # mal
510 | result = 1 - \
511 | 2
512 |
513 | # bien (pero todavía se ve horrible)
514 | result = 1 \
515 | - 2
516 |
517 | # bien - Uso recomendado
518 | long_string = 'First part of the long string' \
519 | ' and second part of the long string'
520 | ```
521 |
522 | * Al continuar una invocación de método encadenado en otra línea mantener el `.` en la segunda línea.
523 |
524 | ```ruby
525 | # mal - es necesario leer la primer línea para entender la segunda línea
526 | one.two.three.
527 | four
528 |
529 | # bien - inmediatamente se ve qué está pasando en la segunda línea
530 | one.two.three
531 | .four
532 | ```
533 |
534 | * Alinea los parámetros de una llamada a un método si ocupan más de una
535 | línea. Cuando se alinean los parámetros no es apropiado que sea con
536 | más indentación de lo debido, y utilizar un indentado único para las
537 | líneas luego del primer parámetro también es aceptable.
538 |
539 | ```ruby
540 | # punto de partida (la línea es muy larga)
541 | def send_mail(source)
542 | Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text)
543 | end
544 |
545 | # mal (doble indentado)
546 | def send_mail(source)
547 | Mailer.deliver(
548 | to: 'bob@example.com',
549 | from: 'us@example.com',
550 | subject: 'Important message',
551 | body: source.text)
552 | end
553 |
554 | # bien (identado bajo el primer parámetro)
555 | def send_mail(source)
556 | Mailer.deliver(to: 'bob@example.com',
557 | from: 'us@example.com',
558 | subject: 'Important message',
559 | body: source.text)
560 | end
561 |
562 | # bien (indentado normal)
563 | def send_mail(source)
564 | Mailer.deliver(
565 | to: 'bob@example.com',
566 | from: 'us@example.com',
567 | subject: 'Important message',
568 | body: source.text
569 | )
570 | end
571 | ```
572 |
573 | * Alinea los elementos de arrays literales que ocupen múltiples líneas.
574 |
575 | ```ruby
576 | # mal - indentado simple
577 | menu_item = ["Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam",
578 | "Baked beans", "Spam", "Spam", "Spam", "Spam", "Spam"]
579 |
580 | # bien
581 | menu_item = [
582 | "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam",
583 | "Baked beans", "Spam", "Spam", "Spam", "Spam", "Spam"
584 | ]
585 |
586 | # bien
587 | menu_item =
588 | ["Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam",
589 | "Baked beans", "Spam", "Spam", "Spam", "Spam", "Spam"]
590 | ```
591 |
592 | * Agrega guiones bajos para números literales grandes para mejorar su lectura.
593 |
594 | ```ruby
595 | # mal - cuantos 0s hay ahi?
596 | num = 1000000
597 |
598 | # bien - mucho más fácil de leer por el cerebro humano
599 | num = 1_000_000
600 | ```
601 | *
602 | Usa letras minúsculas para los prefijos de literales numéricos.
603 | `0o` para base octal, `0x` para base hexadecimal y `0b` para base binaria.
604 | No uses `0d` para numeros decimales.
605 |
606 | ```ruby
607 | # mal
608 | num = 01234
609 | num = 0O1234
610 | num = 0X12AB
611 | num = 0B10101
612 | num = 0D1234
613 | num = 0d1234
614 |
615 | # bien - es fácil separar los prefijos de los numeros
616 | num = 0o1234
617 | num = 0x12AB
618 | num = 0b10101
619 | num = 12
620 |
621 | * Usa RDoc y sus convenciones para la documentación de APIs. No dejes
622 | una línea en blanco entre el bloque de comentario y el `def`.
623 | * Limitá las líneas a 80 caracteres.
624 | * Evita los espacios en blanco.
625 | * No uses los comentarios de bloque. Ellos no pueden tener espacios en blanco
626 | antes y no son tan fáciles de entenderlos como comentarios.
627 |
628 | ```ruby
629 | # mal
630 | == begin
631 | comment line
632 | another comment line
633 | == end
634 |
635 | # bien
636 | # comment line
637 | # another comment line
638 | ```
639 |
640 | ## Sintaxis
641 |
642 | * Usa `::` sólo para referenciar constantes (esto incluye clases
643 | y módulos) y construcciones (como `Array()` o `Nokogiri::HTML()`).
644 | Nunca uses `::` para la invocación de métodos.
645 |
646 | ```ruby
647 | # mal
648 | SomeClass::some_method
649 | some_object::some_method
650 |
651 | # bien
652 | SomeClass.some_method
653 | some_object.some_method
654 | SomeModule::SomeClass::SOME_CONST
655 | SomeModule::SomeClass()
656 | ```
657 |
658 | *
659 | No uses `::` para definir métodos de clase.
660 |
661 | ```ruby
662 | # nal
663 | class Foo
664 | def self::some_method
665 | end
666 | end
667 |
668 | # bien
669 | class Foo
670 | def self.some_method
671 | end
672 | end
673 | ```
674 |
675 | * Usa `def` con paréntesis cuando tengas argumentos. Omite los
676 | paréntesis cuando el método no acepta ningún argumento.
677 |
678 | ```ruby
679 | # mal
680 | def some_method()
681 | # body omitted
682 | end
683 |
684 | # bien
685 | def some_method
686 | # body omitted
687 | end
688 |
689 | # mal
690 | def some_method_with_arguments arg1, arg2
691 | # body omitted
692 | end
693 |
694 | # bien
695 | def some_method_with_arguments(arg1, arg2)
696 | # body omitted
697 | end
698 | ```
699 |
700 |
701 | *
702 | Usa paréntesis alrededor de los argumentos para la invocación de un método,
703 | especialmente si el primer argumento empieza con un paréntesis abierto `(`,
704 | como por ejemplo: `f((3 + 2) + 1)`.
705 |
706 | ```ruby
707 | # mal
708 | x = Math.sin y
709 | # bien
710 | x = Math.sin(y)
711 |
712 | # mal
713 | array.delete e
714 | # bien
715 | array.delete(e)
716 |
717 | # mal
718 | temperance = Person.new 'Temperance', 30
719 | # bien
720 | temperance = Person.new('Temperance', 30)
721 | ```
722 |
723 | Omite siempre los paréntesis para:
724 |
725 | * Métodos sin argumentos:
726 |
727 | ```ruby
728 | # mal
729 | Kernel.exit!()
730 | 2.even?()
731 | fork()
732 | 'test'.upcase()
733 |
734 | # bien
735 | Kernel.exit!
736 | 2.even?
737 | fork
738 | 'test'.upcase
739 | ```
740 |
741 | * Métodos que son parte de un DSL interno (por ejemplo: Rake, Rails, RSpec):
742 |
743 | ```ruby
744 | # mal
745 | validates(:name, presence: true)
746 | # bien
747 | validates :name, presence: true
748 | ```
749 |
750 | * Métodos que son palabras claves en Ruby:
751 |
752 | ```ruby
753 | class Person
754 | # mal
755 | attr_reader(:name, :age)
756 | # bien
757 | attr_reader :name, :age
758 |
759 | # body omitted
760 | end
761 | ```
762 |
763 | Puedes omitir los paréntesis para:
764 |
765 | * Métodos que tienen el grado de palabras reservada (`keyword`) en ruby, pero que no declaran nada. Ejemplo:
766 |
767 | ```ruby
768 | # bien
769 | puts(temperance.age)
770 | system('ls')
771 | # bien también
772 | puts temperance.age
773 | system 'ls'
774 | ```
775 |
776 | *
777 | Define los argumentos opcionales de un método, al final de la lista de argumentos.
778 | Ruby tiene algunos resultados inesperados cuando los argumentos opcionales estan al principio de la lista de argumentos.
779 |
780 | ```ruby
781 | # mal
782 | def some_method(a = 1, b = 2, c, d)
783 | puts "#{a}, #{b}, #{c}, #{d}"
784 | end
785 |
786 | some_method('w', 'x') # => '1, 2, w, x'
787 | some_method('w', 'x', 'y') # => 'w, 2, x, y'
788 | some_method('w', 'x', 'y', 'z') # => 'w, x, y, z'
789 |
790 | # bien
791 | def some_method(c, d, a = 1, b = 2)
792 | puts "#{a}, #{b}, #{c}, #{d}"
793 | end
794 |
795 | some_method('w', 'x') # => '1, 2, w, x'
796 | some_method('w', 'x', 'y') # => 'y, 2, w, x'
797 | some_method('w', 'x', 'y', 'z') # => 'y, z, w, x'
798 | ```
799 |
800 | *
801 | Evita el uso de asignaciones en paralelo para la definición de variables.
802 | La asignacion en paralelo es permitida cuando es el resultado de un metodo llamado con anterioridad.
803 | Es permitido la asignación en paralelo cuando se usa el operador splat (* antes de una variable) o intercambiar una variable (swap).
804 | La asignacion paralela es mas dificil de leer que una asignación separada.
805 |
806 | ```ruby
807 | # mal
808 | a, b, c, d = 'foo', 'bar', 'baz', 'foobar'
809 |
810 | # bien
811 | a = 'foo'
812 | b = 'bar'
813 | c = 'baz'
814 | d = 'foobar'
815 |
816 | # bien - intercambiando una variable
817 | # El Swapping de variables o intercambio de variables es un caso especial
818 | # debido a que permite intercambiar el valor de 2 variables
819 | a = 'foo'
820 | b = 'bar'
821 |
822 | a, b = b, a
823 | puts a # => 'bar'
824 | puts b # => 'foo'
825 |
826 | # bien - usando el valor de retorno de un metodo
827 | # en este caso retorna mas de 1 valor
828 | def multi_return
829 | [1, 2]
830 | end
831 |
832 | first, second = multi_return
833 |
834 | # bien - usando el operador splat (*)
835 | first, *list = [1, 2, 3, 4] # first => 1, list => [2, 3, 4]
836 |
837 | hello_array = *'Hello' # => ["Hello"]
838 |
839 | a = *(1..3) # => [1, 2, 3]
840 | ```
841 |
842 | *
843 | Evita el uso innecesario de la variable `_` durante la asignación paralela.
844 | Variables nombradas con un guión bajo `_` al principio del nombre son preferidas a solo usar un guión bajo `_`.
845 | Usa guión bajo `_` solamente en combinacion con con una variable `splat` definida a lado izquierdo de la asignación
846 | y sólo si la variable splat no tiene ningun guión bajo `_` al principio del nombre.
847 |
848 | ```ruby
849 | # mal
850 | foo = 'one,two,three,four,five'
851 | # Asignación Innecesaria. No agrega ninguna información útil
852 | first, second, _ = foo.split(',')
853 | first, _, _ = foo.split(',')
854 | first, *_ = foo.split(',')
855 |
856 |
857 | # bien
858 | foo = 'one,two,three,four,five'
859 | # el guión bajo es necesario para mostrar que se quiere obtener
860 | # todos los elementos exceptuando el último
861 | *beginning, _ = foo.split(',')
862 | *beginning, something, _ = foo.split(',')
863 |
864 | # sólo el primer elemento
865 | a, = foo.split(',')
866 | # sólo los 2 primeros elementos
867 | a, b, = foo.split(',')
868 |
869 | # Asignación innecesaria en una variable que no se usará, pero
870 | # esta asignación provee unformación útil
871 | first, _second = foo.split(',')
872 | first, _second, = foo.split(',')
873 | first, *_ending = foo.split(',')
874 | ```
875 |
876 | * Nunca uses `for`, a menos que sepas exactamente para qué lo usás. En su
877 | lugar deberías usar los iteradores la mayor parte del tiempo. `for` se
878 | debe implementar en forma de `each` (asi estás agregando un nivel de
879 | indirección), pero con una peculiaridad - `for` no introduce un nuevo
880 | scope (a diferencia de `each`) y las variables que se definen dentro
881 | de su bloque son visibles fuera del mismo.
882 |
883 | ```ruby
884 | arr = [1, 2, 3]
885 |
886 | # mal
887 | for elem in arr do
888 | puts elem
889 | end
890 |
891 | # elem puede ser leída fuera del loop for
892 | elem #=> 3
893 |
894 | # bien
895 | arr.each { |elem| puts elem }
896 |
897 | # elem no puede ser leída fuera del bloque each
898 | elem #=> NameError: undefined local variable or method `elem'
899 | ```
900 |
901 | * Nunca uses `then` para `if/unless` con multilíneas.
902 |
903 | ```ruby
904 | # mal
905 | if some_condition then
906 | # body omitted
907 | end
908 |
909 | # bien
910 | if some_condition
911 | # body omitted
912 | end
913 | ```
914 |
915 | * Siempre escribe la condición en la misma línea para los condicionales `if`/`unless` con multilíneas.
916 |
917 | ```ruby
918 | # mal
919 | if
920 | some_condition
921 | do_something
922 | do_something_else
923 | end
924 |
925 | # bien
926 | if some_condition
927 | do_something
928 | do_something_else
929 | end
930 | ```
931 |
932 | * Prefiere el operador ternario (`?:`) en lugar de las construcciones
933 | `if/then/else/end`. Es más común y obviamente más conciso.
934 |
935 | ```ruby
936 | # mal
937 | result = if some_condition then something else something_else end
938 |
939 | # bien
940 | result = some_condition ? something : something_else
941 | ```
942 |
943 | * Usa una expresión por fila por operador ternario. Esto también
944 | significa que los operadores ternarios no deben anidarse. Es
945 | preferible utilizar construcciones `if/else` en estos casos.
946 |
947 | ```ruby
948 | # mal
949 | some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
950 |
951 | # bien
952 | if some_condition
953 | nested_condition ? nested_something : nested_something_else
954 | else
955 | something_else
956 | end
957 | ```
958 |
959 | * Nunca uses `if x: ...` - fue eliminado en Ruby 1.9. Usa el
960 | operador ternario en su lugar.
961 |
962 | ```ruby
963 | # mal
964 | result = if some_condition: something else something_else end
965 |
966 | # bien
967 | result = some_condition ? something : something_else
968 | ```
969 |
970 | * Nunca uses `if x; ...`. Usa el operador ternario en su lugar.
971 |
972 | * Usa `when x then ...` para condicionales de una línea. La sintaxis
973 | alternativa `when x: ...` fue eliminada en Ruby 1.9.
974 |
975 | * Nunca uses `when x; ...`. Mirá la regla anterior.
976 |
977 | * Usa `!` en lugar de `not`.
978 |
979 | ```ruby
980 | # mal - los paréntesis son necesarios por la precedencia de operador
981 | x = (not something)
982 |
983 | # bien
984 | x = !something
985 | ```
986 |
987 | * Evita el uso de `!!`.
988 |
989 | ```ruby
990 | # mal
991 | x = 'test'
992 | # Analizando si la variable es nil
993 | if !!x
994 | # body omitted
995 | end
996 |
997 | x = false
998 | # La doble negación no funciona con variables boleanas
999 | !!x # => false
1000 |
1001 | # bien
1002 | x = 'test'
1003 | if !x.nil?
1004 | # body omitted
1005 | end
1006 | ```
1007 |
1008 | * Las palabras `and` y `or` están prohibidas. Simplemente no valen
1009 | la pena. En su lugar, siempre usá `&&` y `||`.
1010 |
1011 | ```ruby
1012 | # mal
1013 | # boolean expression
1014 | if some_condition and some_other_condition
1015 | do_something
1016 | end
1017 |
1018 | # control flow
1019 | document.saved? or document.save!
1020 |
1021 | # bien
1022 | # boolean expression
1023 | if some_condition && some_other_condition
1024 | do_something
1025 | end
1026 |
1027 | # control flow
1028 | document.saved? || document.save!
1029 | ```
1030 |
1031 | * Evita usar `?:` (operador ternario) en multilíneas; en su lugar usá `if/unless`.
1032 |
1033 | * Favorecé al uso del modificador `if/unless` cuando tengas que escribir en una línea.
1034 | Otra buena alternativa es el uso del control de flujo con `&&/||`.
1035 |
1036 | ```ruby
1037 | # mal
1038 | if some_condition
1039 | do_something
1040 | end
1041 |
1042 | # bien
1043 | do_something if some_condition
1044 |
1045 | # otra buena opción
1046 | # Usando control de flujos
1047 | some_condition && do_something
1048 | ```
1049 |
1050 | *
1051 | Evita el uso de modificadores `if`/`unless` al final de un bloque que se compone con mas de una lineal.
1052 |
1053 | ```ruby
1054 | # mal
1055 | 10.times do
1056 | # multi-line body omitted
1057 | end if some_condition
1058 |
1059 | # bien
1060 | if some_condition
1061 | 10.times do
1062 | # multi-line body omitted
1063 | end
1064 | end
1065 | ```
1066 |
1067 | *
1068 | Evita el sudo de modificadores `if`/`unless`/`while`/`until` de forma anidada.
1069 | Mejor usa apropiadamente `&&`/`||` if.
1070 |
1071 | ```ruby
1072 | # mal
1073 | do_something if other_condition if some_condition
1074 |
1075 | # bien
1076 | do_something if some_condition && other_condition
1077 | ```
1078 |
1079 | * Favorece `unless` por sobre `if` para condiciones negativas (o control
1080 | de flujo con `||`).
1081 |
1082 | ```ruby
1083 | # mal
1084 | do_something if !some_condition
1085 |
1086 | # mal
1087 | do_something if not some_condition
1088 |
1089 | # bien
1090 | do_something unless some_condition
1091 |
1092 | # otra buena opción
1093 | # Usando control de flujos
1094 | some_condition || do_something
1095 | ```
1096 |
1097 | * Nunca uses `unless` con `else`. Reescribe para que el caso positivo esté primero.
1098 |
1099 | ```ruby
1100 | # mal
1101 | unless success?
1102 | puts 'failure'
1103 | else
1104 | puts 'success'
1105 | end
1106 |
1107 | # bien
1108 | if success?
1109 | puts 'success'
1110 | else
1111 | puts 'failure'
1112 | end
1113 | ```
1114 |
1115 | * No uses paréntesis alrededor de la condición de `if/unless/while/until`.
1116 |
1117 | ```ruby
1118 | # mal
1119 | if (x > 10)
1120 | # body omitted
1121 | end
1122 |
1123 | # bien
1124 | if x > 10
1125 | # body omitted
1126 | end
1127 | ```
1128 |
1129 | * Nunca uses `while/until` condition `do` para un `while/until` multilínea.
1130 |
1131 | ```ruby
1132 | # mal
1133 | while x > 5 do
1134 | # body omitted
1135 | end
1136 |
1137 | until x > 5 do
1138 | # body omitted
1139 | end
1140 |
1141 | # bien
1142 | while x > 5
1143 | # body omitted
1144 | end
1145 |
1146 | until x > 5
1147 | # body omitted
1148 | end
1149 | ```
1150 |
1151 | * Favorecé el uso del modificador `while/until` cuando puedas escribir la
1152 | comparación en una línea.
1153 |
1154 | ```ruby
1155 | # mal
1156 | while some_condition
1157 | do_something
1158 | end
1159 |
1160 | # bien
1161 | do_something while some_condition
1162 | ```
1163 |
1164 | * Favorecé `until` por sobre `while` para condiciones negativas.
1165 |
1166 | ```ruby
1167 | # mal
1168 | do_something while !some_condition
1169 |
1170 | # bien
1171 | do_something until some_condition
1172 | ```
1173 |
1174 | *
1175 | Usa `Kernel#loop` en vez de `while/until` cuando necesites un ciclo infinito.
1176 |
1177 | ```ruby
1178 | # mal
1179 | while true
1180 | do_something
1181 | end
1182 |
1183 | until false
1184 | do_something
1185 | end
1186 |
1187 | # bien
1188 | loop do
1189 | do_something
1190 | end
1191 | ```
1192 |
1193 |
1194 | * Usa `Kernel#loop` con break en lugar de `begin/end/until` o `begin/end/while`
1195 | para validar al final de cada ciclo.
1196 |
1197 | ```ruby
1198 | # mal
1199 | begin
1200 | puts val
1201 | val += 1
1202 | end while val < 0
1203 |
1204 | # bien
1205 | loop do
1206 | puts val
1207 | val += 1
1208 | break unless val < 0
1209 | end
1210 | ```
1211 |
1212 | * Omite los paréntesis alrededor de los parámetros para los métodos
1213 | que forman parte de un DSL interno (ejemplo: Rake, Rails, RSpec),
1214 | métodos que tengan "keyword" status en Ruby (ejemplo: `attr_reader`,
1215 | `puts`) y métodos accesores de atributos. Usa paréntesis alrededor
1216 | de los argumentos de todas las otras llamadas a métodos.
1217 |
1218 | ```ruby
1219 | class Person
1220 | attr_reader :name, :age
1221 |
1222 | # omitted
1223 | end
1224 |
1225 | temperance = Person.new('Temperance', 30)
1226 | temperance.name
1227 |
1228 | puts temperance.age
1229 |
1230 | x = Math.sin(y)
1231 | array.delete(e)
1232 |
1233 | bowling.score.should == 0
1234 | ```
1235 |
1236 | * Omite las llaves externas alrededor de las opciones implícitas
1237 | de un hash.
1238 |
1239 | ```ruby
1240 | # mal
1241 | user.set({ name: 'John', age: 45, permissions: { read: true } })
1242 |
1243 | # bien
1244 | user.set(name: 'John', age: 45, permissions: { read: true })
1245 | ```
1246 |
1247 | * Omite tanto las llaves externas como los paréntesis para métodos que formen
1248 | parte de un DSL interno.
1249 |
1250 | ```ruby
1251 | class Person < ActiveRecord::Base
1252 | # mal
1253 | validates(:name, { presence: true, length: { within: 1..10 } })
1254 |
1255 | # bien
1256 | validates :name, presence: true, length: { within: 1..10 }
1257 | end
1258 | ```
1259 |
1260 | *
1261 | Usa la invocación de procesos cuando solo realices una operacion en un bloque
1262 |
1263 | ```ruby
1264 | # mal
1265 | names.map { |name| name.upcase }
1266 |
1267 | # bien
1268 | names.map(&:upcase)
1269 | ```
1270 |
1271 | * Elige `{...}` por sobre `do...end` para bloques de una línea. Evita
1272 | el uso de `{...}` para bloques multilíneas (encadenamiento de multilínea
1273 | siempre es horrible). Siempre usá `do...end` para "contorl de flujo" y
1274 | "definiciones de métodos" (e.g. en Rakefiles y algunos DSLs). Evita usar
1275 | `do...end` cuando estés encadenando métodos.
1276 |
1277 | ```ruby
1278 | names = ['Bozhidar', 'Steve', 'Sarah']
1279 |
1280 | # mal
1281 | names.each do |name|
1282 | puts name
1283 | end
1284 |
1285 | # bien
1286 | names.each { |name| puts name }
1287 |
1288 | # mal
1289 | names.select do |name|
1290 | name.start_with?('S')
1291 | end.map { |name| name.upcase }
1292 |
1293 | # bien
1294 | names.select { |name| name.start_with?('S') }.map(&:upcase)
1295 | ```
1296 |
1297 | Puede ser que algunas personas piensen que el encadenamiento en multilínea se vería bien con
1298 | el uso de {...}, pero en realidad deberían preguntarse a sí mismos - es el código realmente
1299 | legible y los contenidos de los bloques pueden ser extraídos con métodos elegantes?
1300 |
1301 | * Evita usar `return` cuando no se requiera realizar control de flujo.
1302 |
1303 | ```ruby
1304 | # mal
1305 | def some_method(some_arr)
1306 | return some_arr.size
1307 | end
1308 |
1309 | # bien
1310 | def some_method(some_arr)
1311 | some_arr.size
1312 | end
1313 | ```
1314 |
1315 | * Evita usar `self` cuando no es necesario. (Solo se necesita cuando se sobreescribe el valor de la variable propia de la clase.)
1316 |
1317 | ```ruby
1318 | # mal
1319 | def ready?
1320 | if self.last_reviewed_at > self.last_updated_at
1321 | self.worker.update(self.content, self.options)
1322 | self.status = :in_progress
1323 | end
1324 | self.status == :verified
1325 | end
1326 |
1327 | # bien
1328 | def ready?
1329 | if last_reviewed_at > last_updated_at
1330 | worker.update(content, options)
1331 | self.status = :in_progress
1332 | end
1333 | status == :verified
1334 | end
1335 | ```
1336 |
1337 | * Como convención, evita oscurecer métodos con variables locales, excepto que ambos sean lo mismo.
1338 |
1339 | ```ruby
1340 | class Foo
1341 | attr_accessor :options
1342 |
1343 | # ok
1344 | def initialize(options)
1345 | self.options = options
1346 | # both options and self.options are equivalent here
1347 | end
1348 |
1349 | # mal
1350 | def do_something(options = {})
1351 | unless options[:when] == :later
1352 | output(self.options[:message])
1353 | end
1354 | end
1355 |
1356 | # bien
1357 | def do_something(params = {})
1358 | unless params[:when] == :later
1359 | output(options[:message])
1360 | end
1361 | end
1362 | end
1363 | ```
1364 |
1365 | * No uses el valor de retorno de `=` (asignación) en expresiones
1366 | condicionales a menos que la asignación se encuentre entre paréntesis.
1367 | Esta es una expresión bastante popular entre los Rubyistas que se
1368 | refiere a veces como *asignación segura en condiciones*.
1369 |
1370 | ```ruby
1371 | # mal (+ una advertencia)
1372 | if v = array.grep(/foo/)
1373 | do_something(v)
1374 | ...
1375 | end
1376 |
1377 | # bien (MRI todavía se quejaría, per RuboCop no)
1378 | if (v = array.grep(/foo/))
1379 | do_something(v)
1380 | ...
1381 | end
1382 |
1383 | # bien
1384 | v = array.grep(/foo/)
1385 | if v
1386 | do_something(v)
1387 | ...
1388 | end
1389 | ```
1390 | *
1391 | Usa las abreviaturas para asignar valores después de una operación.
1392 |
1393 | ```ruby
1394 | # mal
1395 | x = x + y
1396 | x = x * y
1397 | x = x**y
1398 | x = x / y
1399 | x = x || y
1400 | x = x && y
1401 |
1402 | # bien
1403 | x += y
1404 | x *= y
1405 | x **= y
1406 | x /= y
1407 | x ||= y
1408 | x &&= y
1409 | ```
1410 |
1411 | * Usa `||=` libremente para inicializar variables.
1412 |
1413 | ```ruby
1414 | # asigna el nombre Bozhidar, solo si la variable 'name' es nil o false
1415 | name ||= 'Bozhidar'
1416 | ```
1417 |
1418 | * No uses `||=` para inicializar variables booleanas. (Considera qué
1419 | pasaría si el valor actual fuese `false`.)
1420 |
1421 | ```ruby
1422 | # mal - asignaría true a enabled aunque ya era false
1423 | enabled ||= true
1424 |
1425 | # bien
1426 | enabled = true if enabled.nil?
1427 | ```
1428 |
1429 | *
1430 | Usa `&&=` para preprocesar variables que pueden no existir.
1431 | Usando `&&=` cambiarás el valor de la variable, solo si existe,
1432 | eliminando la necesidad de comprobar su existencia usando un `if`.
1433 |
1434 | ```ruby
1435 | # mal
1436 | if something
1437 | something = something.downcase
1438 | end
1439 |
1440 | # mal
1441 | something = something ? something.downcase : nil
1442 |
1443 | # ok
1444 | something = something.downcase if something
1445 |
1446 | # bien
1447 | something = something && something.downcase
1448 |
1449 | # mejor
1450 | something &&= something.downcase
1451 | ```
1452 |
1453 | * Evita el uso explícito del operador de igualdad idéntica `===`.
1454 | Como su nombre indica, está destinado a ser utilizado
1455 | implícitamente por expresiones `case` y fuera de ellas provee
1456 | código bastante confuso.
1457 |
1458 | ```ruby
1459 | # mal
1460 | Array === something
1461 | (1..100) === 7
1462 | /something/ === some_string
1463 |
1464 | # bien
1465 | something.is_a?(Array)
1466 | (1..100).include?(7)
1467 | some_string =~ /something/
1468 | ```
1469 | *
1470 | No uses `eql?` cuando puedes usar `==`.
1471 | El comparador de semantica estricto ofrecido por `eql?`
1472 | es raramente necesitado en la práctica.
1473 |
1474 | ```ruby
1475 | # mal - eql? es lo mismo que == para strings
1476 | 'ruby'.eql? some_str
1477 |
1478 | # bien
1479 | 'ruby' == some_str
1480 |
1481 | # eql? tiene sentido aqui, si se quiere diferenciar entre Integer y Float 1
1482 | 1.0.eql? x
1483 | ```
1484 |
1485 | * Evita usar variables especiales de tipo Perl (como `$:`, `$;`, etc.). Son bastante crípticas y su uso en cualquier lugar excepto scripts de una línea está desalentado. Usa los alias amigables para humanos proporcionados por la librería `English`.
1486 |
1487 | ```ruby
1488 | # mal
1489 | $:.unshift File.dirname(__FILE__)
1490 |
1491 | # bien
1492 | require 'English'
1493 | $LOAD_PATH.unshift File.dirname(__FILE__)
1494 | ```
1495 |
1496 | * Nunca uses un espacio entre el nombre de un método y la apertura de un paréntesis.
1497 |
1498 | ```ruby
1499 | # mal
1500 | f (3 + 2) + 1
1501 |
1502 | # bien
1503 | f(3 + 2) + 1
1504 | ```
1505 |
1506 | * Si el primer argumento de un método comienza con un paréntesis abierto,
1507 | siempre utilizá paréntesis en la invocación del método. Por ejemplo,
1508 | escribe `f ((3 + 2) + 1)`.
1509 |
1510 | * Siempre ejecutá el intérprete de Ruby con la opción `-w`, para que
1511 | avise si se olvida alguna de las reglas anteriores!
1512 |
1513 | *
1514 | No uses métodos anidados, mejor usa las funciones lambda.
1515 | Los métodos anidados actualmente producen métodos en el mismo ámbito (ejemplo: clases)
1516 | Ademas el método anidado será redefinido cada vez que se llame al metodo que lo contiene.
1517 |
1518 | ```ruby
1519 | # mal
1520 | def foo(x)
1521 | def bar(y)
1522 | # body omitted
1523 | end
1524 |
1525 | bar(x)
1526 | end
1527 |
1528 | # bien - aunque es igual a lo anterior, la mejora es que 'bar' no será redefinido cada vez que se llame 'foo'
1529 | def bar(y)
1530 | # body omitted
1531 | end
1532 |
1533 | def foo(x)
1534 | bar(x)
1535 | end
1536 |
1537 | # bien tambíen
1538 | def foo(x)
1539 | bar = ->(y) { ... }
1540 | bar.call(x)
1541 | end
1542 | ``
1543 |
1544 | * Usa la nueva sintaxis de lambda literal para bloques de una sola línea.
1545 | Usa el método `lambda` para bloques multilínea.
1546 |
1547 | ```ruby
1548 | # mal
1549 | l = lambda { |a, b| a + b }
1550 | l.call(1, 2)
1551 |
1552 | # correcto, pero se ve extremadamente incómodo
1553 | l = ->(a, b) do
1554 | tmp = a * 7
1555 | tmp * b / 50
1556 | end
1557 |
1558 | # bien - una sola linea
1559 | l = ->(a, b) { a + b }
1560 | l.call(1, 2)
1561 |
1562 | # bien - bloque multilinea
1563 | l = lambda do |a, b|
1564 | tmp = a * 7
1565 | tmp * b / 50
1566 | end
1567 | ```
1568 | *
1569 | No omitas los parentesis cuando estas definiendo una función lambda que utiliza parámetros.
1570 |
1571 | ```ruby
1572 | # mal
1573 | l = ->x, y { something(x, y) }
1574 |
1575 | # bien
1576 | l = ->(x, y) { something(x, y) }
1577 | ```
1578 |
1579 | *
1580 | Omite los paréntesis si tu función lambda no necesita parámetros.
1581 |
1582 | ```ruby
1583 | # mal
1584 | l = ->() { something }
1585 |
1586 | # bien
1587 | l = -> { something }
1588 | ```
1589 |
1590 | * Elige `proc` por sobre `Proc.new`.
1591 |
1592 | ```ruby
1593 | # mal
1594 | p = Proc.new { |n| puts n }
1595 |
1596 | # bien
1597 | p = proc { |n| puts n }
1598 | ```
1599 |
1600 | * Elige `proc.call()` por sobre `proc[]` o `proc.()` tanto para lambdas y procs.
1601 |
1602 | ```ruby
1603 | # mal - se ve similar a un acceso de Enumeración
1604 | l = ->(v) { puts v }
1605 | l[1]
1606 |
1607 | # también mal - sintaxis no común
1608 | l = ->(v) { puts v }
1609 | l.(1)
1610 |
1611 | # bien
1612 | l = ->(v) { puts v }
1613 | l.call(1)
1614 | ```
1615 |
1616 | * Usa `_` para los parámetros sin usar de bloques.
1617 |
1618 | ```ruby
1619 | # mal
1620 | result = hash.map { |k, v| v + 1 }
1621 |
1622 | # bien
1623 | result = hash.map { |_, v| v + 1 }
1624 | ```
1625 |
1626 | * Usa `$stdout/$stderr/$stdin` en lugar de
1627 | `STDOUT/STDERR/STDIN`. `STDOUT/STDERR/STDIN` son constantes, y
1628 | mientras que puedas reasignar constantes (posiblemente para redirigr
1629 | un proceso) en Ruby, vas a tener una advertencia del intérprete si
1630 | hacés eso.
1631 |
1632 | * Usa `warn` en lugar de `$stderr.puts`. Aparte de ser más conciso y
1633 | claro, `warn` te permite suprimir advertencias si lo necesitás
1634 | (seteando el nivel de advertencia a 0 via `-W0`).
1635 |
1636 | * Elige usar `sprintf` y su alias `format` por sobre el método
1637 | críptico `String#%`.
1638 |
1639 | ```ruby
1640 | # mal
1641 | '%d %d' % [20, 10]
1642 | # => '20 10'
1643 |
1644 | # bien
1645 | sprintf('%d %d', 20, 10)
1646 | # => '20 10'
1647 |
1648 | # mejor
1649 | sprintf('%d %d', first: 20, second: 10)
1650 | # => '20 10'
1651 |
1652 | # bien
1653 | format('%d %d', 20, 10)
1654 | # => '20 10'
1655 |
1656 | # mejor
1657 | format('%d %d', first: 20, second: 10)
1658 | # => '20 10'
1659 | ```
1660 |
1661 | *
1662 | Cuando usas tokens de nombres, por favor usa `%s` por sobre `%{name}`, porque al momento de referenciarlos
1663 | estás referenciando el tipo de valor que tomará el token.
1664 |
1665 | ```ruby
1666 | # mal
1667 | format('Hello, %{name}', name: 'John')
1668 |
1669 | # bien
1670 | format('Hello, %s', name: 'John')
1671 | `
1672 |
1673 | * Elige el uso de `Array#join` por sobre el críptico `Array#*` con
1674 | un argumento string.
1675 |
1676 | ```ruby
1677 | # mal
1678 | %w(one two three) * ', '
1679 | # => 'one, two, three'
1680 |
1681 | # bien
1682 | %w(one two three).join(', ')
1683 | # => 'one, two, three'
1684 | ```
1685 |
1686 | * Usa `[*var]` o `Array()` en lugar de la verificación explícita `Array`,
1687 | cuando trabajes con una variable que quieras tratar como un Array, pero
1688 | no estás seguro que sea un array.
1689 |
1690 | ```ruby
1691 | # mal
1692 | paths = [paths] unless paths.is_a? Array
1693 | paths.each { |path| do_something(path) }
1694 |
1695 | # bien
1696 | [*paths].each { |path| do_something(path) }
1697 |
1698 | # bien (y un poquito más legible)
1699 | Array(paths).each { |path| do_something(path) }
1700 | ```
1701 |
1702 | * Usa rangos o `Comparable#between?` en lugar de una comparación lógica
1703 | compleja cuando sea posible.
1704 |
1705 | ```ruby
1706 | # mal
1707 | do_something if x >= 1000 && x <= 2000
1708 |
1709 | # bien
1710 | do_something if (1000..2000).include?(x)
1711 |
1712 | # bien
1713 | do_something if x.between?(1000, 2000)
1714 | ```
1715 |
1716 | * Elige el uso de métodos subyacentes en lugar de las comparaciones
1717 | explícitas con `==`. Comparaciones numéricas están OK.
1718 |
1719 | ```ruby
1720 | # mal
1721 | if x % 2 == 0
1722 | end
1723 |
1724 | if x % 2 == 1
1725 | end
1726 |
1727 | if x == nil
1728 | end
1729 |
1730 | # bien
1731 | if x.even?
1732 | end
1733 |
1734 | if x.odd?
1735 | end
1736 |
1737 | if x.nil?
1738 | end
1739 |
1740 | if x.zero?
1741 | end
1742 |
1743 | if x == 0
1744 | end
1745 | ```
1746 |
1747 | *
1748 | No uses explicitamente no-`nil` para validar una variable,
1749 | a menos que estés tratando con variables boleanas.
1750 |
1751 | ```ruby
1752 | # mal
1753 | do_something if !something.nil?
1754 | do_something if something != nil
1755 |
1756 | # bien
1757 | do_something if something
1758 |
1759 | # bien - solo si se está seguro de que la variable es boleana
1760 | def value_set?
1761 | !@some_boolean.nil?
1762 | end
1763 | ```
1764 |
1765 | * Evita el uso de bloques `BEGIN`.
1766 |
1767 | * Nunca uses bloques `END`. En su lugar usá `Kernel#at_exit`.
1768 |
1769 | ```ruby
1770 | # mal
1771 |
1772 | END { puts 'Goodbye!' }
1773 |
1774 | # bien
1775 |
1776 | at_exit { puts 'Goodbye!' }
1777 | ```
1778 |
1779 | * Evita el uso de flip-flops.
1780 |
1781 | * Evita el uso de condicionales anidados para control de flujo.
1782 | Elige una cláusula de guardia (guard clause) cuando puedas afirmar datos inválidos.
1783 | Una cláusula de guardia es un condicional al principio de una función que trata de
1784 | salir de ella tan pronto como pueda.
1785 |
1786 | ```ruby
1787 | # mal
1788 | def compute_thing(thing)
1789 | if thing[:foo]
1790 | update_with_bar(thing)
1791 | if thing[:foo][:bar]
1792 | partial_compute(thing)
1793 | else
1794 | re_compute(thing)
1795 | end
1796 | end
1797 | end
1798 |
1799 | # bien
1800 | def compute_thing(thing)
1801 | return unless thing[:foo]
1802 | update_with_bar(thing[:foo])
1803 | return re_compute(thing) unless thing[:foo][:bar]
1804 | partial_compute(thing)
1805 | end
1806 | ```
1807 |
1808 | Prefiere `next` en los ciclos (loop) en vez de bloques condicionales.
1809 |
1810 | ```ruby
1811 | # mal
1812 | [0, 1, 2, 3].each do |item|
1813 | if item > 1
1814 | puts item
1815 | end
1816 | end
1817 |
1818 | # bien
1819 | [0, 1, 2, 3].each do |item|
1820 | next unless item > 1
1821 | puts item
1822 | end
1823 | ```
1824 |
1825 |
1826 | *
1827 | * Elige `map` por sobre `collect`, `find` por sobre `detecet`, `select`
1828 | por sobre `find_all`, `reduce` por sobre `inject` y `size` por sobre
1829 | `length`. No es un requerimiento difícil; si el uso de alias realza
1830 | la legibilidad, está bien usarlos. Los métodos de rima son heredados
1831 | de Smalltalk y no son comunes en otros lenguajes de programación. La
1832 | razón para usar `select` por sobre `find_all` es porque va muy bien
1833 | junto con `reject` y su nombre es bastante auto-explicativo.
1834 |
1835 | *
1836 | No uses `count` como sustituto de `size`. Para los objetos de tipo `Enumerable`, pues
1837 | el objeto completo se iterará para saber el numero de elementos.
1838 |
1839 | ```ruby
1840 | # mal
1841 | some_hash.count
1842 |
1843 | # bien
1844 | some_hash.size
1845 | ```
1846 |
1847 | *
1848 | Usa `flat_map` en vez de `map` + `flatten`. Esto no se aplica para arrays con una
1849 | profundidad mayor a 2, por ejemplo. Si `users.first.songs == ['a', ['b',['c']]]`,
1850 | entonces usa `map + flatten` en lugar de `flat_map`. `flat_map` aplana el array con profundidad 1,
1851 | mientras que `flatten` lo aplana completamente.
1852 |
1853 | ```ruby
1854 | # mal
1855 | all_songs = users.map(&:songs).flatten.uniq
1856 |
1857 | # bien
1858 | all_songs = users.flat_map(&:songs).uniq
1859 | ```
1860 |
1861 | *
1862 | Prefiere `reverse_each` to `reverse.each` porque algunas clases que incluyen `Enumerable`
1863 | pueden proveer una implementacion eficiente. Incluso en el peor caso si la clase no implementa una mejora
1864 | the general desde `Enumerable` será tan eficiente como `reverse.each`.
1865 |
1866 | ```ruby
1867 | # mal
1868 | array.reverse.each { ... }
1869 |
1870 | # bien
1871 | array.reverse_each { ... }
1872 |
1873 |
1874 | ## Nombres
1875 |
1876 | > Las únicas dificultades reales en programación son invalidación de
1877 | > caché y nombrar cosas.
1878 | > -- Phil Karlton
1879 |
1880 | * Nombres de referencia en Inglés.
1881 |
1882 | ```ruby
1883 | # mal - referencia no está utilizando caracteres ascii
1884 | заплата = 1_000
1885 |
1886 | # mal - la referencia es una palabra búlgara, escrita con caracteres latinos (en lugar de Cirílico)
1887 | zaplata = 1_000
1888 |
1889 | # bien
1890 | salary = 1_000
1891 | ```
1892 | * Usa `snake_case` para los símbolos, métodos y variables.
1893 |
1894 | ```ruby
1895 | # mal
1896 | :'some symbol'
1897 | :SomeSymbol
1898 | :someSymbol
1899 |
1900 | someVar = 5
1901 |
1902 | def someMethod
1903 | ...
1904 | end
1905 |
1906 | def SomeMethod
1907 | ...
1908 | end
1909 |
1910 | # bien
1911 | :some_symbol
1912 |
1913 | def some_method
1914 | ...
1915 | end
1916 | ```
1917 |
1918 | *
1919 | No separes lo números de las letras, símbolos, métodos o variables.
1920 |
1921 | ```ruby
1922 | # mal
1923 | :some_sym_1
1924 |
1925 | some_var_1 = 1
1926 |
1927 | def some_method_1
1928 | # some code
1929 | end
1930 |
1931 | # bien
1932 | :some_sym1
1933 |
1934 | some_var1 = 1
1935 |
1936 | def some_method1
1937 | # some code
1938 | end
1939 | ```
1940 |
1941 | * Usa `CamelCase` para clases y módulos. (Mantené en mayúsculas los
1942 | acrónimos como HTTP, RFC, XML.)
1943 |
1944 | ```ruby
1945 | # mal
1946 | class Someclass
1947 | ...
1948 | end
1949 |
1950 | class Some_Class
1951 | ...
1952 | end
1953 |
1954 | class SomeXml
1955 | ...
1956 | end
1957 |
1958 | # bien
1959 | class SomeClass
1960 | ...
1961 | end
1962 |
1963 | class SomeXML
1964 | ...
1965 | end
1966 | ```
1967 |
1968 | *
1969 | Usa `snake_case` para nombrar archivos, ejemplo. `hello_world.rb`.
1970 |
1971 | *
1972 | Usa `snake_case` para nombrar directorios, ejemplo.
1973 | `lib/hello_world/hello_world.rb`.
1974 |
1975 | *
1976 | Trata de tener solo una Clase o Módulo por archivo fuente. Nombra el archivo con el nombre
1977 | de la Clase o Módulo, pero reemplazando el nombre de `CamelCase` a `snake_case`.
1978 | ejemplo. `some_class.rb`
1979 |
1980 | ```ruby
1981 | # bien
1982 | class SomeClass
1983 | # No body
1984 | end
1985 | ```
1986 |
1987 | * Usa `SCREAMING_SNAKE_CASE` para las constantes.
1988 |
1989 | ```ruby
1990 | # mal
1991 | SomeConst = 5
1992 |
1993 | # bien
1994 | SOME_CONST = 5
1995 | ```
1996 |
1997 | * Los nombres de los métodos que afirman (métodos que devuelven un
1998 | valor booleano) deben terminar con un signo de pregunta.
1999 | (ejemplo: `Array#empty?`). Los métodos que no devuelvan un booleano,
2000 | no deben terminar con un signo de pregunta.
2001 |
2002 | *
2003 | Evita usar prefijos auxiliares como (`is`, `does`, or `can`) para los nombres de Métodos.
2004 | Estas palabras son redundantes e inconsistentes con el estilo de Métodos boleanos que hay en Ruby core library,
2005 | como por ejemplo `empty?` o `include?`.
2006 |
2007 | ```ruby
2008 | # mal
2009 | class Person
2010 | def is_tall?
2011 | true
2012 | end
2013 |
2014 | def can_play_basketball?
2015 | false
2016 | end
2017 |
2018 | def does_like_candy?
2019 | true
2020 | end
2021 | end
2022 |
2023 | # bien
2024 | class Person
2025 | def tall?
2026 | true
2027 | end
2028 |
2029 | def basketball_player?
2030 | false
2031 | end
2032 |
2033 | def likes_candy?
2034 | true
2035 | end
2036 | end
2037 | ```
2038 |
2039 | * Los nombres de métodos potencialmente *peligrosos* (ejemplo: métodos
2040 | que modifican `self` o los argumentos, `exit!` - no ejecuta
2041 | finalizadores como lo hace `exit`, etc.) deben terminar con un signo
2042 | de exclamación solo si existe una versión segura de ese método
2043 | *peligroso*.
2044 |
2045 | ```ruby
2046 | # mal - no hay ningún método 'seguro' que se llame igual
2047 | class Person
2048 | def update!
2049 | end
2050 | end
2051 |
2052 | # bien
2053 | class Person
2054 | def update
2055 | end
2056 | end
2057 |
2058 | # bien
2059 | class Person
2060 | def update!
2061 | end
2062 |
2063 | def update
2064 | end
2065 | end
2066 | ```
2067 |
2068 | * Define un método non-bang (seguro) en relación al método bang
2069 | (peligroso) si es posible.
2070 |
2071 | ```ruby
2072 | class Array
2073 | def flatten_once!
2074 | res = []
2075 |
2076 | each do |e|
2077 | [*e].each { |f| res << f }
2078 | end
2079 |
2080 | replace(res)
2081 | end
2082 |
2083 | def flatten_once
2084 | dup.flatten_once!
2085 | end
2086 | end
2087 | ```
2088 |
2089 | * Cuando se usa `reduce` con bloques chicos, nombrá los argumentos
2090 | `|a, e|` (accumulator, element).
2091 | * Cuando definas operadores binarios, nombrá el argumento como `other`
2092 | (`<<` y `[]` son excepciones a la regla, ya que su semántica es
2093 | diferente).
2094 |
2095 | ```ruby
2096 | def +(other)
2097 | # body omitted
2098 | end
2099 | ```
2100 |
2101 | ## Comentarios
2102 |
2103 | > El buen código es su mejor documentación. Cuando estés a punto de
2104 | > agregar un comentario, preguntate: "¿Cómo puedo mejorar el código
2105 | > para que no sea necesario este comentario?" Mejorá el código y luego
2106 | > documentalo para que hacerlo aún más claro.
2107 | > -- Steve McConnell
2108 |
2109 | * Escribe código autodocumentado e ignorá el resto de esta sección. En serio!
2110 | * Escribe tus comentarios en Inglés para evitar problemas con los caracteres
2111 | especiales.
2112 | * Usa un espacio entre el primer caracter `#` del comentario y el texto
2113 | propio del comentario.
2114 | * Los comentarios que son más largos que una palabra son capitalizados y usan
2115 | puntuación. Usa [un espacio](http://es.wikipedia.org/wiki/Espacio_entre_oraciones) luego de los puntos.
2116 | * Evita comentarios supérfluos.
2117 |
2118 | ```ruby
2119 | # mal
2120 | counter += 1 # Increments counter by one.
2121 | ```
2122 |
2123 | * Mantené los comentarios existentes actualizados. Un comentario viejo es peor
2124 | que no utilizar comentarios.
2125 |
2126 | > El buen código es como un buen chiste - no necesita explicación
2127 | > -- Russ Olsen
2128 |
2129 | * Evita escribir comentarios para explicar código malo. Refactorizá el código
2130 | para hacerlo más auto-explicativo. (Hazlo o no lo hagas - no hay intentos. --Yoda)
2131 |
2132 | ### Apuntes de Comentarios
2133 |
2134 | * Generalmente los apuntes se tienen que escribir inmediatamente en la primer
2135 | línea encima del código a comentar.
2136 | * La palabra clave del apunte es seguida de dos puntos y un espacio, y luego
2137 | una nota que describe el problema.
2138 | * Si se son necesarias varias líneas para describir el problema, las líneas
2139 | subsiguientes tienen que tener una sangría de dos espacios después del `#`.
2140 |
2141 | ```ruby
2142 | def bar
2143 | # FIXME: This has crashed occasionally since v3.2.1. It may
2144 | # be related to the BarBazUtil upgrade.
2145 | baz(:quux)
2146 | end
2147 | ```
2148 |
2149 | * En los casos donde el problema es tan obvio que cualquier documentación
2150 | fuese redundante, los apuntes se pueden dejar al final de esa línea, sin
2151 | ninguna nota. Su uso debe ser la excepción y no la regla.
2152 |
2153 | ```ruby
2154 | def bar
2155 | sleep 100 # OPTIMIZE
2156 | end
2157 | ```
2158 |
2159 | * Usa `TODO` para resaltar funcionalidades faltantes o funcionalidades que
2160 | deben agregarse más adelante.
2161 | * Usa `FIXME` para resaltar código roto que necesita ser arreglado.
2162 | * Usa `OPTIMIZE` para resaltar código lento o ineficiente que pueda causar
2163 | problemas de performance.
2164 | * Usa `HACK` para resaltar código que utilice prácticas cuestionables que
2165 | no se vean bien y que debería ser refactorizado lo antes posible.
2166 | * Usa `REVIEW` para resaltar cualquier cosa que debe ser revisada para
2167 | confirmar que está funcionando como debería. Por ejemplo: `REVIEW: Are
2168 | we sure this is how the client does X currently?`
2169 | * Usa otra palabra como apunte si sentís que sea apropiado, pero asegurate
2170 | de documentarlas en el `README` de tu proyecto o similar.
2171 |
2172 |
2173 | ### Comentarios mágicos (Magic Comments)
2174 |
2175 | *
2176 | Posiciona un comentario mágico sobre todo el código y la documentacion de un archivo
2177 | (exceptuando los [Shebangs](https://es.wikipedia.org/wiki/Shebang), hablaremos de ellos mas adelante).
2178 |
2179 | ```ruby
2180 | # mal
2181 | # Some documentation about Person
2182 |
2183 | # frozen_string_literal: true
2184 | class Person
2185 | end
2186 |
2187 | # bien
2188 | # frozen_string_literal: true
2189 |
2190 | # Some documentation about Person
2191 | class Person
2192 | end
2193 | ```
2194 |
2195 | *
2196 | Posiciona un comentario mágico por debajo del `shebangs` si hay alguno presente en el archivo.
2197 |
2198 | ```ruby
2199 | # mal
2200 | # frozen_string_literal: true
2201 | #!/usr/bin/env ruby
2202 |
2203 | App.parse(ARGV)
2204 |
2205 | # bien
2206 | #!/usr/bin/env ruby
2207 | # frozen_string_literal: true
2208 |
2209 | App.parse(ARGV)
2210 | ```
2211 |
2212 | *
2213 | Usa un comentario mágico por linea, si necesitas usar mas de uno.
2214 |
2215 | ```ruby
2216 | # mal
2217 | # -*- frozen_string_literal: true; encoding: ascii-8bit -*-
2218 |
2219 | # bien
2220 | # frozen_string_literal: true
2221 | # encoding: ascii-8bit
2222 | ```
2223 |
2224 | *
2225 | Separa los comentarios mágicos del resto del código o de la documentacion usando una linea blanca.
2226 |
2227 | ```ruby
2228 | # mal
2229 | # frozen_string_literal: true
2230 | # Some documentation for Person
2231 | class Person
2232 | # Some code
2233 | end
2234 |
2235 | # bien
2236 | # frozen_string_literal: true
2237 |
2238 | # Some documentation for Person
2239 | class Person
2240 | # Some code
2241 | end
2242 | ```
2243 |
2244 | ## Clases y Módulos
2245 |
2246 | * Usa una estructura coherente para definir tu clase.
2247 |
2248 | ```ruby
2249 | class Person
2250 | # extend and include go first
2251 | extend SomeModule
2252 | include AnotherModule
2253 |
2254 | # constants are next
2255 | SOME_CONSTANT = 20
2256 |
2257 | # afterwards we have attribute macros
2258 | attr_reader :name
2259 |
2260 | # followed by other macros (if any)
2261 | validates :name
2262 |
2263 | # public class methods are next in line
2264 | def self.some_method
2265 | end
2266 |
2267 | # followed by public instance methods
2268 | def some_method
2269 | end
2270 |
2271 | # protected and private methods are grouped near the end
2272 | protected
2273 |
2274 | def some_protected_method
2275 | end
2276 |
2277 | private
2278 |
2279 | def some_private_method
2280 | end
2281 | end
2282 | ```
2283 |
2284 | *
2285 | Separa multiples `mixins` con multiples declaraciones (lineas separadas).
2286 |
2287 | ```ruby
2288 | # mal
2289 | class Person
2290 | include Foo, Bar
2291 | end
2292 |
2293 | # bien
2294 | class Person
2295 | # multiple mixins go in separate statements
2296 | include Foo
2297 | include Bar
2298 | end
2299 | ```
2300 |
2301 | *
2302 | No anides Clases multilineales dentro de otra Clase.
2303 | Intenta separar cada una en diferentes archivos dentro de una carpeta
2304 | que se llame como la Clase en la que quieres anidarlas.
2305 | Ejemplo.
2306 |
2307 | ```ruby
2308 | # mal
2309 |
2310 | # foo.rb
2311 | class Foo
2312 | class Bar
2313 | # 30 methods inside
2314 | end
2315 |
2316 | class Car
2317 | # 20 methods inside
2318 | end
2319 |
2320 | # 30 methods inside
2321 | end
2322 |
2323 |
2324 |
2325 | # bien
2326 |
2327 | # foo.rb
2328 | class Foo
2329 | # 30 methods inside
2330 | end
2331 |
2332 | # foo/bar.rb
2333 | class Foo
2334 | class Bar
2335 | # 30 methods inside
2336 | end
2337 | end
2338 |
2339 | # foo/car.rb
2340 | class Foo
2341 | class Car
2342 | # 20 methods inside
2343 | end
2344 | end
2345 | ```
2346 |
2347 | *
2348 | Define (y vuelve a abrir) las Clases y Módulos del Namespace utilizando un anidamiento específico.
2349 | Usando el operador de resolucion de alcance `::` puedes conducir a sorprendentes busquedas de constantes debido al alcance léxico de Ruby
2350 | [lexical scoping](https://cirw.in/blog/constant-lookup.html), que depende del Módulo que se anida desde el punto de la definición.
2351 | Ejemplo.
2352 |
2353 | ```ruby
2354 | module Utilities
2355 | class Queue
2356 | end
2357 | end
2358 |
2359 | # mal
2360 | class Utilities::Store
2361 | Module.nesting # => [Utilities::Store]
2362 |
2363 | def initialize
2364 | # Refers to the top level ::Queue class because Utilities isn't in the
2365 | # current nesting chain.
2366 | @queue = Queue.new
2367 | end
2368 | end
2369 |
2370 | # bien
2371 | module Utilities
2372 | class WaitingList
2373 | Module.nesting # => [Utilities::WaitingList, Utilities]
2374 |
2375 | def initialize
2376 | @queue = Queue.new # Refers to Utilities::Queue
2377 | end
2378 | end
2379 | end
2380 | ```
2381 |
2382 | * Prefiere los módulos a las clases que únicamente tienen métodos de clases.
2383 | Las clases deben ser utilizadas únicamente cuando tiene sentido crear instancias fuera de ellas.
2384 |
2385 | ```ruby
2386 | # mal
2387 | class SomeClass
2388 | def self.some_method
2389 | # body omitted
2390 | end
2391 |
2392 | def self.some_other_method
2393 | end
2394 | end
2395 |
2396 | # bien
2397 | module SomeClass
2398 | module_function
2399 |
2400 | def some_method
2401 | # body omitted
2402 | end
2403 |
2404 | def some_other_method
2405 | end
2406 | end
2407 | ```
2408 |
2409 | * Elige el uso de `module_function` por sobre `extend self` cuando
2410 | quieras cambiar los métodos de instancia de un módulo en un método
2411 | de clase.
2412 |
2413 | ```ruby
2414 | # mal
2415 | module Utilities
2416 | extend self
2417 |
2418 | def parse_something(string)
2419 | # do stuff here
2420 | end
2421 |
2422 | def other_utility_method(number, string)
2423 | # do some more stuff
2424 | end
2425 | end
2426 |
2427 | # bien
2428 | module Utilities
2429 | module_function
2430 |
2431 | def parse_something(string)
2432 | # do stuff here
2433 | end
2434 |
2435 | def other_utility_method(number, string)
2436 | # do some more stuff
2437 | end
2438 | end
2439 | ```
2440 |
2441 | * Cuando diseñes jerarquías de clases, asegurate de que se ajuseten al
2442 | [Principio de Sustitución de Liskov](http://es.wikipedia.org/wiki/Principio_de_sustituci%C3%B3n_de_Liskov).
2443 | * Tratá de hacer tus clases tan
2444 | [SOLID](http://es.wikipedia.org/wiki/SOLID_(object-oriented_design))
2445 | como sea posible.
2446 | * Siempre proporciona un método `to_s` para clases que representen
2447 | objetos de dominio.
2448 |
2449 | ```ruby
2450 | class Person
2451 | attr_reader :first_name, :last_name
2452 |
2453 | def initialize(first_name, last_name)
2454 | @first_name = first_name
2455 | @last_name = last_name
2456 | end
2457 |
2458 | def to_s
2459 | "#{@first_name} #{@last_name}"
2460 | end
2461 | end
2462 | ```
2463 |
2464 | * Usa la familia de funciones `attr` para definir accesores triviales
2465 | o mutators.
2466 |
2467 | ```ruby
2468 | # mal
2469 | class Person
2470 | def initialize(first_name, last_name)
2471 | @first_name = first_name
2472 | @last_name = last_name
2473 | end
2474 |
2475 | def first_name
2476 | @first_name
2477 | end
2478 |
2479 | def last_name
2480 | @last_name
2481 | end
2482 | end
2483 |
2484 | # bien
2485 | class Person
2486 | attr_reader :first_name, :last_name
2487 |
2488 | def initialize(first_name, last_name)
2489 | @first_name = first_name
2490 | @last_name = last_name
2491 | end
2492 | end
2493 | ```
2494 |
2495 | *
2496 | Pra los `accessors` y `mutators`, evita usar prefijos como `get_` and `set_` en los nombres de funciones.
2497 | Es una convención en Ruby usar el nombre del atributo (`attr_name`) para las funciones de tipo (readers) y
2498 | `attr_name=` para mutators (writers).
2499 |
2500 | ```ruby
2501 | # mal
2502 | class Person
2503 | def get_name
2504 | "#{@first_name} #{@last_name}"
2505 | end
2506 |
2507 | def set_name(name)
2508 | @first_name, @last_name = name.split(' ')
2509 | end
2510 | end
2511 |
2512 | # bien
2513 | class Person
2514 | def name
2515 | "#{@first_name} #{@last_name}"
2516 | end
2517 |
2518 | def name=(name)
2519 | @first_name, @last_name = name.split(' ')
2520 | end
2521 | end
2522 | ```
2523 |
2524 | * Evita el uso de `attr`. En su lugar usá `attr_reader` y `attr_accessor`.
2525 |
2526 | ```ruby
2527 | # mal - crea un único accesor de atributo (deprecado en 1.9)
2528 | attr :something, true
2529 | attr :one, :two, :three # behaves as attr_reader
2530 |
2531 | # bien
2532 | attr_accessor :something
2533 | attr_reader :one, :two, :three
2534 | ```
2535 |
2536 | * Considera usar un `Struct.new` para definir una clase.
2537 | `Struct.new` define por ti los accesores triviales,
2538 | constructor y operadores de comparación.
2539 |
2540 | ```ruby
2541 | # bien
2542 | class Person
2543 | attr_reader :first_name, :last_name
2544 |
2545 | def initialize(first_name, last_name)
2546 | @first_name = first_name
2547 | @last_name = last_name
2548 | end
2549 | end
2550 |
2551 | # mucho mejor
2552 | Person = Struct.new(:first_name, :last_name) do
2553 | end
2554 | ````
2555 |
2556 | * No extiendas un `Struct.new` - ya de por si es una clase nueva. Extendiéndolo introduce un nivel de clase superfluo y también puede introducir errores extraños si el archivo es requerido múltiples veces.
2557 |
2558 | ```ruby
2559 | # mal
2560 | class Person < Struct.new(:first_name, :last_name)
2561 | end
2562 |
2563 | # bien
2564 | Person = Struct.new(:first_name, :last_name)
2565 | ```
2566 |
2567 | * Considera agregar un método factory para proveer más formas sensibles
2568 | de crear instancias de una clase en particular.
2569 |
2570 | ```ruby
2571 | class Person
2572 | def self.create(options_hash)
2573 | # body omitted
2574 | end
2575 | end
2576 | ```
2577 |
2578 | * Prefiere [duck-typing](http://es.wikipedia.org/wiki/Duck_typing) en lugar de herencia.
2579 |
2580 | ```ruby
2581 | # mal
2582 | class Animal
2583 | # abstract method
2584 | def speak
2585 | end
2586 | end
2587 |
2588 | # extend superclass
2589 | class Duck < Animal
2590 | def speak
2591 | puts 'Quack! Quack'
2592 | end
2593 | end
2594 |
2595 | # extend superclass
2596 | class Dog < Animal
2597 | def speak
2598 | puts 'Bau! Bau!'
2599 | end
2600 | end
2601 |
2602 | # bien
2603 | class Duck
2604 | def speak
2605 | puts 'Quack! Quack'
2606 | end
2607 | end
2608 |
2609 | class Dog
2610 | def speak
2611 | puts 'Bau! Bau!'
2612 | end
2613 | end
2614 | ```
2615 |
2616 | * Evita el uso de variables de clas (`@@`) debido a sus comportamientos
2617 | "sucios" en la herencia.
2618 |
2619 | ```ruby
2620 | class Parent
2621 | @@class_var = 'parent'
2622 |
2623 | def self.print_class_var
2624 | puts @@class_var
2625 | end
2626 | end
2627 |
2628 | class Child < Parent
2629 | @@class_var = 'child'
2630 | end
2631 |
2632 | Parent.print_class_var # => will print "child"
2633 | ```
2634 |
2635 | Como puedas ver todas las clases en una jerarquía de clases en realidad
2636 | comparten una variable de clase. Por lo general las variables de instancia
2637 | de clase deben ser preferidas a las variables de clase.
2638 |
2639 | * Asigna niveles de visibilidad adecuados para los métodos (`private`,
2640 | `protected`) de acuerdo con su correcto uso. No vayas por ahi dejando
2641 | todo `public` (que es el estado predeterminado). Después de todo
2642 | ahora estamos programando en *Ruby*, no en *Python*.
2643 | * Indenta las palabas `public`, `protected`, y `private` tanto como los
2644 | métodos a los que se aplican. Dejá una línea en blanco antes y después
2645 | del modificador de visibilidad, en orden de enfatizar que eso aplica a
2646 | todos los métodos que se encuentran debajo.
2647 |
2648 | ```ruby
2649 | class SomeClass
2650 | def public_method
2651 | # ...
2652 | end
2653 |
2654 | private
2655 |
2656 | def private_method
2657 | # ...
2658 | end
2659 |
2660 | def another_private_method
2661 | # ...
2662 | end
2663 | end
2664 | ```
2665 |
2666 | * Usa `def self.method` para definir métodos singleton. Eso hace el
2667 | código más fácil de refactorizar, debido a que el nombre de la clase
2668 | no está repetido.
2669 |
2670 | ```ruby
2671 | class TestClass
2672 | # mal
2673 | def TestClass.some_method
2674 | # body omitted
2675 | end
2676 |
2677 | # bien
2678 | def self.some_other_method
2679 | # body omitted
2680 | end
2681 |
2682 | # También es posible y conveniente cuando
2683 | # quieras definir muchos métodos singleton.
2684 | class << self
2685 | def first_method
2686 | # body omitted
2687 | end
2688 |
2689 | def second_method_etc
2690 | # body omitted
2691 | end
2692 | end
2693 | end
2694 | ```
2695 |
2696 | *
2697 | Ten encuenta que el uso de `alias` alcanza a los Métodos que estan dentro de la clase
2698 | al igual que el uso de `self`. Communica claramente a el usuario que el desvío realizado por
2699 | tu alias no alterará a la Clase en tiempo de ejecución ni a las Subclases a menos que se haga de
2700 | forma explícita..
2701 |
2702 | ```ruby
2703 | class Westerner
2704 | def first_name
2705 | @names.first
2706 | end
2707 |
2708 | alias given_name first_name
2709 | end
2710 | ```
2711 |
2712 | Desde que `alias`, al igual que `def`, es una palabra reservada
2713 | úsala preferentemente con palabras normales como argumentos, no con símbolos
2714 | o Strings. Ejemplo. usa `alias foo bar`, not `alias :foo :bar`.
2715 |
2716 | De igual forma ten cuidado en como Ruby maneja los Alias en conjunto con la Herencia.
2717 | Un alias hace referencia al método para el cual fué definido en el tiempo en el que dicho alias fué creado
2718 | y no funcionará dinamicamente
2719 |
2720 | ```ruby
2721 | class Fugitive < Westerner
2722 | def first_name
2723 | 'Nobody'
2724 | end
2725 | end
2726 | ```
2727 |
2728 | En el ejemplo de arriba `Fugitive#given_name` podría seguir llamando
2729 | al Método original de su clase padre `Westerner#first_name` y no a `Fugitive#first_name`.
2730 | Para sobreescribir también el comportamiento de `Fugitive#given_name`, tu tendrías que
2731 | redefinir también el alias en la clase `Fugitive`, como sigue a continuación.
2732 |
2733 | ```ruby
2734 | class Fugitive < Westerner
2735 | def first_name
2736 | 'Nobody'
2737 | end
2738 |
2739 | alias given_name first_name
2740 | end
2741 | ```
2742 |
2743 | *
2744 | Siempre usa `alias_method` cuando quieres renombrar los Métodos de
2745 | un Módulo, Clases o Clases Singleton en tiempo de ejecución,
2746 | de lo contrario al igual que `alias` podría conducir a casos imprevistos.
2747 |
2748 | ```ruby
2749 | module Mononymous
2750 | def self.included(other)
2751 | other.class_eval { alias_method :full_name, :given_name }
2752 | end
2753 | end
2754 |
2755 | class Sting < Westerner
2756 | include Mononymous
2757 | end
2758 | ```
2759 |
2760 | *
2761 | Cuando el Método de una clase (o Módulo) llama a otros Métodos del mismo tipo,
2762 | se omite el uso de `self` o el uso del propio nombre de la Clase seguido por un `.`
2763 |
2764 | Esto se ve muy a menudo en "Clases de Servicio" o en otros conceptos similares
2765 | donde la Clase se trata como si fuera una función. Esta convencion tiende a
2766 | reducir la repetitividad en este tipo de clases.
2767 |
2768 | ```ruby
2769 | class TestClass
2770 | # mal - Pues esta forma genera mucho trabajo
2771 | # cuando la Clase es renombrada o un Métdodo es movido
2772 | def self.call(param1, param2)
2773 | TestClass.new(param1).call(param2)
2774 | end
2775 |
2776 | # mal - mas palabras, que no son necesarias
2777 | def self.call(param1, param2)
2778 | self.new(param1).call(param2)
2779 | end
2780 |
2781 | # bien
2782 | def self.call(param1, param2)
2783 | new(param1).call(param2)
2784 | end
2785 |
2786 | # ...other methods...
2787 | end
2788 | ```
2789 |
2790 | ## Excepciones
2791 |
2792 | * Señaliza las excepciones utilizando el método `fail`. Usa `raise`
2793 | solo cuando quieras atrapar una excepción y quieras volver a
2794 | llamarlo (porque no está fallando, sino que está lanzando una
2795 | excepción de forma explícita y a propósito).
2796 |
2797 | ```ruby
2798 | begin
2799 | fail 'Oops'
2800 | rescue => error
2801 | raise if error.message != 'Oops'
2802 | end
2803 | ```
2804 |
2805 | * No especifiques explícitamente `RuntimeError` en la versión de dos argumentos de
2806 | `fail/raise`.
2807 |
2808 | ```ruby
2809 | # mal
2810 | fail RuntimeError, 'message'
2811 |
2812 | # bien - señaliza un RuntimeError por defecto
2813 | fail 'message'
2814 | ```
2815 |
2816 | * Elige suministrar una clase de excepción y un mensaje como dos
2817 | argumentos separados para `fail/raise`, en lugar de una instancia
2818 | de excepción.
2819 |
2820 | ```ruby
2821 | # mal
2822 | fail SomeException.new('message')
2823 | # No hay una forma de hacer `fail SomeException.new('message'), backtrace`.
2824 |
2825 | # bien
2826 | fail SomeException, 'message'
2827 | # Consistente con `fail SomeException, 'message', backtrace`.
2828 | ```
2829 |
2830 | * Nunca retornes desde un bloque `ensure`. Si retornás de forma explícita
2831 | desde un método dentro de un bloque `ensure`, el retorno va a tomar
2832 | precedente sobre cualquier excepción que sea llamada, y el método va a
2833 | retornar como si ninguna excepción hubiera sido llamada. De hecho, la
2834 | excepción va a ser desestimada en silencio.
2835 |
2836 | ```ruby
2837 | def foo
2838 | begin
2839 | fail
2840 | ensure
2841 | return 'very bad idea'
2842 | end
2843 | end
2844 | ```
2845 |
2846 | * Usa *bloques implícitos de begin* siempre que sea posible.
2847 |
2848 | ```ruby
2849 | # mal
2850 | def foo
2851 | begin
2852 | # main logic goes here
2853 | rescue
2854 | # failure handling goes here
2855 | end
2856 | end
2857 |
2858 | # bien
2859 | def foo
2860 | # main logic goes here
2861 | rescue
2862 | # failure handling goes here
2863 | end
2864 | ```
2865 |
2866 | * Mitigá la proliferación de bloques `begin` utilizando
2867 | *métodos de contingencia* (un término elegido por Avdi Grimm).
2868 |
2869 | ```ruby
2870 | # mal
2871 | begin
2872 | something_that_might_fail
2873 | rescue IOError
2874 | # handle IOError
2875 | end
2876 |
2877 | begin
2878 | something_else_that_might_fail
2879 | rescue IOError
2880 | # handle IOError
2881 | end
2882 |
2883 | # bien
2884 | def with_io_error_handling
2885 | yield
2886 | rescue IOError
2887 | # handle IOError
2888 | end
2889 |
2890 | with_io_error_handling { something_that_might_fail }
2891 |
2892 | with_io_error_handling { something_else_that_might_fail }
2893 | ```
2894 |
2895 | * No suprimas las excepciones.
2896 |
2897 | ```ruby
2898 | # mal
2899 | begin
2900 | # an exception occurs here
2901 | rescue SomeError
2902 | # the rescue clause does absolutely nothing
2903 | end
2904 |
2905 | # mal
2906 | do_something rescue nil
2907 | ```
2908 |
2909 | * Evita usar `rescue` en su forma de modificador.
2910 |
2911 | ```ruby
2912 | # mal - esto atrapa una excepción de la clase StandardError y sus clases hijas
2913 | read_file rescue handle_error($!)
2914 |
2915 | # bien - esto atrapa solo las excepciones de la clase Errno::ENOENT y sus clases hijas
2916 | def foo
2917 | read_file
2918 | rescue Errno::ENOENT => ex
2919 | handle_error(ex)
2920 | end
2921 | ```
2922 |
2923 |
2924 | * No uses excepciones para control de flujo.
2925 |
2926 | ```ruby
2927 | # mal
2928 | begin
2929 | n / d
2930 | rescue ZeroDivisionError
2931 | puts 'Cannot divide by 0!'
2932 | end
2933 |
2934 | # bien
2935 | if d.zero?
2936 | puts 'Cannot divide by 0!'
2937 | else
2938 | n / d
2939 | end
2940 | ```
2941 |
2942 | * Evita rescatar la clase `Exception`. Esto va a atrapar la señal `exit`,
2943 | siendo necesario que pases `kill -9` al proceso para poder terminarlo.
2944 |
2945 | ```ruby
2946 | # mal
2947 | begin
2948 | # calls to exit and kill signals will be caught (except kill -9)
2949 | exit
2950 | rescue Exception
2951 | puts "you didn't really want to exit, right?"
2952 | # exception handling
2953 | end
2954 |
2955 | # bien
2956 | begin
2957 | # a blind rescue rescues from StandardError, not Exception as many
2958 | # programmers assume.
2959 | rescue => e
2960 | # exception handling
2961 | end
2962 |
2963 | # también está bien
2964 | begin
2965 | # an exception occurs here
2966 |
2967 | rescue StandardError => e
2968 | # exception handling
2969 | end
2970 |
2971 | ```
2972 |
2973 | * Escribe excepciones más específicas primero, de otra forma nunca
2974 | van a poder ser atrapadas.
2975 |
2976 | ```ruby
2977 | # mal
2978 | begin
2979 | # some code
2980 | rescue Exception => e
2981 | # some handling
2982 | rescue StandardError => e
2983 | # some handling
2984 | end
2985 |
2986 | # bien
2987 | begin
2988 | # some code
2989 | rescue StandardError => e
2990 | # some handling
2991 | rescue Exception => e
2992 | # some handling
2993 | end
2994 | ```
2995 |
2996 | * Cierra recursos externos abiertos por tu programa en un bloque
2997 | ensure.
2998 |
2999 | ```ruby
3000 | f = File.open('testfile')
3001 | begin
3002 | # .. process
3003 | rescue
3004 | # .. handle error
3005 | ensure
3006 | f.close unless f.nil?
3007 | end
3008 | ```
3009 |
3010 | *
3011 | Usa versionesde Méetodos de recursos que automaticamente limpian cuando es posible.
3012 |
3013 | ```ruby
3014 | # mal - tu debes cerrar especificamente el archivo
3015 | f = File.open('testfile')
3016 | # some action on the file
3017 | f.close
3018 |
3019 | # bien - El archivo se cerrará automaticamente
3020 | File.open('testfile') do |f|
3021 | # some action on the file
3022 | end
3023 | ```
3024 |
3025 | * Prefiere el uso de excepciones de la standard library en lugar
3026 | de crear nuevas clases de excepciones.
3027 |
3028 | ## Colecciones
3029 |
3030 | * Prefiere el uso de la notación para arrays literales y creación de hashes
3031 | (excepto que necesites pasar parámetros a sus constructores).
3032 |
3033 | ```ruby
3034 | # mal
3035 | arr = Array.new
3036 | hash = Hash.new
3037 |
3038 | # bien
3039 | arr = []
3040 | hash = {}
3041 | ```
3042 |
3043 | * Prefiere usar `%w` en lugar de la sintaxis array literal cuando
3044 | necesites un array de palabras (strings no-vacías sin espacios ni
3045 | caracteres espaciles en cada uno). Aplicá esta regla solo en los arrays
3046 | de dos o más elementos.
3047 |
3048 | ```ruby
3049 | # mal
3050 | STATES = ['draft', 'open', 'closed']
3051 |
3052 | # bien
3053 | STATES = %w(draft open closed)
3054 | ```
3055 |
3056 | * Prefiere `%i` en lugar de la sintaxis de array literal cuando
3057 | necesites un array de símbolos (y no necesitás mantener compatibilidad
3058 | con Ruby 1.9). Aplicá esta regla sólo para arrays con dos o más
3059 | elementos.
3060 |
3061 | ```ruby
3062 | # mal
3063 | STATES = [:draft, :open, :closed]
3064 |
3065 | # bien
3066 | STATES = %i(draft open closed)
3067 | ```
3068 |
3069 | * Evita la creación de grandes espacios en arrays.
3070 |
3071 | ```ruby
3072 | arr = []
3073 | arr[100] = 1 # y así tenés un array con un montón de nils
3074 | ```
3075 |
3076 | * Cuando estés accediendo al primer o último elmento de un array, prefiere
3077 | usar `first` o `last` en lugar de `[0]` o `[-1]`.
3078 |
3079 | * Usa `Set` en lugar de `Array` cuando estés tratando con elementos
3080 | únicos. `Set` implementa una colección de valores desordenados sin
3081 | duplicados. Esto es un híbrido de la vacilidad interoperacional
3082 | intuitiva de `Array`, y velocidad de lectura de `Hash`.
3083 |
3084 | ```ruby
3085 | require 'set'
3086 | s = Set.new [4,1,1,1,2] # => #
3087 | ```
3088 |
3089 | * Prefiere símbolos en lugar de strings y hash keys.
3090 |
3091 | ```ruby
3092 | # mal
3093 | hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
3094 |
3095 | # bien
3096 | hash = { one: 1, two: 2, three: 3 }
3097 | ```
3098 |
3099 | * Evita el uso de objetos mutables como hash keys.
3100 | * Usa la sintaxis de hash literal cuando tus hash keys sean símbolos.
3101 |
3102 | ```ruby
3103 | # mal
3104 | hash = { :one => 1, :two => 2, :three => 3 }
3105 |
3106 | # bien
3107 | hash = { one: 1, two: 2, three: 3 }
3108 | ```
3109 | *
3110 | No mezcles la sintaxis de Ruby 1.9 con las flechas de hash en la misma definicion de hash
3111 | Usa las flechas solamente cuando la clave del hash no es un Símbolo.
3112 |
3113 | ```ruby
3114 | # mal
3115 | { a: 1, 'b' => 2 }
3116 |
3117 | # bien
3118 | { :a => 1, 'b' => 2 }
3119 | ```
3120 |
3121 | * Usa `Hash#key?` en lugar de `Hash#has_key?` y `Hash#value?` en lugar de
3122 | `Hash#has_value?`. Como dice Matz
3123 | [aquí](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/43765),
3124 | Las funciones largas están consideradas deprecadas.
3125 |
3126 | ```ruby
3127 | # mal
3128 | hash.has_key?(:test)
3129 | hash.has_value?(value)
3130 |
3131 | # bien
3132 | hash.key?(:test)
3133 | hash.value?(value)
3134 | ```
3135 |
3136 | *
3137 | Usa `Hash#each_key` en vez de `Hash#keys.each` y
3138 | `Hash#each_value` en vez de `Hash#values.each`.
3139 |
3140 | ```ruby
3141 | # bad
3142 | hash.keys.each { |k| puts k }
3143 | hash.values.each { |v| puts v }
3144 | hash.each { |k, _v| puts k }
3145 | hash.each { |_k, v| puts v }
3146 |
3147 | # good
3148 | hash.each_key { |k| puts k }
3149 | hash.each_value { |v| puts v }
3150 | ```
3151 |
3152 | * Usa `Hash#fetch` cuando estés tratando con hash keys que deben estar
3153 | presentes.
3154 |
3155 | ```ruby
3156 | heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
3157 | # mal - si generamos un error, puede que no lo veamos rápido
3158 | heroes[:batman] # => "Bruce Wayne"
3159 | heroes[:supermann] # => nil
3160 |
3161 | # bien - fetch genera un KeyError, haciendo obvios los problemas
3162 | heroes.fetch(:supermann)
3163 | ```
3164 |
3165 | * Utiliza valores por defecto para hash keys usando `Hash#fetch`, opuesto a generar tu
3166 | propia lógica.
3167 |
3168 | ```ruby
3169 | batman = { name: 'Bruce Wayne', is_evil: false }
3170 |
3171 | # mal - si solo usamos el operador || y tenemos valor falso, no vamos a tener el resultado esperado
3172 | batman[:is_evil] || true # => true
3173 |
3174 | # bien - fetch trabaja mejor con valores falsos
3175 | # si la variable no está definida, obtienes el valor por defecto, en este caso true
3176 | # si la variable está definida, obtienes el valor de la variable, en este caso false
3177 | batman.fetch(:is_evil, true) # => false
3178 | ```
3179 |
3180 | * Prefiere el uso de bloques en lugar del formato por defecto de `Hash#fetch`.
3181 |
3182 | ```ruby
3183 | batman = { name: 'Bruce Wayne' }
3184 |
3185 | # mal - si usamos el valor por defecto, se va a evaluar en el momento
3186 | # por lo que vamos a relantizar el programa, si se utiliza múltiples veces
3187 | batman.fetch(:powers, get_batman_powers) # get_batman_powers is an expensive call
3188 |
3189 | # bien - los bloques se evalúan sin bloquer el proceso, asi solo se llama en caso de una excepción KeyError
3190 | batman.fetch(:powers) { get_batman_powers }
3191 | ```
3192 |
3193 | *
3194 | Usa `Hash#values_at` cuando quieras obtener muchos valores consecutivamente del Hash.
3195 |
3196 | ```ruby
3197 | # mal
3198 | email = data['email']
3199 | username = data['nickname']
3200 |
3201 | # bien
3202 | email, username = data.values_at('email', 'nickname')
3203 | ```
3204 |
3205 | * Confía en el hecho de que desde Ruby 1.9 los hashes están ordenados.
3206 | * Nunca modifiques una colección mientras la estés recorriendo.
3207 |
3208 | *
3209 | Cuando accedas a los elementos de una Coleción, evita el acceso directo
3210 | usando `[n]`, para esto puedes usar una forma alternativa de lectura
3211 | Esto puede salvarte de estar llamando `[]` sobre un valor `nil`.
3212 |
3213 | ```ruby
3214 | # mal
3215 | Regexp.last_match[1]
3216 |
3217 | # bien
3218 | Regexp.last_match(1)
3219 | ```
3220 |
3221 | *
3222 | Si provees una acceso a una coleccion, provee tambien una forma alternativa
3223 | se salvar a los usuarios de obtener un `nil` antes de accesar al elemento en la Colección
3224 |
3225 | ```ruby
3226 | # mal
3227 | def awesome_things
3228 | @awesome_things
3229 | end
3230 |
3231 | # bien
3232 | def awesome_things(index = nil)
3233 | if index && @awesome_things
3234 | @awesome_things[index]
3235 | else
3236 | @awesome_things
3237 | end
3238 | end
3239 | ```
3240 |
3241 |
3242 | ## Números
3243 |
3244 | *
3245 | Usa `Integer` para probar el tipo de un número entero.
3246 | desde que `Fixnum` depende de la plataforma, chequeando el valor de la variable
3247 | con él dará resultados diferentes dependiendo la arquitectura de la máquin 32-bit o 64-bit.
3248 |
3249 | ```ruby
3250 | timestamp = Time.now.to_i
3251 |
3252 | # mal
3253 | timestamp.is_a? Fixnum
3254 | timestamp.is_a? Bignum
3255 |
3256 | # bien
3257 | timestamp.is_a? Integer
3258 | ```
3259 |
3260 | *
3261 | Prefiere el uso de Rangos para generar numeros aleatorios.
3262 |
3263 | ```ruby
3264 | # mal
3265 | rand(6) + 1
3266 |
3267 | # bien
3268 | rand(1..6)
3269 | ```
3270 |
3271 |
3272 | ## Strings
3273 |
3274 | * Prefiere interpolación de strings en lugar de concatenación de strings:
3275 |
3276 | ```ruby
3277 | # mal
3278 | email_with_name = user.name + ' <' + user.email + '>'
3279 |
3280 | # bien
3281 | email_with_name = "#{user.name} <#{user.email}>"
3282 |
3283 | # mejor
3284 | email_with_name = format('%s <%s>', user.name, user.email)
3285 | ```
3286 |
3287 | * Considera el uso de interpolación de string con espacio. Hace que sea más claro
3288 | para separar el código del string.
3289 |
3290 | ```ruby
3291 | "#{ user.last_name }, #{ user.first_name }"
3292 | ```
3293 |
3294 | * Prefiere escribir los con una sola comilla cuando no tengás la necesidad de
3295 | realizar interpolación o usar símbolos especiales como `\t`, `\n`, `'`, etc.
3296 |
3297 | ```ruby
3298 | # mal
3299 | name = "Bozhidar"
3300 |
3301 | # bien
3302 | name = 'Bozhidar'
3303 |
3304 | # bien
3305 | name = "De'Andre"
3306 |
3307 | ```
3308 |
3309 | * Prefiere usar comillas dobles `""` a menos que el String
3310 | contenga `"` o caracteres de escape que quieras suprimir.
3311 |
3312 | ```ruby
3313 | # mal
3314 | sarcasm = "I \"like\" it."
3315 |
3316 | # bien
3317 | sarcasm = 'I "like" it.'
3318 | ```
3319 | * No uses el caracter literal de sintaxis `?x`. Desde Ruby 1.0 esto
3320 | se hizo redundante - `?x` se interpreta como `'x'` (un string con
3321 | solo un caracter dentro).
3322 |
3323 | ```ruby
3324 | # mal
3325 | char = ?c
3326 |
3327 | # bien
3328 | char = 'c'
3329 | ```
3330 |
3331 | * No dejes de usar `{}` alrededor de las variables de instancia o
3332 | globales, siendo interpolados dentro de un string.
3333 |
3334 | ```ruby
3335 | class Person
3336 | attr_reader :first_name, :last_name
3337 |
3338 | def initialize(first_name, last_name)
3339 | @first_name = first_name
3340 | @last_name = last_name
3341 | end
3342 |
3343 | # mal - válido, pero raro
3344 | def to_s
3345 | "#@first_name #@last_name"
3346 | end
3347 |
3348 | # bien
3349 | def to_s
3350 | "#{@first_name} #{@last_name}"
3351 | end
3352 | end
3353 |
3354 | $global = 0
3355 | # mal
3356 | puts "$global = #$global"
3357 |
3358 | # bien
3359 | puts "$global = #{$global}"
3360 | ```
3361 |
3362 | *
3363 | No uses `Object#to_s` para interpolar objectos. Esa Función se llama automaticamente.
3364 |
3365 | ```ruby
3366 | # mal
3367 | message = "This is the #{result.to_s}."
3368 |
3369 | # bien
3370 | message = "This is the #{result}."
3371 | ```
3372 |
3373 | * Evita usar `String#+` cuando necesites construir un pedazo grande de datos.
3374 | En su lugar usá `String#<<`. Concatenación muta la instancia del string en el
3375 | lugar y siempre es más rápido que `String#+`, el cual crea un grupo de nuevos
3376 | objetos de strings.
3377 |
3378 | ```ruby
3379 | # bien y rápido además
3380 | html = ''
3381 | html << 'Page title
'
3382 |
3383 | paragraphs.each do |paragraph|
3384 | html << "#{paragraph}
"
3385 | end
3386 | ```
3387 |
3388 | * Cuando estés usando heredocs para strings multi-línea no te olvides
3389 | del hecho de que ellos necesitan espacios en blanco. Es una buena
3390 | práctica utilizar algo de margen basado en cómo hay que recortar
3391 | el espacio en blanco excesivo.
3392 |
3393 | ```ruby
3394 | code = <<-END.gsub(/^\s+\|/, '')
3395 | |def test
3396 | | some_method
3397 | | other_method
3398 | |end
3399 | END
3400 | #=> "def test\n some_method\n other_method\nend\n"
3401 | ```
3402 |
3403 | *
3404 | Usa delimitadores descriptivos para los [Heredoc](https://es.wikipedia.org/wiki/Here_document)
3405 | Delimitadores correctos pueden agregar informacion valiosa acerca del contenido.
3406 | Algunos Editores de Texto son capaces de reconocer los delimitadores y destacar el contenido
3407 | usando el "Highlight" correspondiente
3408 |
3409 | ```ruby
3410 | # mal
3411 | code = <<~END
3412 | def foo
3413 | bar
3414 | end
3415 | END
3416 |
3417 | # bien
3418 | code = <<~RUBY
3419 | def foo
3420 | bar
3421 | end
3422 | RUBY
3423 |
3424 | # bien
3425 | code = <<~SUMMARY
3426 | An imposing black structure provides a connection between the past and
3427 | the future in this enigmatic adaptation of a short story by revered
3428 | sci-fi author Arthur C. Clarke.
3429 | SUMMARY
3430 | ```
3431 |
3432 | ## Date & Time
3433 |
3434 | *
3435 | Prefiere `Time.now` por sobre `Time.new` cuando tratas de obtener el tiempo actual del sistema.
3436 |
3437 | *
3438 | No uses `DateTime` a menos que necesites crear un Calendario Historico
3439 | y si lo haces especifica explicitamente en el argumento el `inicio` para
3440 | dejar clara tus intenciones.
3441 |
3442 | ```ruby
3443 | # mal - uso de 'DateTime' para el tiempo actual del sistema
3444 | DateTime.now
3445 |
3446 | # bien - uso de 'Time' para el tiempo actual del sistema
3447 | Time.now
3448 |
3449 | # mal - uso de 'DateTime' para una fecha actual
3450 | DateTime.iso8601('2016-06-29')
3451 |
3452 | # bien - uso 'Date' para una fecha actual
3453 | Date.iso8601('2016-06-29')
3454 |
3455 | # bien - uso de 'DateTime' con un argumento extra para representar una fecha histórica
3456 | DateTime.iso8601('1751-04-23', Date::ENGLAND)
3457 | ```
3458 |
3459 | ## Expresiones Regulares
3460 |
3461 | > Algunas personas, cuando se encuentran un problema, piensan
3462 | > "Ya se, voy a usar expresiones regulares." Ahora tienen dos problemas.
3463 | > -- Jamie Zawinski
3464 |
3465 | * No uses expresiones regulares si solo necesitás buscar texto plano en un string:
3466 | `string['text']`
3467 | * Para construcciones simples puedes usar la `regexp` directamente como índice de string.
3468 |
3469 | ```ruby
3470 | match = string[/regexp/] # get content of matched regexp
3471 | first_group = string[/text(grp)/, 1] # get content of captured group
3472 | string[/text (grp)/, 1] = 'replace' # string => 'text replace'
3473 | ```
3474 |
3475 | * Usa grupos que no capturen código cuando no uses resultados capturados con paréntesis.
3476 |
3477 | ```ruby
3478 | /(first|second)/ # mal
3479 | /(?:first|second)/ # bien
3480 | ```
3481 |
3482 | * No uses las variables crípticas de Perl, que denoten las pocisiones de los resultados de regex
3483 | (`$1`, `$2`, etc). En su lugar usá `Regexp.last_match[n]`.
3484 |
3485 | ```ruby
3486 | /(regexp)/ =~ string
3487 | ...
3488 |
3489 | # mal
3490 | process $1
3491 |
3492 | # bien
3493 | process Regexp.last_match[1]
3494 | ```
3495 |
3496 |
3497 | * Evita usar grupos numerados, ya que puede ser difícil de decir qué contienen. En su lugar
3498 | deben usarse grupos con nombre.
3499 |
3500 | ```ruby
3501 | # mal
3502 | /(regexp)/ =~ string
3503 | ...
3504 | process Regexp.last_match[1]
3505 |
3506 | # bien
3507 | /(?regexp)/ =~ string
3508 | ...
3509 | process meaningful_var
3510 | ```
3511 |
3512 | * Clases de caracteres únicamente tienen caracteres especiales que te deberían importar:
3513 | `^`, `-`, `\`, `]`, por lo que no debes escapar `.` o llaves en `[]`.
3514 |
3515 | * Tiene cuidado con `^` y `$`, ya que ellos se igualan con el inicio/final de la línea,
3516 | no el final del string. Si querés igualar el string completo usá: `\A` y `\z` (no
3517 | confundir con `\Z` el cual es el equivalente de `/\n?\z/`).
3518 |
3519 | ```ruby
3520 | string = "some injection\nusername"
3521 | string[/^username$/] # matches
3522 | string[/\Ausername\z/] # don't match
3523 | ```
3524 |
3525 | * Usa el modificador `x` para regexps complejos. Esto los hace más legibles y
3526 | vas a poder agregar mejores comentarios. Pero tené cuidado, que los espacios
3527 | son ignorados.
3528 |
3529 | ```ruby
3530 | regexp = %r{
3531 | start # some text
3532 | \s # white space char
3533 | (group) # first group
3534 | (?:alt1|alt2) # some alternation
3535 | end
3536 | }x
3537 | ```
3538 |
3539 | * Para cambios complejos se pueden usar `sub`/`gsub` con un bloque o un hash.
3540 |
3541 | ```ruby
3542 | words = 'foo bar'
3543 | words.sub(/f/, 'f' => 'F') # => 'Foo bar'
3544 | words.gsub(/\w+/) { |word| word.capitalize } # => 'Foo Bar'
3545 |
3546 |
3547 | ## Porcentajes Literales
3548 |
3549 | * Usa `%()` (es un alias para `%Q`) para un string de una línea, el cual requiere tanto
3550 | interpolación y uso de comillas dobles. Para strings multi-línea, es preferible usar heredocs.
3551 |
3552 | ```ruby
3553 | # mal (no necesita interpolación)
3554 | %(Some text
)
3555 | # should be 'Some text
'
3556 |
3557 | # mal (no tiene comillas dobles)
3558 | %(This is #{quality} style)
3559 | # Debería ser "This is #{quality} style"
3560 |
3561 | # mal (múltiples líneas)
3562 | %(\n#{exclamation}\n
)
3563 | # debería ser un heredoc.
3564 |
3565 | # bien (requiere interpolación, tiene comillas, y es una sola línea)
3566 | %(#{name} | )
3567 | ```
3568 |
3569 | * Evita `%q`, excepto que tengas un string con `'` y `"` dentro.
3570 | Los strings literales son más legibles y deberían ser elegidos,
3571 | excepto que tengamos que escapar un montón de caracteres internos.
3572 |
3573 | ```ruby
3574 | # mal
3575 | name = %q(Bruce Wayne)
3576 | time = %q(8 o'clock)
3577 | question = %q("What did you say?")
3578 |
3579 | # bien
3580 | name = 'Bruce Wayne'
3581 | time = "8 o'clock"
3582 | question = '"What did you say?"'
3583 | ```
3584 |
3585 | * Usa `%r` solo para expresiones regulares que igualen *a más de un* caracter `/`.
3586 |
3587 | ```ruby
3588 | # mal
3589 | %r(\s+)
3590 |
3591 | # todavía está mal
3592 | %r(^/(.*)$)
3593 | # debería ser /^\/(.*)$/
3594 |
3595 | # bien
3596 | %r(^/blog/2011/(.*)$)
3597 | ```
3598 |
3599 | * Evita el uso de `%x`, excepto que ya estés invocando un comando con comillas contrarias (que es bastante inusual).
3600 |
3601 | ```ruby
3602 | # mal
3603 | date = %x(date)
3604 |
3605 | # bien
3606 | date = `date`
3607 | echo = %x(echo `date`)
3608 | ```
3609 |
3610 | * Evita el uso de `%s`. Parece que la comunidad decidió que `:"some string"`
3611 | es la forma preferida para crear un símbolo con espacios dentro.
3612 |
3613 |
3614 | *
3615 | Usa los paréntesis que sean mas apropiados dependiento del tipo de "Porcentaje Literal" que desees usar.
3616 |
3617 | - `()` para String literales(`%q`, `%Q`).
3618 | - `[]` para Array literales(`%w`, `%i`, `%W`, `%I`) al igual que los Array normales.
3619 | - `{}` Para regexp literales(`%r`) a menos que la expresión regular contenga paréntesis de llave `{}`.
3620 | La idea es usar un caracter poco común en la expresión regular. (Por ejemplo `||`)
3621 | - `()` Para todos los otros literales (por ejemplo: `%s`, `%x`)
3622 |
3623 | ```ruby
3624 | # mal
3625 | %q{"Test's king!", John said.}
3626 |
3627 | # bien
3628 | %q("Test's king!", John said.)
3629 |
3630 | # mal
3631 | %w(one two three)
3632 | %i(one two three)
3633 |
3634 | # bien
3635 | %w[one two three]
3636 | %i[one two three]
3637 |
3638 | # mal
3639 | %r((\w+)-(\d+))
3640 | %r{\w{1,2}\d{2,5}}
3641 |
3642 | # bien
3643 | %r{(\w+)-(\d+)}
3644 | %r|\w{1,2}\d{2,5}|
3645 |
3646 |
3647 | ## Metaprogramación
3648 |
3649 | * Evita metaprogramación innecesaria.
3650 |
3651 | * No hagas lío con las clases core cuando estés escribiendo bibliotecas.
3652 | (No uses monkey-patch.)
3653 |
3654 | * La forma de bloque de `class_eval` es preferible en forma de interpolación de string.
3655 | - cuando uses la forma de interpolación de string, siempre usá `__FILE__` y `__LINE__`,
3656 | asi la búsqueda de código tiene sentido:
3657 |
3658 | ```ruby
3659 | class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__
3660 | ```
3661 |
3662 | - `define_method` es mejor que `class_eval{ def ... }`
3663 |
3664 | * Cuando uses `class_eval` (u otro `eval`) con interpolación de string, agrega un bloque de comentario que muestra su apariencia si está interpolada (una práctica que aprendí con el código de Rails):
3665 |
3666 | ```ruby
3667 | # from activesupport/lib/active_support/core_ext/string/output_safety.rb
3668 | UNSAFE_STRING_METHODS.each do |unsafe_method|
3669 | if 'String'.respond_to?(unsafe_method)
3670 | class_eval <<-EOT, __FILE__, __LINE__ + 1
3671 | def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)
3672 | to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block)
3673 | end # end
3674 |
3675 | def #{unsafe_method}!(*args) # def capitalize!(*args)
3676 | @dirty = true # @dirty = true
3677 | super # super
3678 | end # end
3679 | EOT
3680 | end
3681 | end
3682 | ```
3683 |
3684 | * Evita usar `method_missing` para metaprogramación, ya que hace dificil leer el código, el comportamiento no está listado en `#methods`, y las llamadas a métodos mal escritas pueden funcionar silienciosamente, ejemplo: `nukes.launch_state = false`. En su lugar, considerá usar delegation, proxy o `define_method`. Si es necesario, usá `method_missing`:
3685 |
3686 | - Está seguro de [también definir `respond_to_missing?`](http://blog.marc-andre.ca/2010/11/methodmissing-politely.html)
3687 | - Solo atrapá métodos con un prefix bien definido, como `find_by_*` -- hacé tu código lo más asertivo posible.
3688 | - Llamá a `super` al final de tu definición
3689 | - Delegá en métodos asertivos, no mágicos:
3690 |
3691 | ```ruby
3692 | # mal
3693 | def method_missing?(meth, *args, &block)
3694 | if /^find_by_(?.*)/ =~ meth
3695 | # ... lots of code to do a find_by
3696 | else
3697 | super
3698 | end
3699 | end
3700 |
3701 | # bien
3702 | def method_missing?(meth, *args, &block)
3703 | if /^find_by_(?.*)/ =~ meth
3704 | find_by(prop, *args, &block)
3705 | else
3706 | super
3707 | end
3708 | end
3709 |
3710 | # best of all, though, would to define_method as each findable attribute is declared
3711 | ```
3712 |
3713 | *
3714 | Prefiere `public_send` por sobre `send` para no eludir la visibilidad `private`/`protected`.
3715 |
3716 | ```ruby
3717 | # Tenemos una organización ActiveModel que incluye Activatable
3718 | module Activatable
3719 | extend ActiveSupport::Concern
3720 |
3721 | included do
3722 | before_create :create_token
3723 | end
3724 |
3725 | private
3726 |
3727 | def reset_token
3728 | # some code
3729 | end
3730 |
3731 | def create_token
3732 | # some code
3733 | end
3734 |
3735 | def activate!
3736 | # some code
3737 | end
3738 | end
3739 |
3740 | class Organization < ActiveRecord::Base
3741 | include Activatable
3742 | end
3743 |
3744 | linux_organization = Organization.find(...)
3745 | # MAL - viola la privacidad
3746 | linux_organization.send(:reset_token)
3747 | # Bien - debería arrojar una excepción
3748 | linux_organization.public_send(:reset_token)
3749 | ```
3750 |
3751 | *
3752 | Prefiere `__send__` por sobre `send`, ya que `send` puede superponerse a métodos existentes.
3753 |
3754 | ```ruby
3755 | require 'socket'
3756 |
3757 | u1 = UDPSocket.new
3758 | u1.bind('127.0.0.1', 4913)
3759 | u2 = UDPSocket.new
3760 | u2.connect('127.0.0.1', 4913)
3761 | # No enviará un mensaje al objeto receptor.
3762 | # En cambio enviará un mensaje via UDP socket.
3763 | u2.send :sleep, 0
3764 | # Si enviará un mensaje al objeto receptor.
3765 | u2.__send__ ...
3766 | ```
3767 |
3768 |
3769 | ## Varios
3770 |
3771 | * Escribe código seguro con `ruby -w`.
3772 | * Evita los hashes como un parámetro opcional. Acaso el método hace demasiado? (Los
3773 | inicializadores de objetos son excepciones a esta regla).
3774 | * Evita métodos mayores que 10 LOC (lines of code). Idealmente, la mayoría de los métodos van
3775 | a ser menores que 5 LOC. Líneas vacías no cuentan como LOC relevantes.
3776 | * Evita listas de parámetros mayores que tres o cuatro parámetros.
3777 | * Si realmente necesitás métodos "globales", agregalos a tu Kernel
3778 | y convertilos en `private`.
3779 | * Usa variables de instancia en módulos en lugar de variables globales.
3780 |
3781 | ```ruby
3782 | # mal
3783 | $foo_bar = 1
3784 |
3785 | # bien
3786 | module Foo
3787 | class << self
3788 | attr_accessor :bar
3789 | end
3790 | end
3791 |
3792 | Foo.bar = 1
3793 | ```
3794 |
3795 | * Evita `alias` cuando `alias_method` hace mejor el trabajo.
3796 | * Usa `OptionParser` para parsear líneas de opciones de comando complejas
3797 | y `ruby -s` para líneas de opciones de comando triviales.
3798 | * Escribe código en forma funcional, evitando mutación cuando eso tenga sentido.
3799 | * No mutes argumentos excepto que ese sea el propósito del método.
3800 | * Evita más de tres niveles de anidación de bloques.
3801 | * Se consistente. En un mundo ideal, se consistente con estas guías.
3802 | * Usa el sentido común.
3803 |
3804 | ## Herramientas
3805 |
3806 | Aquí hay algunas herramientas que pueden ayudarte a validar el código
3807 | Ruby de forma automática con esta guía.
3808 |
3809 | ### RuboCop
3810 |
3811 | [RuboCop](https://github.com/bbatsov/rubocop) es un validador de código
3812 | Ruby basado en esta guía. RuboCop actualmente cubre una significante parte
3813 | de esta Guía, soportando tanto MRI 1.9 y MRI 2.0, y ya tiene integración
3814 | con Emacs.
3815 |
3816 | ### RubyMine
3817 |
3818 | El código de inspección de [RubyMine](http://www.jetbrains.com/ruby/) está
3819 | [parcialmente basado](http://confluence.jetbrains.com/display/RUBYDEV/RubyMine+Inspections)
3820 | en esta guía.
3821 |
3822 | # Aportes
3823 |
3824 | Nada de lo que está en esta guía está escrito en piedra. Es mi deseo que
3825 | trabajemos juntos con todos los que estén interesados con el estilo de
3826 | código en Ruby, para que podamos crear un recurso que pueda beneficiar a
3827 | toda la comunidad de Ruby.
3828 |
3829 | Siéntanse libres de abrir tickets o enviar pull requests con mejoras. ¡Desde
3830 | ya muchas gracias por su ayuda!
3831 |
3832 | # Licencia
3833 |
3834 | 
3835 | Este trabajo está licenciado bajo [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/deed.en_US)
3836 |
3837 | # Corre la Voz
3838 |
3839 | Una guía de estilos pensada para la comunidad es de poca ayuda para
3840 | esa comunidad si no conoce su existencia. Escribe tweets sobre la guía,
3841 | compartila con tus amigos y compañeros de trabajo. Cada comentario,
3842 | sugerencia u opinión hace que la guía sea un poco mejor. Y lo que más
3843 | queremos que la mejor guía posible, ¿verdad?
3844 |
3845 | Saludos,
3846 | [Bozhidar](https://twitter.com/bbatsov)
3847 |
--------------------------------------------------------------------------------