summaryrefslogtreecommitdiffhomepage
path: root/es-es
diff options
context:
space:
mode:
Diffstat (limited to 'es-es')
-rw-r--r--es-es/bf-es.html.markdown (renamed from es-es/brainfuck-es.html.markdown)20
-rw-r--r--es-es/git-es.html.markdown14
-rw-r--r--es-es/javascript-es.html.markdown20
-rw-r--r--es-es/json-es.html.markdown16
-rw-r--r--es-es/latex-es.html.markdown213
-rw-r--r--es-es/markdown-es.html.markdown6
-rw-r--r--es-es/php-es.html.markdown825
-rw-r--r--es-es/python3-es.html.markdown8
-rw-r--r--es-es/ruby-es.html.markdown253
-rw-r--r--es-es/swift-es.html.markdown596
10 files changed, 1902 insertions, 69 deletions
diff --git a/es-es/brainfuck-es.html.markdown b/es-es/bf-es.html.markdown
index e33d672d..c93b8c3a 100644
--- a/es-es/brainfuck-es.html.markdown
+++ b/es-es/bf-es.html.markdown
@@ -1,5 +1,5 @@
---
-language: brainfuck
+language: bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
@@ -9,8 +9,10 @@ lang: es-es
---
Brainfuck (con mayúscula sólo al inicio de una oración) es un
-lenguaje de programación mínimo, computacionalmente universal
-en tamaño con sólo 8 comandos.
+lenguaje de programación extremadamente pequeño, Turing completo con sólo 8 comandos.
+
+Puedes probar brainfuck en tu navegador con [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/).
+
```
@@ -18,7 +20,7 @@ Cualquier caracter que no sea "><+-.,[]" (sin incluir las comillas)
será ignorado.
Brainfuck es representado por un arreglo de 30,000 celdas inicializadas
-en cero y un apuntador en la celda actual.
+en cero y un puntero apuntando la celda actual.
Existen ocho comandos:
@@ -26,7 +28,7 @@ Existen ocho comandos:
- : Decrementa 1 al valor de la celda actual.
> : Mueve el apuntador a la siguiente celda. (a la derecha)
< : Mueve el apuntador a la celda anterior. (a la izquierda)
-. : Imprime el valor en ASCII de la celda actual (i.e. 65 = 'A')
+. : Imprime el valor en ASCII de la celda actual (p.e. 65 = 'A')
, : Lee un caracter como input y lo escribe en la celda actual.
[ : Si el valor en la celda actual es cero mueve el apuntador
hasta el primer ']' que encuentre. Si no es cero sigue a la
@@ -37,7 +39,7 @@ Existen ocho comandos:
[ y ] forman un while. Obviamente, deben estar balanceados.
-Ahora unos ejemplos de programas escritos con brainfuck.
+Estos son algunos ejemplos de programas escritos con brainfuck.
++++++ [ > ++++++++++ < - ] > +++++ .
@@ -63,7 +65,7 @@ Esto continúa hasta que la celda #1 contenga un cero. Cuando #1 contenga un
cero la celda #2 tendrá el valor inicial de #1. Como este ciclo siempre
terminara en la celda #1 nos movemos a la celda #2 e imprimimos (.).
-Ten en mente que los espacios son sólo para fines de legibilidad.
+Ten en cuenta que los espacios son sólo para fines de legibilidad.
Es lo mismo escribir el ejemplo de arriba que esto:
,[>+<-]>.
@@ -81,7 +83,7 @@ hasta la próxima vez. Para resolver este problema también incrementamos la
celda #4 y luego copiamos la celda #4 a la celda #2. La celda #3 contiene
el resultado.
```
-Y eso es brainfuck. ¿No tan difícil o sí? Como diversión, puedes escribir
+Y eso es brainfuck. No es tan difícil, ¿verdad? Como diversión, puedes escribir
tu propio intérprete de brainfuck o tu propio programa en brainfuck. El
intérprete es relativamente sencillo de hacer, pero si eres masoquista,
-intenta construir tu proprio intérprete de brainfuck... en brainfuck.
+puedes intentar construir tu propio intérprete de brainfuck... en brainfuck.
diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown
index 18b544b4..4e1e68ba 100644
--- a/es-es/git-es.html.markdown
+++ b/es-es/git-es.html.markdown
@@ -18,11 +18,11 @@ versionar y administrar nuestro código fuente.
## Versionamiento, conceptos.
-### Qué es el control de versiones?
+### ¿Qué es el control de versiones?
El control de versiones es un sistema que guarda todos los cambios realizados en
uno o varios archivos, a lo largo del tiempo.
-### Versionamiento centralizado vs Versionamiento Distribuido.
+### Versionamiento centralizado vs versionamiento distribuido.
+ El versionamiento centralizado se enfoca en sincronizar, rastrear, y respaldar
archivos.
@@ -33,9 +33,9 @@ uno o varios archivos, a lo largo del tiempo.
[Información adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones)
-### Por qué usar Git?
+### ¿Por qué usar Git?
-* Se puede trabajar sin conexion.
+* Se puede trabajar sin conexión.
* ¡Colaborar con otros es sencillo!.
* Derivar, crear ramas del proyecto (aka: Branching) es fácil.
* Combinar (aka: Merging)
@@ -47,7 +47,7 @@ uno o varios archivos, a lo largo del tiempo.
### Repositorio
Un repositorio es un conjunto de archivos, directorios, registros, cambios (aka:
-comits), y encabezados (aka: heads). Imagina que un repositorio es una clase,
+commits), y encabezados (aka: heads). Imagina que un repositorio es una clase,
y que sus atributos otorgan acceso al historial del elemento, además de otras
cosas.
@@ -62,12 +62,12 @@ y mas.
### Directorio de trabajo (componentes del repositorio)
-Es basicamente los directorios y archivos dentro del repositorio. La mayoría de
+Es básicamente los directorios y archivos dentro del repositorio. La mayoría de
las veces se le llama "directorio de trabajo".
### Índice (componentes del directorio .git)
-El índice es el área de inicio en git. Es basicamente la capa que separa el
+El índice es el área de inicio en git. Es básicamente la capa que separa el
directorio de trabajo del repositorio en git. Esto otorga a los desarrolladores
más poder sobre lo que se envía y se recibe del repositorio.
diff --git a/es-es/javascript-es.html.markdown b/es-es/javascript-es.html.markdown
index d475cf42..9ef0c63e 100644
--- a/es-es/javascript-es.html.markdown
+++ b/es-es/javascript-es.html.markdown
@@ -30,7 +30,7 @@ Aunque JavaScript no sólo se limita a los navegadores web: Node.js, Un proyecto
// Cada sentencia puede ser terminada con punto y coma ;
hazAlgo();
-// ... aunque no es necesario, ya que el punto y coma se agrega automaticamente
+// ... aunque no es necesario, ya que el punto y coma se agrega automáticamente
// cada que se detecta una nueva línea, a excepción de algunos casos.
hazAlgo()
@@ -109,7 +109,7 @@ null == undefined; // = true
null === undefined; // false
// Los Strings funcionan como arreglos de caracteres
-// Puedes accesar a cada caracter con la función charAt()
+// Puedes acceder a cada caracter con la función charAt()
"Este es un String".charAt(0); // = 'E'
// ...o puedes usar la función substring() para acceder a pedazos más grandes
@@ -186,7 +186,7 @@ miObjeto.miLlave; // = "miValor"
// agregar nuevas llaves.
miObjeto.miTerceraLlave = true;
-// Si intentas accesar con una llave que aún no está asignada tendrás undefined.
+// Si intentas acceder con una llave que aún no está asignada tendrás undefined.
miObjeto.miCuartaLlave; // = undefined
///////////////////////////////////
@@ -301,7 +301,7 @@ i; // = 5 - en un lenguaje que da ámbitos por bloque esto sería undefined, per
//inmediatamente", que preveé variables temporales de fugarse al ámbito global
(function(){
var temporal = 5;
- // Podemos accesar al ámbito global asignando al 'objeto global', el cual
+ // Podemos acceder al ámbito global asignando al 'objeto global', el cual
// en un navegador siempre es 'window'. El objeto global puede tener
// un nombre diferente en ambientes distintos, por ejemplo Node.js .
window.permanente = 10;
@@ -321,7 +321,7 @@ function decirHolaCadaCincoSegundos(nombre){
alert(texto);
}
setTimeout(interna, 5000);
- // setTimeout es asíncrono, así que la funcion decirHolaCadaCincoSegundos
+ // setTimeout es asíncrono, así que la función decirHolaCadaCincoSegundos
// terminará inmediatamente, y setTimeout llamará a interna() a los cinco segundos
// Como interna está "cerrada dentro de" decirHolaCadaCindoSegundos, interna todavía tiene
// acceso a la variable 'texto' cuando es llamada.
@@ -339,7 +339,7 @@ var miObjeto = {
};
miObjeto.miFuncion(); // = "¡Hola Mundo!"
-// Cuando las funciones de un objeto son llamadas, pueden accesar a las variables
+// Cuando las funciones de un objeto son llamadas, pueden acceder a las variables
// del objeto con la palabra clave 'this'.
miObjeto = {
miString: "¡Hola Mundo!",
@@ -401,11 +401,11 @@ var MiConstructor = function(){
miNuevoObjeto = new MiConstructor(); // = {miNumero: 5}
miNuevoObjeto.miNumero; // = 5
-// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a accesar a una
+// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a acceder a una
// propiedad en un objeto que no existe en el objeto el intérprete buscará en
// el prototipo.
-// Algunas implementaciones de JavaScript te permiten accesar al prototipo de
+// Algunas implementaciones de JavaScript te permiten acceder al prototipo de
// un objeto con la propiedad __proto__. Mientras que esto es útil para explicar
// prototipos, no es parte del estándar; veremos formas estándar de usar prototipos
// más adelante.
@@ -440,7 +440,7 @@ miPrototipo.sentidoDeLaVida = 43;
miObjeto.sentidoDeLaVida; // = 43
// Mencionabamos anteriormente que __proto__ no está estandarizado, y que no
-// existe una forma estándar de accesar al prototipo de un objeto. De todas formas.
+// existe una forma estándar de acceder al prototipo de un objeto. De todas formas.
// hay dos formas de crear un nuevo objeto con un prototipo dado.
// El primer método es Object.create, el cual es una adición reciente a JavaScript,
@@ -476,7 +476,7 @@ typeof miNumero; // = 'number'
typeof miNumeroObjeto; // = 'object'
miNumero === miNumeroObjeyo; // = false
if (0){
- // Este código no se ejecutara porque 0 es false.
+ // Este código no se ejecutará porque 0 es false.
}
// Aún así, los objetos que envuelven y los prototipos por defecto comparten
diff --git a/es-es/json-es.html.markdown b/es-es/json-es.html.markdown
index fff678eb..c98049f9 100644
--- a/es-es/json-es.html.markdown
+++ b/es-es/json-es.html.markdown
@@ -21,22 +21,22 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead
"llaves": "siempre debe estar entre comillas (ya sean dobles o simples)",
"numeros": 0,
"strings": "Høla, múndo. Todo el unicode está permitido, así como \"escapar\".",
- "soporta booleanos?": true,
- "vacios": null,
+ "¿soporta booleanos?": true,
+ "vacíos": null,
"numero grande": 1.2e+100,
"objetos": {
- "comentario": "La mayoria de tu estructura vendra de objetos.",
+ "comentario": "La mayoría de tu estructura vendrá de objetos.",
"arreglo": [0, 1, 2, 3, "Los arreglos pueden contener cualquier cosa.", 5],
"otro objeto": {
- "comentario": "Estas cosas pueden estar anidadas, muy util."
+ "comentario": "Estas cosas pueden estar anidadas, muy útil."
}
},
- "tonteria": [
+ "tontería": [
{
"fuentes de potasio": ["bananas"]
},
@@ -50,10 +50,10 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead
"estilo alternativo": {
"comentario": "Mira esto!"
- , "posicion de la coma": "no importa - mientras este antes del valor, entonces sera valido"
- , "otro comentario": "que lindo"
+ , "posición de la coma": "no importa - mientras este antes del valor, entonces sera válido"
+ , "otro comentario": "qué lindo"
},
- "eso fue rapido": "Y, estas listo. Ahora sabes todo lo que JSON tiene para ofrecer."
+ "eso fue rapido": "Y, estás listo. Ahora sabes todo lo que JSON tiene para ofrecer."
}
```
diff --git a/es-es/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
+```