diff options
Diffstat (limited to 'es-es')
-rw-r--r-- | es-es/amd-es.html.markdown | 214 | ||||
-rw-r--r-- | es-es/brainfuck-es.html.markdown | 18 | ||||
-rw-r--r-- | es-es/c++-es.html.markdown | 829 | ||||
-rw-r--r-- | es-es/git-es.html.markdown | 170 | ||||
-rw-r--r-- | es-es/javascript-es.html.markdown | 27 | ||||
-rw-r--r-- | es-es/json-es.html.markdown | 16 | ||||
-rw-r--r-- | es-es/julia-es.html.markdown | 14 | ||||
-rw-r--r-- | es-es/latex-es.html.markdown | 213 | ||||
-rw-r--r-- | es-es/markdown-es.html.markdown | 6 | ||||
-rw-r--r-- | es-es/php-es.html.markdown | 825 | ||||
-rw-r--r-- | es-es/python3-es.html.markdown | 8 | ||||
-rw-r--r-- | es-es/ruby-es.html.markdown | 253 | ||||
-rw-r--r-- | es-es/swift-es.html.markdown | 596 | ||||
-rw-r--r-- | es-es/tmux-es.html.markdown | 253 | ||||
-rw-r--r-- | es-es/visualbasic-es.html.markdown | 286 |
15 files changed, 3569 insertions, 159 deletions
diff --git a/es-es/amd-es.html.markdown b/es-es/amd-es.html.markdown new file mode 100644 index 00000000..7a59ddd6 --- /dev/null +++ b/es-es/amd-es.html.markdown @@ -0,0 +1,214 @@ +--- + +category: tool +tool: amd +contributors: + - ["Frederik Ring", "https://github.com/m90"] + +translators: + - ["Damaso Sanoja", "https://github.com/damasosanoja"] +filename: learnamd-es.js +lang: es-es +--- + +## Iniciando con AMD + +El API del **Módulo de Definición Asíncrono** especifica un mecanismo para definir módulos JavaScript de manera tal que tanto el módulo como sus dependencias puedan ser cargadas de manera asíncrona. Esto es particularmente adecuado para el entorno del navegador donde la carga sincronizada de los módulos genera problemas de rendimiento, usabilidad, depuración y acceso de multi-dominios. + +### Conceptos básicos +```javascript +// El API básico de AMD consiste en tan solo dos métodos: `define` y `require` +// y se basa en la definición y consumo de los módulos: +// `define(id?, dependencias?, fábrica)` define un módulo +// `require(dependencias, callback)` importa un conjunto de dependencias y +// las consume al invocar el callback + +// Comencemos usando define para definir un nuevo módulo +// que no posee dependencias. Lo haremos enviando un nombre +// y una función fábrica para definirla: +define('awesomeAMD', function(){ + var isAMDAwesome = function(){ + return true; + }; + // El valor que regresa la función fábrica del módulo será + // lo que los otros módulos o llamados require recibirán cuando + // soliciten nuestro módulo `awesomeAMD`. + // El valor exportado puede ser cualquier cosa, funciones (constructores), + // objetos, primitivos, incluso indefinidos (aunque eso no ayuda mucho). + return isAMDAwesome; +}); + +// Ahora definamos otro módulo que dependa de nuestro módulo `awesomeAMD`. +// Observe que ahora hay un argumento adicional que define +// las dependencias de nuestro módulo: +define('loudmouth', ['awesomeAMD'], function(awesomeAMD){ + // las dependencias serán enviadas a los argumentos de la fábrica + // en el orden que sean especificadas + var tellEveryone = function(){ + if (awesomeAMD()){ + alert('This is sOoOo rad!'); + } else { + alert('Pretty dull, isn\'t it?'); + } + }; + return tellEveryone; +}); + +// Como ya sabemos utilizar define usemos ahora `require` para poner en marcha +// nuestro programa. La firma de `require` es `(arrayOfDependencies, callback)`. +require(['loudmouth'], function(loudmouth){ + loudmouth(); +}); + +// Para hacer que este tutorial corra código, vamos a implementar una +// versión muy básica (no-asíncrona) de AMD justo aquí: +function define(name, deps, factory){ + // observa como son manejados los módulos sin dependencias + define[name] = require(factory ? deps : [], factory || deps); +} + +function require(deps, callback){ + var args = []; + // primero recuperemos todas las dependencias que necesita + // el llamado require + for (var i = 0; i < deps.length; i++){ + args[i] = define[deps[i]]; + } + // satisfacer todas las dependencias del callback + return callback.apply(null, args); +} +// puedes ver este código en acción aquí: http://jsfiddle.net/qap949pd/ +``` + +### Uso en el mundo real con require.js + +En contraste con el ejemplo introductorio, `require.js` (la librería AMD más popular) implementa la **A** de **AMD**, permitiéndote cargar los módulos y sus dependencias asincrónicamente via XHR: + +```javascript +/* file: app/main.js */ +require(['modules/someClass'], function(SomeClass){ + // el callback es diferido hasta que la dependencia sea cargada + var thing = new SomeClass(); +}); +console.log('So here we are, waiting!'); // esto correrá primero +``` + +Por convención, usualmente guardas un módulo en un fichero. `require.js` puede resolver los nombres de los módulos basados en rutas de archivo, de forma que no tienes que nombrar tus módulos, simplemente referenciarlos usando su ubicación. En el ejemplo `someClass` asumimos que se ubica en la carpeta `modules`, relativa a tu `baseUrl` configurada: + +* app/ + * main.js + * modules/ + * someClass.js + * someHelpers.js + * ... + * daos/ + * things.js + * ... + +Esto significa que podemos definir `someClass` sin especificar su id de módulo: + +```javascript +/* file: app/modules/someClass.js */ +define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){ + // definición de módulo, por supuesto, ocurrirá también asincrónicamente + function SomeClass(){ + this.method = function(){/**/}; + // ... + } + return SomeClass; +}); +``` + +Para alterar el comportamiento del mapeo de ruta usa `requirejs.config(configObj)` en tu `main.js`: + +```javascript +/* file: main.js */ +requirejs.config({ + baseUrl : 'app', + paths : { + // también puedes cargar módulos desde otras ubicaciones + jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min', + coolLibFromBower : '../bower_components/cool-lib/coollib' + } +}); +require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){ + // un fichero `main` necesita llamar a require al menos una vez, + // de otra forma jamás correrá el código + coolLib.doFancyStuffWith(helpers.transform($('#foo'))); +}); +``` +Las aplicaciones basadas en `require.js` usualmente tendrán un solo punto de entrada (`main.js`) que se pasa a la etiqueta del script `require.js` como un atributo de datos. Será cargado y ejecutado automáticamente al cargar la página: + +```html +<!DOCTYPE html> +<html> +<head> + <title>Cien etiquetas de script? Nunca más!</title> +</head> +<body> + <script src="require.js" data-main="app/main"></script> +</body> +</html> +``` + +### Optimizar todo un proyecto usando r.js + +Muchas personas prefieren usar AMD para la organización del código durante el desarrollo, pero quieren enviar para producción un solo fichero en vez de ejecutar cientos de XHRs en las cargas de página. + +`require.js` incluye un script llamado `r.js` (el que probablemente correrás en node.js, aunque Rhino también es soportado) que puede analizar el gráfico de dependencias de tu proyecto, y armar un solo fichero que contenga todos tus módulos (adecuadamente nombrados), minificado y listo para consumo. + +Instálalo usando `npm`: +```shell +$ npm install requirejs -g +``` + +Ahora puedes alimentarlo con un fichero de configuración: +```shell +$ r.js -o app.build.js +``` + +Para nuestro ejemplo anterior el archivo de configuración luciría así: +```javascript +/* file : app.build.js */ +({ + name : 'main', // nombre del punto de entrada + out : 'main-built.js', // nombre del fichero donde se escribirá la salida + baseUrl : 'app', + paths : { + // `empty:` le dice a r.js que esto aún debe ser cargado desde el CDN, usando + // la ubicación especificada en `main.js` + jquery : 'empty:', + coolLibFromBower : '../bower_components/cool-lib/coollib' + } +}) +``` + +Para usar el fichero creado en producción, simplemente intercambia `data-main`: +```html +<script src="require.js" data-main="app/main-built"></script> +``` + +Un increíblemente detallado [resumen de opciones de generación](https://github.com/jrburke/r.js/blob/master/build/example.build.js) está disponible en el repositorio de GitHub. + +### Tópicos no cubiertos en este tutorial +* [Cargador de plugins / transformaciones](http://requirejs.org/docs/plugins.html) +* [Cargando y exportando estilos CommonJS](http://requirejs.org/docs/commonjs.html) +* [Configuración avanzada](http://requirejs.org/docs/api.html#config) +* [Configuración de Shim (cargando módulos no-AMD)](http://requirejs.org/docs/api.html#config-shim) +* [Cargando y optimizando CSS con require.js](http://requirejs.org/docs/optimization.html#onecss) +* [Usando almond.js para construcciones](https://github.com/jrburke/almond) + +### Otras lecturas: + +* [Especificaciones oficiales](https://github.com/amdjs/amdjs-api/wiki/AMD) +* [¿Por qué AMD?](http://requirejs.org/docs/whyamd.html) +* [Definición Universal de Módulos](https://github.com/umdjs/umd) + +### Implementaciones: + +* [require.js](http://requirejs.org) +* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/) +* [cujo.js](http://cujojs.com/) +* [curl.js](https://github.com/cujojs/curl) +* [lsjs](https://github.com/zazl/lsjs) +* [mmd](https://github.com/alexlawrence/mmd) 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/c++-es.html.markdown b/es-es/c++-es.html.markdown new file mode 100644 index 00000000..bcc775e5 --- /dev/null +++ b/es-es/c++-es.html.markdown @@ -0,0 +1,829 @@ +--- +language: c++ +filename: learncpp.cpp +contributors: + - ["Steven Basart", "http://github.com/xksteven"] + - ["Matt Kline", "https://github.com/mrkline"] + - ["Geoff Liu", "http://geoffliu.me"] + - ["Connor Waters", "http://github.com/connorwaters"] +translators: + - ["Gerson Lázaro", "https://gersonlazaro.com"] +lang: es-es +--- + +C++ es un lenguaje de programación de sistemas que, +[de acuerdo a su inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote), +fue diseñado para + +- ser un "mejor C" +- soportar abstracción de datos +- soportar programación orientada a objetos +- soportar programación genérica + +Aunque su sintaxis puede ser más difícil o compleja que los nuevos lenguajes, +es ampliamente utilizado, ya que compila instrucciones nativas que pueden ser +directamente ejecutadas por el procesador y ofrece un estricto control sobre +el hardware (como C), mientras ofrece características de alto nivel como +genericidad, excepciones, y clases. Esta combinación de velocidad y +funcionalidad hace de C ++ uno de los lenguajes de programación más utilizados. + +```c++ +//////////////////// +// Comparación con C +//////////////////// + +// C ++ es _casi_ un superconjunto de C y comparte su sintaxis básica para las +// declaraciones de variables, tipos primitivos y funciones. + +// Al igual que en C, el punto de entrada de tu programa es una función llamada +// main con un retorno de tipo entero. +// Este valor sirve como código de salida del programa. +// Mira http://en.wikipedia.org/wiki/Exit_status para mayor información. +int main(int argc, char** argv) +{ + // Los argumentos de la línea de comandos se pasan por argc y argv de la + // misma manera que en C. + // argc indica el número de argumentos, + // y argv es un arreglo de strings de estilo C (char*) + // representando los argumentos. + // El primer argumento es el nombre con el que el programa es llamado. + // argc y argv pueden omitirse si no te preocupan los argumentos, + // dejando la definición de la función como int main () + + // Un estado de salida 0 indica éxito. + return 0; +} + +// Sin embargo, C ++ varía en algunas de las siguientes maneras: + +// En C++, los caracteres literales son caracteres +sizeof('c') == sizeof(char) == 1 + +// En C, los caracteres literales son enteros +sizeof('c') == sizeof(int) + + +// C++ tiene prototipado estricto +void func(); // función que no acepta argumentos + +// En C +void func(); // función que puede aceptar cualquier número de argumentos + +// Use nullptr en lugar de NULL en C++ +int* ip = nullptr; + +// Las cabeceras (headers) estándar de C están disponibles en C ++, +// pero tienen el prefijo "c" y no tienen sufijo .h. +#include <cstdio> + +int main() +{ + printf("Hola mundo!\n"); + return 0; +} + +////////////////////////// +// Sobrecarga de funciones +////////////////////////// + +// C++ soporta sobrecarga de funciones +// siempre que cada función tenga diferentes parámetros. + +void print(char const* myString) +{ + printf("String %s\n", myString); +} + +void print(int myInt) +{ + printf("Mi entero es %d", myInt); +} + +int main() +{ + print("Hello"); // Resolves to void print(const char*) + print(15); // Resolves to void print(int) +} + +//////////////////////////////////// +// Argumentos de función por defecto +//////////////////////////////////// + +// Puedes proporcionar argumentos por defecto para una función si no son +// proporcionados por quien la llama. + +void doSomethingWithInts(int a = 1, int b = 4) +{ + // Hacer algo con los enteros aqui +} + +int main() +{ + doSomethingWithInts(); // a = 1, b = 4 + doSomethingWithInts(20); // a = 20, b = 4 + doSomethingWithInts(20, 5); // a = 20, b = 5 +} + +// Los argumentos predeterminados deben estar al final de la lista de argumentos. + +void invalidDeclaration(int a = 1, int b) // Error! +{ +} + +///////////////////// +// Espacios de nombre +///////////////////// + +// Espacios de nombres proporcionan ámbitos separados para variable, función y +// otras declaraciones. +// Los espacios de nombres se pueden anidar. + +namespace First { + namespace Nested { + void foo() + { + printf("Esto es First::Nested::foo\n"); + } + } // fin del nombre de espacio Nested +} // fin del nombre de espacio First + +namespace Second { + void foo() + { + printf("Esto es Second::foo\n") + } +} + +void foo() +{ + printf("Este es global: foo\n"); +} + +int main() +{ + + // Incluye todos los símbolos del espacio de nombre Second en el ámbito + // actual. Tenga en cuenta que simplemente foo() no funciona, ya que ahora + // es ambigua si estamos llamando a foo en espacio de nombres Second o en + // el nivel superior. + using namespace Second; + + Second::foo(); // imprime "Esto es Second::foo" + First::Nested::foo(); // imprime "Esto es First::Nested::foo" + ::foo(); // imprime "Este es global: foo" +} + +///////////////// +// Entrada/Salida +///////////////// + +// La entrada y salida de C++ utiliza flujos (streams) +// cin, cout, y cerr representan a stdin, stdout, y stderr. +// << es el operador de inserción >> es el operador de extracción. + + +#include <iostream> // Incluir para el flujo de entrada/salida + +using namespace std; // Los streams estan en std namespace (libreria estandar) + +int main() +{ + int myInt; + + // Imprime a la stdout (o terminal/pantalla) + cout << "Ingresa tu número favorito:\n"; + // Toma una entrada + cin >> myInt; + + // cout puede también ser formateado + cout << "Tu número favorito es " << myInt << "\n"; + // imprime "Tu número favorito es <myInt>" + + cerr << "Usado para mensajes de error"; +} +//////////////////// +// Cadenas (Strings) +//////////////////// + +// Las cadenas en C++ son objetos y tienen muchas funciones +#include <string> + +using namespace std; // Strings también estan en namespace std + +string myString = "Hola"; +string myOtherString = " Mundo"; + +// + es usado para concatenar. +cout << myString + myOtherString; // "Hola Mundo" + +cout << myString + " Tu"; // "Hola Tu" + +// Las cadenas en C++ son mutables y tienen valor semántico. +myString.append(" Perro"); +cout << myString; // "Hola Perro" + + +////////////// +// Referencias +////////////// + +// Además de punteros como los de C, +// C++ tiene _references_. +// Estos tipos de puntero no pueden ser reasignados una vez establecidos +// Y no pueden ser nulos. +// También tienen la misma sintaxis que la propia variable: +// No es necesaria * para eliminar la referencia y +// & (dirección) no se utiliza para la asignación. + +using namespace std; + +string foo = "Yo soy foo"; +string bar = "Yo soy bar"; + +string& fooRef = foo; // Crea una referencia a foo. +fooRef += ". Hola!"; // Modifica foo través de la referencia +cout << fooRef; // Imprime "Yo soy foo. Hola!" + +// No trate de reasignar "fooRef". Esto es lo mismo que "foo = bar", y +// foo == "Yo soy bar" +// después de esta linea. +fooRef = bar; + +const string& barRef = bar; // Crea una referencia constante a bar. +// Como en C, los valores constantes (y punteros y referencias) no pueden ser +// modificados. +barRef += ". Hola!"; // Error, referencia constante no puede ser modificada. + +// Sidetrack: Antes de hablar más sobre referencias, hay que introducir un +// concepto llamado objeto temporal. Supongamos que tenemos el siguiente código: +string tempObjectFun() { ... } +string retVal = tempObjectFun(); + +// Lo que pasa en la segunda línea es en realidad: +// - Un objeto de cadena es retornado desde tempObjectFun +// - Una nueva cadena se construye con el objeto devuelto como argumento al +// constructor +// - El objeto devuelto es destruido +// El objeto devuelto se llama objeto temporal. Objetos temporales son +// creados cada vez que una función devuelve un objeto, y es destruido en el +// fin de la evaluación de la expresión que encierra (Bueno, esto es lo que la +// norma dice, pero los compiladores están autorizados a cambiar este +// comportamiento. Busca "return value optimization" para ver mas detalles). +// Así que en este código: +foo(bar(tempObjectFun())) + +// Suponiendo que foo y bar existen, el objeto retornado de tempObjectFun es +// pasado al bar, y se destruye antes de llamar foo. + +// Ahora, de vuelta a las referencias. La excepción a la regla "en el extremo +// de la expresión encerrada" es si un objeto temporal se une a una +// referencia constante, en cuyo caso su vida se extiende al ámbito actual: + +void constReferenceTempObjectFun() { + // ConstRef obtiene el objeto temporal, y es válido hasta el final de esta + // función. + const string& constRef = tempObjectFun(); + ... +} + +// Otro tipo de referencia introducida en C ++ 11 es específicamente para +// objetos temporales. No se puede tener una variable de este tipo, pero tiene +// prioridad en resolución de sobrecarga: + +void someFun(string& s) { ... } // Referencia regular +void someFun(string&& s) { ... } // Referencia a objeto temporal + +string foo; +someFun(foo); // Llama la función con referencia regular +someFun(tempObjectFun()); // Llama la versión con referencia temporal + +// Por ejemplo, puedes ver estas dos versiones de constructores para +// std::basic_string: +basic_string(const basic_string& other); +basic_string(basic_string&& other); + +// La idea es que si estamos construyendo una nueva cadena de un objeto temporal +// (que va a ser destruido pronto de todos modos), podemos tener un constructor +// mas eficiente que "rescata" partes de esa cadena temporal. Usted verá este +// Concepto denominado "movimiento semántico". + +//////////////////////////////////////////// +// Clases y programación orientada a objetos +//////////////////////////////////////////// + +// Primer ejemplo de clases +#include <iostream> + +// Declara una clase. +// Las clases son usualmente declaradas en archivos de cabeceras (.h o .hpp) +class Dog { + // Variables y funciones de la clase son privados por defecto. + std::string name; + int weight; + +// Todos los miembros siguientes de este son públicos +// Hasta que se encuentre "private" o "protected". +// All members following this are public +// until "private:" or "protected:" is found. +public: + + // Constructor por defecto + Dog(); + + // Declaraciones de funciones de la clase (implementaciones a seguir) + // Nota que usamos std::string aquí en lugar de colocar + // using namespace std; + // arriba. + // Nunca ponga una declaración "using namespace" en un encabezado. + void setName(const std::string& dogsName); + + void setWeight(int dogsWeight); + // Funciones que no modifican el estado del objeto + // Deben marcarse como const. + // Esto le permite llamarlas si se envia una referencia constante al objeto. + // También tenga en cuenta que las funciones deben ser declaradas + // explícitamente como _virtual_ para que sea reemplazada en las clases + // derivadas. + // Las funciones no son virtuales por defecto por razones de rendimiento. + virtual void print() const; + + // Las funciones también se pueden definir en el interior + // del cuerpo de la clase. + // Funciones definidas como tales están entre líneas automáticamente. + void bark() const { std::cout << name << " barks!\n"; } + + // Junto a los constructores, C++ proporciona destructores. + // Estos son llamados cuando un objeto se elimina o está fuera del ámbito. + // Esto permite paradigmas potentes como RAII + // (mira abajo) + // El destructor debe ser virtual si una clase es dervada desde el; + // Si no es virtual, entonces la clase derivada destructor + // No será llamada si el objeto se destruye a través de una referencia de + // la clase base o puntero. + virtual ~Dog(); + + + +}; // Un punto y coma debe seguir la definición de clase. + +// Las funciones de una clase son normalmente implementados en archivos .cpp. +Dog::Dog() +{ + std::cout << "Un perro ha sido construido\n"; +} + +// Objetos (tales como cadenas) deben ser pasados por referencia +// Si los estas modificando o referencia constante en caso contrario. +void Dog::setName(const std::string& dogsName) +{ + name = dogsName; +} + +void Dog::setWeight(int dogsWeight) +{ + weight = dogsWeight; +} + +// Nota que "virtual" sólo se necesita en la declaración, no en la definición. +void Dog::print() const +{ + std::cout << "El perro es " << name << " y pesa " << weight << "kg\n"; +} + +Dog::~Dog() +{ + cout << "Adiós " << name << "\n"; +} + +int main() { + Dog myDog; // imprime "Un perro ha sido construido" + myDog.setName("Barkley"); + myDog.setWeight(10); + myDog.print(); // imprime "El perro es Barkley y pesa 10 kg" + return 0; +} // imprime "Adiós Barkley" + +// Herencia: + +// Esta clase hereda todo lo público y protegido de la clase Dog +class OwnedDog : public Dog { + + void setOwner(const std::string& dogsOwner); + + // Reemplaza el comportamiento de la función de impresión + // de todos los OwnedDogs. Mira + // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping + // Para una introducción más general si no está familiarizado con el + // polimorfismo de subtipo. + // La palabra clave override es opcional, pero asegura que estás + // reemplazando el método de una clase base. + void print() const override; + +private: + std::string owner; +}; + +// Mientras tanto, en el archivo .cpp correspondiente: + +void OwnedDog::setOwner(const std::string& dogsOwner) +{ + owner = dogsOwner; +} + +void OwnedDog::print() const +{ + Dog::print(); // Llama a la función de impresión en la clase base Dog + std::cout << "El perro es de " << owner << "\n"; + // Imprime "El perro es <name> y pesa <weight>" + // "El perro es de <owner>" +} + +//////////////////////////////////////////// +// Inicialización y sobrecarga de operadores +//////////////////////////////////////////// + +// En C ++ se puede sobrecargar el comportamiento +// de los operadores como +, -, *, /, etc. +// Esto se hace mediante la definición de una función que es llamada +// cada vez que se utiliza el operador. + +#include <iostream> +using namespace std; + +class Point { +public: + // Las variables de la clase pueden dar valores por defecto de esta manera. + double x = 0; + double y = 0; + + // Define un constructor por defecto que no hace nada + // pero inicializa el punto al valor por defecto (0, 0) + Point() { }; + + // The following syntax is known as an initialization list + // and is the proper way to initialize class member values + Point (double a, double b) : + x(a), + y(b) + { /* No hace nada excepto inicializar los valores */ } + + // Sobrecarga el operador + + Point operator+(const Point& rhs) const; + + // Sobrecarga el operador += + Point& operator+=(const Point& rhs); + + // También tendría sentido añadir los operadores - y -=, + // Pero vamos a omitirlos por razones de brevedad. +}; + +Point Point::operator+(const Point& rhs) const +{ + // Crea un nuevo punto que es la suma de este y rhs. + return Point(x + rhs.x, y + rhs.y); +} + +Point& Point::operator+=(const Point& rhs) +{ + x += rhs.x; + y += rhs.y; + return *this; +} + +int main () { + Point up (0,1); + Point right (1,0); + // Llama al operador + de Point + // Point llama la función + con right como parámetro + Point result = up + right; + // Prints "Result is upright (1,1)" + cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; + return 0; +} + +///////////////////////// +// Plantillas (Templates) +///////////////////////// + +// Las plantillas en C++ se utilizan sobre todo en la programación genérica, +// a pesar de que son mucho más poderoso que los constructores genéricos +// en otros lenguajes. Ellos también soportan especialización explícita y +// parcial y clases de tipo estilo funcional; de hecho, son un lenguaje +// funcional Turing-completo incrustado en C ++! + +// Empezamos con el tipo de programación genérica que podría estar +// familiarizado. +// Para definir una clase o función que toma un parámetro de tipo: +template<class T> +class Box { +public: + // En este caso, T puede ser usado como cualquier otro tipo. + void insert(const T&) { ... } +}; + +// Durante la compilación, el compilador realmente genera copias de cada +// plantilla con parámetros sustituidos, por lo que la definición completa +// de la clase debe estar presente en cada invocación. +// Es por esto que usted verá clases de plantilla definidas +// Enteramente en archivos de cabecera. + +//Para crear una instancia de una clase de plantilla en la pila: +Box<int> intBox; + +y puedes utilizarlo como era de esperar: +intBox.insert(123); + +// Puedes, por supuesto, anidar plantillas: +Box<Box<int> > boxOfBox; +boxOfBox.insert(intBox); + +// Hasta C++11, había que colocar un espacio entre los dos '>'s, +// de lo contrario '>>' serían analizados como el operador de desplazamiento +// a la derecha. + + +// A veces verás +// template<typename T> +// en su lugar. La palabra clave "class" y las palabras clave "typename" son +// mayormente intercambiables en este caso. Para la explicación completa, mira +// http://en.wikipedia.org/wiki/Typename +// (sí, esa palabra clave tiene su propia página de Wikipedia). + +// Del mismo modo, una plantilla de función: +template<class T> +void barkThreeTimes(const T& input) +{ + input.bark(); + input.bark(); + input.bark(); +} + +// Observe que no se especifica nada acerca de los tipos de parámetros aquí. +// El compilador generará y comprobará cada invocación de la plantilla, +// por lo que la función anterior funciona con cualquier tipo "T" +// que tenga un método 'bark' constante! + + +Dog fluffy; +fluffy.setName("Fluffy") +barkThreeTimes(fluffy); // Imprime "Fluffy barks" 3 veces. + +Los parámetros de la plantilla no tienen que ser las clases: +template<int Y> +void printMessage() { + cout << "Aprende C++ en " << Y << " minutos!" << endl; +} + +// Y usted puede especializar explícitamente plantillas +// para código más eficiente. +// Por supuesto, la mayor parte del mundo real que utiliza una especialización +// no son tan triviales como esta. +// Tenga en cuenta que usted todavía tiene que declarar la función (o clase) +// como plantilla incluso si ha especificado de forma explícita todos +// los parámetros. + +template<> +void printMessage<10>() { + cout << "Aprende C++ rapido en solo 10 minutos!" << endl; +} + +printMessage<20>(); // Prints "Aprende C++ en 20 minutos!" +printMessage<10>(); // Prints "Aprende C++ rapido en solo 10 minutos!" + + +///////////////////// +// Manejador de excepciones +///////////////////// + +// La biblioteca estándar proporciona algunos tipos de excepción +// (mira http://en.cppreference.com/w/cpp/error/exception) +// pero cualquier tipo puede ser lanzado como una excepción +#include <exception> +#include <stdexcept> + +//Todas las excepciones lanzadas dentro del bloque _try_ pueden ser +// capturados por los siguientes manejadores _catch_. +try { + // No asignar excepciones en el heap usando _new_. + throw std::runtime_error("Ocurrió un problema"); +} + +// Captura excepciones por referencia const si son objetos +catch (const std::exception& ex) +{ + std::cout << ex.what(); +} +******************************************************************************** +// Captura cualquier excepción no capturada por bloques _catch_ anteriores +catch (...) +{ + std::cout << "Excepción desconocida capturada"; + throw; // Re-lanza la excepción +} + +/////// +// RAII +/////// + +// RAII significa "Resource Acquisition Is Initialization" +// (Adquisición de recursos es inicialización). +// A menudo se considera el paradigma más poderoso en C++ +// Y el concepto es simple: un constructor de un objeto +// Adquiere recursos de ese objeto y el destructor les libera. + +// Para entender cómo esto es útil, +// Considere una función que utiliza un identificador de archivo C: +void doSomethingWithAFile(const char* filename) +{ + // Para empezar, asuma que nada puede fallar. + + FILE* fh = fopen(filename, "r"); // Abre el archivo en modo lectura + + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + + fclose(fh); // Cierra el manejador de archivos +} + +// Por desgracia, las cosas se complican rápidamente por el control de errores. +// Supongamos que fopen puede fallar, y que doSomethingWithTheFile y +// DoSomethingElseWithIt retornan códigos de error si fallan. +// (Excepciones son la mejor forma de manejar los fallos, +// pero algunos programadores, especialmente los que tienen un fondo C, +// estan en desacuerdo sobre la utilidad de las excepciones). +// Ahora tenemos que comprobar cada llamado por fallos y cerrar el manejador +// del archivo si se ha producido un problema. +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // Abre el archivo en modo lectura + if (fh == nullptr) // El puntero retornado es nulo o falla. + return false; // Reporta el fallo a quien hizo el llamado. + + // Asume que cada función retorna falso si falla + if (!doSomethingWithTheFile(fh)) { + fclose(fh); // Cierre el manejador de archivo para que no se filtre. + return false; // Propaga el error. + } + if (!doSomethingElseWithIt(fh)) { + fclose(fh); // Cierre el manejador de archivo para que no se filtre. + return false; // Propaga el error. + } + + fclose(fh); // Cierre el archivo. + return true; // Indica que todo funcionó correctamente. +} + +// Programadores C suelen limpiar esto un poco usando goto: +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); + if (fh == nullptr) + return false; + + if (!doSomethingWithTheFile(fh)) + goto failure; + + if (!doSomethingElseWithIt(fh)) + goto failure; + + fclose(fh); // Cierre el archivo. + return true; // Indica que todo funcionó correctamente. + +failure: + fclose(fh); + return false; // Propagate el error +} + +// Si las funciones indican errores mediante excepciones, +// Las cosas son un poco más claras, pero pueden optimizarse mas. +void doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // Abrir el archivo en modo lectura + if (fh == nullptr) + throw std::runtime_error("No puede abrirse el archivo."); + + try { + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + } + catch (...) { + fclose(fh); // Asegúrese de cerrar el archivo si se produce un error. + throw; // Luego vuelve a lanzar la excepción. + } + + fclose(fh); // Cierra el archivo +} + +// Compare esto con el uso de la clase de flujo de archivos de C++ (fstream) +// fstream utiliza su destructor para cerrar el archivo. +// Los destructores son llamados automáticamente +// cuando un objeto queda fuera del ámbito. +void doSomethingWithAFile(const std::string& filename) +{ + // ifstream es la abreviatura de el input file stream + std::ifstream fh(filename); // Abre el archivo + + // Hacer algo con el archivo + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + +} // El archivo se cierra automáticamente aquí por el destructor + + +// Esto tiene ventajas _enormes_: +// 1. No importa lo que pase, +// El recurso (en este caso el manejador de archivo) será limpiado. +// Una vez que escribes el destructor correctamente, +// Es _imposible_ olvidar cerrar el identificador y permitir +// fugas del recurso. +// 2. Tenga en cuenta que el código es mucho más limpio. +// El destructor se encarga de cerrar el archivo detrás de cámaras +// Sin que tenga que preocuparse por ello. +// 3. El código es seguro. +// Una excepción puede ser lanzado en cualquier lugar de la función +// y la limpieza ocurrirá. + +// Todo el código idiomático C++ utiliza RAII ampliamente para todos los +// recursos. +// Otros ejemplos incluyen +// - Memoria usando unique_ptr y shared_ptr +// - Contenedores (Containers) - la biblioteca estándar linked list, +// vector (es decir, array con auto-cambio de tamaño), hash maps, etc. +// Destruimos todos sus contenidos de forma automática +// cuando quedan fuera del ámbito. +// - Mutex utilizando lock_guard y unique_lock + + +///////////////////// +// Cosas divertidas +///////////////////// + +// Aspectos de C ++ que pueden sorprender a los recién llegados +// (e incluso algunos veteranos). +// Esta sección es, por desgracia, salvajemente incompleta; +// C++ es uno de los lenguajes con los que mas facil te disparas en el pie. + +// Tu puedes sobreescribir métodos privados! +class Foo { + virtual void bar(); +}; +class FooSub : public Foo { + virtual void bar(); // Sobreescribe Foo::bar! +}; + + +// 0 == false == NULL (La mayoria de las veces)! +bool* pt = new bool; +*pt = 0; // Establece los puntos de valor de 'pt' en falso. +pt = 0; // Establece 'pt' al apuntador nulo. Ambas lineas compilan sin error. + +// nullptr se supone que arregla un poco de ese tema: +int* pt2 = new int; +*pt2 = nullptr; // No compila +pt2 = nullptr; // Establece pt2 como null. + +// Hay una excepción para los valores bool. +// Esto es para permitir poner a prueba punteros nulos con if (!ptr), +// pero como consecuencia se puede asignar nullptr a un bool directamente! +*pt = nullptr; // Esto todavía compila, a pesar de que '*pt' es un bool! + +// '=' != '=' != '='! +// Llama Foo::Foo(const Foo&) o alguna variante (mira movimientos semanticos) +// copia del constructor. +Foo f2; +Foo f1 = f2; + +// Llama Foo::Foo(const Foo&) o variante, pero solo copia el 'Foo' parte de +// 'fooSub'. Cualquier miembro extra de 'fooSub' se descarta. Este +// comportamiento horrible se llama "Corte de objetos." +FooSub fooSub; +Foo f1 = fooSub; + +// Llama a Foo::operator=(Foo&) o variantes. +Foo f1; +f1 = f2; + + +// Cómo borrar realmente un contenedor: +class Foo { ... }; +vector<Foo> v; +for (int i = 0; i < 10; ++i) + v.push_back(Foo()); +// La siguiente línea establece el tamaño de v en 0, +// pero los destructores no son llamados y los recursos no se liberan! + +v.empty(); +v.push_back(Foo()); // Nuevo valor se copia en el primer Foo que insertamos + +// En verdad destruye todos los valores en v. +// Consulta la sección acerca de los objetos temporales para la +// explicación de por qué esto funciona. +v.swap(vector<Foo>()); + +``` +Otras lecturas: + +Una referencia del lenguaje hasta a la fecha se puede encontrar en +<http://cppreference.com/w/cpp> + +Recursos adicionales se pueden encontrar en <http://cplusplus.com> diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown index 73853a9d..4e1e68ba 100644 --- a/es-es/git-es.html.markdown +++ b/es-es/git-es.html.markdown @@ -11,18 +11,18 @@ lang: es-es --- Git es un sistema de control de versiones distribuido diseñado para manejar -cualquier tipo de proyecto ya sea largos o pequeños, con velocidad y eficiencia. +cualquier tipo de proyecto, ya sea grande o pequeño, con velocidad y eficiencia. Git realiza esto haciendo "snapshots" del proyecto, con ello permite versionar y administrar nuestro código fuente. ## Versionamiento, conceptos. -### Que es el control de versiones? -El control de versiones es un sistema que guarda todos los cambios realizados a +### ¿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. @@ -31,15 +31,15 @@ uno o varios archivos, a lo largo del tiempo. + El versionamiento distribuido no tiene una estructura definida, incluso se puede mantener el estilo de los repositorios SVN con git. -[Informacion adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones) +[Información adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones) -### Por que usar Git? +### ¿Por qué usar Git? -* Se puede trabajar sin conexion. -* Colaborar con otros es sencillo!. -* Derivar, Crear ramas del proyecto (aka: Branching) es facil!. +* Se puede trabajar sin conexión. +* ¡Colaborar con otros es sencillo!. +* Derivar, crear ramas del proyecto (aka: Branching) es fácil. * Combinar (aka: Merging) -* Git es rapido. +* Git es rápido. * Git es flexible. ## Arquitectura de Git. @@ -47,11 +47,11 @@ 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, -y que sus atributos otorgan acceso al historial del elemento, ademas de otras +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. -Un repositorio esta compuesto por la carpeta .git y un "arbol de trabajo". +Un repositorio esta compuesto por la carpeta .git y un "árbol de trabajo". ### Directorio .git (componentes del repositorio) @@ -62,38 +62,38 @@ y mas. ### Directorio de trabajo (componentes del repositorio) -Es basicamente los directorios y archivos dentro del repositorio. La mayorioa de +Es básicamente los directorios y archivos dentro del repositorio. La mayoría de las veces se le llama "directorio de trabajo". -### Inidice (componentes del directorio .git) +### Índice (componentes del directorio .git) -El inidice es la area de inicio en git. Es basicamente la capa que separa el -directorio de trabajo, del repositorio en git. Esto otorga a los desarrolladores -mas poder sobre lo que envia y recibe en el repositorio. +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. ### Commit (aka: cambios) Un commit es una captura de un conjunto de cambios, o modificaciones hechas en -el directorio de trabajo. Por ejemplo, si se añaden 5 archivos, se remueven 2, -estos cambios se almacenaran en un commit (aka: captura). Este commit puede ser o +el directorio de trabajo. Por ejemplo, si se añaden 5 archivos, se eliminan 2, +estos cambios se almacenarán en un commit (aka: captura). Este commit puede ser o no ser enviado (aka: "pusheado") hacia un repositorio. ### Branch (rama) -Un "branch", es escencialmente un apuntador hacia el ultimo commit (cambio -registrado) que se ha realizado. A medida que se realizan mas commits, este -apuntador se actualizara automaticamente hacia el ultimo commit. +Un "branch", es escencialmente un apuntador hacia el último commit (cambio +registrado) que se ha realizado. A medida que se realizan más commits, este +apuntador se actualizará automaticamente hacia el ultimo commit. -### "HEAD" y "head" (component of .git dir) +### "HEAD" y "head" (componentes del directorio .git) "HEAD" es un apuntador hacia la rama (branch) que se esta utilizando. Un repositorio solo puede tener un HEAD activo. En cambio "head", es un apuntador a -cualquier commit realizado, un repositorio puede tener cualquier numero de +cualquier commit realizado, un repositorio puede tener cualquier número de "heads". ### conceptos - recursos. -* [Git para informaticos](http://eagain.net/articles/git-for-computer-scientists/) +* [Git para informáticos](http://eagain.net/articles/git-for-computer-scientists/) * [Git para diseñadores](http://hoth.entp.com/output/git_for_designers.html) @@ -102,8 +102,8 @@ cualquier commit realizado, un repositorio puede tener cualquier numero de ### init -Crear un repositorio de git vacio. Las configuraciones, informacion almacenada y -demas son almacenadas en el directorio ".git". +Crear un repositorio de git vacio. Las configuraciones, información almacenada y +demás son almacenadas en el directorio ".git". ```bash $ git init @@ -115,7 +115,7 @@ Se utiliza para configurar las opciones ya sea globalmente, o solamente en el repositorio. ```bash -# Imprime y guarda algunas variables de configuracion basicas. (Globalmente) +# Imprime y guarda algunas variables de configuracion básicas. (Globalmente) $ git config --global user.email $ git config --global user.name @@ -123,15 +123,15 @@ $ git config --global user.email "corre@gmail.com" $ git config --global user.name "nombre" ``` -[Mas sobre git config.](http://git-scm.com/book/es/Personalizando-Git-Configuración-de-Git) +[Más sobre git config.](http://git-scm.com/book/es/Personalizando-Git-Configuración-de-Git) ### help -Otorga un accceso rapido a una guia extremadamente detallada de cada comando en +Otorga un accceso rápido a una guía extremadamente detallada de cada comando en git. O puede ser usada simplemente como un recordatorio de estos. ```bash -# Una vista rapido de los comandos disponibles. +# Una vista rápida de los comandos disponibles. $ git help # Chequear todos los comandos disponibles @@ -146,12 +146,12 @@ $ git help init ### status -Muestra las diferencias entre el archivo indice y el commit al cual apunta el +Muestra las diferencias entre el archivo índice y el commit al cual apunta el HEAD actualmente. ```bash -# Mostrara el "branch", archivos sin añadir a la repo, cambios y otras +# Mostrará el "branch", archivos sin añadir al repo, cambios y otras # diferencias $ git status @@ -161,9 +161,9 @@ $ git help status ### add -Para añadir archivos al arbol (directorio, repositorio) de trabajo. Si no se -utiliza `git add`, los nuevos archivos no se añadiran al arbol de trabajo, por -lo que no se incluiran en los commits (cambios). +Para añadir archivos al árbol (directorio, repositorio) de trabajo. Si no se +utiliza `git add`, los nuevos archivos no se añadirán al arbol de trabajo, por +lo que no se incluirán en los commits (cambios). ```bash # Añade un archivo en el directorio de trabajo actual. @@ -178,31 +178,31 @@ $ git add ./*.py ### branch -Administra las ramas del repositorios ("branches"). Puedes ver, editar, crear y +Administra las ramas del repositorio ("branches"). Puedes ver, editar, crear y borrar ramas ("branches"), usando este comando. ```bash # lista todas las ramas (remotas y locales) $ git branch -a -# Añada una nueva rama ("branch"). +# Añadir una nueva rama ("branch"). $ git branch branchNueva # Eliminar una rama. $ git branch -d branchFoo -# Renombra una rama. +# Renombrar una rama. # git branch -m <anterior> <nuevo> $ git branch -m youngling padawan -# Edita la descripcion de la rama. +# Editar la descripcion de la rama. $ git branch master --edit-description ``` ### checkout Actualiza todos los archivos en el directorio de trabajo para que sean igual que -las versiones almacenadas en el indice, o en un arbol de trabajo especificado. +las versiones almacenadas en el índice, o en un árbol de trabajo especificado. ```bash # Despachar un repositorio. - Por defecto la master branch. (la rama principal llamada 'master') @@ -215,8 +215,8 @@ $ git checkout -b jdei ### clone -Clona, o copia, una repo existente en un nuevo directorio. Tambien añada el -seguimiento hacia las ramas existentes del repo que ha sido clonada, lo que +Clona, o copia, un repositorio existente en un nuevo directorio. También añade el +seguimiento hacia las ramas existentes del repositorio que ha sido clonado, lo que permite subir (push) los archivos hacia una rama remota. ```bash @@ -226,60 +226,60 @@ $ git clone https://github.com/jquery/jquery.git ### commit -Almacena los cambios que almacenados en el indice en un nuevo "commit". Este -commit contiene los cambios hechos mas un resumen hecho por el desarrollador. +Almacena el contenido actual del índice en un nuevo "commit". Este +commit contiene los cambios hechos más un resumen proporcionado por el desarrollador. ```bash -# commit with a message # realizar un commit y añadirle un mensaje. $ git commit -m "jedi anakin wil be - jedis.list" ``` ### diff -Muestra las diferencias entre un archivo en el directorio de trabajo, el indice -y commits. +Muestra las diferencias entre un archivo en el directorio de trabajo, el índice +y los commits. ```bash -# Muestra la diferencia entre un directorio de trabajo y el indice. +# Muestra la diferencia entre un directorio de trabajo y el índice. $ git diff -# Muestra la diferencia entre el indice y los commits mas recientes. +# Muestra la diferencia entre el índice y los commits más recientes. $ git diff --cached -# Muestra la diferencia entre el directorio de trabajo y el commit mas reciente. +# Muestra la diferencia entre el directorio de trabajo y el commit más reciente. $ git diff HEAD ``` ### grep -Permite realizar una busqueda rapida en un repositorio. +Permite realizar una busqueda rápida en un repositorio. -Configuracion opcionales: +Configuraciones opcionales: ```bash # Gracias a Travis Jeffery por compartir lo siguiente. # Permite mostrar numeros de lineas en la salida de grep. $ git config --global grep.lineNumber true -# Realiza una busqueda mas lejible, incluyendo agrupacion. +# Realiza una búsqueda mas legible, incluyendo agrupación. $ git config --global alias.g "grep --break --heading --line-number" ``` ```bash -# Busca por "unaVariable" en todos los archivos ,java +# Busca por "unaVariable" en todos los archivos .java $ git grep 'unaVariable' -- '*.java' -# Busca por una linea que contenga "nombreArreglo" y , "agregar" o "remover" +# Busca por una línea que contenga "nombreArreglo" y "agregar" o "remover" $ git grep -e 'nombreArreglo' --and \( -e agregar -e remover \) ``` -Mas ejemplos: -[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja) +Más ejemplos: + +- [Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja) ### log -Muestra los commits (cambios) registrados en el repositotrio. +Muestra los commits (cambios) registrados en el repositorio. ```bash # Muestra todos los commits. @@ -288,7 +288,7 @@ $ git log # Muestra un numero x de commits. $ git log -n 10 -# Muestra solo los commits que se han combinado en el hisotrial +# Muestra solo los commits que se han combinado en el historial. $ git log --merges ``` @@ -301,7 +301,7 @@ que se trabaja. # Combina la rama especificada en la rama actual. $ git merge jediMaster -# Siempre genere un solo merge commit cuando se utilizar merge. +# Siempre genere un solo merge commit cuando se utiliza merge. $ git merge --no-ff jediMaster ``` @@ -310,7 +310,7 @@ $ git merge --no-ff jediMaster Renombra o mueve un archivo ```bash -# Renombrando un archivo +# Renombrando un archivo. $ git mv HolaMundo.c AdiosMundo.c # Moviendo un archivo. @@ -322,33 +322,31 @@ $ git mv -f archivoA archivoB ### pull -Sube (Empuja) de un repositorio y lo combina en otro en una rama diferente. +Trae los cambios de un repositorio y los combina en otro en una rama diferente. ```bash -# Actualiza el repositorio local, combinando los nuevos cambios. +# Actualiza el repositorio local, combinando los nuevos cambios # de las ramas remotas "origin" y "master". -# from the remote "origin" and "master" branch. # git pull <remota> <rama> $ git pull origin master ``` ### push -Push and merge changes from a branch to a remote & branch. +Envía y combina los cambios de un repositorio local a un repositorio y rama remotos. ```bash -# Push and merge changes from a local repo to a -# Empuja y combina cambios de un repositorio local hacian un repositorio remoto +# Envía y combina cambios de un repositorio local hacia un repositorio remoto # llamados "origin" y "master", respectivamente. # git push <remota> <rama> # git push => por defecto es lo mismo que poner => git push origin master $ git push origin master ``` +### rebase Toma todos los cambios que fueron registrados en una rama, y los repite dentro -de otra rama. -*No reescribe los commits que se han empujado antes a un repositorio publico* +de otra rama. *No reescribe los commits que se han empujado antes a un repositorio público.* ```bash # Integrar ramaExperimento dentro de la rama "master" @@ -356,47 +354,47 @@ de otra rama. $ git rebase master experimentBranch ``` -[Informacion adicional.](http://git-scm.com/book/es/Ramificaciones-en-Git-Procedimientos-básicos-para-ramificar-y-fusionar) +[Información adicional.](http://git-scm.com/book/es/Ramificaciones-en-Git-Procedimientos-básicos-para-ramificar-y-fusionar) -### reset (precaucion) +### reset (precaución) -Reinicia el cabezal actual hacia un estado especificado. Esto permite desacer -combinaciones (merges), pulls, commits, adds y mas. Es un comando util, pero -tambien peligrosa si no se sabe lo que se hace. +Reinicia el HEAD actual hacia un estado especificado. Esto permite deshacer +combinaciones (merges), pulls, commits, adds y más. Es un comando útil, pero +tambien peligroso si no se sabe lo que se hace. ```bash -# Reinica el area principal, con el ultimo cambio registrado. (deja los +# Reinicia el área principal, con el último cambio registrado. (deja los # directorios sin cambios) $ git reset -# Reinica el area principal, con el ultimo cambio registrado, y reescribe el +# Reinicia el área principal, con el último cambio registrado, y reescribe el # directorio de trabajo. $ git reset --hard # Mueve la rama actual hacia el commit especificado (no realiza cambios a los -# directorios), todos los cambios aun existen el directorio. +# directorios), todos los cambios aún existen el directorio. $ git reset 31f2bb1 -# Mueve la rama actual devuelta a un commit especificado asi como el -# directorios (borra todos los cambios que no fueron registros y todos los -# cambios realizados despues del commit especificado). +# Mueve la rama actual devuelta a un commit especificado, así como el +# directorio (borra todos los cambios que no fueron registrados y todos los +# cambios realizados después del commit especificado). $ git reset --hard 31f2bb1 ``` ### rm -Lo contrario de git add, git rm remueve los archivos del directorio de trabajo +Lo contrario de git add, git rm elimina los archivos del directorio de trabajo actual. ```bash -# Remueve FooBar.c +# Elimina FooBar.c $ git rm FooBar.c -# Remueve un archivo de un directorio. +# Elimina un archivo de un directorio. $ git rm /directorio/del/archivo/FooBar.c ``` -## Informacion Adicional +## Información Adicional * [tryGit - Una forma entretenida y rapida de aprender Git.](http://try.github.io/levels/1/challenges/1) diff --git a/es-es/javascript-es.html.markdown b/es-es/javascript-es.html.markdown index fd01e7b9..9ef0c63e 100644 --- a/es-es/javascript-es.html.markdown +++ b/es-es/javascript-es.html.markdown @@ -16,7 +16,7 @@ con Java para aplicaciones más complejas. Debido a su integracion estrecha con web y soporte por defecto de los navegadores modernos se ha vuelto mucho más común para front-end que Java. -JavaScript no sólo se limita a los navegadores web, aunque: Node.js, Un proyecto que proporciona un entorno de ejecución independiente para el motor V8 de Google Chrome, se está volviendo más y más popular. +Aunque JavaScript no sólo se limita a los navegadores web: Node.js, Un proyecto que proporciona un entorno de ejecución independiente para el motor V8 de Google Chrome, se está volviendo más y más popular. ¡La retroalimentación es bienvenida! Puedes encontrarme en: [@adambrenecki](https://twitter.com/adambrenecki), o @@ -30,7 +30,7 @@ JavaScript no sólo se limita a los navegadores web, aunque: Node.js, Un proyect // 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 @@ -124,7 +124,7 @@ undefined; // usado para indicar que un valor no está presente actualmente // (aunque undefined es un valor en sí mismo) // false, null, undefined, NaN, 0 y "" es false; todo lo demás es true. -// Note que 0 is false y "0" es true, a pesar de que 0 == "0". +// Note que 0 es false y "0" es true, a pesar de que 0 == "0". // Aunque 0 === "0" sí es false. /////////////////////////////////// @@ -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,10 +476,7 @@ typeof miNumero; // = 'number' typeof miNumeroObjeto; // = 'object' miNumero === miNumeroObjeyo; // = false if (0){ - // Este código no se ejecutara porque 0 es false. -} -if (Number(0)){ - // Este código sí se ejecutara, puesto que Number(0) es true. + // 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/julia-es.html.markdown b/es-es/julia-es.html.markdown index 95a16412..e4181609 100644 --- a/es-es/julia-es.html.markdown +++ b/es-es/julia-es.html.markdown @@ -45,7 +45,7 @@ Esto se basa en la versión `0.3.11`. # Los comentarios de una línea comienzan con una almohadilla (o signo de gato). #= - Los commentarios multilínea pueden escribirse + Los comentarios multilínea pueden escribirse usando '#=' antes de el texto y '=#' después del texto. También se pueden anidar. =# @@ -174,7 +174,7 @@ otraVariable_123! = 6 # => 6 otra_variable * Los nombres de los tipos comienzan con una letra mayúscula y separación de - palabras se muestra con CamelCase en vez de guion bajo: + palabras se muestra con CamelCase en vez de guión bajo: OtroTipo @@ -214,7 +214,7 @@ matrix = [1 2; 3 4] 3 4 =# -# Añadir cosas a la final de un arreglo con push! y append!. +# Añadir cosas al final de un arreglo con push! y append!. push!(a, 1) # => [1] push!(a, 2) # => [1,2] push!(a, 4) # => [1,2,4] @@ -237,7 +237,7 @@ a[end] # => 6 shift!(a) # => 1 y a es ahora: [2,4,3,4,5,6] unshift!(a, 7) # => [7,2,4,3,4,5,6] -# Los nombres de funciónes que terminan en exclamaciones indican que modifican +# Los nombres de funciones que terminan en exclamaciones indican que modifican # su o sus argumentos de entrada. arr = [5, 4, 6] # => 3-element Array{Int64,1}: [5,4,6] sort(arr) # => [4,5,6] y arr es todavía: [5,4,6] @@ -710,7 +710,7 @@ end # Sólo define una función del mismo nombre que el tipo y llama al constructor # existente para obtener un valor del tipo correcto. -# Este es un constructor externo porque es fuera de la definición del tipo. +# Este es un constructor externo porque está fuera de la definición del tipo. Leon(rugido::String) = Leon("verde", rugido) type Pantera <: Gato # Pantera también es un a subtipo de Gato @@ -730,10 +730,10 @@ end ######################## # En Julia, todas las funciones nombradas son funciones genéricas. -# Esto significa que se construyen a partir de muchos métodosmás pequeños. +# Esto significa que se construyen a partir de muchos métodos más pequeños. # Cada constructor de Leon es un método de la función genérica Leon. -# Por ejemplo, vamos a hacer métodos para para Leon, Pantera, y Tigre de una +# Por ejemplo, vamos a hacer métodos para Leon, Pantera, y Tigre de una # función genérica maullar: # acceso utilizando notación de puntos diff --git a/es-es/latex-es.html.markdown b/es-es/latex-es.html.markdown new file mode 100644 index 00000000..aff3c603 --- /dev/null +++ b/es-es/latex-es.html.markdown @@ -0,0 +1,213 @@ +--- +language: latex +lang: es-es +contributors: + - ["Chaitanya Krishna Ande", "http://icymist.github.io"] + - ["Colton Kohnke", "http://github.com/voltnor"] + - ["Sricharan Chiruvolu", "http://sricharan.xyz"] +translators: + - ["Mario Pérez", "https://github.com/MarioPerezEsteso"] +filename: learn-latex-es.tex +--- + +```tex +% Todas las líneas comentadas comienzan con % +% No existen los comentarios multilínea + +% LaTeX NO es un software de procesamiento de texto que cumple con +% "Lo que ves es lo que tienes" como MS Word u OpenOffice + +% Todos los comandos de LaTeX comienzan con una contrabarra (\) + +% Los documentos LaTeX comienzan definiendo el tipo de documento que se va a +% compilar. Algunos tipos de documentos son libros, informes, presentaciones, +% etc. Las opciones para el documento comienzan en los corchetes []. En este +% caso, se especifica que queremos utilizar una fuente de tamaño 12pt. +\documentclass[12pt]{article} + +% A continuación, definimos los paquetes que utilizará el documento. +% Si quieres incluir gráficos, texto coloreado o código fuente de otro lenguaje, +% debes extender las funciones de LaTeX. Esto se consigue añadiendo paquetes. +% A continuación se incluirán los paquetes float y caption para figuras. +\usepackage{caption} +\usepackage{float} + +% También podemos definir otras propiedades en el documento +\author{Chaitanya Krishna Ande, Colton Kohnke \& Sricharan Chiruvolu} +\date{\today} +\title{Learn LaTeX in Y Minutes!} + +% Ahora estamos preparados para comenzar el documento +% Todo lo que se encuentre antes de esta línea se llama "El Preámbulo" +\begin{document} +% Si especificamos el autor, fecha y título, LaTeX creará una página como título +% por nosotros +\maketitle + +% La mayoría de los artículos de investigación tienen un abstract. Es posible +% utilizar comandos predefinidos para ello. +% Esto debería aparecer en su orden lógico. Tras el título pero antes de las +% secciones principales del cuerpo. +% Este comando está disponible en los tipos de documentos article y report. +\begin{abstract} + Documentación de LaTex escrita en LaTex. +\end{abstract} + +% Los comandos de sección son intuitivos. +% Todos los títulos de secciones son añadidos automáticamente a la tabla de contenidos. +\section{Introducción} +Hola, mi nombre es Mario Pérez y estoy traduciendo este documento para aprender LaTex. + +\section{Otra sección} +Este es el texto de otra sección. Creo que necesitará una subsección. + +\subsection{Esto es una subsección} % Las subsecciones también son fáciles. +Creo que necesitamos otra más. + +\subsubsection{Pitágoras} +Mejor ahora. +\label{subsec:pitagoras} + +% Utilizando el asterisco podemos decirle a LaTeX que no ponga los números de secciones y subsecciones. +% Esto también funciona con otros comandos de LaTeX. +\section*{Esto es una sección no numerada} +¡No todas las secciones tienen que estar numeradas! + +\section{Algunas notas} +LaTeX es generalmente bastante bueno situando el texto donde debe ir. Si una lína \\ necesita \\ ser \\ rota \\ puedes poner \textbackslash\textbackslash en el código fuente. \\ + +\section{Listas} +Las listas son de las cosas más fáciles de crear en LaTeX. Necesito ir a comprar mañana, así que vamos a crear una lista de la compra. +\begin{enumerate} % Esto crea una lista numerada. + % \item crea un elemento + \item Ensalada. + \item 27 sandías. + \item Pescado. + % podemos incluso sobreescribir el número del ítem usando [] + \item[cuántos?] Plátanos. + + No es un ítem de la lista, pero sigue siendo parte de la enumeración. + +\end{enumerate} % Todos los contextos deben tener un final. + +\section{Matemáticas} + +Uno de los usos principales de LaTeX es la producción de artículos académicos o técnicos. Normalmente relacionados con la ciencia y las matemáticas. Debido a esto, necesitamos poder añadir símbolos especiales a nuestro artículo.\\ + +En matemáticas hay muchos símbolos. Más de los que podemos encontrar en un teclado. Flechas o letras por nombrar un par.\\ + +Algunos símbolos juegan un papel fundamental en muchos artículos de investigación matemática. Así es como se establece que todo Y pertenece a X: $\forall$ x $\in$ X. \\ +He necesitado añadir el signo $ antes de los símbolos. Esto se debe a que cuando escribimos, estamos en modo texto. Sin embargo, los símbolos solo pueden utilizarse en modo matemático, al cual se entra con el signo $. +% Lo opuesto también se cumple. Una variable también puede ser mostrada en modo matemático, al que también se puede entrar con \[\] + +\[a^2 + b^2 = c^2 \] + +Mi letra griega favorita es $\xi$. También me gustan $\beta$, $\gamma$ y $\sigma$. +Todavía no he encontrado una letra griega que LaTeX no conozca. + +Los operadores son también una parte esencial de un documento matemático: +funciones trigonométricas ($\sin$, $\cos$, $\tan$), logaritmos y exponenciales ($\log$, $\exp$), límites ($\lim$), etc. tienen comandos predefinidos en LaTeX. + +Vamos a escribir una ecuación para ver cómo se hace: \\ + +$\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$ + +Las fracciones (numeradores-denominadores) pueden escribirse de la siguiente forma: + +% 10 / 7 +$^{10}/_{7}$ + +% Las fracciones relativamente complejas pueden escribirse como +% \frac{numerador}{denominador} +$\frac{n!}{k!(n - k)!}$ \\ + +También podemos insertar ecuaciones en un contexto de ecuación. + +% Mostrar matemáticas en el contexto de ecuaciones +\begin{equation} % entra en modo matemático + c^2 = a^2 + b^2. + \label{eq:pitagoras} % para referencias +\end{equation} % Todos los contextos deben tener un final. + +Podemos referenciar nuestra nueva ecuación. +Ecuación ~\ref{eq:pythagoras} también se conoce como el Teorema de Pitágoras, el cual también se encuentra en la sección ~\ref{subsec:pythagoras}. Muchas cosas pueden ser etiquetadas: figures, equations, sections, etc. + +Los sumatorios e integrales son escritor son los comandos sum e int: + +% Algunos compiladores de LaTeX se quejarán si hay líneas en blanco +% En un contexto de ecuación. +\begin{equation} + \sum_{i=0}^{5} f_{i} +\end{equation} +\begin{equation} + \int_{0}^{\infty} \mathrm{e}^{-x} \mathrm{d}x +\end{equation} + +\section{Figuras} + +Vamos a insertar una figura. Situarla puede ser algo complicado. + +\begin{figure}[H] % H aquí establece la situación de la figura. + \centering % centra la figura en la página + % Inserta una figura escalada por 0.8 el ancho de la página. + %\includegraphics[width=0.8\linewidth]{right-triangle.png} + % La línea anterior ha sido comentada para poder compilar este archivo. Por favor, usa tu imaginación. + \caption{Triángulo con lados $a$, $b$, $c$} + \label{fig:right-triangle} +\end{figure} + +\subsection{Tablas} +También podemos insertar tablas de la misma manera que las figuras. + +\begin{table}[H] + \caption{Título para la tabla.} + % los argumentos en {} describen cómo cada fila va a ser representada. + \begin{tabular}{c|cc} + Número & Nombre & Apellido \\ + \hline % una línea horizontal + 1 & Biggus & Dickus \\ + 2 & Monty & Python + \end{tabular} +\end{table} + +% \section{Hyperlinks} % En construcción + +\section{Haciendo que LaTeX no compile algo (por ejemplo, código fuente)} +Digamos que queremos incluir código fuente dentro de nuestro documento LaTex. En ese caso, debemos indicarle a LaTeX que no trate de compilarlo y simplemente lo muestre en el documento. Esto lo realizamos en el contexto verbatim. + +% Hay otros paquetes para esta misma tarea, pero verbatim es el más básico. +\begin{verbatim} + print("Hola Mundo!") + a%b; % Podemos usar los signos % en verbatim. + aleatorio = 4; # Número aleatorio +\end{verbatim} + +\section{Compilación} + +Ahora mismo te estarás preguntando cómo compilar este fabuloso documento y obtener un documento PDF.\\ +Para obtener el documento final utilizando LaTeX hay que seguir los siguientes pasos: + \begin{enumerate} + \item Escribe el documento en texto plano. + \item Compila el código para producir un PDF. + Los pasos de compilación serán algo parecido a esto (en Linux): \\ + \begin{verbatim} + $pdflatex learn-latex.tex learn-latex.pdf + \end{verbatim} + \end{enumerate} + +Un gran número de editores LaTeX combinan ambos pasos para que sea más sencillo obtener el documento. + +Escribe toda la información de formato en el paso 1 y con el paso 2 obtendrás el documento que has definido en el paso anterior. + +\section{End} + +Esto es todo por ahora. + +% fin del documento +\end{document} +``` + +## Más información sobre LaTeX + +* El wikilibro LaTeX: [https://es.wikibooks.org/wiki/Manual_de_LaTeX](https://es.wikibooks.org/wiki/Manual_de_LaTeX) +* Un tutorial real: [http://www.latex-tutorial.com/](http://www.latex-tutorial.com/) 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/php-es.html.markdown b/es-es/php-es.html.markdown new file mode 100644 index 00000000..fa52353c --- /dev/null +++ b/es-es/php-es.html.markdown @@ -0,0 +1,825 @@ +--- +language: PHP +contributors: + - ["Malcolm Fell", "http://emarref.net/"] + - ["Trismegiste", "https://github.com/Trismegiste"] +translators: + - ["Mario Pérez", "https://github.com/MarioPerezEsteso"] +lang: es-es +filename: learnphp-es.php +--- + +Este documento explica el funcionamiento de PHP 5+. + +```php +<?php // El código PHP debe estar dentro de etiquetas <?php + +// Si tu fichero php solo contiene código php, es una buena práctica +// omitir la etiqueta de cierre php para prevenir salidas acidentales. + +// Dos barras comienzan un comentario de una línea. + +# También lo hará una almohadilla, pero // es más común + +/* + Escribir texto entre una barra-asterisco y asterisco-barra + crea un comentario multilínea. +*/ + +// Utiliza "echo" o "print" para imprimir por pantalla +print('Hola '); // Imprime "Hola " sin salto de línea + +// () son opcionales para print y echo +echo "Mundo\n"; // Imprime "Mundo" con un salto de línea +// (todas las sentencias deben finalizar con un punto y coma) + +// Cualquier cosa fuera de las etiquetas <?php se imprime automáticamente +?> +¡Hola Mundo de nuevo! +<?php + + +/************************************ + * Tipos y variables + */ + +// Las variables comienzan con el símbolo $. +// Una variable válida comienza con una letra o guión bajo, +// seguida de cualquier cantidad de letras, números o guiones bajos. + +// Las variables booleanas no distinguen entre mayúsculas o minúsculas +$boolean = true; // o TRUE o True +$boolean = false; // o FALSE o False + +// Enteros +$int1 = 12; // => 12 +$int2 = -12; // => -12 +$int3 = 012; // => 10 (un 0 al comienzo declara un número octal) +$int4 = 0x0F; // => 15 (un 0x al comienzo declara un hexadecimal) + +// Floats (también conocidos como doubles) +$float = 1.234; +$float = 1.2e3; +$float = 7E-10; + +// Eliminar variable +unset($int1); + +// Operaciones aritméticas +$suma = 1 + 1; // 2 +$diferencia = 2 - 1; // 1 +$producto = 2 * 2; // 4 +$cociente = 2 / 1; // 2 + +// Operaciones aritméticas de escritura rápida +$numero = 0; +$numero += 1; // Incrementa $numero en 1 +echo $numero++; // Imprime 1 (incremento después la evaluación) +echo ++$numero; // Imprime 3 (incremento antes de la evaluación) +$numero /= $float; // Divide y asigna el cociente a $numero + +// Las cadenas de caracteres deben declararse entre comillas simples +$sgl_quotes = '$String'; // => '$String' + +// Evita utilizar comillas dobles excepto para embeber otras variables +$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.' + +// Los caracteres especiales solo son válidos entre comillas dobles +$escaped = "Esto contiene \t un caracter tabulador."; +$unescaped = 'Esto solo contiene una barra y una t: \t'; + +// Rodea una variable entre corchetes si es necesario +$dinero = "Tengo $${numero} en el banco."; + +// Desde PHP 5.3, los nowdocs pueden ser utilizados para multilíneas no interpoladas +$nowdoc = <<<'END' +Multi line +string +END; + +// Heredocs interpola cadenas de caracteres +$heredoc = <<<END +Multi line +$sgl_quotes +END; + +// La concatenación de cadenas de caracteres se realiza con . +echo 'Esta cadena de caracteres ' . 'está concatenada'; + +// Las cadenas de caracteres pueden ser pasadas como parámetros en un echo +echo 'Multiples', 'Parametros', 'Validos'; // Devuelve 'MultiplesParametrosValidos' + + +/******************************** + * Constantes + */ + +// Una constante se define utilizando define() +// y nunca puede ser cambiada en tiempo de ejecución + +// un nombre válido para una constante debe comenzar con una letra o guión bajo, +// seguido por cualquier número de letras, números o guiones bajos. +define("FOO", "algo"); + +// el acceso a una constante se puede realizar llamando a la variable elegida sin un símbolo de $ +echo FOO; // Devuelve 'algo' +echo 'Esto imprime '.FOO; // Devuelve 'Esto imprime algo' + + + +/******************************** + * Arrays + */ + +// Todos los arrays en PHP son asociativos (hashmaps), + +// Los arrays asociativos son conocidos como hashmaps en algunos lenguajes. + +// Funciona con todas las versiones de php +$asociativo = array('Uno' => 1, 'Dos' => 2, 'Tres' => 3); + +// PHP 5.4 introdujo una nueva sintaxis +$asociativo = ['Uno' => 1, 'Dos' => 2, 'Tres' => 3]; + +echo $asociativo['Uno']; // imprime 1 + +// Lista literales implícitamente asignados con claves enteras +$array = ['Uno', 'Dos', 'Tres']; +echo $array[0]; // => "Uno" + +// Añadir un elemento al final de un array +$array[] = 'Cuatro'; +// o +array_push($array, 'Cinco'); + +// Eliminar un elemento de un array +unset($array[3]); + +/******************************** + * Salidas por pantalla + */ + +echo('¡Hola Mundo!'); +// Imprime ¡Hola Mundo! en stdout. +// Stdout es la página web si se está ejecutando en un navegador. + +print('!Hola Mundo!'); // Es lo mismo que echo + +// No es necesario el paréntesis en echo y print +echo '¡Hola Mundo!'; +print '¡Hola Mundo!'; + +$parrafo = 'parrafo'; + +echo 100; // Haz echo de escalares directamente +echo $parrafo; // o de variables + +// Si las etiquetas cortas estás configuradas y tu versión de PHP es +// la 5.4.0 o superior, puede utilizar la sintaxis abreviada de echo +?> +<p><?= $parrafo?></p> +<?php + +$x = 1; +$y = 2; +$x = $y; // $x ahora contiene el mismo valor que $y +$z = &$y; +// $z contiene ahora una referencia a $y. Un cambio en el valor de +// $z cambiará también el valor de $y, y viceversa. +// $x sin embargo, tendrá el valor original de $y + +echo $x; // => 2 +echo $z; // => 2 +$y = 0; +echo $x; // => 2 +echo $z; // => 0 + +// Dump muestra el tipo y valor de una variable en stdout +var_dump($z); // imprime int(0) + +// Para mostrar el valor de una variable en un formato legible para humanos +print_r($array); // imprime: Array ( [0] => Uno [1] => Dos [2] => Tres ) + +/******************************** + * Lógica + */ +$a = 0; +$b = '0'; +$c = '1'; +$d = '1'; + +// assert lanza una advertencia si su argumento no es verdadero + +// Estas comparaciones siempre serán verdaderas, incluso si los tipos no son los mismos. +assert($a == $b); // igualdad +assert($c != $a); // desigualdad +assert($c <> $a); // desigualdad alternativa +assert($a < $c); +assert($c > $b); +assert($a <= $b); +assert($c >= $d); + +// Los siguiente solo será verdadero si los valores coinciden y son del mismo tipo. +assert($c === $d); +assert($a !== $d); +assert(1 === '1'); +assert(1 !== '1'); + +// Operador 'Spaceship' (desde PHP 7) +// Devuelve 0 si ambos valores son iguales +// Devuelve 1 si el valor de la izquierda es mayor +// Devuelve -1 si el valor de la derecha es mayor + +$a = 100; +$b = 1000; + +echo $a <=> $a; // 0 porque son iguales +echo $a <=> $b; // -1 porque $a < $b +echo $b <=> $a; // 1 porque $b > $a + +// Las variables pueden ser convertidas entre tipos, dependiendo de su uso. + +$entero = 1; +echo $entero + $entero; // => 2 + +$string = '1'; +echo $string + $string; // => 2 (los strings son convertidos a enteros) + +$string = 'uno'; +echo $string + $string; // => 0 +// Muestra un 0 porque el operador + no puede convertir la cadena de caracteres 'uno' a un número + +// La conversión de tipos puede ser utilizada para tratar a una variable como otro tipo + +$boolean = (boolean) 1; // => true + +$cero = 0; +$boolean = (boolean) $cero; // => false + +// También hay funciones dedicadas a la conversión de tipos +$entero = 5; +$string = strval($entero); + +$var = null; // Valor nulo + + +/******************************** + * Estructuras de control + */ + +if (true) { + print 'He sido imprimido'; +} + +if (false) { + print 'Yo no'; +} else { + print 'He sido imprimido'; +} + +if (false) { + print 'No se imprime'; +} elseif(true) { + print 'Sí se imprime'; +} + +// operador ternario +print (false ? 'No se imprime' : 'Sí se imprime'); + +// atajo para el operador ternario desde PHP 5.3 +// equivalente de "$x ? $x : 'Sí'"" +$x = false; +print($x ?: 'Sí'); + +// operador 'no definido' desde php 7 +$a = null; +$b = 'Imprime'; +echo $a ?? 'a no está definido'; // imprime 'a no está definido' +echo $b ?? 'b no está definido'; // imprime 'Imprime' + + +$x = 0; +if ($x === '0') { + print 'No imprime'; +} elseif($x == '1') { + print 'No imprime'; +} else { + print 'Imprime'; +} + + + +// Esta sintaxis alternativa se utiliza para plantillas: +?> + +<?php if ($x): ?> +Esto se muestra si la evaluación es verdadera. +<?php else: ?> +En otro caso, se muestra esto. +<?php endif; ?> + +<?php + +// Utiliza el switch para tener algo más de lógica. +switch ($x) { + case '0': + print 'Switch does type coercion'; + break; // Debes incluir un break para no seguir con los casos 'Dos' y 'Tres' + case 'Dos': + case 'Tres': + // Hacer algo si la variables es 'Dos' o 'Tres' + break; + default: + // Hacer algo por defecto +} + +// Los bucles While, do...while y for te serán familiares +$i = 0; +while ($i < 5) { + echo $i++; +}; // Imprime "01234" + +echo "\n"; + +$i = 0; +do { + echo $i++; +} while ($i < 5); // Imprime "01234" + +echo "\n"; + +for ($x = 0; $x < 10; $x++) { + echo $x; +} // Imprime "0123456789" + +echo "\n"; + +$ruedas = ['bicicleta' => 2, 'coche' => 4]; + +// Los bucles foreach pueden iterar por arrays +foreach ($ruedas as $numero_ruedas) { + echo $numero_ruedas; +} // Imprime "24" + +echo "\n"; + +// También se puede iterar sobre las claves, así como sobre los valores +foreach ($ruedas as $vehiculo => $numero_ruedas) { + echo "Un $vehiculo tiene $numero_ruedas ruedas"; +} + +echo "\n"; + +$i = 0; +while ($i < 5) { + if ($i === 3) { + break; // Sale fuera del bucle while + } + echo $i++; +} // Imprime "012" + +for ($i = 0; $i < 5; $i++) { + if ($i === 3) { + continue; // Se salta esta iteración del bucle + } + echo $i; +} // Imprime "0124" + + +/******************************** + * Funciones + */ + +// Define una función con "function": +function mi_funcion () { + return 'Hola'; +} + +echo mi_funcion(); // => "Hola" + +// Un nombre válido de función comienza con una letra o guión bajo, seguido de cualquier +// número de letras, números o guiones bajos. + +function anadir ($x, $y = 1) { // $y es opcional y por defecto es 1 + $resultado = $x + $y; + return $resultado; +} + +echo anadir(4); // => 5 +echo anadir(4, 2); // => 6 + +// $resultado no es accesible fuera de la función +// print $resultado; // Devuelve una advertencia. + +// Desde PHP 5.3 se pueden declarar funciones anónimas +$inc = function ($x) { + return $x + 1; +}; + +echo $inc(2); // => 3 + +function foo ($x, $y, $z) { + echo "$x - $y - $z"; +} + +// Las funciones pueden devolver funciones +function bar ($x, $y) { + // Utiliza 'use' para meter variables de fuera de la función + return function ($z) use ($x, $y) { + foo($x, $y, $z); + }; +} + +$bar = bar('A', 'B'); +$bar('C'); // Imprime "A - B - C" + +// Puedes llamar a funciones utilizando cadenas de caracteres +$nombre_funcion = 'add'; +echo $nombre_funcion(1, 2); // => 3 +// Es útil para determinarl qué función ejecutar. +// O, utiliza call_user_func(callable $callback [, $parameter [, ... ]]); + + +// Puedes obtener todos los parámetros pasados a una función +function parametros() { + $numero_argumentos = func_num_args(); + if ($numero_argumentos > 0) { + echo func_get_arg(0) . ' | '; + } + $args_array = func_get_args(); + foreach ($args_array as $key => $arg) { + echo $key . ' - ' . $arg . ' | '; + } +} + +parametros('Hola', 'Mundo'); // Hola | 0 - Hola | 1 - Mundo | + +// Desde PHP 5.6 se puede obtener un número variable de argumentos +function variable($palabra, ...$lista) { + echo $palabra . " || "; + foreach ($lista as $item) { + echo $item . ' | '; + } +} + +variable("Separa", "Hola", "Mundo") // Separa || Hola | Mundo | + +/******************************** + * Includes + */ + +<?php +// Los ficheros PHP incluidos deben comenzar también con la etiqueta de <?php + +include 'mi-fichero.php'; +// El código de mi-fichero.php ya está disponible en el entorno actual. +// Si el fichero no puede ser incluido (por ejemplo porque no se ha encontrado), +// se muestra una advertencia. + +include_once 'mi-fichero.php'; +// Si el código del fichero mi-fichero.php ya ha sido incluido, ya no se +// incluirá de nuevo. Este previene errores por múltiples declaraciones. + +require 'mi-fichero.php'; +require_once 'mi-fichero.php'; +// Es lo mismo que el include(), pero require() causará un error fatal si el archivo +// no ha podido ser incluido. + +// Contenido de mi-include.php: +<?php + +return 'Cualquier cosa.'; +// acabar archivo + +// Los include y require también pueden devolver un valor. +$valor = include 'mi-include.php'; + +// Los archivos son incluidos en función de la ruta data o, si ninguna ruta es +// especificada se utilizará la directiva de configuración de include_path. Si el +// fichero no se encuentra en el include_path, include comprobará la ruta del código +// que lo llama antes de fallar. +/* */ + +/******************************** + * Clases + */ + +// Las clases son definidas con la palabra clave class + +class MiClase +{ + const MI_CONSTANTE = 'valor'; // Una constante + + static $staticVar = 'static'; + + // Las variables estáticas y su visibilidad + public static $publicStaticVar = 'publicStatic'; + // Accesible solo dentro de su clase + private static $privateStaticVar = 'privateStatic'; + // Accesible desde la clase y las subclases + protected static $protectedStaticVar = 'protectedStatic'; + + // Las propiedades deben declarar su visibilidad + public $propiedad = 'public'; + public $instanceProp; + protected $prot = 'protected'; // Accesible desde la clase y las subclases + private $priv = 'private'; // Accesible solo desde la clase + + // Crear un constructor con __construct + public function __construct($instanceProp) { + // Accede a las variables de la instancia con $this + $this->instanceProp = $instanceProp; + } + + // Los métodos son declarados como funciones dentro de una clase + public function miMetodo() + { + print 'MiClase'; + } + + // la palabra clave final hará una función no sobreescribible + final function noMePuedesSobreEscribir() + { + } + +/* + * Declarar propiedades de clase o métodos como estáticos los hace accesibles sin + * necesidad de instanciar la clase. Una propiedad declarada como estática no + * puede ser accedida mediante una instancia de la clase, pero sí mediante un + * método estático. + */ + + public static function miMetodoEstatico() + { + print 'Soy estático'; + } +} + +// Las constantes de una clase siempre pueden ser accedidas estáticamente +echo MiClase::MI_CONSTANTE; // Muestra 'valor'; + +echo MiClase::$staticVar; // Muestra 'static'; +MiClase::miMetodoEstatico(); // Muestra 'Soy estático'; + +// Instancia una clase usando new +$mi_clase = new MiClase('Una instancia'); +// Los paréntesis son opcionales si no se pasa ningún argumento. + +// Accede a los miembros de una clase utilizando -> +echo $mi_clase->propiedad; // => "public" +echo $mi_clase->instanceProp; // => "Una instancia" +$mi_clase->miMetodo(); // => "MiClase" + + +// Extender clases utilizando "extends" +class MiOtraClase extends MiClase +{ + function imprimePropiedadProtegida() + { + echo $this->prot; + } + + // Sobreescribe un método + function miMetodo() + { + parent::miMetodo(); + print ' > MiOtraClase'; + } +} + +$mi_otra_clase = new MiOtraClase('Propiedad de instancia'); +$mi_otra_clase->imprimePropiedadProtegida(); // => Imprime "protected" +$mi_otra_clase->miMetodo(); // Imprime "MiClase > MiOtraClase" + +final class NoMePuedesExtender +{ +} + +// Puedes utilizar "métodos mágicos" para crear los getters y setters +class MiClaseMapeada +{ + private $propiedad; + + public function __get($key) + { + return $this->$key; + } + + public function __set($key, $value) + { + $this->$key = $value; + } +} + +$x = new MiClaseMapeada(); +echo $x->propiedad; // Utilizará el método __get() +$x->propiedad = 'Algo'; // Utilizará el método __set() + +// Las clases pueden ser abstractas (utilizando la palabra clave abstract) o +// implementando interfaces (utilizando la palabra clave implements). +// Una interfaz puede ser declarada con la palabra clave interface. + +interface InterfazUno +{ + public function hazAlgo(); +} + +interface InterfazDos +{ + public function hazOtraCosa(); +} + +// las interfaces pueden ser extendidas +interface InterfazTres extends InterfazDos +{ + public function hazCualquierOtraCosa(); +} + +abstract class MiClaseAbstracta implements InterfazUno +{ + public $x = 'hazAlgo'; +} + +class MiOtraClase extends MiClaseAbstracta implements InterfazDos +{ + public function hazAlgo() + { + echo $x; + } + + public function hazOtraCosa() + { + echo 'hazOtraCosa'; + } +} + + +// Las clases pueden implementar más de una interfaz +class CualquierOtraClase implements InterfazUno, InterfazDos +{ + public function hazAlgo() + { + echo 'hazAlgo'; + } + + public function hazOtraCosa() + { + echo 'hazOtraCosa'; + } +} + + +/******************************** + * Traits + */ + +// Los traits están disponibles desde PHP 5.4.0 y son declarados utilizando "trait" + +trait MiTrait +{ + public function miMetodoTrait() + { + print 'Tengo trait'; + } +} + +class MiClaseTrait +{ + use MiTrait; +} + +$cls = new MiClaseTrait(); +$cls->miMetodoTrait(); // Imprime "Tengo trait" + + +/******************************** + * Namespaces + */ + +// Esta sección está separada porque una declaración de namespace debe +// ser la primera sentencia en un archivo. Vamos a suponer que no es el caso + +<?php + +// Por defecto, las clases existen en el namespace global y pueden ser llamadas +// explícitamente con una contrabarra. + +$cls = new \MiClase(); + + + +// Estableder el namespace para un archivo +namespace Mi\Namespace; + +class MiClase +{ +} + +// (de otro archivo) +$cls = new Mi\Namespace\MiClase; + +// O de otro namespace. +namespace Mi\Otro\Namespace; + +use Mi\Namespace\MiClase; + +$cls = new MiClase(); + +// O se puede asignar un ales al namespace + +namespace Mi\Otro\Namespace; + +use Mi\Namespace as OtroNamespace; + +$cls = new OtroNamespace\MiClase(); + + +/********************** +* Late Static Binding +* +*/ + +class ClasePadre { + public static function quien() { + echo "Soy una " . __CLASS__ . "\n"; + } + public static function test() { + // Auto referencia a la clase en la que el método está definido + self::quien(); + // Referencia estáticamente a la clase donde el método ha sido llamado + static::quien(); + } +} + +ClasePadre::test(); +/* +Soy una ClasePadre +Soy una ClasePadre +*/ + +class ClaseHija extends ClasePadre { + public static function quien() { + echo "Pero soy una " . __CLASS__ . "\n"; + } +} + +ClaseHija::test(); +/* +Soy una ClasePadre +Pero soy una ClaseHija +*/ + + +/********************** +* Manejo de errores +* +*/ + +// Una simple gestión de errores puede ser realizada con un bloque try catch + +try { + // Haz algo +} catch (Exception $e) { + // Maneja la excepción +} + +// Cuando se utilicen bloques try catch en un entorno con namespaces hay que +// usar lo siguiente + +try { + // Haz algo +} catch (\Exception $e) { + // Maneja la excepción +} + +// Excepciones personalizadas + +class MiExcepcion extends Exception {} + +try { + + $condicion = true; + + if ($condicion) { + throw new MiExcepcion('Ha pasado algo'); + } + +} catch (MiExcepcion $e) { + // Manejar la excepción +} + +``` + +## Más información + +Visita la [documentación oficial de PHP](http://www.php.net/manual/) para más referencias +y apoyo de la comunidad. + +Si estás interesado en buenas prácticas, visita +[PHP The Right Way](http://www.phptherightway.com/). + +Si vienes de un lenguaje con una buena gestión de paquetes, visita +[Composer](http://getcomposer.org/). + +Para estándares comunes, visita el PHP Framework Interoperability Group +[PSR standards](https://github.com/php-fig/fig-standards). diff --git a/es-es/python3-es.html.markdown b/es-es/python3-es.html.markdown index 1c69481a..05fd7065 100644 --- a/es-es/python3-es.html.markdown +++ b/es-es/python3-es.html.markdown @@ -97,7 +97,7 @@ not False # => True None # => None # No uses el símbolo de igualdad `==` para comparar objetos con None -# Usa `is` en lugar de +# Usa `is` en su lugar "etc" is None #=> False None is None #=> True @@ -383,7 +383,7 @@ def keyword_args(**kwargs): keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"} -# You can do both at once, if you like# Puedes hacer ambas a la vez si quieres +# Puedes hacer ambas a la vez si quieres def todos_los_argumentos(*args, **kwargs): print args print kwargs @@ -478,7 +478,7 @@ Humano.roncar() #=> "*roncar*" # Puedes importar módulos import math -print(math.sqrt(16)) #=> 4 +print(math.sqrt(16)) #=> 4.0 # Puedes obtener funciones específicas desde un módulo from math import ceil, floor @@ -511,7 +511,7 @@ def duplicar_numeros(iterable): for i in iterable: yield i + i -# Un generador cera valores sobre la marcha. +# Un generador crea valores sobre la marcha. # En vez de generar y retornar todos los valores de una vez, crea uno en cada iteración. # Esto significa que valores más grandes que 15 no serán procesados en 'duplicar_numeros'. # Fíjate que 'range' es un generador. Crear una lista 1-900000000 tomaría mucho tiempo en crearse. diff --git a/es-es/ruby-es.html.markdown b/es-es/ruby-es.html.markdown index 66a5d0fe..e3e43c18 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 --- @@ -19,7 +29,7 @@ Nadie los usa. Tu tampoco deberías =end -# Lo primero y principal: Todo es un objeto +# En primer lugar: Todo es un objeto # Los números son objetos @@ -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 @@ -103,7 +128,7 @@ ruta = '/mal/nombre/' # Los símbolos (son objetos) # Los símbolos son inmutables, constantes reusables representadas internamente por un -# valor entero. Son usalmente usados en vez de strings para expresar eficientemente +# valor entero. Son normalmente usados en vez de strings para expresar eficientemente # valores específicos y significativos :pendiente.class #=> Symbol @@ -119,18 +144,19 @@ 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] +# Al igual que en aritmética, el acceso como variable[índice] # es sólo azúcar sintáctica # para llamar el método [] de un objeto arreglo.[] 0 #=> 1 @@ -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. diff --git a/es-es/swift-es.html.markdown b/es-es/swift-es.html.markdown new file mode 100644 index 00000000..c04ab02b --- /dev/null +++ b/es-es/swift-es.html.markdown @@ -0,0 +1,596 @@ +--- +language: swift +contributors: + - ["Grant Timmerman", "http://github.com/grant"] + - ["Christopher Bess", "http://github.com/cbess"] + - ["Joey Huang", "http://github.com/kamidox"] + - ["Anthony Nguyen", "http://github.com/anthonyn60"] +translators: + - ["David Hsieh", "http://github.com/deivuh"] +lang: es-es +filename: learnswift-es.swift +--- + +Swift es un lenguaje de programación para el desarrollo en iOS y OS X creado +por Apple. Diseñado para coexistir con Objective-C y ser más resistente contra +el código erroneo, Swift fue introducido en el 2014 en el WWDC, la conferencia +de desarrolladores de Apple. + +Véase también la guía oficial de Apple, [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/), el cual tiene un completo tutorial de Swift. + + +```swift +// Importar un módulo +import UIKit + +// +// MARK: Básicos +// + +// XCode soporta referencias para anotar tu código y agregarlos a lista de la +// barra de saltos. +// MARK: Marca de sección +// TODO: Hacer algo pronto +// FIXME: Arreglar este código + +// En Swift 2, println y print fueron combinados en un solo método print. +// Print añade una nueva línea automáticamente. +print("Hola, mundo") // println ahora es print +print("Hola, mundo", appendNewLine: false) // print sin agregar nueva línea + +// Valores de variables (var) pueden cambiar después de ser asignados +// Valores de constrantes (let) no pueden cambiarse después de ser asignados + +var myVariable = 42 +let øπΩ = "value" // nombres de variable unicode +let π = 3.1415926 +let convenience = "keyword" // nombre de variable contextual +// Las declaraciones pueden ser separadas por punto y coma (;) +let weak = "keyword"; let override = "another keyword" +// Los acentos abiertos (``) permiten utilizar palabras clave como nombres de +// variable +let `class` = "keyword" +let explicitDouble: Double = 70 +let intValue = 0007 // 7 +let largeIntValue = 77_000 // 77000 +let label = "some text " + String(myVariable) // Conversión (casting) +let piText = "Pi = \(π), Pi 2 = \(π * 2)" // Interpolación de string + +// Valores específicos de la compilación (build) +// utiliza la configuración -D +#if false + print("No impreso") + let buildValue = 3 +#else + let buildValue = 7 +#endif +print("Build value: \(buildValue)") // Build value: 7 + +/* + Las opcionales son un aspecto del lenguaje Swift que permite el + almacenamiento de un valor `Some` (algo) o `None` (nada). + + Debido a que Swift requiere que cada propiedad tenga un valor, + hasta un valor 'nil' debe de ser explicitamente almacenado como un + valor opcional. + + Optional<T> es un enum. +*/ +var someOptionalString: String? = "opcional" // Puede ser nil +// Al igual que lo anterior, pero ? es un operador postfix (sufijo) +var someOptionalString2: Optional<String> = "opcional" + +if someOptionalString != nil { + // No soy nil + if someOptionalString!.hasPrefix("opt") { + print("Tiene el prefijo") + } + + let empty = someOptionalString?.isEmpty +} +someOptionalString = nil + +// Opcional implícitamente desenvuelto +var unwrappedString: String! = "Un valor esperado." +// Al igual que lo anterior, pero ! es un operador postfix (sufijo) +var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Un valor esperado." + +if let someOptionalStringConstant = someOptionalString { + // tiene valor `Some` (algo), no nil + if !someOptionalStringConstant.hasPrefix("ok") { + // No tiene el prefijo + } +} + +// Swift tiene soporte de almacenamiento para cualquier tipo de valor. +// AnyObject == id +// A diferencia de Objective-C `id`, AnyObject funciona con cualquier +// valor (Class, Int, struct, etc) +var anyObjectVar: AnyObject = 7 +anyObjectVar = "Cambiado a un valor string, no es buena práctica, pero posible." + +/* + Comentar aquí + + /* + Comentarios anidados también son soportados + */ +*/ + +// +// MARK: Colecciones +// + +/* + Tipos Array (arreglo) y Dictionary (diccionario) son structs (estructuras). + Así que `let` y `var` también indican si son mudables (var) o + inmutables (let) durante la declaración de sus tipos. +*/ + +// Array (arreglo) +var shoppingList = ["catfish", "water", "lemons"] +shoppingList[1] = "bottle of water" +let emptyArray = [String]() // let == inmutable +let emptyArray2 = Array<String>() // igual que lo anterior +var emptyMutableArray = [String]() // var == mudable + + +// Dictionary (diccionario) +var occupations = [ + "Malcolm": "Captain", + "kaylee": "Mechanic" +] +occupations["Jayne"] = "Public Relations" +let emptyDictionary = [String: Float]() // let == inmutable +let emptyDictionary2 = Dictionary<String, Float>() // igual que lo anterior +var emptyMutableDictionary = [String: Float]() // var == mudable + + +// +// MARK: Flujo de control +// + +// Ciclo for (array) +let myArray = [1, 1, 2, 3, 5] +for value in myArray { + if value == 1 { + print("Uno!") + } else { + print("No es uno!") + } +} + +// Ciclo for (dictionary) +var dict = ["uno": 1, "dos": 2] +for (key, value) in dict { + print("\(key): \(value)") +} + +// Ciclo for (range) +for i in -1...shoppingList.count { + print(i) +} +shoppingList[1...2] = ["steak", "peacons"] +// Utilizar ..< para excluir el último valor + +// Ciclo while +var i = 1 +while i < 1000 { + i *= 2 +} + +// Ciclo do-while +do { + print("Hola") +} while 1 == 2 + +// Switch +// Muy potente, se puede pensar como declaraciones `if` con _azúcar sintáctico_ +// Soportan String, instancias de objetos, y primitivos (Int, Double, etc) +let vegetable = "red pepper" +switch vegetable { +case "celery": + let vegetableComment = "Add some raisins and make ants on a log." +case "cucumber", "watercress": + let vegetableComment = "That would make a good tea sandwich." +case let localScopeValue where localScopeValue.hasSuffix("pepper"): + let vegetableComment = "Is it a spicy \(localScopeValue)?" +default: // obligatorio (se debe cumplir con todos los posibles valores de entrada) + let vegetableComment = "Everything tastes good in soup." +} + + +// +// MARK: Funciones +// + +// Funciones son un tipo de primera-clase, quiere decir que pueden ser anidados +// en funciones y pueden ser pasados como parámetros + +// Función en documentación de cabeceras Swift (formato reStructedText) + +/** + Una operación de saludo + + - Una viñeta en la documentación + - Otra viñeta en la documentación + + :param: name Un nombre + :param: day Un día + :returns: Un string que contiene el valor de name y day +*/ +func greet(name: String, day: String) -> String { + return "Hola \(name), hoy es \(day)." +} +greet("Bob", "Martes") + +// Similar a lo anterior, a excepción del compartamiento de los parámetros +// de la función +func greet2(requiredName: String, externalParamName localParamName: String) -> String { + return "Hola \(requiredName), hoy es el día \(localParamName)" +} +greet2(requiredName:"John", externalParamName: "Domingo") + +// Función que devuelve múltiples valores en una tupla +func getGasPrices() -> (Double, Double, Double) { + return (3.59, 3.69, 3.79) +} +let pricesTuple = getGasPrices() +let price = pricesTuple.2 // 3.79 +// Ignorar tupla (u otros) valores utilizando _ (guión bajo) +let (_, price1, _) = pricesTuple // price1 == 3.69 +print(price1 == pricesTuple.1) // true +print("Gas price: \(price)") + +// Cantidad variable de argumentos +func setup(numbers: Int...) { + // Es un arreglo + let number = numbers[0] + let argCount = numbers.count +} + +// Pasando y devolviendo funciones +func makeIncrementer() -> (Int -> Int) { + func addOne(number: Int) -> Int { + return 1 + number + } + return addOne +} +var increment = makeIncrementer() +increment(7) + +// Pasando como referencia +func swapTwoInts(inout a: Int, inout b: Int) { + let tempA = a + a = b + b = tempA +} +var someIntA = 7 +var someIntB = 3 +swapTwoInts(&someIntA, &someIntB) +print(someIntB) // 7 + + +// +// MARK: Closures (Clausuras) +// +var numbers = [1, 2, 6] + +// Las funciones son un caso especial de closure ({}) + +// Ejemplo de closure. +// `->` Separa los argumentos del tipo de retorno +// `in` Separa la cabecera del cuerpo del closure +numbers.map({ + (number: Int) -> Int in + let result = 3 * number + return result +}) + +// Cuando se conoce el tipo, como en lo anterior, se puede hacer esto +numbers = numbers.map({ number in 3 * number }) +// o esto +//numbers = numbers.map({ $0 * 3 }) + +print(numbers) // [3, 6, 18] + +// Closure restante +numbers = sorted(numbers) { $0 > $1 } + +print(numbers) // [18, 6, 3] + +// Bastante corto, debido a que el operador < infiere los tipos + +numbers = sorted(numbers, < ) + +print(numbers) // [3, 6, 18] + +// +// MARK: Estructuras +// + +// Las estructuras y las clases tienen capacidades similares +struct NamesTable { + let names = [String]() + + // Subscript personalizado + subscript(index: Int) -> String { + return names[index] + } +} + +// Las estructuras tienen un inicializador designado autogenerado (implícitamente) +let namesTable = NamesTable(names: ["Me", "Them"]) +let name = namesTable[1] +print("Name is \(name)") // Name is Them + +// +// MARK: Clases +// + +// Las clases, las estructuras y sus miembros tienen tres niveles de control de acceso +// Éstos son: internal (predeterminado), public, private + +public class Shape { + public func getArea() -> Int { + return 0; + } +} + +// Todos los métodos y las propiedades de una clase son public (públicas) +// Si solo necesitas almacenar datos en un objecto estructurado, +// debes de utilizar `struct` + +internal class Rect: Shape { + var sideLength: Int = 1 + + // Getter y setter personalizado + private var perimeter: Int { + get { + return 4 * sideLength + } + set { + // `newValue` es una variable implícita disponible para los setters + sideLength = newValue / 4 + } + } + + // Lazily loading (inicialización bajo demanda) a una propiedad + // subShape queda como nil (sin inicializar) hasta que getter es llamado + lazy var subShape = Rect(sideLength: 4) + + // Si no necesitas un getter y setter personalizado + // pero aún quieres ejecutar código antes y después de hacer get o set + // a una propiedad, puedes utilizar `willSet` y `didSet` + var identifier: String = "defaultID" { + // El argumento `willSet` será el nombre de variable para el nuevo valor + willSet(someIdentifier) { + print(someIdentifier) + } + } + + init(sideLength: Int) { + self.sideLength = sideLength + // Siempre poner super.init de último al momento de inicializar propiedades + // personalizadas + super.init() + } + + func shrink() { + if sideLength > 0 { + --sideLength + } + } + + override func getArea() -> Int { + return sideLength * sideLength + } +} + +// Una clase simple `Square` que extiende de `Rect` +class Square: Rect { + convenience init() { + self.init(sideLength: 5) + } +} + +var mySquare = Square() +print(mySquare.getArea()) // 25 +mySquare.shrink() +print(mySquare.sideLength) // 4 + +// Conversión de tipo de instancia +let aShape = mySquare as Shape + +// Comparar instancias, no es igual a == que compara objetos (equal to) +if mySquare === mySquare { + print("Yep, it's mySquare") +} + +// Inicialización (init) opcional +class Circle: Shape { + var radius: Int + override func getArea() -> Int { + return 3 * radius * radius + } + + // Un signo de interrogación como sufijo después de `init` es un init opcional + // que puede devolver nil + init?(radius: Int) { + self.radius = radius + super.init() + + if radius <= 0 { + return nil + } + } +} + +var myCircle = Circle(radius: 1) +print(myCircle?.getArea()) // Optional(3) +print(myCircle!.getArea()) // 3 +var myEmptyCircle = Circle(radius: -1) +print(myEmptyCircle?.getArea()) // "nil" +if let circle = myEmptyCircle { + // no será ejecutado debido a que myEmptyCircle es nil + print("circle is not nil") +} + + +// +// MARK: Enums +// + + +// Los enums pueden ser opcionalmente de un tipo específico o de su propio tipo +// Al igual que las clases, pueden contener métodos + +enum Suit { + case Spades, Hearts, Diamonds, Clubs + func getIcon() -> String { + switch self { + case .Spades: return "♤" + case .Hearts: return "♡" + case .Diamonds: return "♢" + case .Clubs: return "♧" + } + } +} + +// Los valores de enum permite la sintaxis corta, sin necesidad de poner +// el tipo del enum cuando la variable es declarada de manera explícita +var suitValue: Suit = .Hearts + +// Enums de tipo no-entero requiere asignaciones de valores crudas directas +enum BookName: String { + case John = "John" + case Luke = "Luke" +} +print("Name: \(BookName.John.rawValue)") + +// Enum con valores asociados +enum Furniture { + // Asociación con Int + case Desk(height: Int) + // Asociación con String e Int + case Chair(String, Int) + + func description() -> String { + switch self { + case .Desk(let height): + return "Desk with \(height) cm" + case .Chair(let brand, let height): + return "Chair of \(brand) with \(height) cm" + } + } +} + +var desk: Furniture = .Desk(height: 80) +print(desk.description()) // "Desk with 80 cm" +var chair = Furniture.Chair("Foo", 40) +print(chair.description()) // "Chair of Foo with 40 cm" + + +// +// MARK: Protocolos +// + +// `protocol` puede requerir que los tipos tengan propiedades +// de instancia específicas, métodos de instancia, métodos de tipo, +// operadores, y subscripts + + +protocol ShapeGenerator { + var enabled: Bool { get set } + func buildShape() -> Shape +} + +// Protocolos declarados con @objc permiten funciones opcionales, +// que te permite evaluar conformidad +@objc protocol TransformShape { + optional func reshaped() + optional func canReshape() -> Bool +} + +class MyShape: Rect { + var delegate: TransformShape? + + func grow() { + sideLength += 2 + + // Pon un signo de interrogación después de la propiedad opcional, + // método, o subscript para ignorar un valor nil y devolver nil + // en lugar de tirar un error de tiempo de ejecución + // ("optional chaining") + if let allow = self.delegate?.canReshape?() { + // test for delegate then for method + self.delegate?.reshaped?() + } + } +} + + +// +// MARK: Otros +// + +// `extension`: Agrega funcionalidades a tipos existentes + +// Square ahora se "conforma" al protocolo `Printable` +extension Square: Printable { + var description: String { + return "Area: \(self.getArea()) - ID: \(self.identifier)" + } +} + +print("Square: \(mySquare)") + +// También puedes hacer extend a tipos prefabricados (built-in) +extension Int { + var customProperty: String { + return "This is \(self)" + } + + func multiplyBy(num: Int) -> Int { + return num * self + } +} + +print(7.customProperty) // "This is 7" +print(14.multiplyBy(3)) // 42 + +// Generics: Similar Java y C#. Utiliza la palabra clave `where` para +// especificar los requerimientos de los genéricos. + +func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? { + for (index, value) in enumerate(array) { + if value == valueToFind { + return index + } + } + return nil +} +let foundAtIndex = findIndex([1, 2, 3, 4], 3) +print(foundAtIndex == 2) // true + +// Operadores: +// Operadores personalizados puede empezar con los siguientes caracteres: +// / = - + * % < > ! & | ^ . ~ +// o +// Caracteres unicode: math, symbol, arrow, dingbat, y line/box. +prefix operator !!! {} + +// Un operador prefix que triplica la longitud del lado cuando es utilizado +prefix func !!! (inout shape: Square) -> Square { + shape.sideLength *= 3 + return shape +} + +// Valor actual +print(mySquare.sideLength) // 4 + +// Cambiar la longitud del lado utilizando el operador !!!, +// incrementa el tamaño por 3 +!!!mySquare +print(mySquare.sideLength) // 12 +``` diff --git a/es-es/tmux-es.html.markdown b/es-es/tmux-es.html.markdown new file mode 100644 index 00000000..a7354be1 --- /dev/null +++ b/es-es/tmux-es.html.markdown @@ -0,0 +1,253 @@ +--- +category: tool +tool: tmux +contributors: + - ["mdln", "https://github.com/mdln"] +filename: LearnTmux-es.txt +translators: + - ["Damaso Sanoja", "https://github.com/damasosanoja"] +lang: es-es +--- + + +[tmux](http://tmux.sourceforge.net) +es un terminal multiplexor: habilita la creación, acceso y control +de múltiples terminales controlados desde una sola pantalla. tmux +puede ser separado de una pantalla y continuar corriendo en el fondo +y luego ser insertado nuevamente. + + +``` + + tmux [command] # Corre un comando + # 'tmux' sin comandos creará una nueva sesión + + new # Crea una nueva sesión + -s "Session" # Crea sesión con nombre + -n "Window" # Crea ventana con nombre + -c "/dir" # Comienza en el directorio destino + + attach # Adjunta sesión última/disponible + -t "#" # Adjunta sesión destino + -d # Separa la sesión de otras instancias + + ls # Lista las sesiones abiertas + -a # Lista todas las sesiones abiertas + + lsw # Lista las ventanas + -a # Lista todas las ventanas + -s # Lista todas las ventanas en la sesión + + lsp # Lista los páneles + -a # Lista todos los páneles + -s # Lista todos los páneles de la sesión + -t # Lista los páneles de aplicación en el destino + + kill-window # Cierra la ventana actual + -t "#" # Cierra la ventana destino + -a # Cierra todas las ventanas + -a -t "#" # Cierra todas las ventanas menos el destino + + kill-session # Cierra la sesión actual + -t "#" # Cierra la sesión destino + -a # Cierra todas las sesiones + -a -t "#" # Cierra todas las sesiones menos el destino + +``` + + +### Atajos de Teclado + +El método para controlar una sesión adjunta tmux es mediante +combinaciones de teclas llamadas teclas 'Prefijo'. + +``` +---------------------------------------------------------------------- + (C-b) = Ctrl + b # combinación 'Prefijo' necesaria para usar atajos + + (M-1) = Meta + 1 -o- Alt + 1 +---------------------------------------------------------------------- + + ? # Lista todos los atajos de teclado + : # Entra en la línea de comandos tmux + r # Fuerza el redibujado del cliente adjuntado + c # Crea una nueva ventana + + ! # Separa el panel actual fuera de la ventana. + % # Separa el panel actual en dos, izquierdo y derecho + " # Separa el panel actual en dos, superior e inferior + + n # Cambia a la siguiente ventana + p # Cambia a la ventana previa + { # Intercambia el panel actual con el anterior + } # Intercambia el panel actual con el próximo + + s # Selecciona una nueva sesión para el cliente adjuntado + interactivamente + w # Elegir la ventana actual interactivamente + 0 al 9 # Seleccionar ventanas 0 al 9 + + d # Separa el cliente actual + D # Elige un cliente para separar + + & # Cierra la ventana actual + x # Cierra el panel actual + + Up, Down # Cambia al panel superior, inferior, izquierdo, o derecho + Left, Right + + M-1 to M-5 # Organizar páneles: + # 1) uniformes horizontales + # 2) uniformes verticales + # 3) principal horizontal + # 4) principal vertical + # 5) mozaico + + C-Up, C-Down # Redimensiona el panel actual en pasos de una celda + C-Left, C-Right + + M-Up, M-Down # Redimensiona el panel actual en pasos de cinco celdas + M-Left, M-Right + +``` + + +### Configurando ~/.tmux.conf + +tmux.conf puede usarse para establecer opciones automáticas al arrancar, parecido a como .vimrc o init.el hacen. + +``` +# Ejemplo de tmux.conf +# 2014.10 + + +### General +########################################################################### + +# Habilita UTF-8 +setw -g utf8 on +set-option -g status-utf8 on + +# Fuera de pantalla/Historia límite +set -g history-limit 2048 + +# Comienzo de índice +set -g base-index 1 + +# Ratón +set-option -g mouse-select-pane on + +# Forza recarga de fichero de configuración +unbind r +bind r source-file ~/.tmux.conf + + +### Atajos de teclado +########################################################################### + +# Desvincula C-b como el prefijo por defecto +unbind C-b + +# Establece el nuevo prefijo +set-option -g prefix ` + +# Regresa a la ventana previa cuando el prefijo es accionado dos veces +bind C-a last-window +bind ` last-window + +# Permite intercambiar C-a y ` usando F11/F12 +bind F11 set-option -g prefix C-a +bind F12 set-option -g prefix ` + +# Preferencias de atajos +setw -g mode-keys vi +set-option -g status-keys vi + +# Moviéndose entre paneles con movimientos de teclas vim +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R + +# Ciclo/Intercambio de Ventana +bind e previous-window +bind f next-window +bind E swap-window -t -1 +bind F swap-window -t +1 + +# División rápida de paneles +bind = split-window -h +bind - split-window -v +unbind '"' +unbind % + +# Activar sesión mas interna (cuando se anida tmux) para enviar comandos +bind a send-prefix + + +### Temas +########################################################################### + +# Paleta de Colores de la Barra de estado +set-option -g status-justify left +set-option -g status-bg black +set-option -g status-fg white +set-option -g status-left-length 40 +set-option -g status-right-length 80 + +# Paleta de Colores del Borde del Panel +set-option -g pane-active-border-fg green +set-option -g pane-active-border-bg black +set-option -g pane-border-fg white +set-option -g pane-border-bg black + +# Paleta de Colores de Mensajes +set-option -g message-fg black +set-option -g message-bg green + +# Paleta de Colores de la Ventana +setw -g window-status-bg black +setw -g window-status-current-fg green +setw -g window-status-bell-attr default +setw -g window-status-bell-fg red +setw -g window-status-content-attr default +setw -g window-status-content-fg yellow +setw -g window-status-activity-attr default +setw -g window-status-activity-fg yellow + + +### UI +########################################################################### + +# Notificación +setw -g monitor-activity on +set -g visual-activity on +set-option -g bell-action any +set-option -g visual-bell off + +# Establece automáticamente títulos de ventanas +set-option -g set-titles on +set-option -g set-titles-string '#H:#S.#I.#P #W #T' # window number,program name,active (or not) + +# Ajustes de barra de estado +set -g status-left "#[fg=red] #H#[fg=green]:#[fg=white]#S#[fg=green] |#[default]" + +# Muestra indicadores de rendimiento en barra de estado +# Requiere https://github.com/thewtex/tmux-mem-cpu-load/ +set -g status-interval 4 +set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] | #[fg=cyan]%H:%M #[default]" + +``` + + +### Referencias + +[Tmux | Inicio](http://tmux.sourceforge.net) + +[Tmux Manual](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux) + +[Gentoo Wiki](http://wiki.gentoo.org/wiki/Tmux) + +[Archlinux Wiki](https://wiki.archlinux.org/index.php/Tmux) + +[Mostrar CPU/MEM % en barra de estado](https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux) diff --git a/es-es/visualbasic-es.html.markdown b/es-es/visualbasic-es.html.markdown new file mode 100644 index 00000000..c7f581c0 --- /dev/null +++ b/es-es/visualbasic-es.html.markdown @@ -0,0 +1,286 @@ +--- +language: Visual Basic +contributors: + - ["Brian Martin", "http://brianmartin.biz"] +translators: + - ["Adolfo Jayme Barrientos", "https://github.com/fitojb"] +author: Brian Martin +author_url: https://github.com/fitojb +filename: learnvisualbasic-es.vb +lang: es-es +--- + +```vb +Module Module1 + + Sub Main() + ' Un vistazo rápido a las aplicaciones de consola de Visual Basic antes + ' de que profundicemos en el tema. + ' El apóstrofo inicia una línea de comentario. + ' Para explorar este tutorial dentro del Compilador de Visual Basic, + ' he creado un sistema de navegación. + ' Dicho sistema se explicará a medida que avancemos en este + ' tutorial; gradualmente entenderás lo que significa todo. + Console.Title = ("Aprende X en Y minutos") + Console.WriteLine("NAVEGACIÓN") 'Mostrar + Console.WriteLine("") + Console.ForegroundColor = ConsoleColor.Green + Console.WriteLine("1. Salida «Hola, mundo»") + Console.WriteLine("2. Entrada «Hola, mundo»") + Console.WriteLine("3. Calcular números enteros") + Console.WriteLine("4. Calcular números decimales") + Console.WriteLine("5. Una calculadora funcional") + Console.WriteLine("6. Uso de bucles «Do While»") + Console.WriteLine("7. Uso de bucles «For While»") + Console.WriteLine("8. Declaraciones condicionales") + Console.WriteLine("9. Selecciona una bebida") + Console.WriteLine("50. Acerca de") + Console.WriteLine("Elige un número de la lista anterior") + Dim selection As String = Console.ReadLine + Select Case selection + Case "1" 'Salida «hola, mundo» + Console.Clear() 'Limpia la consola y abre la subrutina privada + SalidaHolaMundo() 'Abre la subrutina privada nombrada + Case "2" 'Entrada «hola, mundo» + Console.Clear() + EntradaHolaMundo() + Case "3" 'Calcular números enteros + Console.Clear() + CalcularNumerosEnteros() + Case "4" 'Calcular números decimales + Console.Clear() + CalcularNumerosDecimales() + Case "5" 'Una calculadora funcional + Console.Clear() + CalculadoraFuncional() + Case "6" 'Uso de bucles «Do While» + Console.Clear() + UsoBuclesDoWhile() + Case "7" 'Uso de bucles «For While» + Console.Clear() + UsoBuclesFor() + Case "8" 'Declaraciones condicionales + Console.Clear() + DeclaracionCondicional() + Case "9" 'Declaración «If/Else» + Console.Clear() + DeclaracionIfElse() 'Selecciona una bebida + Case "50" 'Cuadro de mensaje «Acerca de» + Console.Clear() + Console.Title = ("Aprende X en Y minutos :: Acerca de") + MsgBox("Tutorial escrito por Brian Martin (@BrianMartinn") + Console.Clear() + Main() + Console.ReadLine() + + End Select + End Sub + + 'Uno - He usado números para guiarme por el sistema de navegación anterior + 'cuando regrese posteriormente a implementarlo. + + 'Usamos subrutinas privadas para separar distintas secciones del programa. + Private Sub SalidaHolaMundo() + 'Título de la aplicación de consola + Console.Title = "Salida «Hola, mundo» | Aprende X en Y minutos" + 'Usa Console.Write("") o Console.WriteLine("") para mostrar salidas. + 'Seguido por Console.Read(), o bien, Console.Readline() + 'Console.ReadLine() muestra la salida en la consola. + Console.WriteLine("Hola, mundo") + Console.ReadLine() + End Sub + + 'Dos + Private Sub EntradaHolaMundo() + Console.Title = "«Hola, mundo, soy...» | Aprende X en Y minutos" + ' Variables + ' Los datos que introduzca un usuario deben almacenarse. + ' Las variables también empiezan por Dim y terminan por As VariableType. + + ' En este tutorial queremos conocer tu nombre y hacer que el programa + ' responda a este. + Dim nombredeusuario As String + 'Usamos «string» porque es una variable basada en texto. + Console.WriteLine("Hola, ¿cómo te llamas? ") 'Preguntar nombre de usuario. + nombredeusuario = Console.ReadLine() 'Almacenar nombre del usuario. + Console.WriteLine("Hola, " + nombredeusuario) 'La salida es Hola, nombre + Console.ReadLine() 'Muestra lo anterior. + 'El código anterior te hará una pregunta y mostrará la respuesta. + 'Entre otras variables está Integer, la cual usaremos para números enteros. + End Sub + + 'Tres + Private Sub CalcularNumerosEnteros() + Console.Title = "Calcular números enteros | Aprende X en Y minutos" + Console.Write("Primer número: ") 'Escribe un núm. entero, 1, 2, 104, etc + Dim a As Integer = Console.ReadLine() + Console.Write("Segundo número: ") 'Escribe otro número entero. + Dim b As Integer = Console.ReadLine() + Dim c As Integer = a + b + Console.WriteLine(c) + Console.ReadLine() + 'Lo anterior es una calculadora sencilla + End Sub + + 'Cuatro + Private Sub CalcularNumerosDecimales() + Console.Title = "Calcular con tipo doble | Aprende X en Y minutos" + 'Por supuesto, nos gustaría sumar decimales. + 'Por ello podríamos cambiar del tipo Integer al Double. + + 'Escribe un número fraccionario, 1.2, 2.4, 50.1, 104.9 etc + Console.Write("Primer número: ") + Dim a As Double = Console.ReadLine + Console.Write("Segundo número: ") 'Escribe el segundo número. + Dim b As Double = Console.ReadLine + Dim c As Double = a + b + Console.WriteLine(c) + Console.ReadLine() + 'Este programa puede sumar 1.1 y 2.2 + End Sub + + 'Cinco + Private Sub CalculadoraFuncional() + Console.Title = "La calculadora funcional | Aprende X en Y minutos" + 'Pero si quieres que la calculadora reste, divida, multiplique y + 'sume. + 'Copia y pega lo anterior. + Console.Write("Primer número: ") + Dim a As Double = Console.ReadLine + Console.Write("Segundo número: ") + Dim b As Integer = Console.ReadLine + Dim c As Integer = a + b + Dim d As Integer = a * b + Dim e As Integer = a - b + Dim f As Integer = a / b + + 'Mediante las líneas siguientes podremos restar, + 'multiplicar y dividir los valores a y b + Console.Write(a.ToString() + " + " + b.ToString()) + 'Queremos dar un margen izquierdo de 3 espacios a los resultados. + Console.WriteLine(" = " + c.ToString.PadLeft(3)) + Console.Write(a.ToString() + " * " + b.ToString()) + Console.WriteLine(" = " + d.ToString.PadLeft(3)) + Console.Write(a.ToString() + " - " + b.ToString()) + Console.WriteLine(" = " + e.ToString.PadLeft(3)) + Console.Write(a.ToString() + " / " + b.ToString()) + Console.WriteLine(" = " + f.ToString.PadLeft(3)) + Console.ReadLine() + + End Sub + + 'Seis + Private Sub UsoBuclesDoWhile() + 'Igual que la subrutina privada anterior + 'Esta vez preguntaremos al usuario si quiere continuar (¿sí o no?) + 'Usamos el bucle Do While porque no sabemos si el usuario quiere + 'usar el programa más de una vez. + Console.Title = "Uso de bucles «Do While» | Aprende X en Y minutos" + Dim respuesta As String 'Usamos la variable «String» porque la resp. es texto + Do 'Comenzamos el programa con + Console.Write("Primer número: ") + Dim a As Double = Console.ReadLine + Console.Write("Segundo número: ") + Dim b As Integer = Console.ReadLine + Dim c As Integer = a + b + Dim d As Integer = a * b + Dim e As Integer = a - b + Dim f As Integer = a / b + + Console.Write(a.ToString() + " + " + b.ToString()) + Console.WriteLine(" = " + c.ToString.PadLeft(3)) + Console.Write(a.ToString() + " * " + b.ToString()) + Console.WriteLine(" = " + d.ToString.PadLeft(3)) + Console.Write(a.ToString() + " - " + b.ToString()) + Console.WriteLine(" = " + e.ToString.PadLeft(3)) + Console.Write(a.ToString() + " / " + b.ToString()) + Console.WriteLine(" = " + f.ToString.PadLeft(3)) + Console.ReadLine() + 'Preguntar si el usuario quiere continuar. Desafortunadamente, + 'distingue entre mayúsculas y minúsculas. + Console.Write("¿Quieres continuar? (s / n)") + 'El programa toma la variable, la muestra y comienza de nuevo. + respuesta = Console.ReadLine + 'La orden que hará funcionar esta variable es en este caso «s» + Loop While respuesta = "s" + + End Sub + + 'Siete + Private Sub UsoBuclesFor() + 'A veces el programa debe ejecutarse solo una vez. + 'En este programa contaremos a partir de 10. + + Console.Title = "Uso de bucles «For» | Aprende X en Y minutos" + 'Declarar Variable y desde qué número debe contar en Step -1, + 'Step -2, Step -3, etc. + For i As Integer = 10 To 0 Step -1 + Console.WriteLine(i.ToString) 'Muestra el valor del contador + Next i 'Calcular el valor nuevo + Console.WriteLine("Iniciar") '¡¡Comencemos el programa, nene!! + Console.ReadLine() '¡¡ZAS!! - Quizá me he emocionado bastante :) + End Sub + + 'Ocho + Private Sub DeclaracionCondicional() + Console.Title = "Declaraciones condicionales | Aprende X en Y minutos" + Dim nombredeUsuario As String = Console.ReadLine + Console.WriteLine("Hola, ¿cómo te llamas? ") 'Preguntar nombre de usuario. + nombredeUsuario = Console.ReadLine() 'Almacena el nombre de usuario. + If nombredeUsuario = "Adam" Then + Console.WriteLine("Hola, Adam") + Console.WriteLine("Gracias por crear este útil sitio web") + Console.ReadLine() + Else + Console.WriteLine("Hola, " + nombredeUsuario) + Console.WriteLine("¿Has visitado www.learnxinyminutes.com?") + Console.ReadLine() 'Termina y muestra la declaración anterior. + End If + End Sub + + 'Nueve + Private Sub DeclaracionIfElse() + Console.Title = "Declaración «If / Else» | Aprende X en Y minutos" + 'A veces es importante considerar más de dos alternativas. + 'A veces, algunas de estas son mejores. + 'Cuando esto sucede, necesitaríamos más de una declaración «if». + 'Una declaración «if» es adecuada para máquinas expendedoras. + 'En las que el usuario escribe un código (A1, A2, A3) para elegir. + 'Pueden combinarse todas las elecciones en una sola declaración «if». + + Dim seleccion As String = Console.ReadLine 'Valor de la selección + Console.WriteLine("A1. para 7Up") + Console.WriteLine("A2. para Fanta") + Console.WriteLine("A3. para Dr. Pepper") + Console.WriteLine("A4. para Coca-Cola") + Console.ReadLine() + If selection = "A1" Then + Console.WriteLine("7up") + Console.ReadLine() + ElseIf selection = "A2" Then + Console.WriteLine("fanta") + Console.ReadLine() + ElseIf selection = "A3" Then + Console.WriteLine("dr. pepper") + Console.ReadLine() + ElseIf selection = "A4" Then + Console.WriteLine("coca-cola") + Console.ReadLine() + Else + Console.WriteLine("Selecciona un producto") + Console.ReadLine() + End If + + End Sub + +End Module + +``` + +## Referencias + +Aprendí Visual Basic en la aplicación de consola. Esta me permitió entender los principios de la programación para, posteriormente, aprender otros lenguajes con facilidad. + +He creado un <a href="http://www.vbbootcamp.co.uk/" Title="Tutorial de Visual Basic">tutorial de Visual Basic</a> más exhaustivo para quienes quieran saber más. + +Toda la sintaxis es válida. Copia el código y pégalo en el compilador de Visual Basic y ejecuta (F5) el programa. |