diff options
Diffstat (limited to 'es-es')
-rw-r--r-- | es-es/brainfuck-es.html.markdown | 18 | ||||
-rw-r--r-- | es-es/git-es.html.markdown | 14 | ||||
-rw-r--r-- | es-es/javascript-es.html.markdown | 20 | ||||
-rw-r--r-- | es-es/json-es.html.markdown | 16 | ||||
-rw-r--r-- | es-es/markdown-es.html.markdown | 6 | ||||
-rw-r--r-- | es-es/ruby-es.html.markdown | 247 |
6 files changed, 260 insertions, 61 deletions
diff --git a/es-es/brainfuck-es.html.markdown b/es-es/brainfuck-es.html.markdown index e33d672d..550511da 100644 --- a/es-es/brainfuck-es.html.markdown +++ b/es-es/brainfuck-es.html.markdown @@ -9,8 +9,10 @@ lang: es-es --- Brainfuck (con mayúscula sólo al inicio de una oración) es un -lenguaje de programación mínimo, computacionalmente universal -en tamaño con sólo 8 comandos. +lenguaje de programación extremadamente pequeño, Turing completo con sólo 8 comandos. + +Puedes probar brainfuck en tu navegador con [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/). + ``` @@ -18,7 +20,7 @@ Cualquier caracter que no sea "><+-.,[]" (sin incluir las comillas) será ignorado. Brainfuck es representado por un arreglo de 30,000 celdas inicializadas -en cero y un apuntador en la celda actual. +en cero y un puntero apuntando la celda actual. Existen ocho comandos: @@ -26,7 +28,7 @@ Existen ocho comandos: - : Decrementa 1 al valor de la celda actual. > : Mueve el apuntador a la siguiente celda. (a la derecha) < : Mueve el apuntador a la celda anterior. (a la izquierda) -. : Imprime el valor en ASCII de la celda actual (i.e. 65 = 'A') +. : Imprime el valor en ASCII de la celda actual (p.e. 65 = 'A') , : Lee un caracter como input y lo escribe en la celda actual. [ : Si el valor en la celda actual es cero mueve el apuntador hasta el primer ']' que encuentre. Si no es cero sigue a la @@ -37,7 +39,7 @@ Existen ocho comandos: [ y ] forman un while. Obviamente, deben estar balanceados. -Ahora unos ejemplos de programas escritos con brainfuck. +Estos son algunos ejemplos de programas escritos con brainfuck. ++++++ [ > ++++++++++ < - ] > +++++ . @@ -63,7 +65,7 @@ Esto continúa hasta que la celda #1 contenga un cero. Cuando #1 contenga un cero la celda #2 tendrá el valor inicial de #1. Como este ciclo siempre terminara en la celda #1 nos movemos a la celda #2 e imprimimos (.). -Ten en mente que los espacios son sólo para fines de legibilidad. +Ten en cuenta que los espacios son sólo para fines de legibilidad. Es lo mismo escribir el ejemplo de arriba que esto: ,[>+<-]>. @@ -81,7 +83,7 @@ hasta la próxima vez. Para resolver este problema también incrementamos la celda #4 y luego copiamos la celda #4 a la celda #2. La celda #3 contiene el resultado. ``` -Y eso es brainfuck. ¿No tan difícil o sí? Como diversión, puedes escribir +Y eso es brainfuck. No es tan difícil, ¿verdad? Como diversión, puedes escribir tu propio intérprete de brainfuck o tu propio programa en brainfuck. El intérprete es relativamente sencillo de hacer, pero si eres masoquista, -intenta construir tu proprio intérprete de brainfuck... en brainfuck. +puedes intentar construir tu propio intérprete de brainfuck... en brainfuck. diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown index 18b544b4..4e1e68ba 100644 --- a/es-es/git-es.html.markdown +++ b/es-es/git-es.html.markdown @@ -18,11 +18,11 @@ versionar y administrar nuestro código fuente. ## Versionamiento, conceptos. -### Qué es el control de versiones? +### ¿Qué es el control de versiones? El control de versiones es un sistema que guarda todos los cambios realizados en uno o varios archivos, a lo largo del tiempo. -### Versionamiento centralizado vs Versionamiento Distribuido. +### Versionamiento centralizado vs versionamiento distribuido. + El versionamiento centralizado se enfoca en sincronizar, rastrear, y respaldar archivos. @@ -33,9 +33,9 @@ uno o varios archivos, a lo largo del tiempo. [Información adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones) -### Por qué usar Git? +### ¿Por qué usar Git? -* Se puede trabajar sin conexion. +* Se puede trabajar sin conexión. * ¡Colaborar con otros es sencillo!. * Derivar, crear ramas del proyecto (aka: Branching) es fácil. * Combinar (aka: Merging) @@ -47,7 +47,7 @@ uno o varios archivos, a lo largo del tiempo. ### Repositorio Un repositorio es un conjunto de archivos, directorios, registros, cambios (aka: -comits), y encabezados (aka: heads). Imagina que un repositorio es una clase, +commits), y encabezados (aka: heads). Imagina que un repositorio es una clase, y que sus atributos otorgan acceso al historial del elemento, además de otras cosas. @@ -62,12 +62,12 @@ y mas. ### Directorio de trabajo (componentes del repositorio) -Es basicamente los directorios y archivos dentro del repositorio. La mayoría de +Es básicamente los directorios y archivos dentro del repositorio. La mayoría de las veces se le llama "directorio de trabajo". ### Índice (componentes del directorio .git) -El índice es el área de inicio en git. Es basicamente la capa que separa el +El índice es el área de inicio en git. Es básicamente la capa que separa el directorio de trabajo del repositorio en git. Esto otorga a los desarrolladores más poder sobre lo que se envía y se recibe del repositorio. diff --git a/es-es/javascript-es.html.markdown b/es-es/javascript-es.html.markdown index d475cf42..9ef0c63e 100644 --- a/es-es/javascript-es.html.markdown +++ b/es-es/javascript-es.html.markdown @@ -30,7 +30,7 @@ Aunque JavaScript no sólo se limita a los navegadores web: Node.js, Un proyecto // Cada sentencia puede ser terminada con punto y coma ; hazAlgo(); -// ... aunque no es necesario, ya que el punto y coma se agrega automaticamente +// ... aunque no es necesario, ya que el punto y coma se agrega automáticamente // cada que se detecta una nueva línea, a excepción de algunos casos. hazAlgo() @@ -109,7 +109,7 @@ null == undefined; // = true null === undefined; // false // Los Strings funcionan como arreglos de caracteres -// Puedes accesar a cada caracter con la función charAt() +// Puedes acceder a cada caracter con la función charAt() "Este es un String".charAt(0); // = 'E' // ...o puedes usar la función substring() para acceder a pedazos más grandes @@ -186,7 +186,7 @@ miObjeto.miLlave; // = "miValor" // agregar nuevas llaves. miObjeto.miTerceraLlave = true; -// Si intentas accesar con una llave que aún no está asignada tendrás undefined. +// Si intentas acceder con una llave que aún no está asignada tendrás undefined. miObjeto.miCuartaLlave; // = undefined /////////////////////////////////// @@ -301,7 +301,7 @@ i; // = 5 - en un lenguaje que da ámbitos por bloque esto sería undefined, per //inmediatamente", que preveé variables temporales de fugarse al ámbito global (function(){ var temporal = 5; - // Podemos accesar al ámbito global asignando al 'objeto global', el cual + // Podemos acceder al ámbito global asignando al 'objeto global', el cual // en un navegador siempre es 'window'. El objeto global puede tener // un nombre diferente en ambientes distintos, por ejemplo Node.js . window.permanente = 10; @@ -321,7 +321,7 @@ function decirHolaCadaCincoSegundos(nombre){ alert(texto); } setTimeout(interna, 5000); - // setTimeout es asíncrono, así que la funcion decirHolaCadaCincoSegundos + // setTimeout es asíncrono, así que la función decirHolaCadaCincoSegundos // terminará inmediatamente, y setTimeout llamará a interna() a los cinco segundos // Como interna está "cerrada dentro de" decirHolaCadaCindoSegundos, interna todavía tiene // acceso a la variable 'texto' cuando es llamada. @@ -339,7 +339,7 @@ var miObjeto = { }; miObjeto.miFuncion(); // = "¡Hola Mundo!" -// Cuando las funciones de un objeto son llamadas, pueden accesar a las variables +// Cuando las funciones de un objeto son llamadas, pueden acceder a las variables // del objeto con la palabra clave 'this'. miObjeto = { miString: "¡Hola Mundo!", @@ -401,11 +401,11 @@ var MiConstructor = function(){ miNuevoObjeto = new MiConstructor(); // = {miNumero: 5} miNuevoObjeto.miNumero; // = 5 -// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a accesar a una +// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a acceder a una // propiedad en un objeto que no existe en el objeto el intérprete buscará en // el prototipo. -// Algunas implementaciones de JavaScript te permiten accesar al prototipo de +// Algunas implementaciones de JavaScript te permiten acceder al prototipo de // un objeto con la propiedad __proto__. Mientras que esto es útil para explicar // prototipos, no es parte del estándar; veremos formas estándar de usar prototipos // más adelante. @@ -440,7 +440,7 @@ miPrototipo.sentidoDeLaVida = 43; miObjeto.sentidoDeLaVida; // = 43 // Mencionabamos anteriormente que __proto__ no está estandarizado, y que no -// existe una forma estándar de accesar al prototipo de un objeto. De todas formas. +// existe una forma estándar de acceder al prototipo de un objeto. De todas formas. // hay dos formas de crear un nuevo objeto con un prototipo dado. // El primer método es Object.create, el cual es una adición reciente a JavaScript, @@ -476,7 +476,7 @@ typeof miNumero; // = 'number' typeof miNumeroObjeto; // = 'object' miNumero === miNumeroObjeyo; // = false if (0){ - // Este código no se ejecutara porque 0 es false. + // Este código no se ejecutará porque 0 es false. } // Aún así, los objetos que envuelven y los prototipos por defecto comparten diff --git a/es-es/json-es.html.markdown b/es-es/json-es.html.markdown index fff678eb..c98049f9 100644 --- a/es-es/json-es.html.markdown +++ b/es-es/json-es.html.markdown @@ -21,22 +21,22 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead "llaves": "siempre debe estar entre comillas (ya sean dobles o simples)", "numeros": 0, "strings": "Høla, múndo. Todo el unicode está permitido, así como \"escapar\".", - "soporta booleanos?": true, - "vacios": null, + "¿soporta booleanos?": true, + "vacíos": null, "numero grande": 1.2e+100, "objetos": { - "comentario": "La mayoria de tu estructura vendra de objetos.", + "comentario": "La mayoría de tu estructura vendrá de objetos.", "arreglo": [0, 1, 2, 3, "Los arreglos pueden contener cualquier cosa.", 5], "otro objeto": { - "comentario": "Estas cosas pueden estar anidadas, muy util." + "comentario": "Estas cosas pueden estar anidadas, muy útil." } }, - "tonteria": [ + "tontería": [ { "fuentes de potasio": ["bananas"] }, @@ -50,10 +50,10 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead "estilo alternativo": { "comentario": "Mira esto!" - , "posicion de la coma": "no importa - mientras este antes del valor, entonces sera valido" - , "otro comentario": "que lindo" + , "posición de la coma": "no importa - mientras este antes del valor, entonces sera válido" + , "otro comentario": "qué lindo" }, - "eso fue rapido": "Y, estas listo. Ahora sabes todo lo que JSON tiene para ofrecer." + "eso fue rapido": "Y, estás listo. Ahora sabes todo lo que JSON tiene para ofrecer." } ``` diff --git a/es-es/markdown-es.html.markdown b/es-es/markdown-es.html.markdown index d90e3eb5..bc481df7 100644 --- a/es-es/markdown-es.html.markdown +++ b/es-es/markdown-es.html.markdown @@ -11,7 +11,7 @@ lang: es-es Markdown fue creado por John Gruber en 2004. Su propósito es ser una sintaxis fácil de leer y escribir que se convierta fácilmente a HTML (y, actualmente, otros formatos también). -¡Denme todo la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests! +¡Denme toda la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests! ```markdown @@ -44,7 +44,7 @@ Esto es un h2 ------------- <!-- Estilos para texto plano --> -<!-- El texto puede ser fácilmente estilizaedo con italicas, negritas o tachado +<!-- El texto puede ser fácilmente estilizado con italicas, negritas o tachado usando markdown --> *Este texto está en itálicas.* @@ -62,7 +62,7 @@ Markdown en Github, también tenemos: --> ~~Este texto está tachado.~~ -<!-- Los párrafos son una o múltuples líneas de texto adyacentes separadas por +<!-- Los párrafos son una o múltiples líneas de texto adyacentes separadas por una o múltiples líneas en blanco--> Este es un párrafo. Estoy escribiendo un párrafo, ¿No es divertido? diff --git a/es-es/ruby-es.html.markdown b/es-es/ruby-es.html.markdown index 66a5d0fe..d8b67fe7 100644 --- a/es-es/ruby-es.html.markdown +++ b/es-es/ruby-es.html.markdown @@ -5,8 +5,18 @@ contributors: - ["David Underwood", "http://theflyingdeveloper.com"] - ["Joel Walden", "http://joelwalden.net"] - ["Luke Holder", "http://twitter.com/lukeholder"] + - ["Tristan Hume", "http://thume.ca/"] + - ["Nick LaMuro", "https://github.com/NickLaMuro"] + - ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"] + - ["Ariel Krakowski", "http://www.learneroo.com"] + - ["Dzianis Dashkevich", "https://github.com/dskecse"] + - ["Levi Bostian", "https://github.com/levibostian"] + - ["Rahil Momin", "https://github.com/iamrahil"] + - ["Gabriel Halley", "https://github.com/ghalley"] + - ["Persa Zula", "http://persazula.com"] translators: - ["Camilo Garrido", "http://www.twitter.com/hirohope"] + - ["Erick Bernal", "http://www.twitter.com/billowkib"] lang: es-es --- @@ -33,6 +43,8 @@ Tu tampoco deberías 8 - 1 #=> 7 10 * 2 #=> 20 35 / 5 #=> 7 +2**5 #=> 32 +5 % 3 #=> 2 # La aritmética es sólo azúcar sintáctico # para llamar un método de un objeto @@ -55,8 +67,6 @@ false.class #=> FalseClass # Desigualdad 1 != 1 #=> false 2 != 1 #=> true -!true #=> false -!false #=> true # Además de 'false', 'nil' es otro valor falso @@ -70,14 +80,29 @@ false.class #=> FalseClass 2 <= 2 #=> true 2 >= 2 #=> true +# Operadores lógicos +true && false #=> false +true || false #=> true +!true #=> false + +# Existen versiones alternativas de los operadores lógicos con menor prioridad +# Estos son usados como constructores controladores de flujo que encadenan +# sentencias hasta que una de ellas retorne verdadero o falso + +# `has_otra_cosa` solo se llama si `has_algo` retorna verdadero. +has_algo() and has_otra_cosa() +# `registra_error` solo se llama si `has_algo` falla +has_algo() or registra_error() + + # Los strings son objetos 'Soy un string'.class #=> String "Soy un string también".class #=> String -referente = "usar interpolacion de strings" +referente = "usar interpolación de strings" "Yo puedo #{referente} usando strings de comillas dobles" -#=> "Yo puedo usar interpolacion de strings usando strings de comillas dobles" +#=> "Yo puedo usar interpolación de strings usando strings de comillas dobles" # Imprime a la salida estándar @@ -119,15 +144,16 @@ status == :aprovado #=> false # Arreglos # Esto es un arreglo -[1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] +arreglo = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] # Arreglos pueden contener elementos de distintos tipos -arreglo = [1, "hola", false] #=> => [1, "hola", false] +[1, "hola", false] #=> => [1, "hola", false] # Arreglos pueden ser indexados # Desde el frente arreglo[0] #=> 1 +arreglo.first #=> 1 arreglo[12] #=> nil # Tal como la aritmética, el acceso como variable[índice] @@ -138,15 +164,25 @@ arreglo.[] 12 #=> nil # Desde el final arreglo[-1] #=> 5 +arreglo.last #=> 5 + +# Con un índice de inicio y longitud +arreglo[2, 3] #=> [3, 4, 5] -# Con un índice de inicio y final -arreglo[2, 4] #=> [3, 4, 5] +# Invertir un arreglo +a = [1, 2, 3] +a.reverse! #=> [3, 2, 1] # O con rango arreglo[1..3] #=> [2, 3, 4] # Añade elementos a un arreglo así arreglo << 6 #=> [1, 2, 3, 4, 5, 6] +# O así +arreglo.push(6) #=> [1, 2, 3, 4, 5, 6] + +#Verifica si un elemento ya existe en ese arreglo +arreglo.include?(1) #=> true # Hashes son los diccionarios principales de Ruby con pares llave/valor. # Hashes se denotan con llaves: @@ -161,17 +197,16 @@ hash['numero'] #=> 5 # Preguntarle a un hash por una llave que no existe retorna 'nil': hash['nada aqui'] #=> nil -# Itera sobre un hash con el método 'each': -hash.each do |k, v| - puts "#{k} is #{v}" -end - # Desde Ruby 1.9, hay una sintaxis especial cuando se usa un símbolo como llave: nuevo_hash = { defcon: 3, accion: true} nuevo_hash.keys #=> [:defcon, :accion] +# Verifica la existencia de llaves y valores en el hash +new_hash.has_key?(:defcon) #=> true +new_hash.has_value?(3) #=> true + # Tip: Tanto los arreglos como los hashes son Enumerable (enumerables) # Comparten muchos métodos útiles tales como 'each', 'map', 'count', y más @@ -194,9 +229,15 @@ end #=> iteracion 4 #=> iteracion 5 -# Aunque -# Nadie usa los ciclos `for` -# Usa `each`, así: +# SIN EMBARGO, nadie usa ciclos `for` +# En su lugar debes usar el método "each" y pasarle un block (bloque). +# Un bloque es un fragmento código que puedes pasar a métodos como `each`. +# Es símilar a las funciones lambda, funciones anónimas o `closures` en otros +# lenguajes de programación. +# +# El método `each` de un Range (rango) ejecuta el bloque una vez por cada elemento. +# Al bloque se le pasa un contador como parametro. +# Usar el método `each` con un bloque se ve así: (1..5).each do |contador| puts "iteracion #{contador}" @@ -207,10 +248,27 @@ end #=> iteracion 4 #=> iteracion 5 -counter = 1 -while counter <= 5 do - puts "iteracion #{counter}" - counter += 1 +# También puedes envolver el bloque entre llaves: +(1..5).each { |counter| puts "iteración #{contador}" } + +#El contenido de las estructuras de datos en ruby puede ser iterado usando `each`. +arreglo.each do |elemento| + puts "#{elemento} es parte del arreglo" +end +hash.each do |llave, valor| + puts "#{llave} es #{valor}" +end + +# Si aún necesitas un índice puedes usar "each_with_index" y definir una variable +# índice. +arreglo.each_with_index do |element, index| + puts "#{element} tiene la posición #{index} en el arreglo" +end + +contador = 1 +while contador <= 5 do + puts "iteracion #{contador}" + contador += 1 end #=> iteracion 1 #=> iteracion 2 @@ -218,6 +276,19 @@ end #=> iteracion 4 #=> iteracion 5 +# Hay una gran variedad de otras funciones iterativas útiles en Ruby, +# por ejemplo `map`, `reduce`, `inject`, entre otras. Map, por ejemplo, +# toma el arreglo sobre el cuál está iterando, le hace cambios +# definidos en el bloque, y retorna un arreglo completamente nuevo. +arreglo = [1,2,3,4,5] +duplicado = array.map do |elemento| + elemento * 2 +end +puts duplicado +#=> [2,4,6,8,10] +puts array +#=> [1,2,3,4,5] + nota = 'B' case nota @@ -234,6 +305,34 @@ when 'F' else puts "Sistema alternativo de notas, ¿eh?" end +#=> "Mejor suerte para la proxima" + +# Los casos también pueden usar rangos +nota = 82 + +case nota +when 90..100 + puts 'Excelente!' +when 80..100 + puts 'Buen trabajo' +else + puts '¡Reprobaste!' +end +#=> "Buen trabajo" + +# Manejo de excepciones +begin + # código que podría causar excepción + raise NoMemoryError, 'Se te acabó la memoria' +rescue NoMemoryError => variable_de_excepcion + puts 'El error NoMemoryError ocurrió', variable_de_excepcion +rescue RuntimeError => otra_variable_de_excepcion + puts 'El error RuntimeError ocurrió' +else + puts 'Esto se ejecuta si ningun error ocurrió' +ensure + puts 'Este código siempre se ejecuta, sin importar que' +end # Funciones @@ -244,7 +343,7 @@ end # Funciones (y todos los bloques) implícitamente retornan el valor de la última instrucción doble(2) #=> 4 -# Paréntesis son opcionales cuando el resultado es ambiguo +# Paréntesis son opcionales cuando el resultado no es ambiguo doble 3 #=> 6 doble doble 3 #=> 12 @@ -259,7 +358,7 @@ suma 3, 4 #=> 7 suma suma(3,4), 5 #=> 12 # yield -# Todos los métodos tienen un parámetro de bloqueo opcional e implícitp +# Todos los métodos tienen un parámetro bloque opcional e implícito # puede llamarse con la palabra clave 'yield' def alrededor @@ -274,6 +373,17 @@ alrededor { puts 'hola mundo' } # hola mundo # } +# Puedes pasar un bloque a una función +# '&' representa una referencia a un bloque +def visitantes(&bloque) + bloque.call +end + +# Puedes pasar una lista de argumentos, que serán convertidos en un arreglo +# Para eso sirve el operador ('*') +def visitantes(*arreglo) + arreglo.each { |visitante| puts visitante } +end # Define una clase con la palabra clave 'class' class Humano @@ -299,16 +409,26 @@ class Humano @nombre end + # La funcionalidad anterior puede ser encapsulada usando el método attr_accessor + # de la siguiente manera + + attr_accessor :name + + # Los métodos de tipo getter y setter también se pueden crear de manera individual + # de la siguiente manera + + attr_reader :name + attr_writer :name + # Un método de clase usa 'self' (sí mismo) para distinguirse de métodos de instancia. # Sólo puede ser llamado en la clase, no por una instancia. def self.decir(mensaje) - puts "#{mensaje}" + puts mensaje end def especie @@especie end - end @@ -328,6 +448,23 @@ dwight.nombre #=> "Dwight K. Schrute" # Llama el método de clase Humano.decir("Hi") #=> "Hi" +# El alcance de las variables es definido por la manera en que las nombramos. +# Las variables que inician con $ tienen un alcance global +$var = "Soy una variable global" +defined? $var #=> "global-variable" + +# Las variables que empiezan con @ tienen un alcance de instancia +@var = "Soy una variable de instancia" +defined? @var #=> "instance-variable" + +# Variables que empiezan con @@ tienen un alcance de clase +@@var = "Soy una variable de clase" +defined? @@var #=> "class variable" + +# Las variables que empiezan con letra mayuscula son constantes +Var = "Soy una constante" +defined? Var #=> "constant" + # Las clases también son un objeto en ruby. Por lo cual, las clases también pueden tener variables de instancia. # Variables de clase son compartidas a través de la clase y todos sus descendientes. @@ -371,7 +508,67 @@ end class Doctor < Humano end -Human.bar # 0 +Humano.bar # 0 Doctor.bar # nil +module ModuloEjemplo + def foo + 'foo' + end +end + +# Al incluir un módulo sus métodos se comparten con las instancias de la clase +# Al extender un módulo sus métodos se comparten con la clase misma + +class Persona + include ModuloEjemplo +end + +class Libro + extend ModuloEjemplo +end + +Persona.foo # => NoMethodError: undefined method `foo' for Persona:Class +Persona.new.foo # => 'foo' +Libro.foo # => 'foo' +Libro.new.foo # => NoMethodError: undefined method `foo' + +# Las llamadas de retorno (callbacks) son ejecutadas cuando se incluye o +# extiende un módulo +module EjemploConcern + def self.incluido(base) + base.extend(MetodosClase) + base.send(:include, MetodosInstancia) + end + + module MetodosClase + def bar + 'bar' + end + end + + module MetodosInstancia + def qux + 'qux' + end + end +end + +class Algo + include EjemploConcern +end + +Algo.bar #=> 'bar' +Algo.qux #=> NoMethodError: undefined method `qux' +Algo.new.bar # => NoMethodError: undefined method `bar' +Algo.new.qux # => 'qux' ``` + +## Recursos adicionales +- [Aprende Ruby Mediante Ejemplo con Ejercicios](http://www.learneroo.com/modules/61/nodes/338) - Una variante de +esta referencia con ejercicios en navegador. +- [Documentación Oficial](http://www.ruby-doc.org/core-2.1.1/) +- [Ruby desde otros lenguajes](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/) +- [Programando Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - Una +[edición antigua](http://ruby-doc.com/docs/ProgrammingRuby/) gratuita disponible en línea. +- [Guía de estilo de Ruby](https://github.com/bbatsov/ruby-style-guide) - Guía de estilo creada por la comunidad. |