├── .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 | ![Creative Commons License](http://i.creativecommons.org/l/by/3.0/88x31.png) 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 | --------------------------------------------------------------------------------