summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ISSUE_TEMPLATE.md9
-rw-r--r--c.html.markdown2
-rw-r--r--es-es/perl6-es.html.markdown1935
-rw-r--r--it-it/python3-it.html.markdown1016
-rw-r--r--matlab.html.markdown6
-rw-r--r--objective-c.html.markdown5
-rw-r--r--pt-br/c-pt.html.markdown7
-rw-r--r--ruby.html.markdown145
-rw-r--r--solidity.html.markdown14
-rwxr-xr-xtoml.html.markdown7
-rw-r--r--tr-tr/c++-tr.html.markdown1077
-rw-r--r--tr-tr/git-tr.html.markdown595
-rw-r--r--zh-cn/python3-cn.html.markdown3
13 files changed, 4740 insertions, 81 deletions
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
index 022dedab..96278da9 100644
--- a/ISSUE_TEMPLATE.md
+++ b/ISSUE_TEMPLATE.md
@@ -1,3 +1,12 @@
+## Is this a major issue that you cannot fix?
+
+**Being a community driven documents of languages and tools,"YOUR" contributions
+are also important.
+If the issue you're reporting is trivial to report to maintainers why not contribute
+to fix it. In that way, you will have contributed to an awesome open-source project.
+The changes can be typo fix, fixing of data in examples or grammar fix. If you found it,
+why not do it and take full credit for it?**
+
Make sure the issue title is prepended with '[language/lang-code]' if the language is
already on the site.
If it's a request for a new language, use: '[Request] [language/lang-code]'
diff --git a/c.html.markdown b/c.html.markdown
index 0c6df413..684d330a 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -101,7 +101,7 @@ int main (int argc, char** argv)
char y_char = 'y'; // Char literals are quoted with ''
// longs are often 4 to 8 bytes; long longs are guaranteed to be at least
- // 64 bits
+ // 8 bytes
long x_long = 0;
long long x_long_long = 0;
diff --git a/es-es/perl6-es.html.markdown b/es-es/perl6-es.html.markdown
new file mode 100644
index 00000000..bf3ae65e
--- /dev/null
+++ b/es-es/perl6-es.html.markdown
@@ -0,0 +1,1935 @@
+---
+name: perl6
+category: language
+language: perl6
+filename: perl6-es.p6
+contributors:
+ - ["vendethiel", "http://github.com/vendethiel"]
+ - ["Samantha McVey", "https://cry.nu"]
+translators:
+ - ["Luis F. Uceta", "https://github.com/uzluisf"]
+lang: es-es
+---
+
+Perl 6 es un lenguaje de programación altamente capaz y con características
+abundantes para hacerlo el lenguage ideal por los próximos 100 años.
+
+El compilador primario de Perl 6 se llama [Rakudo](http://rakudo.org), el cual
+se ejecuta en JVM y en [MoarVM](http://moarvm.com).
+
+Meta-nota: dos signos de números (##) son usados para indicar párrafos,
+mientras que un solo signo de número (#) indica notas.
+
+`#=>` representa la salida de un comando.
+
+```perl6
+# Un comentario de una sola línea comienza con un signo de número
+
+#`(
+ Comentarios multilíneas usan #` y signos de encerradura tales
+ como (), [], {}, 「」, etc.
+)
+```
+
+## Variables
+
+```perl6
+## En Perl 6, se declara una variable lexical usando `my`
+my $variable;
+## Perl 6 tiene 3 tipos básicos de variables: escalares, arrays, y hashes.
+```
+
+### Escalares
+
+```perl6
+# Un escalar representa un solo valor. Variables escalares comienzan
+# con un `$`
+
+my $str = 'Cadena';
+# Las comillas inglesas ("") permiten la intepolación (lo cual veremos
+# luego):
+my $str2 = "Cadena";
+
+## Los nombres de variables pueden contener pero no terminar con comillas
+## simples y guiones. Sin embargo, pueden contener
+## (y terminar con) guiones bajos (_):
+my $nombre'de-variable_ = 5; # Esto funciona!
+
+my $booleano = True; # `True` y `False` son valores booleanos en Perl 6.
+my $inverso = !$booleano; # Puedes invertir un booleano con el operador prefijo `!`
+my $bool-forzado = so $str; # Y puedes usar el operador prefijo `so` que
+ # convierte su operador en un Bool
+```
+
+### Arrays y Listas
+
+```perl6
+## Un array representa varios valores. Variables arrays comienzan con `@`.
+## Las listas son similares pero son un tipo inmutable.
+
+my @array = 'a', 'b', 'c';
+# equivalente a:
+my @letras = <a b c>; # array de palabras, delimitado por espacios.
+ # Similar al qw de perl5, o el %w de Ruby.
+my @array = 1, 2, 3;
+
+say @array[2]; # Los índices de un array empiezan por el 0 -- Este es
+ # el tercer elemento.
+
+say "Interpola todos los elementos de un array usando [] : @array[]";
+#=> Interpola todos los elementos de un array usando [] : 1 2 3
+
+@array[0] = -1; # Asigna un nuevo valor a un índice del array
+@array[0, 1] = 5, 6; # Asigna varios valores
+
+my @llaves = 0, 2;
+@array[@llaves] = @letras; # Asignación usando un array que contiene valores
+ # índices
+say @array; #=> a 6 b
+```
+
+### Hashes, o Pairs (pares) de llaves-valores.
+
+```perl6
+## Un hash contiene parejas de llaves y valores.
+## Puedes construir un objeto Pair usando la sintaxis `LLave => Valor`.
+## Tablas de hashes son bien rápidas para búsqueda, y son almacenadas
+## sin ningún orden.
+## Ten en cuenta que las llaves son "aplanadas" en contexto de hash, y
+## cualquier llave duplicada es deduplicada.
+my %hash = 1 => 2,
+ 3 => 4;
+my %hash = foo => "bar", # las llaves reciben sus comillas
+ # automáticamente.
+ "some other" => "value", # las comas colgantes estań bien.
+ ;
+
+## Aunque los hashes son almacenados internamente de forma diferente a los
+## arrays, Perl 6 te permite crear un hash usando un array
+## con un número par de elementos fácilmente.
+my %hash = <llave1 valor1 llave2 valor2>;
+
+my %hash = llave1 => 'valor1', llave2 => 'valor2'; # ¡el mismo resultado!
+
+## También puedes usar la sintaxis "pareja con dos puntos":
+## (especialmente útil para parámetros nombrados que verás más adelante)
+my %hash = :w(1), # equivalente a `w => 1`
+ # esto es útil para el atajo `True`:
+ :truey, # equivalente a `:truey(True)`, o `truey => True`
+ # y para el `False`:
+ :!falsey, # equivalente a `:falsey(False)`, o `falsey => False`
+ ;
+
+say %hash{'llave1'}; # Puedes usar {} para obtener el valor de una llave
+say %hash<llave2>; # Si es una cadena de texto, puedes actualmente usar <>
+ # (`{llave1}` no funciona, debido a que Perl 6 no tiene
+ # palabras desnudas (barewords en inglés))
+```
+
+## Subrutinas
+
+```perl6
+## Subrutinas, o funciones como otros lenguajes las llaman, son
+## creadas con la palabra clave `sub`.
+sub di-hola { say "¡Hola, mundo!" }
+
+## Puedes proveer argumentos (tipados). Si especificado,
+## el tipo será chequeado al tiempo de compilación si es posible.
+## De lo contrario, al tiempo de ejecución.
+sub di-hola-a(Str $nombre) {
+ say "¡Hola, $nombre!";
+}
+
+## Una subrutina devuelve el último valor evaluado del bloque.
+sub devolver-valor {
+ 5;
+}
+say devolver-valor; # imprime 5
+sub devolver-vacio {
+}
+say devolver-vacio; # imprime Nil
+
+## Algunas estructuras de control producen un valor. Por ejemplo if:
+sub devuelva-si {
+ if True {
+ "Truthy";
+ }
+}
+say devuelva-si; # imprime Truthy
+
+## Otras no, como un bucle for:
+sub return-for {
+ for 1, 2, 3 { }
+}
+say return-for; # imprime Nil
+
+## Una subrutina puede tener argumentos opcionales:
+sub con-opcional($arg?) { # el signo "?" marca el argumento opcional
+ say "Podría returnar `(Any)` (valor de Perl parecido al 'null') si no me pasan
+ un argumento, o returnaré mi argumento";
+ $arg;
+}
+con-opcional; # devuelve Any
+con-opcional(); # devuelve Any
+con-opcional(1); # devuelve 1
+
+## También puedes proveer un argumento por defecto para
+## cuando los argumentos no son proveídos:
+sub hola-a($nombre = "Mundo") {
+ say "¡Hola, $nombre!";
+}
+hola-a; #=> ¡Hola, Mundo!
+hola-a(); #=> ¡Hola, Mundo!
+hola-a('Tú'); #=> ¡Hola, Tú!
+
+## De igual manera, al usar la sintaxis parecida a la de los hashes
+## (¡Hurra, sintaxis unificada!), puedes pasar argumentos *nombrados*
+## a una subrutina. Ellos son opcionales, y por defecto son del tipo "Any".
+sub con-nombre($arg-normal, :$nombrado) {
+ say $arg-normal + $nombrado;
+}
+con-nombre(1, nombrado => 6); #=> 7
+## Sin embargo, debes tener algo en cuenta aquí:
+## Si pones comillas alrededor de tu llave, Perl 6 no será capaz de verla
+## al tiempo de compilación, y entonces tendrás un solo objeto Pair como
+## un argumento posicional, lo que significa que el siguiente ejemplo
+## falla:
+con-nombre(1, 'nombrado' => 6);
+
+con-nombre(2, :nombrado(5)); #=> 7
+
+## Para hacer un argumento nombrado mandatorio, puedes utilizar el
+## inverso de `?`, `!`:
+sub con-nombre-mandatorio(:$str!) {
+ say "$str!";
+}
+con-nombre-mandatorio(str => "Mi texto"); #=> Mi texto!
+con-nombre-mandatorio; # error al tiempo de ejecución:
+ # "Required named parameter not passed"
+ # ("Parámetro nombrado requerido no proveído")
+con-nombre-mandatorio(3);# error al tiempo de ejecución:
+ # "Too many positional parameters passed"
+ # ("Demasiados argumentos posicionales proveídos")
+
+## Si una subrutina toma un argumento booleano nombrado ...
+sub toma-un-bool($nombre, :$bool) {
+ say "$nombre toma $bool";
+}
+## ... puedes usar la misma sintaxis de hash de un "booleano corto":
+takes-a-bool('config', :bool); # config toma True
+takes-a-bool('config', :!bool); # config toma False
+
+## También puedes proveer tus argumentos nombrados con valores por defecto:
+sub nombrado-definido(:$def = 5) {
+ say $def;
+}
+nombrado-definido; #=> 5
+nombrado-definido(def => 15); #=> 15
+
+## Dado que puedes omitir los paréntesis para invocar una función sin
+## argumentos, necesitas usar "&" en el nombre para almacenar la función
+## `di-hola` en una variable.
+my &s = &di-hola;
+my &otra-s = sub { say "¡Función anónima!" }
+
+## Una subrutina puede tener un parámetro "slurpy", o "no importa cuantos",
+## indicando que la función puede recibir cualquier número de parámetros.
+sub muchos($principal, *@resto) { #`*@` (slurpy) consumirá lo restante
+## Nota: Puedes tener parámetros *antes que* un parámetro "slurpy" (como
+## aquí) pero no *después* de uno.
+ say @resto.join(' / ') ~ "!";
+}
+say muchos('Feliz', 'Cumpleaño', 'Cumpleaño'); #=> Feliz / Cumpleaño!
+ # Nota que el asterisco (*) no
+ # consumió el parámetro frontal.
+
+## Puedes invocar un función con un array usando el
+## operador "aplanador de lista de argumento" `|`
+## (actualmente no es el único rol de este operador pero es uno de ellos)
+sub concat3($a, $b, $c) {
+ say "$a, $b, $c";
+}
+concat3(|@array); #=> a, b, c
+ # `@array` fue "aplanado" como parte de la lista de argumento
+```
+
+## Contenedores
+
+```perl6
+## En Perl 6, valores son actualmente almacenados en "contenedores".
+## El operador de asignación le pregunta al contenedor en su izquierda
+## almacenar el valor a su derecha. Cuando se pasan alrededor, contenedores
+## son marcados como inmutables. Esto significa que, en una función, tu
+## tendrás un error si tratas de mutar uno de tus argumentos.
+## Si realmente necesitas hacerlo, puedes preguntar por un contenedor
+## mutable usando `is rw`:
+sub mutar($n is rw) {
+ $n++;
+ say "¡\$n es ahora $n!";
+}
+
+my $m = 42;
+mutar $m; # ¡$n es ahora 43!
+
+## Esto funciona porque estamos pasando el contenedor $m para mutarlo. Si
+## intentamos pasar un número en vez de pasar una variable, no funcionará
+## dado que no contenedor ha sido pasado y números enteros son inmutables
+## por naturaleza:
+
+mutar 42; # Parámetro '$n' esperaba un contenedor mutable,
+ # pero recibió un valor Int
+
+## Si en cambio quieres una copia, debes usar `is copy`.
+
+## Por si misma, una subrutina devuelve un contenedor, lo que significa
+## que puede ser marcada con rw:
+my $x = 42;
+sub x-almacena() is rw { $x }
+x-almacena() = 52; # En este caso, los paréntesis son mandatorios
+ # (porque de otra forma, Perl 6 piensa que la función
+ # `x-almacena` es un identificador).
+say $x; #=> 52
+```
+
+## Estructuras de control
+### Condicionales
+
+```perl6
+## - `if`
+## Antes de hablar acerca de `if`, necesitamos saber cuales valores son
+## "Truthy" (representa True (verdadero)), y cuales son "Falsey"
+## (o "Falsy") -- representa False (falso). Solo estos valores son
+## Falsey: 0, (), {}, "", Nil, un tipo (como `Str` o`Int`) y
+## por supuesto False. Todos los valores son Truthy.
+if True {
+ say "¡Es verdadero!";
+}
+
+unless False {
+ say "¡No es falso!";
+}
+
+## Como puedes observar, no necesitas paréntesis alrededor de condiciones.
+## Sin embargo, necesitas las llaves `{}` alrededor del cuerpo de un bloque:
+# if (true) say; # !Esto no funciona!
+
+## También puedes usar sus versiones sufijos seguidas por la palabra clave:
+say "Un poco verdadero" if True;
+
+## - La condicional ternaria, "?? !!" (como `x ? y : z` en otros lenguajes)
+## devuelve $valor-si-verdadera si la condición es verdadera y
+## $valor-si-falsa si es falsa.
+## my $resultado = $valor condición ?? $valor-si-verdadera !! $valor-si-falsa;
+
+my $edad = 30;
+say $edad > 18 ?? "Eres un adulto" !! "Eres menor de 18";
+```
+
+### given/when, ó switch
+
+```perl6
+## - `given`-`when` se parece al `switch` de otros lenguajes, pero es más
+## poderoso gracias a la coincidencia inteligente ("smart matching" en inglés)
+## y la "variable tópica" $_ de Perl.
+##
+## Esta variable ($_) contiene los argumentos por defecto de un bloque,
+## la iteración actual de un loop (a menos que sea explícitamente
+## nombrado), etc.
+##
+## `given` simplemente pone su argumento en `$_` (como un bloque lo haría),
+## y `when` lo compara usando el operador de "coincidencia inteligente" (`~~`).
+##
+## Dado que otras construcciones de Perl 6 usan esta variable (por ejemplo,
+## el bucle `for`, bloques, etc), esto se significa que el poderoso `when` no
+## solo se aplica con un `given`, sino que se puede usar en cualquier
+## lugar donde exista una variable `$_`.
+
+given "foo bar" {
+ say $_; #=> foo bar
+ when /foo/ { # No te preocupies acerca de la coincidencia inteligente –
+ # solo ten presente que `when` la usa.
+ # Esto es equivalente a `if $_ ~~ /foo/`.
+ say "¡Yay!";
+ }
+ when $_.chars > 50 { # coincidencia inteligente con cualquier cosa True es True,
+ # i.e. (`$a ~~ True`)
+ # por lo tanto puedes también poner condiciones "normales".
+ # Este `when` es equivalente a este `if`:
+ # if $_ ~~ ($_.chars > 50) {...}
+ # que significa:
+ # if $_.chars > 50 {...}
+ say "¡Una cadena de texto bien larga!";
+ }
+ default { # lo mismo que `when *` (usando la Whatever Star)
+ say "Algo más";
+ }
+}
+```
+
+### Construcciones de bucle
+
+```perl6
+## - `loop` es un bucle infinito si no le pasas sus argumentos,
+## pero también puede ser un bucle for al estilo de C:
+loop {
+ say "¡Este es un bucle infinito!";
+ last; # last interrumpe el bucle, como la palabra clave `break`
+ # en otros lenguajes.
+}
+
+loop (my $i = 0; $i < 5; $i++) {
+ next if $i == 3; # `next` salta a la siguiente iteración, al igual
+ # que `continue` en otros lenguajes. Ten en cuenta que
+ # también puedes usar la condicionales postfix (sufijas)
+ # bucles, etc.
+ say "¡Este es un bucle al estilo de C!";
+}
+
+## - `for` - Hace iteraciones en un array
+for @array -> $variable {
+ say "¡He conseguido una $variable!";
+}
+
+## Como vimos con `given`, la variable de una "iteración actual" por defecto
+## es `$_`. Esto significa que puedes usar `when` en un bucle `for` como
+## normalmente lo harías con `given`.
+for @array {
+ say "he conseguido a $_";
+
+ .say; # Esto es también permitido.
+ # Una invocación con punto (dot call) sin "tópico" (recibidor) es
+ # enviada a `$_` por defecto.
+ $_.say; # lo mismo de arriba, lo cual es equivalente.
+}
+
+for @array {
+ # Puedes...
+ next if $_ == 3; # Saltar a la siguiente iteración (`continue` en
+ # lenguages parecido a C)
+ redo if $_ == 4; # Re-hacer la iteración, manteniendo la
+ # misma variable tópica (`$_`)
+ last if $_ == 5; # Salir fuera del bucle (como `break`
+ # en lenguages parecido a C)
+}
+
+## La sintaxis de "bloque puntiagudo" no es específica al bucle for.
+## Es solo una manera de expresar un bloque en Perl 6.
+if computación-larga() -> $resultado {
+ say "El resultado es $resultado";
+}
+```
+
+## Operadores
+
+```perl6
+## Dados que los lenguajes de la familia Perl son lenguages basados
+## mayormente en operadores, los operadores de Perl 6 son actualmente
+## subrutinas un poco cómicas en las categorías sintácticas. Por ejemplo,
+## infix:<+> (adición) o prefix:<!> (bool not).
+
+## Las categorías son:
+## - "prefix" (prefijo): anterior a (como `!` en `!True`).
+## - "postfix" (sufijo): posterior a (como `++` en `$a++`).
+## - "infix" (infijo): en medio de (como `*` en `4 * 3`).
+## - "circumfix" (circunfijo): alrededor de (como `[`-`]` en `[1, 2]`).
+## - "post-circumfix" (pos-circunfijo): alrededor de un término,
+## posterior a otro término.
+## (como `{`-`}` en `%hash{'key'}`)
+
+## La lista de asociatividad y precedencia se explica más abajo.
+
+## ¡Bueno, ya estás listo(a)!
+
+## * Chequeando igualdad
+
+## - `==` se usa en comparaciones numéricas.
+3 == 4; # Falso
+3 != 4; # Verdadero
+
+## - `eq` se usa en comparaciones de cadenas de texto.
+'a' eq 'b';
+'a' ne 'b'; # no igual
+'a' !eq 'b'; # lo mismo que lo anterior
+
+## - `eqv` es equivalencia canónica (or "igualdad profunda")
+(1, 2) eqv (1, 3);
+
+## - Operador de coincidencia inteligente (smart matching): `~~`
+## Asocia (aliasing en inglés) el lado izquierda a la variable $_
+## y después evalúa el lado derecho.
+## Aquí algunas comparaciones semánticas comunes:
+
+## Igualdad de cadena de texto o numérica
+
+'Foo' ~~ 'Foo'; # True si las cadenas de texto son iguales.
+12.5 ~~ 12.50; # True si los números son iguales.
+
+## Regex - Para la comparación de una expresión regular en contra
+## del lado izquierdo. Devuelve un objeto (Match), el cual evalúa
+## como True si el regex coincide con el patrón.
+
+my $obj = 'abc' ~~ /a/;
+say $obj; # 「a」
+say $obj.WHAT; # (Match)
+
+## Hashes
+'llave' ~~ %hash; # True si la llave existe en el hash
+
+## Tipo - Chequea si el lado izquierdo "tiene un tipo" (puede chequear
+## superclases y roles)
+
+1 ~~ Int; # True (1 es un número entero)
+
+## Coincidencia inteligente contra un booleano siempre devuelve ese
+## booleano (y lanzará una advertencia).
+
+1 ~~ True; # True
+False ~~ True; # True
+
+## La sintaxis general es $arg ~~ &función-returnando-bool;
+## Para una lista completa de combinaciones, usa esta tabla:
+## http://perlcabal.org/syn/S03.html#Smart_matching
+
+## También, por supuesto, tienes `<`, `<=`, `>`, `>=`.
+## Sus equivalentes para cadenas de texto están disponibles:
+## `lt`, `le`, `gt`, `ge`.
+3 > 4;
+
+## * Constructores de rango
+3 .. 7; # 3 a 7, ambos incluidos
+## `^` en cualquier lado excluye a ese lado:
+3 ^..^ 7; # 3 a 7, no incluidos (básicamente `4 .. 6`)
+## Esto también funciona como un atajo para `0..^N`:
+^10; # significa 0..^10
+
+## Esto también nos permite demostrar que Perl 6 tiene arrays
+## ociosos/infinitos, usando la Whatever Star:
+my @array = 1..*; # 1 al Infinito! `1..Inf` es lo mismo.
+say @array[^10]; # puedes pasar arrays como subíndices y devolverá
+ # un array de resultados. Esto imprimirá
+ # "1 2 3 4 5 6 7 8 9 10" (y no se quedaré sin memoria!)
+## Nota: Al leer una lista infinita, Perl 6 "cosificará" los elementos que
+## necesita y los mantendrá en la memoria. Ellos no serán calculados más de
+## una vez. Tampoco calculará más elementos de los que necesita.
+
+## Un índice de array también puede ser una clausura ("closure" en inglés).
+## Será llamada con la longitud como el argumento
+say join(' ', @array[15..*]); #=> 15 16 17 18 19
+## lo que es equivalente a:
+say join(' ', @array[-> $n { 15..$n }]);
+## Nota: Si tratas de hacer cualquiera de esos con un array infinito,
+## provocará un array infinito (tu programa nunca terminará)
+
+## Puedes usar eso en los lugares que esperaría, como durante la asignación
+## a un array
+my @números = ^20;
+
+## Aquí los números son incrementados por "6"; más acerca del
+## operador `...` adelante.
+my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99;
+@números[5..*] = 3, 9 ... *; # aunque la secuencia es infinita,
+ # solo los 15 números necesarios será calculados.
+say @números; #=> 0 1 2 3 4 3 9 15 21 [...] 81 87
+ # (solamente 20 valores)
+
+## * And &&, Or ||
+3 && 4; # 4, el cual es Truthy. Invoca `.Bool` en `4` y obtiene `True`.
+0 || False; # False. Invoca `.Bool` en `0`
+
+## * Versiones circuito corto de lo de arriba
+## && Devuelve el primer argumento que evalúa a False, o el último.
+
+my ( $a, $b, $c ) = 1, 0, 2;
+$a && $b && $c; # Devuelve 0, el primer valor que es False
+
+## || Devuelve el primer argumento que evalúa a True.
+$b || $a; # 1
+
+## Y porque tu lo querrás, también tienes operadores de asignación
+## compuestos:
+$a *= 2; # multiplica y asigna. Equivalente a $a = $a * 2;
+$b %%= 5; # divisible por y asignación. Equivalente $b = $b %% 5;
+@array .= sort; # invoca el método `sort` y asigna el resultado devuelto.
+```
+
+## ¡Más sobre subrutinas!
+
+```perl6
+## Como dijimos anteriormente, Perl 6 tiene subrutinas realmente poderosas.
+## Veremos unos conceptos claves que la hacen mejores que en cualquier otro
+## lenguaje :-).
+```
+
+### !Desempacado!
+
+```perl6
+## Es la abilidad de extraer arrays y llaves (También conocido como
+## "destructuring"). También funcionará en `my` y en las listas de parámetros.
+my ($f, $g) = 1, 2;
+say $f; #=> 1
+my ($, $, $h) = 1, 2, 3; # mantiene los anónimos no interesante
+say $h; #=> 3
+
+my ($cabeza, *@cola) = 1, 2, 3; # Sí, es lo mismo que con subrutinas "slurpy"
+my (*@small) = 1;
+
+sub desempacar_array(@array [$fst, $snd]) {
+ say "Mi primero es $fst, mi segundo es $snd! De todo en todo, soy un @array[].";
+ # (^ recuerda que `[]` interpola el array)
+}
+desempacar_array(@cola); #=> My first is 2, my second is 3 ! All in all, I'm 2 3
+
+
+## Si no está usando el array, puedes también mantenerlo anónimo, como un
+## escalar:
+sub primero-de-array(@ [$fst]) { $fst }
+primero-de-array(@small); #=> 1
+primero-de-array(@tail); # Lanza un error "Demasiados argumentos posicionales
+ # proveídos"
+ # (lo que significa que el array es muy grande).
+
+## También puedes usar un slurp ...
+sub slurp-en-array(@ [$fst, *@rest]) { # Podrías mantener `*@rest` anónimos
+ say $fst + @rest.elems; # `.elems` returna la longitud de una lista.
+ # Aquí, `@rest` es `(3,)`, since `$fst` holds the `2`.
+}
+slurp-en-array(@tail); #=> 3
+
+## Hasta podrías hacer un extracción usando una slurpy (pero no sería útil ;-).)
+sub fst(*@ [$fst]) { # o simplemente: `sub fst($fst) { ... }`
+ say $fst;
+}
+fst(1); #=> 1
+fst(1, 2); # errores con "Too many positional parameters passed"
+
+## También puedes desestructurar hashes (y clases, las cuales
+## veremos adelante). La sintaxis es básicamente
+## `%nombre-del-hash (:llave($variable-para-almacenar))`.
+## El hash puede permanecer anónimos si solo necesitas los valores extraídos.
+sub llave-de(% (:azul($val1), :red($val2))) {
+ say "Valores: $val1, $val2.";
+}
+## Después invócala con un hash: (necesitas mantener las llaves
+## de los parejas de llave y valor para ser un hash)
+llave-de({azul => 'blue', rojo => "red"});
+#llave-de(%hash); # lo mismo (para un `%hash` equivalente)
+
+## La última expresión de una subrutina es devuelta inmediatamente
+## (aunque puedes usar la palabra clave `return`):
+sub siguiente-indice($n) {
+ $n + 1;
+}
+my $nuevo-n= siguiente-indice(3); # $nuevo-n es ahora 4
+
+## Este es cierto para todo, excepto para las construcciones de bucles
+## (debido a razones de rendimiento): Hay una razón de construir una lista
+## si la vamos a desechar todos los resultados.
+## Si todavías quieres construir una, puedes usar la sentencia prefijo `do`:
+## (o el prefijo `gather`, el cual veremos luego)
+sub lista-de($n) {
+ do for ^$n { # nota el uso del operador de rango `^` (`0..^N`)
+ $_ # iteración de bucle actual
+ }
+}
+my @list3 = lista-de(3); #=> (0, 1, 2)
+```
+
+### lambdas
+
+```perl6
+## Puedes crear una lambda con `-> {}` ("bloque puntiagudo") o `{}` ("bloque")
+my &lambda = -> $argumento { "El argumento pasado a esta lambda es $argumento" }
+## `-> {}` y `{}` son casi la misma cosa, excepto que la primerra puede
+## tomar argumentos, y la segunda puede ser malinterpretada como un hash
+## por el parseador.
+
+## Podemos, por ejemplo, agregar 3 a cada valor de un array usando map:
+my @arraymas3 = map({ $_ + 3 }, @array); # $_ es el argumento implícito
+
+## Una subrutina (`sub {}`) tiene semánticas diferentes a un
+## bloque (`{}` or `-> {}`): Un bloque no tiene "contexto funcional"
+## (aunque puede tener argumentos), lo que significa que si quieres devolver
+## algo desde un bloque, vas a returnar desde la función parental. Compara:
+sub is-in(@array, $elem) {
+ # esto `devolverá` desde la subrutina `is-in`
+ # Una vez que la condición evalúa a True, el bucle terminará
+ map({ return True if $_ == $elem }, @array);
+}
+sub truthy-array(@array) {
+ # esto producirá un array de `True` Y `False`:
+ # (también puedes decir `anon sub` para "subrutina anónima")
+ map(sub ($i) { if $i { return True } else { return False } }, @array);
+ # ^ el `return` solo devuelve desde la `sub`
+}
+
+## También puedes usar la "whatever star" para crear una función anónima
+## (terminará con el último operador en la expresión actual)
+my @arraymas3 = map(*+3, @array); # `*+3` es lo mismo que `{ $_ + 3 }`
+my @arraymas3 = map(*+*+3, @array); # lo mismo que `-> $a, $b { $a + $b + 3 }`
+ # también `sub ($a, $b) { $a + $b + 3 }`
+say (*/2)(4); #=> 2
+ # Inmediatamente ejecuta la función que Whatever creó.
+say ((*+3)/5)(5); #=> 1.6
+ # ¡funciona hasta con los paréntesis!
+
+## Pero si necesitas más que un argumento (`$_`) en un bloque
+## (sin depender en `-> {}`), también puedes usar la sintaxis implícita
+## de argumento, `$` :
+map({ $^a + $^b + 3 }, @array); # equivalente a lo siguiente:
+map(sub ($a, $b) { $a + $b + 3 }, @array); # (aquí con `sub`)
+
+## Nota : Esos son ordernados lexicográficamente.
+# `{ $^b / $^a }` es como `-> $a, $b { $b / $a }`
+```
+
+### Acerca de tipos...
+
+```perl6
+## Perl 6 es gradualmente tipado. Esto quiere decir que tu especifica el
+## tipo de tus variables/argumentos/devoluciones (return), o puedes omitirlos
+## y serán "Any" por defecto.
+## Obviamente tienes acceso a algunas tipos básicos, como Int y Str.
+## Las construcciones para declarar tipos son "class", "role", lo cual
+## verás más adelante.
+
+## Por ahora, examinemos "subset" (subconjunto).
+## Un "subset" es un "sub-tipo" con chequeos adicionales.
+## Por ejemplo: "un número entero bien grande es un Int que es mayor que 500"
+## Puedes especificar el tipo del que creas el subconjunto (por defecto, Any),
+## y añadir chequeos adicionales con la palabra clave "where" (donde):
+subset EnteroGrande of Int where * > 500;
+```
+
+### Despacho Múltiple (Multiple Dispatch)
+
+```perl6
+## Perl 6 puede decidir que variante de una subrutina invocar basado en el
+## tipo de los argumento, o precondiciones arbitrarias, como con un tipo o
+## un `where`:
+
+## con tipos
+multi sub dilo(Int $n) { # nota la palabra clave `multi` aquí
+ say "Número: $n";
+}
+multi dilo(Str $s) { # un multi es una subrutina por defecto
+ say "Cadena de texto: $s";
+}
+dilo("azul"); # prints "Cadena de texto: azul"
+dilo(True); # falla al *tiempo de compilación* con
+ # "calling 'dilo' will never work with arguments of types ..."
+ # (invocar 'dilo' nunca funcionará con argumentos de tipos ...")
+## con precondición arbitraria (¿recuerdas los subconjuntos?):
+multi es-grande(Int $n where * > 50) { "¡Sí!" } # usando una clausura
+multi es-grande(Int $ where 10..50) { "Tal vez." } # Usando coincidencia inteligente
+ # (podrías usar un regexp, etc)
+multi es-grande(Int $) { "No" }
+
+subset Par of Int where * %% 2;
+
+multi inpar-o-par(Par) { "Par" } # El caso principal usando el tipo.
+ # No nombramos los argumentos,
+multi inpar-o-par($) { "Inpar" } # "else"
+
+## ¡Podrías despachar basado en la presencia de argumentos posicionales!
+multi sin_ti-o-contigo(:$with!) { # Necesitas hacerlo mandatorio
+ # para despachar en contra del argumento.
+ say "¡Puedo vivir! Actualmente, no puedo.";
+}
+multi sin_ti-o-contigo {
+ say "Definitivamente no puedo vivir.";
+}
+## Esto es muy útil para muchos propósitos, como subrutinas `MAIN` (de las
+## cuales hablaremos luego), y hasta el mismo lenguaje la está usando
+## en muchos lugares.
+##
+## - `is`, por ejemplo, es actualmente un `multi sub` llamado
+## `trait_mod:<is>`.
+## - `is rw`, es simplemente un despacho a una función con esta signatura:
+## sub trait_mod:<is>(Routine $r, :$rw!) {}
+##
+## (¡lo pusimos en un comentario dado que ejecutando esto sería una terrible
+## idea!)
+```
+
+## Ámbito (Scoping)
+
+```perl6
+## En Perl 6, a diferencia de otros lenguajes de scripting, (tales como
+## (Python, Ruby, PHP), debes declarar tus variables antes de usarlas. El
+## declarador `my`, del cual aprendiste anteriormente, usa "ámbito léxical".
+## Hay otros declaradores (`our`, `state`, ..., ) los cuales veremos luego.
+## Esto se llama "ámbito léxico", donde en los bloques internos,
+## puedes acceder variables de los bloques externos.
+my $archivo-en-ámbito = 'Foo';
+sub externo {
+ my $ámbito-externo = 'Bar';
+ sub interno {
+ say "$archivo-en-ámbito $ámbito-externo";
+ }
+ &interno; # devuelve la función
+}
+outer()(); #=> 'Foo Bar'
+
+## Como puedes ver, `$archivo-en-ámbito` y `$ámbito-externo`
+## fueron capturados. Pero si intentaramos usar `$bar` fuera de `foo`,
+## la variable estaría indefinida (y obtendrías un error al tiempo de
+## compilación).
+```
+
+## Twigils
+
+```perl6
+## Hay muchos `twigils` especiales (sigilos compuestos) en Perl 6.
+## Los twigils definen el ámbito de las variables.
+## Los twigils * y ? funcionan con variables regulares:
+## * Variable dinámica
+## ? Variable al tiempo de compilación
+## Los twigils ! y . son usados con los objetos de Perl 6:
+## ! Atributo (miembro de la clase)
+## . Método (no una variable realmente)
+
+## El twigil `*`: Ámbito dinámico
+## Estas variables usan el twigil `*` para marcar variables con ámbito
+## dinámico. Variables con ámbito dinámico son buscadas a través del
+## invocador, no a través del ámbito externo.
+
+my $*ambito_din_1 = 1;
+my $*ambito_din_2 = 10;
+
+sub di_ambito {
+ say "$*ambito_din_1 $*ambito_din_2";
+}
+
+sub invoca_a_di_ambito {
+ my $*ambito_din_1 = 25; # Define a $*ambito_din_1 solo en esta subrutina.
+ $*ambito_din_2 = 100; # Cambiará el valor de la variable en ámbito.
+ di_ambito(); #=> 25 100 $*ambito_din_1 y 2 serán buscadas en la invocación.
+ # Se usa el valor de $*ambito_din_1 desde el ámbito léxico de esta
+ # subrutina aunque los bloques no están anidados (están anidados por
+ # invocación).
+}
+di_ambito(); #=> 1 10
+invoca_a_di_ambito(); #=> 25 100
+ # Se usa a $*ambito_din_1 como fue definida en invoca_a_di_ambito
+ # aunque la estamos invocando desde afuera.
+di_ambito(); #=> 1 100 Cambiamos el valor de $*ambito_din_2 en invoca_a_di_ambito
+ # por lo tanto su valor a cambiado.
+```
+
+## Modelo de Objeto
+
+```perl6
+## Para invocar a un método en un objeto, agrega un punto seguido por el
+## nombre del objeto:
+## => $object.method
+## Las classes son declaradas usando la palabra clave `class`. Los atributos
+## son declarados con la palabra clave `has`, y los métodos con `method`.
+## Cada atributo que es privado usa el twigil `!`. Por ejemplo: `$!attr`.
+## Atributos públicos inmutables usan el twigil `.` (los puedes hacer
+## mutables con `is rw`).
+## La manera más fácil de recordar el twigil `$.` is comparándolo
+## con como los métodos son llamados.
+
+## El modelo de objeto de Perl 6 ("SixModel") es muy flexible, y te permite
+## agregar métodos dinámicamente, cambiar la semántica, etc ...
+## (no hablaremos de todo esto aquí. Por lo tanto, refiérete a:
+## https://docs.perl6.org/language/objects.html).
+
+class Clase-Atrib {
+ has $.atrib; # `$.atrib` es inmutable.
+ # Desde dentro de la clase, usa `$!atrib` para modificarlo.
+ has $.otro-atrib is rw; # Puedes marcar un atributo como público con `rw`.
+ has Int $!atrib-privado = 10;
+
+ method devolver-valor {
+ $.atrib + $!atrib-privado;
+ }
+
+ method asignar-valor($param) { # Métodos pueden tomar parámetros.
+ $!attrib = $param; # Esto funciona porque `$!` es siempre mutable.
+ # $.attrib = $param; # Incorrecto: No puedes usar la versión inmutable `$.`.
+
+ $.otro-atrib = 5; # Esto funciona porque `$.otro-atrib` es `rw`.
+ }
+
+ method !metodo-privado {
+ say "Este método es privado para la clase !";
+ }
+};
+
+## Crear una nueva instancia de Clase-Atrib con $.atrib asignado con 5:
+## Nota: No puedes asignarle un valor a atrib-privado desde aquí (más de
+## esto adelante).
+my $class-obj = Clase-Atrib.new(atrib => 5);
+say $class-obj.devolver-valor; #=> 5
+# $class-obj.atrib = 5; # Esto falla porque `has $.atrib` es inmutable
+$class-obj.otro-atrib = 10; # En cambio, esto funciona porque el atributo
+ # público es mutable (`rw`).
+```
+
+### Herencia de Objeto
+
+```perl6
+## Perl 6 también tiene herencia (junto a herencia múltiple)
+## Mientras los métodos declarados con `method` son heredados, aquellos
+## declarados con `submethod` no lo son.
+## Submétodos son útiles para la construcción y destrucción de tareas,
+## tales como BUILD, o métodos que deben ser anulados por subtipos.
+## Aprenderemos acerca de BUILD más adelante.
+
+class Padre {
+ has $.edad;
+ has $.nombre;
+ # Este submétodo no será heredado por la clase Niño.
+ submethod color-favorito {
+ say "Mi color favorito es Azul";
+ }
+ # Este método será heredado
+ method hablar { say "Hola, mi nombre es $!nombre" }
+}
+# Herencia usa la palabra clave `is`
+class Niño is Padre {
+ method hablar { say "Goo goo ga ga" }
+ # Este método opaca el método `hablar` de Padre.
+ # Este niño no ha aprendido a hablar todavía.
+}
+my Padre $Richard .= new(edad => 40, nombre => 'Richard');
+$Richard.color-favorito; #=> "Mi color favorito es Azul"
+$Richard.hablar; #=> "Hola, mi nombre es Richard"
+## $Richard es capaz de acceder el submétodo; él sabe como decir su nombre.
+
+my Niño $Madison .= new(edad => 1, nombre => 'Madison');
+$Madison.hablar; # imprime "Goo goo ga ga" dado que el método fue cambiado
+ # en la clase Niño.
+# $Madison.color-favorito # no funciona porque no es heredado
+
+## Cuando se usa `my T $var` (donde `T` es el nombre de la clase), `$var`
+## inicia con `T` en si misma, por lo tanto puedes invocar `new` en `$var`.
+## (`.=` es sólo la invocación por punto y el operador de asignación:
+## `$a .= b` es lo mismo que `$a = $a.b`)
+## Por ejemplo, la instancia $Richard pudo también haber sido declarada así:
+## my $Richard = Padre.new(edad => 40, nombre => 'Richard');
+
+## También observa que `BUILD` (el método invocado dentro de `new`)
+## asignará propiedades de la clase padre, por lo que puedes pasar
+## `val => 5`.
+```
+
+### Roles, o Mixins
+
+```perl6
+## Roles son suportados también (comúnmente llamados Mixins en otros
+## lenguajes)
+role PrintableVal {
+ has $!counter = 0;
+ method print {
+ say $.val;
+ }
+}
+
+## Se "importa" un mixin (un "role") con "does":
+class Item does PrintableVal {
+ has $.val;
+
+ ## Cuando se utiliza `does`, un `rol` se mezcla en al clase literalmente:
+ ## los métodos y atributos se ponen juntos, lo que significa que una clase
+ ## puede acceder los métodos y atributos privados de su rol (pero no lo inverso!):
+ method access {
+ say $!counter++;
+ }
+
+ ## Sin embargo, esto:
+ ## method print {}
+ ## es SÓLO válido cuando `print` no es una `multi` con el mismo dispacho.
+ ## (esto significa que una clase padre puede opacar una `multi print() {}`
+ ## de su clase hijo/a, pero es un error sin un rol lo hace)
+
+ ## NOTA: Puedes usar un rol como una clase (con `is ROLE`). En este caso,
+ ## métodos serán opacados, dado que el compilador considerará `ROLE`
+ ## como una clase.
+}
+```
+
+## Excepciones
+
+```perl6
+## Excepciones están construidas al tope de las clases, en el paquete
+## `X` (como `X::IO`).
+## En Perl 6, excepciones son lanzadas automáticamente.
+open 'foo'; #=> Failed to open file foo: no such file or directory
+## También imprimirá la línea donde el error fue lanzado y otra información
+## concerniente al error.
+
+## Puedes lanzar una excepción usando `die`:
+die 'Error!'; #=> Error!
+
+## O más explícitamente:
+die X::AdHoc.new(payload => 'Error!');
+
+## En Perl 6, `orelse` es similar al operador `or`, excepto que solamente
+## coincide con variables indefinidas, en cambio de cualquier cosa
+## que evalúa a falso.
+## Valores indefinidos incluyen: `Nil`, `Mu` y `Failure`, también como
+## `Int`, `Str` y otros tipos que no han sido inicializados a ningún valor
+## todavía.
+## Puedes chequear si algo está definido o no usando el método defined:
+my $no-inicializada;
+say $no-inicializada.defined; #=> False
+## Al usar `orelse`, se desarmará la excepción y creará un alias de dicho
+## fallo en $_
+## Esto evitará que sea automáticamente manejado e imprima una marejada de
+## mensajes de errores en la pantalla.
+## Podemos usar el método de excepción en $_ para acceder la excepción:
+open 'foo' orelse say "Algo pasó {.exception}";
+
+## Esto también funciona:
+open 'foo' orelse say "Algo pasó $_"; #=> Algo pasó
+ #=> Failed to open file foo: no such file or directory
+## Ambos ejemplos anteriores funcionan pero en caso de que consigamos un
+## objeto desde el lado izquierdo que no es un fallo, probablemente
+## obtendremos una advertencia. Más abajo vemos como usar `try` y `CATCH`
+## para ser más expecíficos con las excepciones que capturamos.
+```
+
+### Usando `try` y `CATCH`
+
+```perl6
+## Al usar `try` y `CATCH`, puedes contener y manejar excepciones sin
+## interrumpir el resto del programa. `try` asignará la última excepción
+## a la variable especial `$!`.
+## Nota: Esto no tiene ninguna relación con las variables $!.
+
+try open 'foo';
+say "Bueno, lo intenté! $!" if defined $!; #=> Bueno, lo intenté! Failed to open file
+ #foo: no such file or directory
+## Ahora, ¿qué debemos hacer si queremos más control sobre la excepción?
+## A diferencia de otros lenguajes, en Perl 6 se pone el bloque `CATCH`
+## *dentro* del bloque a intentar (`try`). Similarmente como $_ fue asignada
+## cuando 'disarmamos' la excepción con `orelse`, también usamos $_ en el
+## bloque CATCH.
+## Nota: ($! es solo asignada *después* del bloque `try`)
+## Por defecto, un bloque `try` tiene un bloque `CATCH` que captura
+## cualquier excepción (`CATCH { default {} }`).
+
+try { my $a = (0 %% 0); CATCH { say "Algo pasó: $_" } }
+ #=> Algo pasó: Attempt to divide by zero using infix:<%%>
+
+## Puedes redefinir lo anterior usando `when` y (`default`)
+## para manejar las excepciones que desees:
+try {
+ open 'foo';
+ CATCH { # En el bloque `CATCH`, la excepción es asignada a $_
+ when X::AdHoc { say "Error: $_" }
+ #=>Error: Failed to open file /dir/foo: no such file or directory
+
+ ## Cualquier otra excepción será levantada de nuevo, dado que no
+ ## tenemos un `default`.
+ ## Básicamente, si un `when`
+ ## Basically, if a `when` matches (or there's a `default`) marks the
+ ## exception as
+ ## "handled" so that it doesn't get re-thrown from the `CATCH`.
+ ## You still can re-throw the exception (see below) by hand.
+ }
+}
+
+## En Perl 6, excepciones poseen ciertas sutilezas. Algunas
+## subrutinas en Perl 6 devuelven un `Failure`, el cual es un tipo de
+## "excepción no levantada". Ellas no son levantadas hasta que tu intentas
+## mirar a sus contenidos, a menos que invoques `.Bool`/`.defined` sobre
+## ellas - entonces, son manejadas.
+## (el método `.handled` es `rw`, por lo que puedes marcarlo como `False`
+## por ti mismo)
+## Puedes levantar un `Failure` usando `fail`. Nota que si el pragma
+## `use fatal` estás siendo utilizado, `fail` levantará una excepión (como
+## `die`).
+fail "foo"; # No estamos intentando acceder el valor, por lo tanto no problema.
+try {
+ fail "foo";
+ CATCH {
+ default { say "Levantó un error porque intentamos acceder el valor del fallo!" }
+ }
+}
+
+## También hay otro tipo de excepción: Excepciones de control.
+## Esas son excepciones "buenas", las cuales suceden cuando cambias el flujo
+## de tu programa, usando operadores como `return`, `next` or `last`.
+## Puedes capturarlas con `CONTROL` (no lista un 100% en Rakudo todavía).
+```
+
+## Paquetes
+
+```perl6
+## Paquetes son una manera de reusar código. Paquetes son como
+## "espacio de nombres" (namespaces en inglés), y cualquier elemento del
+## modelo seis (`module`, `role`, `class`, `grammar`, `subset` y `enum`)
+## son paquetes por ellos mismos. (Los paquetes son como el mínimo común
+## denominador)
+## Los paquetes son importantes - especialmente dado que Perl es bien
+## reconocido por CPAN, the Comprehensive Perl Archive Nertwork.
+
+## Puedes usar un módulo (traer sus declaraciones al ámbito) con `use`
+use JSON::Tiny; # si intalaste Rakudo* o Panda, tendrás este módulo
+say from-json('[1]').perl; #=> [1]
+
+## A diferencia de Perl 5, no deberías declarar paquetes usando
+## la palabra clave `package`. En vez, usa `class Nombre::Paquete::Aquí;`
+## para declarar una clase, o si solamente quieres exportar
+## variables/subrutinas, puedes usar `module`.
+
+module Hello::World { # forma de llaves
+ # Si `Hello` no existe todavía, solamente será una cola ("stub"),
+ # que puede ser redeclarada más tarde.
+ # ... declaraciones aquí ...
+}
+unit module Parse::Text; # forma de ámbito de archivo
+
+grammar Parse::Text::Grammar { # Una gramática (grammar en inglés) es un paquete,
+ # en el cual puedes usar `use`
+} # Aprenderás más acerca de gramáticas en la sección de regex
+
+## Como se dijo anteriormente, cualquier parte del modelo seis es también un
+## paquete. Dado que `JSON::Tiny` usa su propia clase `JSON::Tiny::Actions`,
+## tu puedes usarla de la manera siguiente:
+my $acciones = JSON::Tiny::Actions.new;
+
+## Veremos como exportar variables y subrutinas en la siguiente parte:
+```
+
+## Declaradores
+
+```perl6
+## En Perl 6, tu obtienes diferentes comportamientos basado en como declaras
+## una variable.
+## Ya has visto `my` y `has`, ahora exploraremos el resto.
+
+## * las declaraciones `our` ocurren al tiempo `INIT` (ve "Phasers" más abajo)
+## Es como `my`, pero también crea una variable paquete.
+## (Todas las cosas relacionadas con paquetes (`class`, `role`, etc) son
+## `our` por defecto)
+module Var::Incrementar {
+ our $nuestra-var = 1; # Nota: No puedes colocar una restricción de tipo
+ my $mi-var = 22; # como Int (por ejemplo) en una variable `our`.
+ our sub Inc {
+
+ our sub disponible { # Si tratas de hacer subrutinas internas `our`...
+ # Mejor que sepas lo que haces (No lo haga!).
+ say "No hagas eso. En serio. Estás jugando con fuego y te quemarás.";
+ }
+
+ my sub no-disponible { # `my sub` es por defecto
+ say "No puedes acceder aquí desde fuera. Soy 'my'!";
+ }
+ say ++$nuestra-var; # Incrementa la variable paquete y muestra su valor
+ }
+
+}
+say $Var::Incrementar::nuestra-var; #=> 1 Esto funciona
+say $Var::Incrementar::mi-var; #=> (Any) Esto no funcionará.
+
+Var::Incrementar::Inc; #=> 2
+Var::Incrementar::Inc; #=> 3 # Nota como el valor de $nuestra-var fue
+ # retenido
+Var::Incrementar::no-disponible; #=> Could not find symbol '&no-disponible'
+
+## * `constant` (ocurre al tiempo `BEGIN`)
+## Puedes usar la palabra clave `constant` para declarar una
+## variable/símbolo al tiempo de compilación:
+constant Pi = 3.14;
+constant $var = 1;
+
+## Y por si te estás preguntando, sí, también puede contener listas infinitas.
+constant porque-no = 5, 15 ... *;
+say porque-no[^5]; #=> 5 15 25 35 45
+
+## * `state` (ocurre al tiempo de ejecución, pero una sola vez)
+## Variables "states" son solo inicializadas una vez.
+## (ellas existen en otros lenguaje como `static` en C)
+sub aleatorio-fijo {
+ state $valor = rand;
+ say $valor;
+}
+aleatorio-fijo for ^10; # imprimirá el mismo número 10 veces
+
+## Nota, sin embargo, que ellas existen separadamente en diferentes contextos.
+## Si declaras una función con un `state` dentro de un bucle, recreará la
+## variable por cada iteración del bucle. Observa:
+for ^5 -> $a {
+ sub foo {
+ state $valor = rand; # Esto imprimirá un valor diferente
+ # por cada valor de `$a`
+ }
+ for ^5 -> $b {
+ say foo; # Esto imprimirá el mismo valor 5 veces, pero sólo 5.
+ # La siguiente iteración ejecutará `rand` nuevamente.
+ }
+}
+```
+
+## Phasers
+
+```perl6
+## Un phaser en Perl 6 es un bloque que ocurre a determinados puntos de tiempo
+## en tu programa. Se les llama phaser porque marca un cambio en la fase de
+## de tu programa. Por ejemplo, cuando el programa es compilado, un bucle
+## for se ejecuta, dejas un bloque, o una excepción se levanta.
+## (¡`CATCH` es actualmente un phaser!)
+## Algunos de ellos pueden ser utilizados por sus valores devueltos, otros
+## no pueden (aquellos que tiene un "[*]" al inicio de su texto de
+## explicación).
+## ¡Tomemos una mirada!
+
+## * Phasers al tiempo de compilación
+BEGIN { say "[*] Se ejecuta al tiempo de compilación, " ~
+ "tan pronto como sea posible, una sola vez" }
+CHECK { say "[*] Se ejecuta al tiempo de compilación, " ~
+ "tan tarde como sea posible, una sola vez" }
+
+## * Phasers al tiempo de ejecución
+INIT { say "[*] Se ejecuta al tiempo de ejecución, " ~
+ "tan pronto como sea posible, una sola vez" }
+END { say "Se ejecuta al tiempo de ejecución, " ~
+ "tan tarde como sea posible, una sola vez" }
+
+## * Phasers de bloques
+ENTER { say "[*] Se ejecuta cada vez que entra en un bloque, " ~
+ "se repite en bloques de bucle" }
+LEAVE { say "Se ejecuta cada vez que abandona un bloque, incluyendo " ~
+ "cuando una excepción ocurre. Se repite en bloques de bucle"}
+
+PRE {
+ say "Impone una precondición a cada entrada de un bloque, " ~
+ "antes que ENTER (especialmente útil para bucles)";
+ say "Si este bloque no returna un valor truthy, " ~
+ "una excepción del tipo X::Phaser::PrePost será levantada.";
+}
+
+## Ejemplos:
+for 0..2 {
+ PRE { $_ > 1 } # Esto fallará con un "Precondition failed"
+}
+
+POST {
+ say "Impone una postcondAsserts a poscondición a la salida de un bloque, " ~
+ "después de LEAVE (especialmente útil para bucles)";
+ say "Si este bloque no returna un valor truthy, " ~
+ "una excepción del tipo X::Phaser::PrePost será levantada, como con PRE.";
+}
+for 0..2 {
+ POST { $_ < 2 } # Esto fallará con un "Postcondition failed"
+}
+
+## * Phasers de bloques/excepciones
+sub {
+ KEEP { say "Se ejecuta cuando sales de un bloque exitosamente
+ (sin lanzar un excepción)" }
+ UNDO { say "Se ejecuta cuando sale de bloque sin éxito
+ (al lanzar una excepción)" }
+}
+
+## * Phasers de bucle
+for ^5 {
+ FIRST { say "[*] La primera vez que un bucle se ejecuta, antes que ENTER" }
+ NEXT { say "Al tiempo de la continuación del bucle, antes que LEAVE" }
+ LAST { say "Al tiempo de la terminación del bucle, después de LEAVE" }
+}
+
+## * Phasers de rol/clase
+COMPOSE { "Cuando un rol es compuesto en una clase. /!\ NO IMPLEMENTADO TODAVÍA" }
+
+## Ellos permite pequeños trucos o código brillante...:
+say "Este código tomó " ~ (time - CHECK time) ~ "s para compilar";
+
+## ... o brillante organización:
+sub do-db-stuff {
+ $db.start-transaction; # comienza una transacción nueva
+ KEEP $db.commit; # commit (procede con) la transacción si todo estuvo bien
+ UNDO $db.rollback; # o retrocede si todo falló
+}
+```
+
+## Prefijos de sentencias
+
+```perl6
+## Los prefijos de sentencias actúan como los phasers: Ellos afectan el
+## comportamiento del siguiente código.
+## Debido a que son ejecutados en línea con el código ejecutable, ellos
+## se escriben en letras minúsculas. (`try` and `start` están teoréticamente
+## en esa lista, pero serán explicados en otra parte)
+## Nota: Ningunos de estos (excepto `start`) necesitan las llaves `{` y `}`.
+
+## - `do` (el cual ya viste) - ejecuta un bloque o una sentencia como un
+## término.
+## Normalmente no puedes usar una sentencia como un valor (o término):
+##
+## my $valor = if True { 1 } # `if` es una sentencia - error del parseador
+##
+## Esto funciona:
+my $a = do if True { 5 } # con `do`, `if` ahora se comporta como un término.
+
+## - `once` - se asegura que una porción de código se ejecute una sola vez.
+for ^5 { once say 1 }; #=> 1
+ # solo imprime ... una sola vez.
+## Al igual que `state`, ellos son clonados por ámbito
+for ^5 { sub { once say 1 }() } #=> 1 1 1 1 1
+ # Imprime una sola vez por ámbito léxico
+
+## - `gather` - Hilo de co-rutina
+## `gather` te permite tomar (`take`) varios valores en un array,
+## al igual que `do`. Encima de esto, te permite tomar cualquier expresión.
+say gather for ^5 {
+ take $_ * 3 - 1;
+ take $_ * 3 + 1;
+} #=> -1 1 2 4 5 7 8 10 11 13
+say join ',', gather if False {
+ take 1;
+ take 2;
+ take 3;
+} # no imprime nada.
+
+## - `eager` - Evalúa una sentencia ávidamente (forza contexto ávido)
+## No intentes esto en casa:
+##
+## eager 1..*; # esto probablemente se colgará por un momento
+## # (y podría fallar...).
+##
+## Pero considera lo siguiente:
+constant tres-veces = gather for ^3 { say take $_ }; # No imprime nada
+
+## frente a esto:
+constant tres-veces = eager gather for ^3 { say take $_ }; #=> 0 1 2
+```
+
+## Iterables
+
+```perl6
+## En Perl 6, los iterables son objetos que pueden ser iterados similar
+## a la construcción `for`.
+## `flat`, aplana iterables:
+say (1, 10, (20, 10) ); #=> (1 10 (20 10)) Nota como la agrupación se mantiene
+say (1, 10, (20, 10) ).flat; #=> (1 10 20 10) Ahora el iterable es plano
+
+## - `lazy` - Aplaza la evaluación actual hasta que el valor sea requirido
+## (forza contexto perezoso)
+my @lazy-array = (1..100).lazy;
+say @lazy-array.is-lazy; #=> True # Chequea por "pereza" con el método `is-lazy`.
+say @lazy-array; #=> [...] No se ha iterado sobre la lista
+for @lazy-array { .print }; # Esto funciona y hará tanto trabajo como sea necesario.
+
+[//]: # ( TODO explica que gather/take y map son todos perezosos)
+## - `sink` - Un `eager` que desecha los resultados (forza el contexto sink)
+constant nilthingie = sink for ^3 { .say } #=> 0 1 2
+say nilthingie.perl; #=> Nil
+
+## - `quietly` - Un bloque `quietly` reprime las advertencias:
+quietly { warn 'Esto es una advertencia!' }; #=> No salida
+
+## - `contend` - Intenta efectos secundarios debajo de STM
+## ¡No implementado todavía!
+```
+
+## ¡Más operadores!
+
+```perl6
+## ¡Todo el mundo ama los operadores! Tengamos más de ellos.
+
+## La lista de precedencia puede ser encontrada aquí:
+## https://docs.perl6.org/language/operators#Operator_Precedence
+## Pero primero, necesitamos un poco de explicación acerca
+## de la asociatividad:
+
+## * Operadores binarios:
+$a ! $b ! $c; # con asociatividad izquierda `!`, esto es `($a ! $b) ! $c`
+$a ! $b ! $c; # con asociatividad derecha `!`, esto es `$a ! ($b ! $c)`
+$a ! $b ! $c; # sin asociatividad `!`, esto es ilegal
+$a ! $b ! $c; # con una cadena de asociatividad `!`, esto es `($a ! $b) and ($b ! $c)`
+$a ! $b ! $c; # con asociatividad de lista `!`, esto es `infix:<>`
+
+## * Operadores unarios:
+!$a! # con asociatividad izquierda `!`, esto es `(!$a)!`
+!$a! # con asociatividad derecha `!`, esto es `!($a!)`
+!$a! # sin asociatividad `!`, esto es ilegal
+```
+
+### ¡Crea tus propios operadores!
+
+```perl6
+## Okay, has leído todo esto y me imagino que debería mostrarte
+## algo interesante.
+## Te mostraré un pequeño secreto (o algo no tan secreto):
+## En Perl 6, todos los operadores son actualmente solo subrutinas.
+
+## Puedes declarar un operador como declaras una subrutina:
+sub prefix:<ganar>($ganador) { # se refiere a las categorías de los operadores
+ # (exacto, es el "operador de palabras" `<>`)
+ say "¡$ganador ganó!";
+}
+ganar "El Rey"; #=> ¡El Rey Ganó!
+ # (prefijo se pone delante)
+
+## todavías puedes invocar la subrutina con su "nombre completo":
+say prefix:<!>(True); #=> False
+
+sub postfix:<!>(Int $n) {
+ [*] 2..$n; # usando el meta-operador reduce ... Ve más abajo!
+}
+say 5!; #=> 120
+ # Operadores sufijos (postfix) van *directamente* después del témino.
+ # No espacios en blanco. Puedes usar paréntesis para disambiguar,
+ # i.e. `(5!)!`
+
+
+sub infix:<veces>(Int $n, Block $r) { # infijo va en el medio
+ for ^$n {
+ $r(); # Necesitas los paréntesis explícitos para invocar la función
+ # almacenada en la variable `$r`. De lo contrario, te estaría
+ # refiriendo a la variable (no a la función), como con `&r`.
+ }
+}
+3 veces -> { say "hola" }; #=> hola
+ #=> hola
+ #=> hola
+ # Se te recomienda que ponga espacios
+ # alrededor de la invocación de operador infijo.
+
+## Para los circunfijos y pos-circunfijos
+sub circumfix:<[ ]>(Int $n) {
+ $n ** $n
+}
+say [5]; #=> 3125
+ # un circunfijo va alrededor. De nuevo, no espacios en blanco.
+
+sub postcircumfix:<{ }>(Str $s, Int $idx) {
+ ## un pos-circunfijo es
+ ## "después de un término y alrededor de algo"
+ $s.substr($idx, 1);
+}
+say "abc"{1}; #=> b
+ # depués del término `"abc"`, y alrededor del índice (1)
+
+## Esto es de gran valor -- porque todo en Perl 6 usa esto.
+## Por ejemplo, para eliminar una llave de un hash, tu usas el adverbio
+## `:delete` (un simple argumento con nombre debajo):
+%h{$llave}:delete;
+## es equivalente a:
+postcircumfix:<{ }>(%h, $llave, :delete); # (puedes invocar
+ # operadores de esta forma)
+## ¡*Todos* usan los mismos bloques básicos!
+## Categorías sintácticas (prefix, infix, ...), argumentos nombrados
+## (adverbios), ... - usados para construir el lenguaje - están al alcance
+## de tus manos y disponibles para ti.
+## (obviamente, no se te recomienda que hagas un operador de *cualquier
+## cosa* -- Un gran poder conlleva una gran responsabilidad.)
+```
+
+### Meta-operadores!
+
+```perl6
+## ¡Prepárate! Prepárate porque nos estamos metiendo bien hondo
+## en el agujero del conejo, y probablemente no querrás regresar a
+## otros lenguajes después de leer esto.
+## (Me imagino que ya no quieres a este punto).
+## Meta-operadores, como su nombre lo sugiere, son operadores *compuestos*.
+## Básicamente, ellos son operadores que se aplican a otros operadores.
+
+## * El meta-operador reduce (reducir)
+## Es un meta-operador prefijo que toman una función binaria y
+## una o varias listas. Sino se pasa ningún argumento,
+## returna un "valor por defecto" para este operador
+## (un valor sin significado) o `Any` si no hay ningún valor.
+##
+## De lo contrario, remueve un elemento de la(s) lista(s) uno a uno, y
+## aplica la función binaria al último resultado (o al primer elemento de
+## la lista y el elemento que ha sido removido).
+##
+## Para sumar una lista, podrías usar el meta-operador "reduce" con `+`,
+## i.e.:
+say [+] 1, 2, 3; #=> 6
+## es equivalente a `(1+2)+3`
+
+say [*] 1..5; #=> 120
+## es equivalente a `((((1*2)*3)*4)*5)`.
+
+## Puedes reducir con cualquier operador, no solo con operadores matemáticos.
+## Por ejemplo, podrías reducir con `//` para conseguir
+## el primer elemento definido de una lista:
+say [//] Nil, Any, False, 1, 5; #=> False
+ # (Falsey, pero definido)
+
+## Ejemplos con valores por defecto:
+say [*] (); #=> 1
+say [+] (); #=> 0
+ # valores sin significado, dado que N*1=N y N+0=N.
+say [//]; #=> (Any)
+ # No hay valor por defecto para `//`.
+## También puedes invocarlo con una función de tu creación usando
+## los dobles corchetes:
+sub add($a, $b) { $a + $b }
+say [[&add]] 1, 2, 3; #=> 6
+
+## * El meta-operador zip
+## Este es un meta-operador infijo que también puede ser usado como un
+## operador "normal". Toma una función binaria opcional (por defecto, solo
+## crear un par), y remueve un valor de cada array e invoca su función
+## binaria hasta que no tenga más elementos disponibles. Al final, returna
+## un array con todos estos nuevos elementos.
+(1, 2) Z (3, 4); # ((1, 3), (2, 4)), dado que por defecto, la función
+ # crea un array.
+1..3 Z+ 4..6; # (5, 7, 9), usando la función personalizada infix:<+>
+
+## Dado que `Z` tiene asociatividad de lista (ve la lista más arriba),
+## puedes usarlo en más de una lista
+(True, False) Z|| (False, False) Z|| (False, False); # (True, False)
+
+## Y pasa que también puedes usarlo con el meta-operador reduce:
+[Z||] (True, False), (False, False), (False, False); # (True, False)
+
+
+## Y para terminar la lista de operadores:
+
+## * El operador secuencia
+## El operador secuencia es uno de la más poderosas características de
+## Perl 6: Está compuesto, en la izquierda, de la lista que quieres que
+## Perl 6 use para deducir (y podría incluir una clausura), y en la derecha,
+## un valor o el predicado que dice cuando parar (o Whatever para una
+## lista infinita perezosa).
+my @list = 1, 2, 3 ... 10; # deducción básica
+#my @list = 1, 3, 6 ... 10; # esto muere porque Perl 6 no puede deducir el final
+my @list = 1, 2, 3 ...^ 10; # como con rangos, puedes excluir el último elemento
+ # (la iteración cuando el predicado iguala).
+my @list = 1, 3, 9 ... * > 30; # puedes usar un predicado
+ # (con la Whatever Star, aquí).
+my @list = 1, 3, 9 ... { $_ > 30 }; # (equivalente a lo de arriba)
+
+my @fib = 1, 1, *+* ... *; # lista infinita perezosa de la serie fibonacci,
+ # computada usando una clausura!
+my @fib = 1, 1, -> $a, $b { $a + $b } ... *; # (equivalene a lo de arriba)
+my @fib = 1, 1, { $^a + $^b } ... *; #(... también equivalene a lo de arriba)
+## $a and $b siempre tomarán el valor anterior, queriendo decir que
+## ellos comenzarán con $a = 1 y $b = 1 (valores que hemos asignado
+## de antemano). Por lo tanto, $a = 1 y $b = 2 (resultado del anterior $a+$b),
+## etc.
+
+say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55
+ # (usandi un rango como el índice)
+## Nota: Los elementos de un rango, una vez cosificados, no son re-calculados.
+## Esta es la razón por la cual `@primes[^100]` tomará más tiempo la primera
+## vez que se imprime. Después de esto, será hará en un instante.
+```
+
+## Expresiones Regulares
+
+```perl6
+## Estoy seguro que has estado esperando por esta parte. Bien, ahora que
+## sabes algo acerca de Perl 6, podemos comenzar. Primeramente, tendrás
+## que olvidarte acerca de "PCRE regexps" (perl-compatible regexps)
+## (expresiones regulares compatible de perl).
+##
+## IMPORTANTE: No salte esto porque ya sabes acerca de PCRE. Son totalmente
+## distintos. Algunas cosas son las mismas (como `?`, `+`, y `*`) pero
+## algunas veces la semántica cambia (`|`). Asegúrate de leer esto
+## cuidadosamente porque podrías trospezarte sino lo haces.
+##
+## Perl 6 tiene muchas características relacionadas con RegExps. Después de
+## todo, Rakudo se parsea a si mismo. Primero vamos a estudiar la sintaxis
+## por si misma, después hablaremos acerca de gramáticas (parecido a PEG),
+## las diferencias entre los declaradores `token`, `regex`, y `rule` y
+## mucho más.
+## Nota aparte: Todavía tienes acceso a los regexes PCRE usando el
+## mofificador `:P5` (Sin embargo, no lo discutiremos en este tutorial).
+##
+## En esencia, Perl 6 implementa PEG ("Parsing Expression Grammars")
+## ("Parseado de Expresiones de Gramáticas") nativamente. El orden jerárquico
+## para los parseos ambiguos es determinado por un examen multi-nivel de
+## desempate:
+## - La coincidencia de token más larga. `foo\s+` le gana a `foo`
+## (por 2 o más posiciones)
+## - El prefijo literal más largo. `food\w*` le gana a `foo\w*` (por 1)
+## - Declaración desde la gramática más derivada a la menos derivada
+## (las gramáticas son actualmente clases)
+## - La declaración más temprana gana
+say so 'a' ~~ /a/; #=> True
+say so 'a' ~~ / a /; #=> True # ¡Más legible con los espacios!
+
+## Nota al lector (del traductor):
+## Como pudiste haber notado, he decidido traducir "match" y sus diferentes
+## formas verbales como "coincidir" y sus diferentes formas. Cuando digo que
+## un regex (o regexp) coincide con cierto texto, me refiero a que el regex
+## describe cierto patrón dentro del texto. Por ejemplo, el regex "cencia"
+## coincide con el texto "reminiscencia", lo que significa que dentro del
+## texto aparece ese patrón de caracteres (una `c`, seguida de una `e`,
+## (seguida de una `n`, etc.)
+
+## En todos nuestros ejemplos, vamos a usar el operador de
+## "coincidencia inteligente" contra una expresión regular ("regexp" or
+## "regex" de aquí en adelante). Estamos convirtiendo el resultado usando `so`,
+## pero en efecto, está devolviendo un objeto Match. Ellos saben como responder
+## a la indexación de lista, indexación de hash, y devolver la cadena de
+## texto coincidente.
+## Los resultados de la coincidencia están disponible como `$/` (en
+## ámbito implícito lexical). También puedes usar las variables de captura
+## las cuales comienzan con 0:
+## `$0`, `$1', `$2`...
+##
+## Nota que `~~` no hace un chequeo de inicio/final (es decir,
+## el regexp puede coincider con solo un carácter de la cadena de texto).
+## Explicaremos luego como hacerlo.
+
+## En Perl 6, puedes tener un carácter alfanumérico como un literal,
+## todo lo demás debe escaparse usando una barra invertida o comillas.
+say so 'a|b' ~~ / a '|' b /; # `True`. No sería lo mismo si no se escapara `|`
+say so 'a|b' ~~ / a \| b /; # `True`. Otra forma de escaparlo
+
+## El espacio en blanco actualmente no se significa nada en un regexp,
+## a menos que uses el adverbio `:s` (`:sigspace`, espacio significante).
+say so 'a b c' ~~ / a b c /; #=> `False`. Espacio no significa nada aquí.
+say so 'a b c' ~~ /:s a b c /; #=> `True`. Agregamos el modificador `:s` aquí.
+## Si usamos solo un espacio entre cadenas de texto en un regexp, Perl 6
+## nos advertirá:
+say so 'a b c' ~~ / a b c /; #=> 'False' # Espacio no significa nada aquí.
+## Por favor usa comillas o el modificador :s (:sigspace) para suprimir
+## esta advertencia, omitir el espacio, o cambiar el espaciamiento. Para
+## arreglar esto y hacer los espacios menos ambiguos, usa por lo menos
+## dos espacios entre las cadenas de texto o usa el adverbio `:s`.
+
+## Como vimos anteriormente, podemos incorporar `:s` dentro de los
+## delimitadores de barras. También podemos ponerlos fuera de ellos si
+## especificamos `m` for `match` (coincidencia):
+say so 'a b c' ~~ m:s/a b c/; #=> `True`
+## Al usar `m` para especificar 'match', podemos también otros delimitadore:
+say so 'abc' ~~ m{a b c}; #=> `True`
+say so 'abc' ~~ m[a b c]; #=> `True`
+
+## Usa el adverbio :i para especificar que no debería haber distinción entre
+## minúsculas y mayúsculas:
+say so 'ABC' ~~ m:i{a b c}; #=> `True`
+
+## Sin embargo, es importante para como los modificadores son aplicados
+## (lo cual verás más abajo)...
+
+## Cuantificando - `?`, `+`, `*` y `**`.
+## - `?` - 0 o 1
+so 'ac' ~~ / a b c /; # `False`
+so 'ac' ~~ / a b? c /; # `True`, la "b" coincidió (apareció) 0 veces.
+so 'abc' ~~ / a b? c /; # `True`, la "b" coincidió 1 vez.
+
+## ... Como debes saber, espacio en blancos son importante porque
+## determinan en que parte del regexp es el objetivo del modificador:
+so 'def' ~~ / a b c? /; # `False`. Solamente la `c` es opcional
+so 'def' ~~ / a b? c /; # `False`. Espacio en blanco no es significante
+so 'def' ~~ / 'abc'? /; # `True`. El grupo "abc"completo es opcional.
+
+## Aquí (y más abajo) el cuantificador aplica solamente a la `b`
+
+## - `+` - 1 o más
+so 'ac' ~~ / a b+ c /; # `False`; `+` quiere por lo menos una coincidencia
+so 'abc' ~~ / a b+ c /; # `True`; una es suficiente
+so 'abbbbc' ~~ / a b+ c /; # `True`, coincidió con 4 "b"s
+
+## - `*` - 0 o más
+so 'ac' ~~ / a b* c /; # `True`, todos son opcionales.
+so 'abc' ~~ / a b* c /; # `True`
+so 'abbbbc' ~~ / a b* c /; # `True`
+so 'aec' ~~ / a b* c /; # `False`. "b"(s) son opcionales, no reemplazables.
+
+## - `**` - Cuantificador (sin límites)
+## Si entrecierras los ojos lo suficiente, pueder ser que entiendas
+## por qué la exponenciación es usada para la cantidad.
+so 'abc' ~~ / a b**1 c /; # `True` (exactamente una vez)
+so 'abc' ~~ / a b**1..3 c /; # `True` (entre una y tres veces)
+so 'abbbc' ~~ / a b**1..3 c /; # `True`
+so 'abbbbbbc' ~~ / a b**1..3 c /; # `False` (demasiado)
+so 'abbbbbbc' ~~ / a b**3..* c /; # `True` (rangos infinitos no son un problema)
+
+## - `<[]>` - Clases de carácteres
+## Las clases de carácteres son equivalentes a las clases `[]` de PCRE,
+## pero usan una sintaxis de Perl 6:
+say 'fooa' ~~ / f <[ o a ]>+ /; #=> 'fooa'
+
+## Puedes usar rangos:
+say 'aeiou' ~~ / a <[ e..w ]> /; #=> 'ae'
+
+## Al igual que regexes normales, si quieres usar un carácter especial,
+## escápalo (el último está escapando un espacio)
+say 'he-he !' ~~ / 'he-' <[ a..z \! \ ]> + /; #=> 'he-he !'
+
+## Obtendrás una advertencia si pones nombres duplicados
+## (lo cual tiene el efecto de capturar la frase escrita)
+'he he' ~~ / <[ h e ' ' ]> /; # Advierte "Repeated characters found in characters
+ # class"
+
+## También puedes negarlos... (equivalenta a `[^]` en PCRE)
+so 'foo' ~~ / <-[ f o ]> + /; # False
+
+## ... y componerlos:
+so 'foo' ~~ / <[ a..z ] - [ f o ]> + /; # False (cualquier letra excepto f y o)
+so 'foo' ~~ / <-[ a..z ] + [ f o ]> + /; # True (no letra excepto f and o)
+so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (el signo + no reemplaza la
+ # parte de la izquierda)
+```
+
+### Grupos y Capturas
+
+```perl6
+## Grupo: Puedes agrupar partes de tu regexp con `[]`.
+## Estos grupos *no son* capturados (como con `(?:)` en PCRE).
+so 'abc' ~~ / a [ b ] c /; # `True`. El agrupamiento no hace casi nada
+so 'foo012012bar' ~~ / foo [ '01' <[0..9]> ] + bar /;
+## La línea anterior returna `True`.
+## Coincidimos (o encotramos el patrón) "012" una o más de una vez (
+## (el signo `+` fue aplicado al grupo).
+## Pero esto no va demasiado lejos, porque no podemos actualmente obtener
+## devuelta el patrón que coincidió.
+
+## Captura: Podemos actualmente *capturar* los resultados del regexp,
+## usando paréntesis.
+so 'fooABCABCbar' ~~ / foo ( 'A' <[A..Z]> 'C' ) + bar /; # `True`. (usando `so`
+ # aquí, `$/` más abajo)
+
+## Ok. Comenzando con las explicaciones de grupos. Como dijimos,
+### nuestra objeto `Match` está disponible en la variable `$/`:
+say $/; # Imprimirá algo extraño (explicaremos luego) o
+ # "Nil" si nada coincidió
+
+## Como dijimos anteriormente, un objeto Match tiene indexación de array:
+say $/[0]; #=> 「ABC」 「ABC」
+ # Estos corchetes extranos son los objetos `Match`.
+ # Aquí, tenemos un array de ellos.
+say $0; # Lo mismo que lo anterior.
+
+## Nuestra captura es `$0` porque es la primera y única captura en el
+## regexp. Podrías estarte preguntando porque un array y la respuesta es
+## simple: Algunas capturas (indezadas usando `$0`, `$/[0]` o una nombrada)
+## será un array si y solo si puedes tener más de un elemento.
+## (Así que, con `*`, `+` y `**` (cualquiera los operandos), pero no con `?`).
+## Usemos algunos ejemplos para ver como funciona:
+
+## Nota: Pusimos A B C entre comillas para demostrar que el espacio en blanco
+## entre ellos no es significante. Si queremos que el espacio en blanco
+## *sea* significante, podemos utilizar el modificador `:sigspace`.
+so 'fooABCbar' ~~ / foo ( "A" "B" "C" )? bar /; # `True`
+say $/[0]; #=> 「ABC」
+say $0.WHAT; #=> (Match)
+ # Puede haber más de uno, por lo tanto es solo un solo objeto match.
+so 'foobar' ~~ / foo ( "A" "B" "C" )? bar /; #=> True
+say $0.WHAT; #=> (Any)
+ # Esta captura no coincidió, por lo tanto está vacía
+so 'foobar' ~~ / foo ( "A" "B" "C" ) ** 0..1 bar /; # `True`
+say $0.WHAT; #=> (Array)
+ # Un cuantificador específico siempre capturará un Array,
+ # puede ser un rango o un valor específico (hasta 1).
+
+## Las capturas son indezadas por anidación. Esto quiere decir que un grupo
+## dentro de un grup estará anidado dentro de su grupo padre: `$/[0][0]`,
+## para este código:
+'hello-~-world' ~~ / ( 'hello' ( <[ \- \~ ]> + ) ) 'world' /;
+say $/[0].Str; #=> hello~
+say $/[0][0].Str; #=> ~
+
+## Esto se origina de un hecho bien simple: `$/` no contiene cadenas de
+## texto, números enteros o arrays sino que solo contiene objetos Match.
+## Estos objetos contienen los métodos `.list`, `.hash` y `.Str`. (Pero
+## también puedes usar `match<llave>` para accesar un hash y `match[indice]`
+## para accesar un array.
+say $/[0].list.perl; #=> (Match.new(...),).list
+ # Podemos ver que es una lista de objetos Match.
+ # Estos contienen un montón de información: dónde la
+ # coincidencia comenzó o terminó, el "ast"
+ # (chequea las acciones más abajo), etc.
+ # Verás capturas nombradas más abajo con las gramáticas.
+
+## Alternativas - el `or` de regexes
+## Advertencia: Es diferente a los regexes de PCRE.
+so 'abc' ~~ / a [ b | y ] c /; # `True`. o "b" o "y".
+so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviamente suficiente...
+
+## La diferencia entre este `|` y el otro al que estás acustombrado es LTM.
+## LTM significa "Longest Token Matching", traducido libremente como
+## "Coincidencia de Token Más Larga". Esto significa que el motor ("engine")
+## siempre intentará coindidir tanto como sea posible en la cadena de texto.
+## Básicamente, intentará el patrón más largo que concuerde con el regexp.
+'foo' ~~ / fo | foo /; # `foo` porque es más largo.
+## Para decidir cual parte es la "más larga", primero separa el regex en
+## dos partes:
+## El "prefijo declarativo" (la parte que puede ser analizada estáticamente)
+## y las partes procedimentales.
+## Los prefijos declarativos incluyen alternaciones (`|`), conjunciones (`&`),
+## invocaciones de sub-reglas (no han sido introducidos todavía), clases de
+## caracteres y cuantificadores.
+## Las partes procidimentales incluyen todo lo demás: referencias a elementos
+## anteriores, aserciones de código, y otras cosas que tradicionalmente no pueden
+## ser representadas por regexes normales.
+##
+## Entonces, todas las alternativas se intentan al mismo tiempo, y la
+## más larga gana.
+## Ejemplos:
+## DECLARATIVO | PROCEDIMENTAL
+/ 'foo' \d+ [ <subrule1> || <subrule2> ] /;
+## DECLARATIVO (grupos anidados no son un problema)
+/ \s* [ \w & b ] [ c | d ] /;
+## Sin embargo, las clausuras y la recursión (de regexes nombrados)
+## son procedimentales.
+## ... Hay más reglas complicadas, como la especifidad (los literales ganan
+## son las clases de caracteres)
++
+## Nota: la primera coincidencia `or` todavía existen, pero ahora se
+## deletrea `||`
+'foo' ~~ / fo || foo /; # `fo` ahora.
+```
+
+## Extra: la subrutina MAIN
+
+```perl6
+## La subrutina `MAIN` se invoca cuando tu ejecuta un archivo de Perl 6
+## directamente. Es realmente poderosa porque Perl 6 actualmente parsea
+## los argumentos y los pasas a la subrutina. También maneja argumentos
+## nombrados (`--foo`) y hasta autogenerará un `--help`.
+sub MAIN($nombre) { say "¡Hola, $nombre!" }
+## Esto produce:
+## $ perl6 cli.pl
+## Uso:
+## t.pl <nombre>
+
+## Y dado que una subrutina regular en Perl 6, puedes tener múltiples
+## despachos:
+## (usando un "Bool" por un argumento nombrado para que podamos hacer
+## `--replace` a cambio de `--replace=1`)
+subset File of Str where *.IO.d; # convierte a un objeto IO para chequear si
+ # un archivo existe
+
+multi MAIN('add', $key, $value, Bool :$replace) { ... }
+multi MAIN('remove', $key) { ... }
+multi MAIN('import', File, Str :$as) { ... } # omitiendo parámetros nombrados
+## Esto produce:
+## $ perl6 cli.pl
+## Uso:
+## t.pl [--replace] add <key> <value>
+## t.pl remove <key>
+## t.pl [--as=<Str>] import (File)
+## Como puedes ver, esto es *realmente* poderoso.
+## Fue tan lejos como para mostrar las constantes en líneas.
+## (el tipo solo se muestra cuando el argumento `$`/ es nombrado)
+```
+
+## APÉNDICE A:
+### Lista de cosas
+
+```perl6
+## Consideramos que por ahora ya sabes lo básico de Perl 6.
+## Esta sección es solo para listar algunas operaciones comunes
+## las cuales no están en la "parte principal" del tutorial.
+
+## Operadores
+
+## * Comparación para ordenar
+## Ellos returnan un valor de los enum `Order`: `Less`, `Same` y `More`
+## (los cuales representan los números -1, 0 o +1).
+1 <=> 4; # comparación de orden para caracteres numéricos
+'a' leg 'b'; # comparación de orden para cadenas de texto
+$obj eqv $obj2; # comparación de orden usando la semántica eqv
+
+## * Ordenación genérica
+3 before 4; # True
+'b' after 'a'; # True
+
+## * Operador (por defecto) de circuito corto
+## Al igual que `or` y `||`, pero devuelve el primer valor *defined*
+## (definido):
+say Any // Nil // 0 // 5; #=> 0
+
+## * Circuito corto exclusivo or (XOR)
+## Devuelve `True` si uno (y solo uno) de sus argumentos es verdadero:
+say True ^^ False; #=> True
+
+## * Flip Flop
+## Los operadores flip flop (`ff` y `fff`, equivalente a `..`/`...` en P5)
+## son operadores que toman dos predicados para evalualarlos:
+## Ellos son `False` hasta que su lado izquierdo devuelve `True`, entonces
+## son `True` hasta que su lado derecho devuelve `True`.
+## Como los rangos, tu puedes excluir la iteración cuando se convierte en
+## `True`/`False` usando `^` en cualquier lado.
+## Comencemos con un ejemplo:
+for <well met young hero we shall meet later> {
+ # por defecto, `ff`/`fff` hace coincidencia inteligente (`~~`) contra `$_`:
+ if 'met' ^ff 'meet' { # no entrará el bucle if por "met"
+ # (se explica más abajo).
+ .say
+ }
+
+ if rand == 0 ff rand == 1 { # compara variables más que `$_`
+ say "Esto ... probablemente nunca se ejecutará ...";
+ }
+}
+## Esto imprimirá "young hero we shall meet" (exluyendo "met"):
+## el flip-flop comenzará devolviendo `True` cuando primero encuentra "met"
+## (pero no returnará `False` por "met" dabido al `^` al frente de `ff`),
+## hasta que ve "meet", lo cual es cuando comenzará devolviendo `False`.
+
+## La diferencia entre `ff` (al estilo de awk) y `fff` (al estilo de sed)
+## es que `ff` probará su lado derecho cuando su lado izquierdo cambia
+## a `True`, y puede returnar a `False` inmediamente (*excepto* que será
+## `True` por la iteración con la cual coincidió). Por lo contrario,
+## `fff` esperará por la próxima iteración para intentar su lado
+## derecho, una vez que su lado izquierdo ha cambiado:
+.say if 'B' ff 'B' for <A B C B A>; #=> B B
+ # porque el lado derecho se puso a prueba
+ # directamente (y returnó `True`).
+ # Las "B"s se imprimen dadó que coincidió
+ # en ese momento (returnó a `False`
+ # inmediatamente).
+.say if 'B' fff 'B' for <A B C B A>; #=> B C B
+ # El lado derecho no se puso a prueba
+ # hasta que `$_` se convirtió en "C"
+ # (y por lo tanto no coincidió
+ # inmediamente).
+
+## Un flip-flop puede cambiar estado cuantas veces se necesite:
+for <test start print it stop not printing start print again stop not anymore> {
+ .say if $_ eq 'start' ^ff^ $_ eq 'stop'; # excluye a "start" y "stop",
+ #=> "print it print again"
+}
+
+## También podrías usar una Whatever Star, lo cual es equivalente
+## a `True` para el lado izquierdo o `False` para el lado derecho:
+for (1, 3, 60, 3, 40, 60) { # Nota: los paréntesis son superfluos aquí
+ # (algunas veces se les llaman "paréntesis superticiosos")
+ .say if $_ > 50 ff *; # Una vez el flip-flop alcanza un número mayor que 50,
+ # no returnará jamás a `False`
+ #=> 60 3 40 60
+}
+
+## También puedes usar esta propiedad para crear un `If`
+## que no pasará la primera vez:
+for <a b c> {
+ .say if * ^ff *; # el flip-flop es `True` y nunca returna a `False`,
+ # pero el `^` lo hace *que no se ejecute* en la
+ # primera iteración
+ #=> b c
+}
+
+## - `===` es la identidad de valor y usa `.WHICH`
+## en los objetos para compararlos.
+## - `=:=` es la identidad de contenedor y usa `VAR()`
+## en los objetos para compararlos.
+
+```
+Si quieres ir más allá de lo que se muestra aquí, puedes:
+
+ - Leer la [documentación de Perl 6](https://docs.perl6.org/). Esto es un recurso
+ grandioso acerca de Perl 6. Si estás buscando por algo en particular, usa la
+ barra de búsquedas. Esto te dará un menú de todas las páginas concernientes
+ a tu término de búsqueda (¡Es mucho mejor que usar Google para encontrar
+ documentos acerca de Perl 6!)
+ - Leer el [Perl 6 Advent Calendar](http://perl6advent.wordpress.com/). Este es
+ un gran recurso de fragmentos de código de Perl 6 y explicaciones. Si la documentación
+ no describe algo lo suficientemente bien, puedes encontrar información más detallada
+ aquí. Esta información puede ser un poquito más antigua pero hay muchos ejemplos y
+ explicaciones. Las publicaciones fueron suspendidas al final del 2015 cuando
+ el lenguaje fue declarado estable y Perl 6.c fue lanzado.
+ - Unirte a `#perl6` en `irc.freenode.net`. Las personas aquí son siempre serviciales.
+ - Chequear la [fuente de las funciones y clases de Perl 6
+ ](https://github.com/rakudo/rakudo/tree/nom/src/core). Rakudo está principalmente
+ escrito en Perl 6 (con mucho de NQP, "Not Quite Perl" ("No Perl Todavía"), un
+ subconjunto de Perl 6 que es más fácil de implementar y optimizar).
+ - Leer [documentos acerca del diseño del lenguaje](http://design.perl6.org).
+ Estos explican P6 desde la perspectiva de un implementador, lo cual es bastante
+ interesante.
diff --git a/it-it/python3-it.html.markdown b/it-it/python3-it.html.markdown
new file mode 100644
index 00000000..06ef9a5e
--- /dev/null
+++ b/it-it/python3-it.html.markdown
@@ -0,0 +1,1016 @@
+---
+language: python3
+filename: learnpython3-it.py
+contributors:
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Zachary Ferguson", "http://github.com/zfergus2"]
+ - ["evuez", "http://github.com/evuez"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+translators:
+ - ["Draio", "http://github.com/Draio/"]
+ - ["Ale46", "http://github.com/Ale46/"]
+ - ["Tommaso Pifferi", "http://github.com/neslinesli93/"]
+lang: it-it
+---
+
+Python è stato creato da Guido Van Rossum agli inizi degli anni 90. Oggi è uno dei più popolari linguaggi esistenti. Mi sono innamorato di Python per la sua chiarezza sintattica. E' sostanzialmente pseudocodice eseguibile.
+
+Feedback sono altamente apprezzati! Potete contattarmi su [@louiedinh](http://twitter.com/louiedinh) oppure [at] [google's email service]
+
+Nota: Questo articolo è riferito a Python 3 in modo specifico. Se volete avete la necessità di utilizzare Python 2.7 potete consultarla [qui](https://learnxinyminutes.com/docs/it-it/python-it/)
+
+```python
+
+# I commenti su una sola linea iniziano con un cancelletto
+
+
+""" Più stringhe possono essere scritte
+ usando tre ", e sono spesso usate
+ come documentazione
+"""
+
+####################################################
+## 1. Tipi di dati primitivi ed Operatori
+####################################################
+
+# Ci sono i numeri
+3 # => 3
+
+# La matematica è quello che vi aspettereste
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+
+# Risultato della divisione intera troncata sia in positivo che in negativo
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # works on floats too
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# Il risultato di una divisione è sempre un numero decimale (float)
+10.0 / 3 # => 3.3333333333333335
+
+# Operazione Modulo
+7 % 3 # => 1
+
+# Elevamento a potenza (x alla y-esima potenza)
+2**3 # => 8
+
+# Forzare le precedenze con le parentesi
+(1 + 3) * 2 # => 8
+
+# I valori booleani sono primitive del linguaggio (nota la maiuscola)
+True
+False
+
+# nega con not
+not True # => False
+not False # => True
+
+# Operatori Booleani
+# Nota "and" e "or" sono case-sensitive
+True and False # => False
+False or True # => True
+
+# Note sull'uso di operatori Bool con interi
+# False è 0 e True è 1
+# Non confonderti tra bool(ints) e le operazioni bitwise and/or (&,|)
+0 and 2 # => 0
+-5 or 0 # => -5
+0 == False # => True
+2 == True # => False
+1 == True # => True
+-5 != False != True #=> True
+
+# Uguaglianza è ==
+1 == 1 # => True
+2 == 1 # => False
+
+# Disuguaglianza è !=
+1 != 1 # => False
+2 != 1 # => True
+
+# Altri confronti
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# I confronti possono essere concatenati!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# ('is' vs. '==')
+# 'is' controlla se due variabili si riferiscono allo stesso oggetto
+# '==' controlla se gli oggetti puntati hanno lo stesso valore.
+a = [1, 2, 3, 4] # a punta ad una nuova lista [1, 2, 3, 4]
+b = a # b punta a ciò a cui punta a
+b is a # => True, a e b puntano allo stesso oggeto
+b == a # => True, gli oggetti di a e b sono uguali
+b = [1, 2, 3, 4] # b punta ad una nuova lista [1, 2, 3, 4]
+b is a # => False, a e b non puntano allo stesso oggetto
+b == a # => True, gli oggetti di a e b sono uguali
+
+# Le stringhe sono create con " o '
+"Questa è una stringa."
+'Anche questa è una stringa.'
+
+# Anche le stringhe possono essere sommate! Ma cerca di non farlo.
+"Hello " + "world!" # => "Hello world!"
+# Le stringhe (ma non le variabili contenenti stringhe) possono essere
+# sommate anche senza '+'
+"Hello " "world!" # => "Hello world!"
+
+# Una stringa può essere considerata come una lista di caratteri
+"Questa è una stringa"[0] # => 'Q'
+
+# Puoi conoscere la lunghezza di una stringa
+len("Questa è una stringa") # => 20
+
+# .format può essere usato per formattare le stringhe, in questo modo:
+"{} possono essere {}".format("Le stringhe", "interpolate") # => "Le stringhe possono essere interpolate"
+
+# Puoi ripetere gli argomenti di formattazione per risparmiare un po' di codice
+"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick")
+# => "Jack be nimble, Jack be quick, Jack jump over the candle stick"
+
+# Puoi usare dei nomi se non vuoi contare gli argomenti
+"{nome} vuole mangiare {cibo}".format(nome="Bob", cibo="le lasagne") # => "Bob vuole mangiare le lasagne"
+
+# Se il tuo codice Python 3 necessita di eseguire codice Python 2.x puoi ancora
+# utilizzare il vecchio stile di formattazione:
+"%s possono essere %s nel %s modo" % ("Le stringhe", "interpolate", "vecchio") # => "Le stringhe possono essere interpolate nel vecchio modo"
+
+# None è un oggetto
+None # => None
+
+# Non usare il simbolo di uguaglianza "==" per comparare oggetti a None
+# Usa "is" invece
+"etc" is None # => False
+None is None # => True
+
+# None, 0, e stringhe/liste/dizionari/tuple vuoti vengono considerati
+# falsi (False). Tutti gli altri valori sono considerati veri (True).
+bool(0) # => False
+bool("") # => False
+bool([]) # => False
+bool({}) # => False
+bool(()) # => False
+
+####################################################
+## 2. Variabili e Collections
+####################################################
+
+# Python ha una funzione per scrivere (sul tuo schermo)
+print("Sono Python. Piacere di conoscerti!") # => Sono Python. Piacere di conoscerti!
+
+# Di default la funzione print() scrive e va a capo aggiungendo un carattere
+# newline alla fine della stringa. È possibile utilizzare l'argomento opzionale
+# end per cambiare quest'ultimo carattere aggiunto.
+print("Hello, World", end="!") # => Hello, World!
+
+# Un modo semplice per ricevere dati in input dalla riga di comando
+variabile_stringa_input = input("Inserisci del testo: ") # Restituisce i dati letti come stringa
+# Nota: Nelle precedenti vesioni di Python, il metodo input()
+# era chiamato raw_input()
+
+# Non c'è bisogno di dichiarare una variabile per assegnarle un valore
+# Come convenzione, per i nomi delle variabili, si utilizzano i caratteri
+# minuscoli separati, se necessario, da underscore
+some_var = 5
+some_var # => 5
+
+# Accedendo ad una variabile non precedentemente assegnata genera un'eccezione.
+# Dai un'occhiata al Control Flow per imparare di più su come gestire
+# le eccezioni.
+some_unknown_var # Genera un errore di nome
+
+# if può essere usato come un'espressione
+# È l'equivalente dell'operatore ternario in C
+"yahoo!" if 3 > 2 else 2 # => "yahoo!"
+
+# Le liste immagazzinano sequenze
+li = []
+# Puoi partire con una lista pre-riempita
+other_li = [4, 5, 6]
+
+# Aggiungere alla fine di una lista con append
+li.append(1) # li ora è [1]
+li.append(2) # li ora è [1, 2]
+li.append(4) # li ora è [1, 2, 4]
+li.append(3) # li ora è [1, 2, 4, 3]
+# Rimuovi dalla fine della lista con pop
+li.pop() # => 3 e li ora è [1, 2, 4]
+# Rimettiamolo a posto
+li.append(3) # li ora è [1, 2, 4, 3] di nuovo.
+
+# Accedi ad una lista come faresti con un array
+li[0] # => 1
+# Guarda l'ultimo elemento
+li[-1] # => 3
+
+# Guardare al di fuori dei limiti genera un IndexError
+li[4] # Genera IndexError
+
+# Puoi guardare gli intervalli con la sintassi slice (a fetta).
+# (E' un intervallo chiuso/aperto per voi tipi matematici.)
+li[1:3] # => [2, 4]
+# Ometti l'inizio
+li[2:] # => [4, 3]
+# Ometti la fine
+li[:3] # => [1, 2, 4]
+# Seleziona ogni seconda voce
+li[::2] # =>[1, 4]
+# Copia al contrario della lista
+li[::-1] # => [3, 4, 2, 1]
+# Usa combinazioni per fare slices avanzate
+# li[inizio:fine:passo]
+
+# Crea una copia (one layer deep copy) usando la sintassi slices
+li2 = li[:] # => li2 = [1, 2, 4, 3] ma (li2 is li) risulterà falso.
+
+# Rimuovi arbitrariamente elementi da una lista con "del"
+del li[2] # li è ora [1, 2, 3]
+
+# Rimuove la prima occorrenza di un elemento
+li.remove(2) # Ora li è [1, 3, 4, 5, 6]
+li.remove(2) # Emette un ValueError, poichè 2 non è contenuto nella lista
+
+# Inserisce un elemento all'indice specificato
+li.insert(1, 2) # li è di nuovo [1, 2, 3, 4, 5, 6]
+
+ Ritorna l'indice della prima occorrenza dell'elemento fornito
+li.index(2) # => 1
+li.index(7) # Emette un ValueError, poichè 7 non è contenuto nella lista
+
+# Puoi sommare le liste
+# Nota: i valori per li e per other_li non vengono modificati.
+li + other_li # => [1, 2, 3, 4, 5, 6]
+
+# Concatena le liste con "extend()"
+li.extend(other_li) # Adesso li è [1, 2, 3, 4, 5, 6]
+
+# Controlla l'esistenza di un valore in una lista con "in"
+1 in li # => True
+
+# Esamina la lunghezza con "len()"
+len(li) # => 6
+
+
+# Le tuple sono come le liste ma immutabili.
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # Genera un TypeError
+
+# Note that a tuple of length one has to have a comma after the last element but
+# tuples of other lengths, even zero, do not.
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
+
+# Puoi fare tutte queste cose da lista anche sulle tuple
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Puoi scompattare le tuple (o liste) in variabili
+a, b, c = (1, 2, 3) # a è ora 1, b è ora 2 e c è ora 3
+d, e, f = 4, 5, 6 # puoi anche omettere le parentesi
+# Le tuple sono create di default se non usi le parentesi
+g = 4, 5, 6 # => (4, 5, 6)
+# Guarda come è facile scambiare due valori
+e, d = d, e # d è ora 5 ed e è ora 4
+
+# I dizionari memorizzano insiemi di dati indicizzati da nomi arbitrari (chiavi)
+empty_dict= {}
+# Questo è un dizionario pre-caricato
+filled_dict = {"uno": 1, "due": 2, "tre": 3}
+
+# Nota: le chiavi dei dizionari devono essere di tipo immutabile. Questo per
+# assicurare che le chiavi possano essere convertite in calori hash costanti
+# per un risposta più veloce.
+invalid_dict = {[1,2,3]: "123"} # => Emette un TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # I valori, invece, possono essere di qualunque tipo
+
+# Accedi ai valori indicando la chiave tra []
+filled_dict["uno"] # => 1
+
+# Puoi ottenere tutte le chiavi di un dizionario con "keys()"
+# (come oggetto iterabile). Per averle in formato lista è necessario
+# utilizzare list().
+# Nota - Nei dizionari l'ordine delle chiavi non è garantito.
+# Il tuo risultato potrebbe non essere uguale a questo.
+list(filled_dict.keys()) # => ["tre", "due", "uno"]
+
+
+# Puoi ottenere tutti i valori di un dizionario con "values()"
+# (come oggetto iterabile).
+# Anche in questo caso, er averle in formato lista, è necessario utilizzare list()
+# Anche in questo caso, come per le chiavi, l'ordine non è garantito
+list(filled_dict.values()) # => [3, 2, 1]
+
+# Controlla l'esistenza delle chiavi in un dizionario con "in"
+"uno" in filled_dict # => True
+1 in filled_dict # => False
+
+# Cercando una chiave non esistente genera un KeyError
+filled_dict["quattro"] # KeyError
+
+# Usa il metodo "get()" per evitare KeyError
+filled_dict.get("uno") # => 1
+filled_dict.get("quattro") # => None
+# Il metodo get supporta un argomento di default quando il valore è mancante
+filled_dict.get("uno", 4) # => 1
+filled_dict.get("quattro", 4) # => 4
+
+
+# "setdefault()" inserisce un valore per una chiave in un dizionario
+# solo se la chiave data non è già presente
+filled_dict.setdefault("cinque", 5) # filled_dict["cinque"] viene impostato a 5
+filled_dict.setdefault("cinque", 6) # filled_dict["cinque"] rimane 5
+
+# Aggiungere una coppia chiave->valore a un dizionario
+filled_dict.update({"quattro":4}) # => {"uno": 1, "due": 2, "tre": 3, "quattro": 4}
+filled_dict["quattro"] = 4 # un altro modo pe aggiungere a un dizionario
+
+# Rimuovi una chiave da un dizionario con del
+del filled_dict["uno"] # Rimuove la chiave "uno" dal dizionario
+
+# Da Python 3.5 puoi anche usare ulteriori opzioni di spacchettamento
+{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
+{'a': 1, **{'a': 2}} # => {'a': 2}
+
+# I set sono come le liste ma non possono contenere doppioni
+empty_set = set()
+# Inizializza un "set()" con un dei valori. Sì, sembra un dizionario.
+some_set = {1, 1, 2, 2, 3, 4} # set_nuovo è {1, 2, 3, 4}
+
+# Come le chiavi di un dizionario, gli elementi di un set devono essere
+# di tipo immutabile
+invalid_set = {[1], 1} # => Genera un "TypeError: unhashable type: 'list'""
+valid_set = {(1,), 1}
+
+# Aggiungere uno o più elementi ad un set
+some_set.add(5) # some_set ora è {1, 2, 3, 4, 5}
+
+# Fai intersezioni su un set con &
+other_set = {3, 4, 5, 6}
+some_set & other_set # => {3, 4, 5}
+
+# Fai unioni su set con |
+some_set | other_set # => {1, 2, 3, 4, 5, 6}
+
+# Fai differenze su set con -
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# Effettua la differenza simmetrica con ^
+{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
+
+# Controlla se il set a sinistra contiene quello a destra
+{1, 2} >= {1, 2, 3} # => False
+
+# Controlla se il set a sinistra è un sottoinsieme di quello a destra
+{1, 2} <= {1, 2, 3} # => True
+
+# Controlla l'esistenza in un set con in
+2 in some_set # => True
+10 in some_set # => False
+
+
+
+####################################################
+## 3. Control Flow e oggetti Iterabili
+####################################################
+
+# Dichiariamo una variabile
+some_var = 5
+
+# Questo è un controllo if. L'indentazione è molto importante in python!
+# Come convenzione si utilizzano quattro spazi, non la tabulazione.
+# Il seguente codice stampa "some_var è minore di 10"
+if some_var > 10:
+ print("some_var è maggiore di 10")
+elif some_var < 10: # La clausolo elif è opzionale
+ print("some_var è minore di 10")
+else: # Anche else è opzionale
+ print("some_var è 10.")
+
+"""
+I cicli for iterano sulle liste, cioé ripetono un codice per ogni elemento
+# di una lista.
+Il seguente codice scriverà:
+ cane è un mammifero
+ gatto è un mammifero
+ topo è un mammifero
+"""
+for animale in ["cane", "gatto", "topo"]:
+ # Puoi usare format() per interpolare le stringhe formattate.
+ print("{} is a mammal".format(animal))
+
+"""
+"range(numero)" restituisce una lista di numeri da zero al numero dato
+Il seguente codice scriverà:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print(i)
+
+"""
+"range(lower, upper)" restituisce una lista di numeri dal più piccolo (lower)
+al più grande (upper).
+Il seguente codice scriverà:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
+
+"""
+"range(lower, upper, step)" rrestituisce una lista di numeri dal più piccolo
+(lower) al più grande (upper), incrementando del valore step.
+Se step non è indicato, avrà come valore di default 1.
+Il seguente codice scriverà:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+"""
+
+I cicli while vengono eseguiti finchè una condizione viene a mancare
+Il seguente codice scriverà:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print(x)
+ x += 1 # Forma compatta per x = x + 1
+
+# Gestione delle eccezioni con un blocco try/except
+try:
+ # Usa "raise" per generare un errore
+ raise IndexError("Questo è un IndexError")
+except IndexError as e:
+ pass # Pass è solo una non-operazione. Solitamente vorrai rimediare all'errore.
+except (TypeError, NameError):
+ pass # Eccezioni multiple possono essere gestite tutte insieme, se necessario.
+else: # Clausola opzionale al blocco try/except. Deve essere dopo tutti i blocchi except
+ print("Tutto ok!") # Viene eseguita solo se il codice dentro try non genera eccezioni
+finally: # Eseguito sempre
+ print("Possiamo liberare risorse qui")
+
+# Se ti serve solo un try/finally, per liberare risorse, puoi usare il metodo with
+with open("myfile.txt") as f:
+ for line in f:
+ print(line)
+
+# In Python qualunque oggetto in grado di essere trattato come una
+# sequenza è definito un oggetto Iterable (itarabile).
+# L'oggetto restituito da una funzione range è un iterabile.
+
+filled_dict = {"uno": 1, "due": 2, "tre": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => dict_keys(['uno', 'due', 'tre']).
+# Questo è un oggetto che implementa la nostra interfaccia Iterable.
+
+# È possibile utilizzarlo con i loop:
+for i in our_iterable:
+ print(i) # Scrive uno, due, tre
+
+# Tuttavia non possiamo recuperarne i valori tramite indice.
+our_iterable[1] # Genera un TypeError
+
+# Un oggetto iterabile è in grado di generare un iteratore
+our_iterator = iter(our_iterable)
+
+# L'iteratore è un oggetto che ricorda il suo stato mentro lo si "attraversa"
+# Possiamo accedere al successivo elemento con "next()".
+next(our_iterator) # => "uno"
+
+# Mantiene il suo stato mentro eseguiamo l'iterazione
+next(our_iterator) # => "due"
+next(our_iterator) # => "tre"
+
+# Dopo che un iteratore ha restituito tutti i suoi dati, genera
+# un'eccezione StopIteration
+next(our_iterator) # Raises StopIteration
+
+# Puoi prendere tutti gli elementi di un iteratore utilizzando list().
+list(filled_dict.keys()) # => Returns ["one", "two", "three"]
+
+
+
+####################################################
+## 4. Funzioni
+####################################################
+
+# Usa "def" per creare nuove funzioni
+def aggiungi(x, y):
+ print("x è {} e y è {}".format(x, y)) // Scrive i valori formattati in una stringa
+ return x + y # Restituisce la somma dei valori con il metodo return
+
+# Chiamare funzioni con parametri
+aggiungi(5, 6) # => scrive "x è 5 e y è 6" e restituisce 11
+
+# Un altro modo per chiamare funzioni è con parole chiave come argomenti
+aggiungi(y=6, x=5) # In questo modo non è necessario rispettare l'ordine degli argomenti
+
+# Puoi definire funzioni che accettano un numero non definito di argomenti
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) # => (1, 2, 3)
+
+# Puoi definire funzioni che accettano un numero variabile di parole chiave
+# come argomento, che saranno interpretati come un dizionario usando **
+def keyword_args(**kwargs):
+ return kwargs
+
+# Chiamiamola per vedere cosa succede
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
+
+# Puoi farle entrambi in una volta, se ti va
+def all_the_args(*args, **kwargs):
+ print(args)
+ print(kwargs)
+"""
+all_the_args(1, 2, a=3, b=4) stampa:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Quando chiami funzioni, puoi fare l'opposto di args/kwargs!
+# Usa * per sviluppare gli argomenti posizionale ed usa ** per
+# espandere gli argomenti parola chiave
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # equivalente a foo(1, 2, 3, 4)
+all_the_args(**kwargs) # equivalente a foo(a=3, b=4)
+all_the_args(*args, **kwargs) # equivalente a foo(1, 2, 3, 4, a=3, b=4)
+
+
+# Restituire valori multipli (with tuple assignments)
+def swap(x, y):
+ return y, x # Restituisce valori multipli come tupla senza parentesi
+ # (Nota: le parentesi sono state escluse ma possono essere messe)
+
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # Le parentesi sono state escluse ma possono essere incluse.
+
+# Funzioni - Visibilità delle variabili (variable scope)
+x = 5
+
+def set_x(num):
+ # La variabile locale x non è la variabile globale x
+ x = num # => 43
+ print(x) # => 43
+
+def set_global_x(num):
+ global x
+ print(x) # => 5
+ x = num # la variabile globable x è ora 6
+ print(x) # => 6
+
+set_x(43)
+set_global_x(6)
+
+
+# Python ha "first class functions"
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) # => 13
+
+# Ci sono anche funzioni anonime
+(lambda x: x > 2)(3) # => True
+(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
+
+# È possibile creare "mappe" e "filtri"
+list(map(add_10, [1, 2, 3])) # => [11, 12, 13]
+list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3]
+
+list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7]
+
+# Possiamo usare le "list comprehensions" per mappe e filtri
+# Le "list comprehensions" memorizzano l'output come una lista che può essere
+# di per sé una lista annidata
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
+
+# Puoi fare anche la comprensione di set e dizionari
+{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'}
+{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
+
+
+####################################################
+## 5. Modules
+####################################################
+
+# Puoi importare moduli
+import math
+print(math.sqrt(16)) # => 4.0
+
+# Puoi ottenere specifiche funzione da un modulo
+from math import ceil, floor
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
+
+# Puoi importare tutte le funzioni da un modulo
+# Attenzione: questo non è raccomandato
+from math import *
+
+# Puoi abbreviare i nomi dei moduli
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+
+# I moduli di Python sono normali file python. Ne puoi
+# scrivere di tuoi ed importarli. Il nome del modulo
+# è lo stesso del nome del file.
+
+# Potete scoprire quali funzioni e attributi
+# sono definiti in un modulo
+import math
+dir(math)
+
+# Se nella cartella corrente hai uno script chiamato math.py,
+# Python caricherà quello invece del modulo math.
+# Questo succede perchè la cartella corrente ha priorità
+# sulle librerie standard di Python
+
+# Se hai uno script Python chiamato math.py nella stessa
+# cartella del tua script, Python caricherà quello al posto del
+# comune modulo math.
+# Questo accade perché la cartella locale ha la priorità
+# sulle librerie built-in di Python.
+
+
+####################################################
+## 6. Classes
+####################################################
+
+# Usiamo l'istruzione "class" per creare una classe
+class Human:
+
+ # Un attributo della classe. E' condiviso tra tutte le istanze delle classe
+ species = "H. sapiens"
+
+ # Si noti che i doppi underscore iniziali e finali denotano gli oggetti o
+ # attributi utilizzati da Python ma che vivono nel namespace controllato
+ # dall'utente
+ # Metodi, oggetti o attributi come: __init__, __str__, __repr__, etc. sono
+ # chiamati metodi speciali (o talvolta chiamati "dunder methods").
+ # Non dovresti inventare tali nomi da solo.
+
+ def __init__(self, name):
+ # Assegna l'argomento all'attributo name dell'istanza
+ self.name = name
+
+ # Inizializza una proprietà
+ self._age = 0
+
+ # Un metodo dell'istanza. Tutti i metodi prendo "self" come primo argomento
+ def say(self, msg):
+ print("{name}: {message}".format(name=self.name, message=msg))
+
+ # Un altro metodo dell'istanza
+ def sing(self):
+ return 'yo... yo... microphone check... one two... one two...'
+
+ # Un metodo della classe è condiviso fra tutte le istanze
+ # Sono chiamati con la classe chiamante come primo argomento
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Un metodo statico è chiamato senza classe o istanza di riferimento
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+ # Una property è come un metodo getter.
+ # Trasforma il metodo age() in un attributo in sola lettura, che ha
+ # lo stesso nome
+ # In Python non c'è bisogno di scrivere futili getter e setter.
+ @property
+ def age(self):
+ return self._age
+
+ # Questo metodo permette di modificare una property
+ @age.setter
+ def age(self, age):
+ self._age = age
+
+ # Questo metodo permette di cancellare una property
+ @age.deleter
+ def age(self):
+ del self._age
+
+# Quando l'interprete Python legge un sorgente esegue tutto il suo codice.
+# Questo controllo su __name__ assicura che questo blocco di codice venga
+# eseguito solo quando questo modulo è il programma principale.
+
+if __name__ == '__main__':
+ # Crea un'istanza della classe
+ i = Human(name="Ian")
+ i.say("hi") # "Ian: hi"
+ j = Human("Joel")
+ j.say("hello") # "Joel: hello"
+ # i e j sono istanze del tipo Human, o in altre parole sono oggetti Human
+
+ # Chiama un metodo della classe
+ i.say(i.get_species()) # "Ian: H. sapiens"
+ # Cambia l'attributo condiviso
+ Human.species = "H. neanderthalensis"
+ i.say(i.get_species()) # => "Ian: H. neanderthalensis"
+ j.say(j.get_species()) # => "Joel: H. neanderthalensis"
+
+ # Chiama un metodo statico
+ print(Human.grunt()) # => "*grunt*"
+
+ # Non è possibile chiamare il metodo statico con l'istanza dell'oggetto
+ # poiché i.grunt() metterà automaticamente "self" (l'oggetto i)
+ # come argomento
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # Aggiorna la property (age) di questa istanza
+ i.age = 42
+ # Leggi la property
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # Cancella la property
+ del i.age
+ i.age # => questo genererà un AttributeError
+
+
+####################################################
+## 6.1 Ereditarietà (Inheritance)
+####################################################
+
+# L'ereditarietà consente di definire nuove classi figlio che ereditano metodi e
+# variabili dalla loro classe genitore.
+
+# Usando la classe Human definita sopra come classe base o genitore, possiamo
+# definire una classe figlia, Superhero, che erediterà le variabili di classe
+# come "species", "name" e "age", così come i metodi, come "sing" e "grunt",
+# dalla classe Human, ma potrà anche avere le sue proprietà uniche.
+
+# Per importare le funzioni da altri file usa il seguente formato
+# from "nomefile-senza-estensione" import "funzione-o-classe"
+
+from human import Human
+
+# Specificare le classi genitore come parametri della definizione della classe
+class Superhero(Human):
+
+ # Se la classe figlio deve ereditare tutte le definizioni del genitore
+ # senza alcuna modifica, puoi semplicemente usare la parola chiave "pass"
+ # (e nient'altro)
+
+ #Le classi figlio possono sovrascrivere gli attributi dei loro genitori
+ species = 'Superhuman'
+
+ # Le classi figlie ereditano automaticamente il costruttore della classe
+ # genitore, inclusi i suoi argomenti, ma possono anche definire ulteriori
+ # argomenti o definizioni e sovrascrivere i suoi metodi (compreso il
+ # costruttore della classe).
+ # Questo costruttore eredita l'argomento "nome" dalla classe "Human" e
+ # aggiunge gli argomenti "superpowers" e "movie":
+
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
+
+ # aggiungi ulteriori attributi della classe
+ self.fictional = True
+ self.movie = movie
+ self.superpowers = superpowers
+
+ # La funzione "super" ti consente di accedere ai metodi della classe
+ # genitore che sono stati sovrascritti dalla classe figlia,
+ # in questo caso il metodo __init__.
+ # Il seguente codice esegue il costruttore della classe genitore:
+ super().__init__(name)
+
+ # Sovrascrivere il metodo "sing"
+ def sing(self):
+ return 'Dun, dun, DUN!'
+
+ # Aggiungi un ulteriore metodo dell'istanza
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
+
+
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
+
+ # Controllo del tipo di istanza
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+
+ # Ottieni il "Method Resolution search Order" usato sia da getattr ()
+ # che da super (). Questo attributo è dinamico e può essere aggiornato
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+
+ # Esegui il metodo principale ma utilizza il proprio attributo di classe
+ print(sup.get_species()) # => Superhuman
+
+ # Esegui un metodo che è stato sovrascritto
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # Esegui un metodo di Human
+ sup.say('Spoon') # => Tick: Spoon
+
+ # Esegui un metodo che esiste solo in Superhero
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # Attributo di classe ereditato
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Attributo che esiste solo in Superhero
+ print('Am I Oscar eligible? ' + str(sup.movie))
+
+####################################################
+## 6.2 Ereditarietà multipla
+####################################################
+
+# Un'altra definizione di classe
+# bat.py
+class Bat:
+
+ species = 'Baty'
+
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
+
+ # Questa classe ha anche un metodo "say"
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
+
+ # E anche un suo metodo personale
+ def sonar(self):
+ return '))) ... ((('
+
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('hello'))
+ print(b.fly)
+
+# Definizione di classe che eredita da Superhero e Bat
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# Definisci Batman come classe figlia che eredita sia da Superhero che da Bat
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # In genere per ereditare gli attributi devi chiamare super:
+ # super(Batman, self).__init__(*args, **kwargs)
+ # Ma qui abbiamo a che fare con l'ereditarietà multipla, e super()
+ # funziona solo con la successiva classe nell'elenco MRO.
+ # Quindi, invece, chiamiamo esplicitamente __init__ per tutti gli
+ # antenati. L'uso di *args e **kwargs consente di passare in modo
+ # pulito gli argomenti, con ciascun genitore che "sbuccia un
+ # livello della cipolla".
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # sovrascrivere il valore per l'attributo name
+ self.name = 'Sad Affleck'
+
+ def sing(self):
+ return 'nan nan nan nan nan batman!'
+
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # Ottieni il "Method Resolution search Order" utilizzato da getattr() e super().
+ # Questo attributo è dinamico e può essere aggiornato
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # Esegui il metodo del genitore ma utilizza il proprio attributo di classe
+ print(sup.get_species()) # => Superhuman
+
+ # Esegui un metodo che è stato sovrascritto
+ print(sup.sing()) # => nan nan nan nan nan batman!
+
+ # Esegui un metodo da Human, perché l'ordine di ereditarietà è importante
+ sup.say('I agree') # => Sad Affleck: I agree
+
+ # Esegui un metodo che esiste solo nel 2o antenato
+ print(sup.sonar()) # => ))) ... (((
+
+ # Attributo di classe ereditato
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # Attributo ereditato dal secondo antenato il cui valore predefinito
+ # è stato ignorato.
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
+
+
+
+####################################################
+## 7. Advanced
+####################################################
+
+# I generatori ti aiutano a creare codice pigro (lazy code).
+# Codice che darà un risultato solo quando sarà "valutato"
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# I generatori sono efficienti in termini di memoria perché caricano
+# solo i dati necessari per elaborare il valore successivo nell'iterabile.
+# Ciò consente loro di eseguire operazioni su intervalli di valori
+# altrimenti proibitivi.
+# NOTA: `range` sostituisce` xrange` in Python 3.
+for i in double_numbers(range(1, 900000000)): # `range` is a generator.
+ print(i)
+ if i >= 30:
+ break
+
+# Proprio come è possibile creare una "list comprehension", è possibile
+# creare anche delle "generator comprehensions".
+values = (-x for x in [1,2,3,4,5])
+for x in values:
+ print(x) # prints -1 -2 -3 -4 -5 to console/terminal
+
+# Puoi anche trasmettere una "generator comprehensions" direttamente
+# ad un elenco.
+values = (-x for x in [1,2,3,4,5])
+gen_to_list = list(values)
+print(gen_to_list) # => [-1, -2, -3, -4, -5]
+
+
+# Decoratori
+# In questo esempio "beg" avvolge/wrappa "say".
+# Se say_please è True, cambierà il messaggio restituito.
+from functools import wraps
+
+def beg(target_function):
+ @wraps(target_function)
+ def wrapper(*args, **kwargs):
+ msg, say_please = target_function(*args, **kwargs)
+ if say_please:
+ return "{} {}".format(msg, "Per favore! Sono povero :(")
+ return msg
+
+ return wrapper
+
+
+@beg
+def say(say_please=False):
+ msg = "Puoi comprarmi una birra?"
+ return msg, say_please
+
+
+print(say()) # Puoi comprarmi una birra?
+print(say(say_please=True)) # Puoi comprarmi una birra? Per favore! Sono povero :(
+```
+
+## Pronto per qualcosa di più?
+
+### Gratis Online
+
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
+* [Ideas for Python Projects](http://pythonpracticeprojects.com)
+* [The Official Docs](http://docs.python.org/3/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Course](http://www.python-course.eu/index.php)
+* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
+* [A curated list of awesome Python frameworks, libraries and software](https://github.com/vinta/awesome-python)
+* [30 Python Language Features and Tricks You May Not Know About](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html)
+* [Official Style Guide for Python](https://www.python.org/dev/peps/pep-0008/)
+* [Python 3 Computer Science Circles](http://cscircles.cemc.uwaterloo.ca/)
+* [Dive Into Python 3](http://www.diveintopython3.net/index.html)
+* [A Crash Course in Python for Scientists](http://nbviewer.jupyter.org/gist/anonymous/5924718)
diff --git a/matlab.html.markdown b/matlab.html.markdown
index 6dc9f697..b88b1c03 100644
--- a/matlab.html.markdown
+++ b/matlab.html.markdown
@@ -374,8 +374,8 @@ disp('Hello World') % Print out a string
fprintf % Print to Command Window with more control
% Conditional statements (the parentheses are optional, but good style)
-if (a > 15)
- disp('Greater than 15')
+if (a > 23)
+ disp('Greater than 23')
elseif (a == 23)
disp('a is 23')
else
@@ -545,7 +545,7 @@ ans = multiplyLatBy(a,3)
% The method can also be called using dot notation. In this case, the object
% does not need to be passed to the method.
-ans = a.multiplyLatBy(a,1/3)
+ans = a.multiplyLatBy(1/3)
% Matlab functions can be overloaded to handle objects.
% In the method above, we have overloaded how Matlab handles
diff --git a/objective-c.html.markdown b/objective-c.html.markdown
index 04c4e529..de3884af 100644
--- a/objective-c.html.markdown
+++ b/objective-c.html.markdown
@@ -731,7 +731,10 @@ if ([myClass conformsToProtocol:@protocol(CarUtilities)]) {
///////////////////////////////////////
// Blocks are statements of code, just like a function, that are able to be used as data.
// Below is a simple block with an integer argument that returns the argument plus 4.
-int (^addUp)(int n); // Declare a variable to store the block.
+^(int n) {
+ return n + 4;
+}
+int (^addUp)(int n); // Declare a variable to store a block.
void (^noParameterBlockVar)(void); // Example variable declaration of block with no arguments.
// Blocks have access to variables in the same scope. But the variables are readonly and the
// value passed to the block is the value of the variable when the block is created.
diff --git a/pt-br/c-pt.html.markdown b/pt-br/c-pt.html.markdown
index 0dca7ab0..d594b7b9 100644
--- a/pt-br/c-pt.html.markdown
+++ b/pt-br/c-pt.html.markdown
@@ -638,16 +638,17 @@ typedef void (*minha_função_type)(char *);
## Leitura adicional
É recomendado ter uma cópia de [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language).
-Este é *o* livro sobre C, escrito pelos criadores da linguage. Mas cuidado - ele é antigo e contém alguns erros (bem,
-ideias que não são consideradas boas hoje) ou práticas mudadas.
+Este é *o* livro sobre C, escrito pelos criadores da linguagem. Mas cuidado - ele é antigo e contém alguns erros (bem,
+ideias que não são mais consideradas boas) ou práticas ultrapassadas.
Outra boa referência é [Learn C the hard way](http://c.learncodethehardway.org/book/).
Se você tem uma pergunta, leia [compl.lang.c Frequently Asked Questions](http://c-faq.com).
É importante usar espaços e indentação adequadamente e ser consistente com seu estilo de código em geral.
-Código legível é melhor que código 'esperto' e rápido. Para adotar um estilo de código bom e são, veja
+Código legível é melhor que código 'esperto' e rápido. Para adotar um estilo de código bom e sensato, veja
[Linux kernel coding style](https://www.kernel.org/doc/Documentation/CodingStyle).
Além disso, Google é teu amigo.
+
[1] http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
diff --git a/ruby.html.markdown b/ruby.html.markdown
index e0a6bb6e..bbc8c558 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -15,32 +15,28 @@ contributors:
- ["Gabriel Halley", "https://github.com/ghalley"]
- ["Persa Zula", "http://persazula.com"]
- ["Jake Faris", "https://github.com/farisj"]
+ - ["Corey Ward", "https://github.com/coreyward"]
---
```ruby
# This is a comment
-=begin
-This is a multiline comment
-No-one uses them
-You shouldn't either
-=end
+# In Ruby, (almost) everything is an object.
+# This includes numbers…
+3.class #=> Integer
-# First and foremost: Everything is an object.
-
-# Numbers are objects
-
-3.class #=> Fixnum
-
-3.to_s #=> "3"
+# …strings…
+"Hello".class #=> String
+# …even methods!
+"Hello".method(:class).class #=> Method
# Some basic arithmetic
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
35 / 5 #=> 7
-2**5 #=> 32
+2 ** 5 #=> 32
5 % 3 #=> 2
# Bitwise operators
@@ -52,6 +48,7 @@ You shouldn't either
# for calling a method on an object
1.+(3) #=> 4
10.* 5 #=> 50
+100.methods.include?(:/) #=> true
# Special values are objects
nil # equivalent to null in other languages
@@ -72,9 +69,10 @@ false.class #=> FalseClass
# apart from false itself, nil is the only other 'falsey' value
-!nil #=> true
-!false #=> true
-!0 #=> false
+!!nil #=> false
+!!false #=> false
+!!0 #=> true
+!!"" #=> true
# More comparisons
1 < 10 #=> true
@@ -82,7 +80,8 @@ false.class #=> FalseClass
2 <= 2 #=> true
2 >= 2 #=> true
-# Combined comparison operator
+# Combined comparison operator (returns `1` when the first argument is greater,
+# `-1` when the second argument is greater, and `0` otherwise)
1 <=> 10 #=> -1
10 <=> 1 #=> 1
1 <=> 1 #=> 0
@@ -90,7 +89,6 @@ false.class #=> FalseClass
# Logical operators
true && false #=> false
true || false #=> true
-!true #=> false
# There are alternate versions of the logical operators with much lower
# precedence. These are meant to be used as flow-control constructs to chain
@@ -101,23 +99,17 @@ do_something() and do_something_else()
# `log_error` only called if `do_something` fails.
do_something() or log_error()
-
-# Strings are objects
-
-'I am a string'.class #=> String
-"I am a string too".class #=> String
+# String interpolation
placeholder = 'use string interpolation'
"I can #{placeholder} when using double quoted strings"
#=> "I can use string interpolation when using double quoted strings"
-# Prefer single quoted strings to double quoted ones where possible
-# Double quoted strings perform additional inner calculations
-
-# Combine strings, but not with numbers
+# You can combine strings using `+`, but not with other types
'hello ' + 'world' #=> "hello world"
'hello ' + 3 #=> TypeError: can't convert Fixnum into String
'hello ' + 3.to_s #=> "hello 3"
+"hello #{3}" #=> "hello 3"
# Combine strings and operators
'hello ' * 3 #=> "hello hello hello "
@@ -150,9 +142,8 @@ snake_case = true
# Use descriptive variable names
path_to_project_root = '/good/name/'
-path = '/bad/name/'
+m = '/bad/name/'
-# Symbols (are objects)
# Symbols are immutable, reusable constants represented internally by an
# integer value. They're often used instead of strings to efficiently convey
# specific, meaningful values
@@ -167,6 +158,11 @@ status == 'pending' #=> false
status == :approved #=> false
+Strings can be converted into symbols and vice versa:
+
+status.to_s #=> "pending"
+"argon".to_sym #=> :argon
+
# Arrays
# This is an array
@@ -196,7 +192,7 @@ array.last #=> 5
array[2, 3] #=> [3, 4, 5]
# Reverse an Array
-a=[1,2,3]
+a = [1,2,3]
a.reverse! #=> [3,2,1]
# Or with a range
@@ -223,7 +219,7 @@ hash['number'] #=> 5
# Asking a hash for a key that doesn't exist returns nil:
hash['nothing here'] #=> nil
-# Since Ruby 1.9, there's a special syntax when using symbols as keys:
+# When using symbols for keys in a hash, you can use this alternate syntax:
new_hash = { defcon: 3, action: true }
@@ -246,33 +242,26 @@ else
'else, also optional'
end
+
+# In Ruby, traditional `for` loops aren't very common. Instead, these
+# basic loops are implemented using enumerable, which hinges on `each`:
+
+(1..5).each do |counter|
+ puts "iteration #{counter}"
+end
+
+# Which is roughly equivalent to this, which is unusual to see in Ruby:
+
for counter in 1..5
puts "iteration #{counter}"
end
-#=> iteration 1
-#=> iteration 2
-#=> iteration 3
-#=> iteration 4
-#=> iteration 5
-# HOWEVER, No-one uses for loops.
-# Instead you should use the "each" method and pass it a block.
-# A block is a bunch of code that you can pass to a method like "each".
-# It is analogous to lambdas, anonymous functions or closures in other
-# programming languages.
+# The `do |variable| ... end` construct above is called a “block”. Blocks are similar
+# to lambdas, anonymous functions or closures in other programming languages. They can
+# be passed around as objects, called, or attached as methods.
#
# The "each" method of a range runs the block once for each element of the range.
# The block is passed a counter as a parameter.
-# Calling the "each" method with a block looks like this:
-
-(1..5).each do |counter|
- puts "iteration #{counter}"
-end
-#=> iteration 1
-#=> iteration 2
-#=> iteration 3
-#=> iteration 4
-#=> iteration 5
# You can also surround blocks in curly brackets:
(1..5).each { |counter| puts "iteration #{counter}" }
@@ -365,10 +354,10 @@ def double(x)
x * 2
end
-# Methods (and all blocks) implicitly return the value of the last statement
+# Methods (and blocks) implicitly return the value of the last statement
double(2) #=> 4
-# Parentheses are optional where the result is unambiguous
+# Parentheses are optional where the interpretation is unambiguous
double 3 #=> 6
double double 3 #=> 12
@@ -399,25 +388,57 @@ surround { puts 'hello world' }
# }
-# You can pass a block to a method
-# "&" marks a reference to a passed block
+# Blocks can be converted into a `proc` object, which wraps the block
+# and allows it to be passed to another method, bound to a different scope,
+# or manipulated otherwise. This is most common in method parameter lists,
+# where you frequently see a trailing `&block` parameter that will accept
+# the block, if one is given, and convert it to a `Proc`. The naming here is
+# convention; it would work just as well with `&pineapple`:
def guests(&block)
- block.call 'some_argument'
+ block.class #=> Proc
+ block.call(4)
end
+# The `call` method on the Proc is similar to calling `yield` when a block is
+# present. The arguments passed to `call` will be forwarded to the block as arugments:
+
+guests { |n| "You have #{n} guests." }
+# => "You have 4 guests."
+
# You can pass a list of arguments, which will be converted into an array
# That's what splat operator ("*") is for
def guests(*array)
array.each { |guest| puts guest }
end
-# If a method returns an array, you can use destructuring assignment
-def foods
- ['pancake', 'sandwich', 'quesadilla']
+# Destructuring
+
+# Ruby will automatically destrucure arrays on assignment to multiple variables:
+a, b, c = [1, 2, 3]
+a #=> 1
+b #=> 2
+c #=> 3
+
+# In some cases, you will want to use the splat operator: `*` to prompt destructuring
+# of an array into a list:
+
+ranked_competitors = ["John", "Sally", "Dingus", "Moe", "Marcy"]
+
+def best(first, second, third)
+ puts "Winners are #{first}, #{second}, and #{third}."
end
-breakfast, lunch, dinner = foods
-breakfast #=> 'pancake'
-dinner #=> 'quesadilla'
+
+best *ranked_competitors.first(3) #=> Winners are John, Sally, and Dingus.
+
+# The splat operator can also be used in parameters:
+def best(first, second, third, *others)
+ puts "Winners are #{first}, #{second}, and #{third}."
+ puts "There were #{others.count} other participants."
+end
+
+best *ranked_competitors
+#=> Winners are John, Sally, and Dingus.
+#=> There were 2 other participants.
# By convention, all methods that return booleans end with a question mark
5.even? # false
diff --git a/solidity.html.markdown b/solidity.html.markdown
index a0f8cd40..b657b6a1 100644
--- a/solidity.html.markdown
+++ b/solidity.html.markdown
@@ -134,7 +134,7 @@ uint constant VERSION_ID = 0x123A1; // A hex constant
// All state variables (those outside a function)
// are by default 'internal' and accessible inside contract
// and in all contracts that inherit ONLY
-// Need to explicitly set to 'public' to allow external contracts to access
+// Need to explicitly set to 'public' to allow external contracts to access
int256 public a = 8;
// For int and uint, can explicitly set space in steps of 8 up to 256
@@ -352,7 +352,7 @@ function increment(uint x) constant returns (uint x) {
// y is a state variable, and can't be changed in a constant function
}
-// 'pure' is more strict than 'constant', and does not
+// 'pure' is more strict than 'constant', and does not
// even allow reading of state vars
// The exact rules are more complicated, so see more about
// constant/pure:
@@ -384,7 +384,7 @@ function depositEther() public payable {
// Prefer loops to recursion (max call stack depth is 1024)
-// Also, don't setup loops that you haven't bounded,
+// Also, don't setup loops that you haven't bounded,
// as this can hit the gas limit
// B. Events
@@ -399,11 +399,11 @@ function depositEther() public payable {
event LogSent(address indexed from, address indexed to, uint amount); // note capital first letter
// Call
-Sent(from, to, amount);
+LogSent(from, to, amount);
-// For an external party (a contract or external entity), to watch using
+// For an external party (a contract or external entity), to watch using
// the Web3 Javascript library:
-Coin.Sent().watch({}, '', function(error, result) {
+Coin.LogSent().watch({}, '', function(error, result) {
if (!error) {
console.log("Coin transfer: " + result.args.amount +
" coins were sent from " + result.args.from +
@@ -709,7 +709,7 @@ contract CrowdFunder {
return contributions.length - 1; // return id
}
- function checkIfFundingCompleteOrExpired()
+ function checkIfFundingCompleteOrExpired()
public
{
if (totalRaised > minimumToRaise) {
diff --git a/toml.html.markdown b/toml.html.markdown
index 980563f9..39caaa23 100755
--- a/toml.html.markdown
+++ b/toml.html.markdown
@@ -102,9 +102,10 @@ boolMustBeLowercase = true
# Datetime #
############
-date1 = 1979-05-27T07:32:00Z # follows the RFC 3339 spec
-date2 = 1979-05-27T07:32:00 # without offset
-date3 = 1979-05-27 # without offset nor time
+date1 = 1979-05-27T07:32:00Z # UTC time, following RFC 3339/ISO 8601 spec
+date2 = 1979-05-26T15:32:00+08:00 # with RFC 3339/ISO 8601 offset
+date3 = 1979-05-27T07:32:00 # without offset
+date4 = 1979-05-27 # without offset or time
####################
# COLLECTION TYPES #
diff --git a/tr-tr/c++-tr.html.markdown b/tr-tr/c++-tr.html.markdown
new file mode 100644
index 00000000..a1318876
--- /dev/null
+++ b/tr-tr/c++-tr.html.markdown
@@ -0,0 +1,1077 @@
+---
+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"]
+ - ["Ankush Goyal", "http://github.com/ankushg07"]
+ - ["Jatin Dhankhar", "https://github.com/jatindhankhar"]
+ - ["Adem Budak", "https://github.com/p1v0t"]
+---
+
+C++
+[yaratıcısı Bjarne Stroustrup'a göre](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
+
+- "daha iyi bir C" yapmak
+- veri soyutlamayı desteklemek
+- nesneye yönelik programlamayı deskteklemek
+- tipten bağımsız programlamayı desteklemek
+
+için tasarlanmış bir sistem programlama dilir.
+
+Sözdizimi daha yeni dillerden daha zor veya karmaşık olsa da işlemcinin doğrudan çalıştırabileceği
+native komutlara derlenerek, donanım üzerinde (C gibi) sıkı bir kontrol sağlar, bunu yaparken
+tipten bağımsızlık, exception'lar ve sınıflar gibi yüksek-seviyeli özellikleri destekler.
+Bu hız ve kullanışlılık C++'ı en çok kullanılan dillerden biri yapar.
+
+```c++
+//////////////////
+// C ile karşılaştırma
+//////////////////
+
+// C++ _neredeyse_ C'nin bir üstkümesidir, değişken tanımı, basit tipleri
+ve fonksiyonları için temelde aynı sözdizimini paylaşır.
+
+// Aynı C gibi, programın başlangıç noktası bir integer döndüren
+// main fonksiyonudur.
+// Bu değer programın bitiş statüsünü belli eder.
+// Daha fazla bilgi için bknz http://en.wikipedia.org/wiki/Exit_status .
+
+int main(int argc, char** argv)
+{
+ // Komut satırı argümanları C'de olduğu gibi argv ve argc ile geçilir
+ // argc, argüman sayısını belli eder,
+ // argv, argümanları belli eden, C-stili string'lerin (char*) dizisidir.
+ // İlk argüman çağrılan programın adıdır.
+ // Eğer argümanları umursamıyorsan, argv ve argc kullanılmayabilir
+ // int main() gibi
+
+ // 0 çıkış durumu başarıyı belirtir.
+ return 0;
+}
+
+// Bunlara rağmen C++ aşağıdaki noktalarda farklılaşır:
+
+// C++'ta, karakterler char türündendir
+sizeof('c') == sizeof(char) == 1
+
+// C'de, karakterler int türündendir
+sizeof('c') == sizeof(int)
+
+
+// C++ katı bir prototip kuralına sahiptir
+void func(); // fonksiyon argüman kabul etmez
+
+// C'de
+void func(); // fonksiyon herhangi bir sayıda argüman kabul edebilir
+
+// C++'da NULL yerine nullptr kullanılır
+int* ip = nullptr;
+
+// C standard başlıkları başına "c" eklenip, sondaki .h
+// kullanılmadan C++'ta kullanılabilir
+#include <cstdio>
+
+int main()
+{
+ printf("Hello, world!\n");
+ return 0;
+}
+
+//////////////////////////////////
+// Fonksiyonun fazladan yüklenmesi
+//////////////////////////////////
+
+// C++ herbir fonksiyonun farklı parametereler
+// aldığı fonksiyon fazladan yüklenmesini desktekler
+
+void print(char const* myString)
+{
+ printf("String %s\n", myString);
+}
+
+void print(int myInt)
+{
+ printf("My int is %d", myInt);
+}
+
+int main()
+{
+ print("Hello"); // void print(const char*) fonksiyonunu çağırır.
+ print(15); // void print(int) fonksiyonunu çağırır.
+}
+
+////////////////////////////////
+// Default fonksiyon argümanları
+/////////////////////////////i//
+
+// Eğer çağırıcı tarafından fonksiyona argüman sağlanmamışsa,
+// fonksiyona default argüman verebilirsin
+
+void doSomethingWithInts(int a = 1, int b = 4)
+{
+ // Burada int'lerle birşeyler yap
+}
+
+int main()
+{
+ doSomethingWithInts(); // a = 1, b = 4
+ doSomethingWithInts(20); // a = 20, b = 4
+ doSomethingWithInts(20, 5); // a = 20, b = 5
+}
+
+// Default argümanlar, argüman listesinin sonunda yer almalı.
+
+void invalidDeclaration(int a = 1, int b) // Hata!
+{
+}
+
+
+/////////////////////////
+// Namespace(İsim uzayı)
+/////////////////////////
+
+// Namespace'ler değişken, fonksiyon ve diğer bildirimlerin
+// kapsama alanını ayırır.
+// Namespace'ler içiçe geçebilir.
+
+namespace First {
+ namespace Nested {
+ void foo()
+ {
+ printf("This is First::Nested::foo\n");
+ }
+ } // Nested namespace'inin sonu
+} // First namespace'inin sonu
+
+namespace Second {
+ void foo()
+ {
+ printf("This is Second::foo\n");
+ }
+}
+
+void foo()
+{
+ printf("This is global foo\n");
+}
+
+int main()
+{
+ // Second namespace'i içinideki tüm sembolleri mevcut kapsama alanına dahil eder.
+ // Dikkat edersen artık yalnızca foo() çağrısı çalışmayacaktır çünkü hangi
+ // namespace'ten çağrıldığı açık değildir.
+ using namespace Second;
+
+ Second::foo(); // "This is Second::foo" yazdırıır
+ First::Nested::foo(); // "This is First::Nested::foo" yazdırır
+ ::foo(); // "This is global foo" yazdırır.
+}
+
+///////////////
+// Input/Output
+///////////////
+
+// C++'ta input ve output stream'leri kullanır.
+// cin, cout ve cerr,sırasıyla, stdin, stdout, ve stderr'i temsil eder.
+// << araya ekleme ve >> aradan çıkarma operatörüdür.
+
+#include <iostream> // I/O stream'lerini dahil etmek için
+
+using namespace std; // Streamler std namespace'i içindedir(standard kütüphane)
+
+int main()
+{
+ int myInt;
+
+ // stdout (veya terminal/screen)'ta çıktı verir
+ cout << "Enter your favorite number:\n";
+ // Girdiyi alır
+ cin >> myInt;
+
+ // cout ayrıca formatlanabilir
+ cout << "Your favorite number is " << myInt << "\n";
+ // prints "Your favorite number is <myInt>"
+
+ cerr << "Used for error messages";
+}
+
+//////////////
+// String'ler
+/////////////
+
+// String'ler C++'ta nesnedir ve pek çok üye fonksiyonu vardır
+#include <string>
+
+using namespace std; // String'ler de std namespace'i içindedir. (standard kütüphane)
+
+string myString = "Hello";
+string myOtherString = " World";
+
+// + eklemek için kullanıldır
+cout << myString + myOtherString; // "Hello World"
+
+cout << myString + " You"; // "Hello You"
+
+// C++'ta stringler are mutable'dır (değişebilir).
+myString.append(" Dog");
+cout << myString; // "Hello Dog"
+
+
+///////////////////////
+// Reference (Referans)
+///////////////////////
+
+// C'deki pointer'lara ek olarak
+// C++ _reference_'lara sahiptir.
+// Bunlar bir kere atandınğında tekrardan atanamayan pointer'dır
+// ve null olamaz.
+// Değişkenin kendisiyle aynı sözdizimine sahiptir:
+// Değerine ulaşmak için * ihtiyaç yoktur ve
+// atama için & (address of) kullanılmaz.
+
+using namespace std;
+
+string foo = "I am foo";
+string bar = "I am bar";
+
+
+string& fooRef = foo; // Bu foo'nun reference'ını oluşturur.
+fooRef += ". Hi!"; // foo'yu reference'ı üzerinden değiştirir.
+cout << fooRef; // "I am foo. Hi!" yazdırır.
+
+// "fooRef"e yeniden atama yapmaz. Bu "foo = bar" denktir ve bu satırdan sonra
+// foo == "I am bar" olur
+cout << &fooRef << endl; // foo'un adresini yazdırır
+fooRef = bar;
+cout << &fooRef << endl; //Hala foo'nun adresini yazdırır
+cout << fooRef; //"I am bar" yazdırır
+
+// fooRef'in adresi aynı kalır yani hala foo'nun adresidir.
+
+const string& barRef = bar; // bar'a const reference oluşturur
+// C'de olduğu gibi, const değerler (pointer'lar ve reference'ler) değiştirilemez.
+barRef += ". Hi!"; // Hata, const reference'ler değiştirilemez.
+
+// Kısa bir ekleme: reference'lere devam etmeden önce, geçici nesne konseptinden
+// bahsetmeliyiz. Mesela aşadaki gibi bir kod var:
+string tempObjectFun() { ... }
+string retVal = tempObjectFun();
+
+// Bu iki satırda aslında ne oluyor:
+// - tempObjectFun fonksiyonundan bir string nesnesi dönüyor
+// - dönmüş olan nesneyle yeni bir string oluşturuyor
+/ - dönmüş olan nesne yok ediliyor
+// İşte bu dönen nesneye geçici nesne denir. Geçici nesneler fonksiyon nesne
+// döndürdüğünde oluşturulur ve ifade işini bitirdiğinde yok edilir (Aslında,
+// standard'ın söylediği şey bu ama derleyiciler bu davranışı değiştirmemize
+// izin veriyor. Daha fazla detay için "return value optimization" diye
+// aratabilirsin. Sonuç olarak aşağıdaki kodda:
+foo(bar(tempObjectFun()))
+
+// foo ve bar'ın varolduğunu kabul ediyoruz, tempObjectFun'dan dönen nesne
+// bar'a geçti ve foo çağrılmadan önce yokedildir.
+
+// Şimdi reference'lara dönelim. "ifadenin sonunda" kuralının bir istisnası
+// eğer geçici nesne const reference'a geçildiyse oratya çıkar, bu durumda
+// nesnenin ömrü mevcut kapsama alanına kadar uzar:
+
+void constReferenceTempObjectFun() {
+ // constRef geçici nesneyi alır ve bu durum fonksiyonun sonuna kadar geçerlidir.
+ const string& constRef = tempObjectFun();
+ ...
+}
+
+// C++11 ile gelen diğer bir reference geçici nesnelere özeldir. Bu türden birden
+// bir tip tanımlayamazsın ama aşırı yüklenme sırasında bu tipler öncelik alır:
+void someFun(string& s) { ... } // Regular reference
+void someFun(string&& s) { ... } // Geçici nesneye reference
+
+string foo;
+someFun(foo); // regular reference'ı çağırır
+someFun(tempObjectFun()); // geçici reference'ı çağırır
+
+/////////////////////
+// Enum
+/////////////////////
+
+// Enum'lar sabit değerler yapmak için kullanılır ve çoğunlukla kodun daha okunaklı
+// olması için kullanılır
+
+enum ECarTypes
+{
+ Sedan,
+ Hatchback,
+ SUV,
+ Wagon
+};
+
+ECarTypes GetPreferredCarType()
+{
+ return ECarTypes::Hatchback;
+}
+
+// C++11 ile beraber bir tipi enum'a atamanın kolay bir yolu var, bu enum'un istenen
+// tipe dönüştürmek için kullanışlı bir yöntem
+enum ECarTypes : uint8_t
+{
+ Sedan, // 0
+ Hatchback, // 1
+ SUV = 254, // 254
+ Hybrid // 255
+};
+
+void WriteByteToFile(uint8_t InputValue)
+{
+ // Serialize the InputValue to a file
+}
+
+void WritePreferredCarTypeToFile(ECarTypes InputCarType)
+{
+ // enum uint8_t tipine dönüştürüldü
+ WriteByteToFile(InputCarType);
+}
+
+// Diğer yandan enum'ların yanlışlıkla integer tipini veya diğer enumlara dönüşmesini
+// istemiyorsan enum class olarak tanımlayabilirsin
+enum class ECarTypes : uint8_t
+{
+ Sedan, // 0
+ Hatchback, // 1
+ SUV = 254, // 254
+ Hybrid // 255
+};
+
+void WriteByteToFile(uint8_t InputValue)
+{
+ // Serialize the InputValue to a file
+}
+
+void WritePreferredCarTypeToFile(ECarTypes InputCarType)
+{
+ // ECarTypes, uint8_t tipinde olmasına rağmen, "enum class" olarak
+ // tanımlandığından derlenmeyecektir!
+ WriteByteToFile(InputCarType);
+}
+
+///////////////////////////////////////////
+// Sınıflar ve nesneye yönelik proglamalama
+///////////////////////////////////////////
+
+// Sınıflara(class) ilk örnek
+#include <iostream>
+
+// Sınıfı tanımla.
+// Sınıflar genelde header (.h veya .hpp) dosyalarında tanımlanır.
+class Dog {
+ // Member variables and functions are private by default.
+ // Üye değişkenler ve fonksiyonlar default olarak private'dir.
+ std::string name;
+ int weight;
+
+// Aşağıda, "private:" veya "protected:" bulunana kadar
+// bütün üyeler public'tir.
+public:
+
+ // Default constructor
+ Dog();
+
+ // Üye fonksiyon bildirimi (gerçeklenimi aşağıda)
+ // Dikkat ederseniz using namespace std; yerine
+ // std::string kullandık.
+ // Hiçbir zaman header dosyasında "using namespace std;" kullanma.
+ void setName(const std::string& dogsName);
+
+ void setWeight(int dogsWeight);
+
+ // Nesnenin durumunu değiştirmeyen fonksiyonlar const ile işaretlenmelidir
+
+ // Türetilen sınıflarda fonksiyonu override edebilmek için başına
+ // _virtual_ eklenmelidir.
+ // Fonksiyonlar, performanslar ilgili nedenlerden ötürü default olarak virtual değildir
+ virtual void print() const;
+
+ // Fonksiyonlar class içinde de tanımlanabilir.
+ // Bu şekille tanımlanan fonksiyonlar otomatik olarak inline olur.
+ void bark() const { std::cout << name << " barks!\n"; }
+
+ // C++ constructor'ların yanında destructor'da sağlar.
+ // Bunlar nesne silindiğinde veya scope'un dışına çıktığında çağrılır.
+ // Bu RAII gibi güçlü paradigmaları etkin kılar.
+ // (aşağıda açıklandı)
+ // Eğer sınıf kendisinden türetiliyorsa, destructor virtual olmalıdır,
+ // eğer virtual değilse, türetilmiş sınıfın destructor'ı nesne, ana sınıf
+ // referans'ı veya pointer'ı üzerinden yok edildiğinde, çağrılmayacaktır.
+ virtual ~Dog();
+
+}; // class tanımının sonuda noktalı virgül(;) olmalıdır.
+
+// Sınıfın üye fonksiyonları genelde .cpp dosyaları içinde gerçeklenir.
+Dog::Dog()
+{
+ std::cout << "A dog has been constructed\n";
+}
+
+// Objects (such as strings) should be passed by reference
+// Nesneler (string gibi) reference ile fonksiyonlara geçilmelidir
+// Eğer nesneleri değiştirilecekse reference ile fonksiyonlara geçilmelidir,
+// değiştirilmeyecekse const reference ile geçilmelidir.
+void Dog::setName(const std::string& dogsName)
+{
+ name = dogsName;
+}
+
+void Dog::setWeight(int dogsWeight)
+{
+ weight = dogsWeight;
+}
+
+// Dikkat edersen "virtual" yalnızca bildirimde gerekli, tanımlamada değil.
+void Dog::print() const
+{
+ std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
+}
+
+Dog::~Dog()
+{
+ std::cout << "Goodbye " << name << "\n";
+}
+
+int main() {
+ Dog myDog; // "A dog has been constructed" yazdırır
+ myDog.setName("Barkley");
+ myDog.setWeight(10);
+ myDog.print(); // "Dog is Barkley and weighs 10 kg" yazdırır.
+ return 0;
+} // "Goodbye Barkley" yazdırır.
+
+// Inheritance(Miras)
+
+// Bu sınıf, Dog sınıfında public ve protected olan herşeyi miras alır,
+// private olanları da miras alır ama, public ve protected sınıflar aracılıyla
+// yapılmıyorsa, doğrudan erişemez.
+class OwnedDog : public Dog {
+
+public:
+ void setOwner(const std::string& dogsOwner);
+
+ // print fonksiyonunun davranışını bütün OwnedDogs sınıfı için override eder
+ // (üstünden geçer, kendine uyarlar).
+ // bknz http://en.wikipedia.org/wiki/Polymorphism_(computer_science)
+ // override anahtar sözcüpü kullanılma da olur ama kullanılması aslında bir temel
+ // temel sınıf fonksiyonunun üzerinden geçtiğimizi gösterir.
+ void print() const override;
+
+private:
+ std::string owner;
+};
+
+// Bu arada takip eden .cpp dosyasında:
+
+void OwnedDog::setOwner(const std::string& dogsOwner)
+{
+ owner = dogsOwner;
+}
+
+void OwnedDog::print() const
+{
+ Dog::print(); // Ana dog sınıfındaki print fonksiyonunu çağırır
+ std::cout << "Dog is owned by " << owner << "\n";
+ // "Dog is <name> and weights <weight>"
+ // "Dog is owned by <owner>"
+ // yazdırır
+}
+
+/////////////////////////////////////////////////////
+// ilk değer atama ve Operatörün fazladan yüklenmesi
+/////////////////////////////////////////////////////
+
+// C++ dilinde +, -, *, /, gibi operatörlerin davranışını fazladan yükleyebilirsiniz.
+// Bu, operator her kullandınıldığında çağrılan bir fonksiyon tanımlamasıyla yapılır.
+
+#include <iostream>
+using namespace std;
+
+class Point {
+public:
+ // Üye değişkenkenlere default değer atanabilir.
+ double x = 0;
+ double y = 0;
+
+ // Default constructor
+ Point() { };
+
+ Point (double a, double b) :
+ x(a),
+ y(b)
+ { /* İlk değer atama dışında birşey yapma */ }
+
+ // + operatorünün fazladan yükle.
+ Point operator+(const Point& rhs) const;
+
+ // += operatorünü fazladan yükle
+ Point& operator+=(const Point& rhs);
+
+ // - ve -= operatorleri fazladan yüklemek de mantıklı olurdu
+ // ama kısa tutmak için burda değinmedik.
+};
+
+Point Point::operator+(const Point& rhs) const
+{
+ // yeni bir nokta oluştur ve bunu rhs ile topla
+ 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);
+ // Bu Point + operatorünü çağırır
+ Point result = up + right;
+ // "Result is upright (1,1)" yazdırır.
+ cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
+ return 0;
+}
+
+////////////////////////
+// Şablonlar (Templates)
+////////////////////////
+
+// Şablonlar C++ dilinde tipten bağımsız programlama için kullanılır.
+
+// Zaten aşina olduğun tipten bağımsız programlamayla başladık. Bir tip parametresi
+alan fonksiyon veya sınıf tanımlamaık için:
+template<class T>
+class Box {
+public:
+ // Bu sınıfta T, herhangi bir tip için kullanılabilir.
+ void insert(const T&) { ... }
+};
+
+// Derleme esnasında derleyici aslında, parametreleri yerine konmuş şekilde herbir şablonu üretir,
+// bu yüzden sınıfın tam tanımı her çağrılma sırasında var olmak zorundadır. Bu nedenle şablon sınıflarını
+// tamamen header dosyalarında görürsün.
+
+// Stack'ta şablon sınıfın bir örneğini oluşturmak için:
+Box<int> intBox;
+
+// ve, anladığın gibi, kullanabilirsin:
+intBox.insert(123);
+
+// Tabi, şablonları içiçe geçirebilirsin:
+Box<Box<int> > boxOfBox;
+boxOfBox.insert(intBox);
+
+// C++11'den önce iki '>' arasına boşluk koymak zorundaydık yoksa sağa kaydırma
+// operatörü olarak algılanabilirdi.
+
+// Bazen şunu da görebilirsin
+// template<typename T>
+// 'class' ve 'typename' anahtar sözcükleri çoğunlukla
+// birbirlerinin yerine kullanılabilir. Tam açıklama için, bknz.
+// http://en.wikipedia.org/wiki/Typename
+// (evet, bu anahtar sözcüğün kendi Wikipedia sayfası var).
+
+// Benzer şekilde, bir şablon fonksiyon:
+template<class T>
+void barkThreeTimes(const T& input)
+{
+ input.bark();
+ input.bark();
+ input.bark();
+}
+
+// Dikkat edersen tip parametresi hakkında birşey belirtilmedi. Derleyici bunları üretecek
+// ve her parametre geçişinde tip-kontrolü yapacaktır, bu nedenle de fonksiyon herhangi bir T
+// tipi için çalışacaktır!
+
+Dog fluffy;
+fluffy.setName("Fluffy")
+barkThreeTimes(fluffy); // Üç kere "Fluffy barks" yazdırır.
+
+// Şablonun parametresi sınıf olmak zorunda değildir:
+template<int Y>
+void printMessage() {
+ cout << "Learn C++ in " << Y << " minutes!" << endl;
+}
+
+// Ve template'i daha etkili kod için dışarıdan özelleştirebilirsin.
+// Tabiki gerçek-dünya kullanımlarında özelleştirme bunun kadar kolay değildir.
+// Dikkat edersen, bütün parametreleri dıştan özelleştirmiş olsak bile
+// hala fonksiyonu (veya sınıfı( template olarak tanımlamamız gerekli.
+template<>
+void printMessage<10>() {
+ cout << "Learn C++ faster in only 10 minutes!" << endl;
+}
+
+printMessage<20>(); // "Learn C++ in 20 minutes!" yazdırır
+printMessage<10>(); // "Learn C++ faster in only 10 minutes!" yazdırır
+
+
+///////////////////////////////////////////////
+// İstisnai Durum Yönetimi (Exception Handling)
+///////////////////////////////////////////////
+
+// Standard kütüphane bazı istisnai tipler sağlar
+// (bknz http://en.cppreference.com/w/cpp/error/exception)
+// ama herhangi bir tip de istisnai durum fırlatabilir
+
+#include <exception>
+#include <stdexcept>
+
+// _try_ bloğu içinde fırlatılan bütün istisnai durumlar, takip eden, _catch_ ile
+// yakalanabilir.
+try {
+ // _new_ kullanarak heap'ten istisnai durumlar için yer ayırma
+ throw std::runtime_error("A problem occurred");
+}
+
+// istisnai durumlar nesne ise const reference ile yakala
+catch (const std::exception& ex)
+{
+ std::cout << ex.what();
+}
+
+// Bir önceki _catch_ bloğundan kaçan istisnai durum burda yakala
+catch (...)
+{
+ std::cout << "Unknown exception caught";
+ throw; // Tekrardan istisnai durum fırlatır
+}
+
+///////
+// RAII
+///////
+
+// RAII, "Resource Acquisition Is Initialization" kelimelerinin kısaltmasıdır.
+// Bu Türkçe, "Kaynak alımı aynı zamanda ilk değer atamasıdır." olarak çevrilebilir.
+// Bunu basitçe constructor ile ayrılan hafızanın destructor ile iade edilmesi olarak
+// düşünebiliriz.
+
+// Bunun ne şekilde kullanışlı olduğunu görmek için
+// bir C dosyasının, dosya işleme biçimine bakabiliriz:
+void doSomethingWithAFile(const char* filename)
+{
+ // Başlangıçta herşeyin yolunda gittiğini düşünelim
+
+ FILE* fh = fopen(filename, "r"); // Dosyayı okuma modunda aç
+
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+ fclose(fh); // Dosyayı kapat
+}
+
+// Malesef hatalarla başa çıkmaya çalışırken işler hızlıca karmaşıklaşır.
+// Mesela fopen'ın başarısız olduğunu varsayalım, ve doSoomethingWithTheFile ve
+// doSomethingWithIt hata kodları gönderdi.
+// (İstisnai durumlar yonetimi, hata koduna tercih ediler bir yöntemdir, ama bazı
+// programcılar, özellikle C arkaplanı olanlar, aynı fikirde değildir.
+// Bu durumda her bir fonksiyon çağrısını kontrol etmeli ve bir problem oluştuysa
+// dosyayı kapatmalıyız.
+
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r"); // Dosyayı okuma modunda aç
+ if (fh == nullptr) // Başarısız olma durumunda dönen değer null olur
+ return false; // Başarısız olma durumunu çağırıcıya bildir
+
+ // Başarısız olma durumunda her iki fonksiyonun da false döndürdüğünü kabul edelim
+ if (!doSomethingWithTheFile(fh)) {
+ fclose(fh); // Dosyayı kapatalım, akıntı olmasın.
+ return false; // Hatayı bildir
+ }
+ if (!doSomethingElseWithIt(fh)) {
+ fclose(fh); // Dosyayı kapatalım, akıntı olmasın.
+ return false; // Hatayı bildir
+ }
+
+ fclose(fh); // Dosyayı kapat
+ return true; // Başarı durumunu ifade eder
+}
+
+// C programcıları biraz goto kullanarak bu durumu temizler
+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); // Dosyayı kapat
+ return true; // Başarı durumunu ifade eder
+
+failure:
+ fclose(fh);
+ return false; // Hatayı bildir
+}
+
+// Eğer fonksiyon istisnai durum yönetimi araçlarını kullanırsa
+// işler daha temiz olur ama hala en iyi durumun altında kalır.
+void doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r");
+ if (fh == nullptr)
+ throw std::runtime_error("Could not open the file.");
+
+ try {
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+ }
+ catch (...) {
+ fclose(fh); // Hata durumunda dosyayı kapattığından emin ol
+ throw; // Sonra, tekrardan istisnai durum fırlat
+ }
+
+ fclose(fh); // Dosyayı kapat
+ // Herşey başarılı
+}
+
+// Şimdi aynı şeyi C++'ın dosya stream sınıfıyla (fstream) karşılaştıralım
+// fstream, dosyayı kapatmak için kendi destructor'ını kullanır.
+// Destructor'ın, nesne scope dışına çıktığında otomatik olarak çağrıldığını
+// hatırlayın.
+void doSomethingWithAFile(const std::string& filename)
+{
+ std::ifstream fh(filename); // Dosyayı aç
+
+ // Dosyayla birşeyler yap
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+} // Dosya, destructor tarafından otomatik olarak kapatıldı
+
+// Bunun _çok büyük_ avantajları var:
+// 1. Ne olursa olursun,
+// kaynak (bu örnekte dosya tutucusu) temizlenecektir.
+// Destructor doğru yazıldığında,
+// Tutucuyu kapatmayı unutma ve kaynak akıntısı _imkansız_dır.
+// 2. Kodun çok daha temiz olduğuna dikkat edin.
+// Destructor, dosyayı kapatma işini, endilenmemize gerek kalmadan
+// arka planda halleder.
+// 3. Kod, istisnai durumlara karşı korunaklıdır.
+// İstisnai durum fonksiyonun herhangi bir yerinde fırlatılabilir ve
+// temizleme işi gene de yapılır.
+
+// Bütün C++ kodu deyimleri RAII prensibini tüm kaynakları için kullanır.
+// Ek örnekler şunlardır:
+// - unique_ptr ve shared_ptr ile hafıza kullanımı
+// - Tutucular - standard kütüphane linked list,
+// vector (yani kendiliğinden boyu ayarlanan dizi), hash map vs.
+// scope'un dışına çıktığında içerini otomatik olarak yok eden tüm yapılar.
+// - lock_guard ve unique_lock kullanan mutex'ler
+
+///////////////////////////////////////
+// Lambda İfadeleri (C++11 ve yukarısı)
+///////////////////////////////////////
+
+// lambda'lar, tam olarak çağrıldığı yerde bir anonim fonksiyon tanımlamak
+// veya fonksiyona argüman geçmek için uygun bir yoldur.
+
+// Mesela, pair'lardan oluşan bir vector'u, pair'ın ikinci değerine
+// göre sıralamak isteyelim
+
+vector<pair<int, int> > tester;
+tester.push_back(make_pair(3, 6));
+tester.push_back(make_pair(1, 9));
+tester.push_back(make_pair(5, 0));
+
+// sort fonksiyonuna üçüncü argüman olarak lambda ifadesini geç
+// sort, <algorithm> başlığında tanımlı
+
+sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs) {
+ return lhs.second < rhs.second;
+ });
+
+// Lambda ifadesinin söz dizimine dikkat edin,
+// lambda'daki [], değişkenleri "tutmak" için kullanılır
+// "Tutma listesi", fonksiyon gövdesinde nelerin, ne şekilde erişilebilir olduğunu tanımlar
+// Şunlardan biri olabilir:
+// 1. bir değer : [x]
+ 2. bir referans : [&x]
+ 3. mevcut scope içindeki herhangi bir değişkene referans ile [&]
+ 4. 3 ile aynı, ama değer ile [=]
+// Mesela:
+vector<int> dog_ids;
+// number_of_dogs = 3;
+for(int i = 0; i < 3; i++) {
+ dog_ids.push_back(i);
+}
+
+int weight[3] = {30, 50, 10};
+
+// Mesela dog_ids vector'unu dog'ların ağırlıklarına göre sıralamak isteyelim
+// Yani en sonunda şöyle olmalı: [2, 0, 1]
+
+// Burada lambda ifadesi oldukça kullanışlıdır
+
+sort(dog_ids.begin(), dog_ids.end(), [&weight](const int &lhs, const int &rhs) {
+ return weight[lhs] < weight[rhs];
+ });
+// Dikkat edersen "weight" dizisini referans ile aldık.
+// C++'da lambdalar hakkında daha fazla bilgi için : http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11
+
+//////////////////////////////////
+// Akıllı For (C++11 ve yukarısı)
+//////////////////////////////////
+
+// Akıllı for döngüsünü bir tutucuyu dolaşmak için kullanabilirsin
+int arr[] = {1, 10, 3};
+
+for(int elem: arr){
+ cout << elem << endl;
+}
+
+// Tutucunun elemanlarının tipi için endişe etmeden "auto" kullanabilirsin
+// Mesela:
+
+for(auto elem: arr) {
+ // arr dizisinin elemanlarıyla ilgili bir şeyler yap
+}
+
+/////////////////////
+// Güzel Şeyler
+/////////////////////
+
+// C++ dilinin bakış açısı yeni başlayanlar için (hatta dili iyi bilenler için bile)
+// şaşırtıcı olabilir.
+// Bu bölüm, ne yazık ki, büyük ölçüde tam değil; C++ kendi ayağına ateş edilebilecek kolay
+// dillerden biridir.
+
+// private metodları override edebilirsin!
+class Foo {
+ virtual void bar();
+};
+class FooSub : public Foo {
+ virtual void bar(); // Foo::bar fonksiyonu override edilir!
+};
+
+
+// 0 == false == NULL (çoğu zaman)!
+bool* pt = new bool;
+*pt = 0; // 'pt'nin gösterdiği değere false atar.
+pt = 0; // 'pt'ye null pointer atar. Her iki satır uyarısız derlenir.
+
+// nullptr'ın bu meselenin bazılarını çözmesi beklenmiştir:
+int* pt2 = new int;
+*pt2 = nullptr; // Derlenmez.
+pt2 = nullptr; // pt2'ye null atar.
+
+// bool tipleri için bir istisna vardır.
+// Bu null pointer'ları if(!ptr) ile test etmek içindir.
+// ama sonuç olarak bir bool değerine nullptr atayabilirsin!
+*pt = nullptr; // '*pt' değeri bir boll olmasına rağmen, hala derlenir!
+
+
+// '=' != '=' != '='!
+// Calls Foo::Foo(const Foo&) or some variant (see move semantics) copy
+// Foo::Foo(const Foo&) çağrısını veya kopyalama constructor'ının bir çeşidinin çağrısınıyapar(taşıma semantiklerine bknz.)
+Foo f2;
+Foo f1 = f2;
+
+// Foo::operator=(Foo&) çağrısını yapar.
+Foo f1;
+f1 = f2;
+
+
+///////////////////////////////////////
+// Tuple (C++11 ve yukarısı)
+///////////////////////////////////////
+
+#include<tuple>
+
+// Ana fikir olarak, Tuple, eski veri yapılarına (C'deki struct'lar) benzer ama isimli veri üyeleri yerine
+// elemanlarına tuple içindeki sırasına göre erişilir.
+
+// Tuple'ı inşa ederek başlayalım
+// değişkenleri tuple içinde paketliyoruz
+auto first = make_tuple(10, 'A');
+const int maxN = 1e9;
+const int maxL = 15;
+auto second = make_tuple(maxN, maxL);
+
+// 'first' tuple'ının değerlerini yazdırma
+cout << get<0>(first) << " " << get<1>(first) << "\n"; // 10 A yazdırır
+
+// 'second' tuple'ının değerlerini yazdırma
+cout << get<0>(second) << " " << get<1>(second) << "\n"; // 1000000000 15 yazdırır
+
+// Değişkenleri tuple'dan çıkarma
+
+int first_int;
+char first_char;
+tie(first_int, first_char) = first;
+cout << first_int << " " << first_char << "\n"; // 10 A yazdırır
+
+// Ayrıca şu şekide de tuple oluşturabiliriz.
+
+tuple<int, char, double> third(11, 'A', 3.14141);
+// tuple_size, tuple'daki eleman sayısını (constexpr olarak) döndürür
+
+cout << tuple_size<decltype(third)>::value << "\n"; // 3 yazdırır
+
+// tuple_cat, tuple'daki tüm elemanları aynı sırada birleştirir.
+
+auto concatenated_tuple = tuple_cat(first, second, third);
+// concatenated_tuple = (10, 'A', 1e9, 15, 11, 'A', 3.14141) olur
+
+cout << get<0>(concatenated_tuple) << "\n"; // 10 yazdırır
+cout << get<3>(concatenated_tuple) << "\n"; // 15 yazdırır
+cout << get<5>(concatenated_tuple) << "\n"; // 'A' yazdırır
+
+
+/////////////////////
+// Tutucular
+/////////////////////
+
+// Tutucular veya Standard Şablon Kütüphanesi(STL) önceden tanımlanmış şablonlar sunar.
+// Bunlar elemanları için ayrılan hafıza alanını yönetir
+// ve onlara erişim ve değiştirmek için üye fonksiyonlar sağlar
+
+// Bazı tutucular şunlardır:
+
+// Vector (Dinamik Dizi)
+// koşma anında nesne dizisi veya list oluşturmamızı sağlar
+#include <vector>
+string val;
+vector<string> my_vector; // vector'ü tanımla
+cin >> val;
+my_vector.push_back(val); // val değerini my_vector vectörüne push edecektir
+my_vector.push_back(val); // val değerini yeniden push edecektir (şu an iki elemanı var)
+
+// vector içinde dolaşmak için iki seçenek var:
+// ya klasik döngüyle (0. index'ten son index'e kadar iterasyon yaparak)
+for (int i = 0; i < my_vector.size(); i++) {
+ cout << my_vector[i] << endl; // vector'ün elemanlarına uşamak için [] operatörünü kullanabiliriz
+}
+
+// ya da iteratör kulllanarak:
+vector<string>::iterator it; // vector için iterator tanımla
+for (it = my_vector.begin(); it != my_vector.end(); ++it) {
+ cout << *it << endl;
+}
+
+// Set(Küme)
+// Set'ler benzersiz(unique) elemanları belirli bir sırada saklayan tutuculardır.
+// Set, benzersiz değerleri, herhangi bir fonksiyon veya kod gerektirmeksizin, sıralı olarak
+
+#include<set>
+set<int> ST; // int tipi için set tanımlar
+ST.insert(30); // ST kümesini 30 değerini dahil eder
+ST.insert(10); // ST kümesini 10 değerini dahil eder
+ST.insert(20); // ST kümesini 20 değerini dahil eder
+ST.insert(30); // ST kümesini 30 değerini dahil eder
+// Şimdi kümedeki elemanlar aşağıdaki gibidir
+// 10 20 30
+
+// Bir eleman silmek için:
+ST.erase(20); // 20 değerine sahip elemanı siler
+// Set ST: 10 30
+// Iterator kullanarak Set içinde iterasyon yapmak için:
+set<int>::iterator it;
+for(it=ST.begin();it<ST.end();it++) {
+ cout << *it << endl;
+}
+// Output:
+// 10
+// 30
+
+// Tutucuyu tamamen silmek için Tutucu_Adi.clear() kullanırız
+ST.clear();
+cout << ST.size(); // ST kümesinin eleman sayısı(size)nı yazdırır.
+// Output: 0
+
+// NOTE: Aynı elemanlari içerebilen kümle için multiset kullanırız
+
+// Map(Harita)
+// Map, elemanları anahtar değer, haritalanmış değer şeklinde özel bir sırada saklar.
+// anahtar_değer -> haritalanmış_değer
+
+#include<map>
+map<char, int> mymap; // Anahtar char ve değer int olacak şekilde map tanımlar
+
+mymap.insert(pair<char,int>('A',1));
+// 1 değeri için A anahtar değerini ekler
+mymap.insert(pair<char,int>('Z',26));
+// 26 değeri için Z anahtar değerini ekler
+
+// Map'te dolaşma
+map<char,int>::iterator it;
+for (it=mymap.begin(); it!=mymap.end(); ++it)
+ std::cout << it->first << "->" << it->second << '\n';
+// Output:
+// A->1
+// Z->26
+
+// Anahtar'a atanmış değeri bulmak için
+it = mymap.find('Z');
+cout << it->second;
+
+// Output: 26
+
+
+/////////////////////////////////////////////
+// Mantıksal ve Bit seviyesindeki operatörler
+/////////////////////////////////////////////
+
+// Pek çok C++ operatörleri diğer dillerdekiyle aynıdır
+
+// Mantıksal operatörler
+
+// C++, bool ifadelerinde Kısa-devre değerlendirmesini kullanır yani ikinci argüman yalnızca ilk argüman
+// ifadenin değerine karar vermek için yeterli değilse çalıştırılır
+
+true && false // **mantıksal ve** işlemi yapılır ve yanlış sonucu üretilir
+true || false // **mantıksal veya** işlemi yapılır ve true sonucu üretilir
+! true // **mantıksal değil** işlemi yapılır ve yalnış sonucu üretilir
+
+// Sembolleri kullanmak yerine onlara karşılık gelen anahtar kelimeler kullanılabilir
+true and false // **mantıksal ve** işlemi yapılır ve yanlış sonucu üretilir
+true or false // **mantıksal veya** işlemi yapılır ve true sonucu üretilir
+not true // **mantıksal değil** işlemi yapılır ve yalnış sonucu üretilir
+
+// Bit seviyesindeki operatörler
+
+// **<<** Sola kaydırma operatörü
+// << bitleri sola kaydırır
+4 << 1 // 4'ün bitlerini 1 sola kaydırır ve 8 sonucunu verir
+// x << n, x * 2^n olarak düşünülebilir
+
+
+// **>>** Sağa kaydırma operatörü
+// >> bitleri sağa kaydırır
+4 >> 1 // 4'ün bitlerini 1 sağa kaydırır ve 2 sonucunu verir
+// x >> n, x / 2^n olarak düşünülebilir
+
+~4 // Bit seviyesinde değil işlemini gerçekleştirir
+4 | 3 // Bit seviyesinde veya işlemini gerçekleştirir
+4 & 3 // Bit seviyesinde ve işlemini gerçekleştirir
+4 ^ 3 // Bit seviyesinde xor işlemini gerçekleştirir
+
+// Eşdeğer anahtar kelimeler
+compl 4 // Bit seviyesinde değil işlemini gerçekleştirir
+4 bitor 3 // Bit seviyesinde veya işlemini gerçekleştiri
+4 bitand 3 // Bit seviyesinde ve işlemini gerçekleştirir
+4 xor 3 // Bit seviyesinde xor işlemini gerçekleştirir
+
+
+```
+İleri okuma:
+
+Güncel bir referans
+<http://cppreference.com/w/cpp> adresinde bulunabilir
+
+Ek kaynaklar <http://cplusplus.com> adresinde bulunabilir
diff --git a/tr-tr/git-tr.html.markdown b/tr-tr/git-tr.html.markdown
new file mode 100644
index 00000000..533bb21a
--- /dev/null
+++ b/tr-tr/git-tr.html.markdown
@@ -0,0 +1,595 @@
+---
+category: tool
+tool: git
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Leo Rudberg" , "http://github.com/LOZORD"]
+ - ["Betsy Lorton" , "http://github.com/schbetsy"]
+ - ["Bruno Volcov", "http://github.com/volcov"]
+ - ["Andrew Taylor", "http://github.com/andrewjt71"]
+ - ["Jason Stathopulos", "http://github.com/SpiritBreaker226"]
+ - ["Milo Gilad", "http://github.com/Myl0g"]
+ - ["Adem Budak", "https://github.com/p1v0t"]
+
+filename: LearnGit.txt
+---
+
+Git dağınık versiyon kontrol ve kaynak kod yönetim sistemidir.
+
+Bunu projenin bir seri anlık durumunu kaydederek yapar ve bu anlık durumları
+kullanarak versiyon ve kaynak kodu yönetmeni sağlar.
+
+## Versiyonlama Konseptleri
+
+### Versiyon kontrol nedir?
+
+Versiyon kontrol, zaman içerisinde dosya(lar)daki değişikliği kaydeden sistemdir.
+
+### Merkezi Versiyonlama vs. Dağınık Versiyonlama
+
+* Merkezi versiyon kontrolü dosyaların eşitlenmesine, takibine ve yedeklenmesine odaklanır.
+* Dağınık versiyon kontrolü değişimin paylaşılmasına odaklanır. Her değişiminin benzersiz bir adı vardır.
+* Dağınık sistemlerin belirlenmiş bir yapısı yoktur. Git ile kolayca SVN'deki gibi merkezi bir sistem elde edebilirsin.
+
+[Daha fazla bilgi](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
+
+### Neden Git?
+
+* Çevrimdışı çalışabilir
+* Diğerleriyle beraber çalışmak kolaydır!
+* Dallanma kolaydır!
+* Dallanma hızlıdır!
+* Git hızlıdır
+* Git esnektir
+
+## Git Mimarisi
+
+### Repository
+
+Bir grup dosya, dizin, geriye dönük kayıt, commit, head. Bunları kaynak kodun veri
+yapısı gibi düşünebilirsin, herbir kaynak kod "elemanı" seni kendi revizyon geçmişine
+eriştirir.
+
+Bir git repo'su .git dizini ve çalışma ağacından oluşur.
+
+### .git Dizini (repository bileşeni)
+
+.git dizini bütün konfigrasyon, log, dallanma, HEAD ve daha fazlasını tutar.
+[detaylı liste](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
+
+### Çalışma Ağacı (repository bileşeni)
+
+Temelde repo'daki dizinlerin ve dosyalarındır. Sıkça çalışma ağacın olarak anılır.
+
+### Index (.git dizininin birleşeni)
+
+Index git'in evreleme alanıdır (staging area). Temelde çalışma ağacını Git repo'sundan
+ayıran bir katmandır. Bu geliştiricilere neyin Git repo'suna gönderileceği hakkında daha
+fazla güç verir.
+
+### Commit
+
+Bir git commit'i Çalışma Ağacındaki bir takım değişiklerdir. Mesela 5 tane dosya
+eklemişsindir ve diğer 2 tanesini silmişindir, bu değişikler commit'te (anlık kayıtta)
+tutulacaktır. Bu commit daha sonra diğer repo'lara bastırılabilir (pushed) ve bastırılmaz!
+
+### Branch
+
+Bir branch esasen yaptığın son commit'e göstericidir(pointer). Commit'lemeye devam ettiğinde,
+bu gösterici otomatik olarak son commit'e güncellenir.
+
+### Tag
+
+Bir tag, tarihteki belirli bir noktanın işaretidir. İnsanlar bunu genelde
+sürüm notları için kullanır (v1.0 vs.)
+
+### HEAD ve head (.git dizininin birleşenleri)
+
+HEAD mevcut branch'a bir göstericidir. Bir repository yalnızca 1 *aktif*
+HEAD'e sahiptir.
+head, commit'e bir göstericidir. Bir repository herhangi bir sayıda head'e sahip olabilir.
+
+### Git'in Stage'leri
+* Modified - Dosyada değişikler yapıldı ama henüz Git Veritabanına commit yapılmadı.
+* Staged - Modified edilmiş bir dosyayı, sonraki commit'e gitmek üzere işaretler.
+* Committed - Dosyalar Git Veritabanına commit'lendi.
+
+### Kavramsal Kaynaklar
+
+* [Bilgisayar Bilimciler için Git](http://eagain.net/articles/git-for-computer-scientists/)
+* [Tasarımcılar için Git](http://hoth.entp.com/output/git_for_designers.html)
+
+## Komutlar
+
+### init
+
+Boş bir Git repository'si oluştur. Git repository'sinin ayarları, depolanmış
+bilgileri ve daha fazlası ".git" adlı dizinde (bir klasör) tutulur.
+
+```bash
+$ git init
+```
+
+### config
+
+Ayarları yapılandırmak için. Repository, sistemin kendisi veya global yapılandırmalar
+için olarabilir. (global yapılandırma dosyası `~/.gitconfig`).
+
+```bash
+# Print & Set Some Basic Config Variables (Global)
+$ git config --global user.email "MyEmail@Zoho.com"
+$ git config --global user.name "My Name"
+```
+
+[git config hakkında daha fazla bilgi için.](http://git-scm.com/docs/git-config)
+
+### help
+
+Her bir komutun detaylı kılavuzuna hızlı bir erişim için. Ya da sadece bazı şeylerin
+anlamı için hızlı bir hatırlatıcı için.
+
+```bash
+# Quickly check available commands
+$ git help
+
+# Check all available commands
+$ git help -a
+
+# Command specific help - user manual
+# git help <command_here>
+$ git help add
+$ git help commit
+$ git help init
+# or git <command_here> --help
+$ git add --help
+$ git commit --help
+$ git init --help
+```
+
+### dosyaları ignore etme
+
+git'in bazı dosya(ları) ve klasör(leri) kasıtlı olarak takip etmemesi için. Genel
+olarak,repository'de ne de olsa paylaşılacak, private ve temp dosyaları için.
+
+```bash
+$ echo "temp/" >> .gitignore
+$ echo "private_key" >> .gitignore
+```
+
+### status
+
+index dosyası(temelde çalıştığın repo) ve mevcut HEAD commit arasındaki farkı göstermek için.
+
+```bash
+# Will display the branch, untracked files, changes and other differences
+$ git status
+
+# To learn other "tid bits" about git status
+$ git help status
+```
+
+### add
+
+Dosyaları staging area'ya eklemek için. Eğer yeni dosyaları staging area'ya `git add`
+yapmazsanız, commit'lere eklenmez!
+
+```bash
+# add a file in your current working directory
+$ git add HelloWorld.java
+
+# add a file in a nested dir
+$ git add /path/to/file/HelloWorld.c
+
+# Regular Expression support!
+$ git add ./*.java
+
+# You can also add everything in your working directory to the staging area.
+$ git add -A
+```
+Bu yalnızca dosyayı staging area'a/index'e ekler, çalışılan dizine/repo'ya commit etmez.
+
+### branch
+
+Branch'ları yönetir. Bu komutu kullanarak, branch'ları görebilir, düzenleyebilir, oluşturabilir, silebilirsin.
+
+```bash
+# list existing branches & remotes
+$ git branch -a
+
+# create a new branch
+$ git branch myNewBranch
+
+# delete a branch
+$ git branch -d myBranch
+
+# rename a branch
+# git branch -m <oldname> <newname>
+$ git branch -m myBranchName myNewBranchName
+
+# edit a branch's description
+$ git branch myBranchName --edit-description
+```
+
+### tag
+
+tag'leri yönetir
+
+```bash
+# List tags
+$ git tag
+
+# Create a annotated tag
+# The -m specifies a tagging message, which is stored with the tag.
+# If you don’t specify a message for an annotated tag,
+# Git launches your editor so you can type it in.
+$ git tag -a v2.0 -m 'my version 2.0'
+
+# Show info about tag
+# That shows the tagger information, the date the commit was tagged,
+# and the annotation message before showing the commit information.
+$ git show v2.0
+
+# Push a single tag to remote
+$ git push origin v2.0
+
+# Push a lot of tags to remote
+$ git push origin --tags
+```
+
+### checkout
+
+index'in versiyonun eşlemek için çalışma ağacındaki,veya belirtilen ağactaki, tüm dosyaları günceller.
+
+```bash
+# Checkout a repo - defaults to master branch
+$ git checkout
+
+# Checkout a specified branch
+$ git checkout branchName
+
+# Create a new branch & switch to it
+# equivalent to "git branch <name>; git checkout <name>"
+
+$ git checkout -b newBranch
+```
+
+### clone
+
+Varolan bir repository'i yeni bir dizine clone'lar veya kopyalar.
+Ayrıca clone'lanmış repodaki her bir branch için, uzak branch'a bastırmana izin veren,
+uzak takip branch'ları ekler.
+
+```bash
+# Clone learnxinyminutes-docs
+$ git clone https://github.com/adambard/learnxinyminutes-docs.git
+
+# shallow clone - faster cloning that pulls only latest snapshot
+$ git clone --depth 1 https://github.com/adambard/learnxinyminutes-docs.git
+
+# clone only a specific branch
+$ git clone -b master-cn https://github.com/adambard/learnxinyminutes-docs.git --single-branch
+```
+
+### commit
+
+index'in mevcut içeriğini yeni bir "commit"te saklar. Bu commit, kullanıcının oluşturduğu
+bir mesajı ve yapılan değişiklikleri saklar.
+
+```bash
+# commit with a message
+$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
+
+# signed commit with a message (user.signingkey must have been set
+# with your GPG key e.g. git config --global user.signingkey 5173AAD5)
+$ git commit -S -m "signed commit message"
+
+# automatically stage modified or deleted files, except new files, and then commit
+$ git commit -a -m "Modified foo.php and removed bar.php"
+
+# change last commit (this deletes previous commit with a fresh commit)
+$ git commit --amend -m "Correct message"
+```
+
+### diff
+
+Shows differences between a file in the working directory, index and commits.
+Bir dosyanın, çalışma ağacı, index ve commit'ler arasındaki farklarını göster.
+
+```bash
+# Show difference between your working dir and the index
+$ git diff
+
+# Show differences between the index and the most recent commit.
+$ git diff --cached
+
+# Show differences between your working dir and the most recent commit
+$ git diff HEAD
+```
+
+### grep
+
+Bir repository'de hızlıca arama yapmana izin verir.
+
+İsteğe Bağlı Yapılandırmalar:
+
+```bash
+# Thanks to Travis Jeffery for these
+# Set line numbers to be shown in grep search results
+$ git config --global grep.lineNumber true
+
+# Make search results more readable, including grouping
+$ git config --global alias.g "grep --break --heading --line-number"
+```
+
+```bash
+# Search for "variableName" in all java files
+$ git grep 'variableName' -- '*.java'
+
+# Search for a line that contains "arrayListName" and, "add" or "remove"
+$ git grep -e 'arrayListName' --and \( -e add -e remove \)
+```
+
+Daha fazla örnek için
+[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
+
+### log
+
+Repository'deki commitleri gösterir.
+
+```bash
+# Show all commits
+$ git log
+
+# Show only commit message & ref
+$ git log --oneline
+
+# Show merge commits only
+$ git log --merges
+
+# Show all commits represented by an ASCII graph
+$ git log --graph
+```
+
+### merge
+
+Dış commit'lerdeki değişiklikleri mevcut branch'a "merge" et (birleştir).
+
+```bash
+# Merge the specified branch into the current.
+$ git merge branchName
+
+# Always generate a merge commit when merging
+$ git merge --no-ff branchName
+```
+
+### mv
+
+Bir dosyayı yeniden taşı veya yeniden adlandır
+
+```bash
+# Renaming a file
+$ git mv HelloWorld.c HelloNewWorld.c
+
+# Moving a file
+$ git mv HelloWorld.c ./new/path/HelloWorld.c
+
+# Force rename or move
+# "existingFile" already exists in the directory, will be overwritten
+$ git mv -f myFile existingFile
+```
+
+### pull
+
+Bir repository'den çeker ve diğer branch'a merge eder.
+
+```bash
+# Update your local repo, by merging in new changes
+# from the remote "origin" and "master" branch.
+# git pull <remote> <branch>
+$ git pull origin master
+
+# By default, git pull will update your current branch
+# by merging in new changes from its remote-tracking branch
+$ git pull
+
+# Merge in changes from remote branch and rebase
+# branch commits onto your local repo, like: "git fetch <remote> <branch>, git
+# rebase <remote>/<branch>"
+$ git pull origin master --rebase
+```
+
+### push
+
+Bir branch'taki değişikleri, uzak branch'a bastır ve birleştir.
+
+```bash
+# Push and merge changes from a local repo to a
+# remote named "origin" and "master" branch.
+# git push <remote> <branch>
+$ git push origin master
+
+# By default, git push will push and merge changes from
+# the current branch to its remote-tracking branch
+$ git push
+
+# To link up current local branch with a remote branch, add -u flag:
+$ git push -u origin master
+# Now, anytime you want to push from that same local branch, use shortcut:
+$ git push
+```
+
+### stash
+
+Stash'leme çalışma dizinindeki kirli durumu alır ve bitmemiş değişiklikler
+yığınına kaydeder. Bu değişikleri istediğin zaman tekrar uygulayabilirsin.
+
+Mesela git repo'nda bazı işler yaptın ama remote'dan pull yapmak istiyorsun.
+Bazı dosyalarında kirli (commit'lenmemiş) değişiklikler olduğundan `git pull`
+yapamazsın. Onun yerine önce `git stash` ile değişikliklerini yığına kaydet!
+
+(stash, sözlük anlamı: bir şeyi, özel bir yere güvenli biçimde saklamak)
+
+```bash
+$ git stash
+Saved working directory and index state \
+ "WIP on master: 049d078 added the index file"
+ HEAD is now at 049d078 added the index file
+ (To restore them type "git stash apply")
+```
+
+Şimdi pull yapabilirsin!
+
+```bash
+git pull
+```
+`...changes apply...`
+
+Herşeyin tamam olduğunu kontrol et
+
+```bash
+$ git status
+# On branch master
+nothing to commit, working directory clean
+```
+Şu ana kadar neleri stash'lediğini `git stash list` kullanarak görebilirsin.
+Stash'lenen şeyler Son-Giren-İlk-Çıkar şeklinde tutulduğundan en son değişim
+en üste olacaktır.
+
+```bash
+$ git stash list
+stash@{0}: WIP on master: 049d078 added the index file
+stash@{1}: WIP on master: c264051 Revert "added file_size"
+stash@{2}: WIP on master: 21d80a5 added number to log
+```
+Şimdi de kirli değişiklileri yığından çıkarıp uygulayalım.
+
+```bash
+$ git stash pop
+# On branch master
+# Changes not staged for commit:
+# (use "git add <file>..." to update what will be committed)
+#
+# modified: index.html
+# modified: lib/simplegit.rb
+#
+```
+
+`git stash apply` da aynı şeyi yapar
+
+Şimdi kendi işine dönmeye hazırsın!
+
+[Ek Okuma.](http://git-scm.com/book/en/v1/Git-Tools-Stashing)
+
+### rebase (dikkat)
+
+Branch'ta commit'lenen tüm değişimleri al ve onları başka bir branch'ta tekrar oynat
+*Public repo'ya push edilmiş commit'leri rebase etme*
+
+```bash
+# Rebase experimentBranch onto master
+# git rebase <basebranch> <topicbranch>
+$ git rebase master experimentBranch
+```
+
+[Ek Okuma.](http://git-scm.com/book/en/Git-Branching-Rebasing)
+
+### reset (dikkat)
+
+Reset the current HEAD to the specified state. This allows you to undo merges,
+pulls, commits, adds, and more. It's a great command but also dangerous if you
+don't know what you are doing.
+
+HEAD'i belirtilen duruma resetle. Bu merge'leri, pull'ları, commit'leri, add'leri
+ve daha fazlasını geriye almanı sağlar. Muhteşem bir komuttur ama aynı zamanda, ne
+yaptığını bilmiyorsan, tehlikelidir.
+
+```bash
+# Reset the staging area, to match the latest commit (leaves dir unchanged)
+$ git reset
+
+# Reset the staging area, to match the latest commit, and overwrite working dir
+$ git reset --hard
+
+# Moves the current branch tip to the specified commit (leaves dir unchanged)
+# all changes still exist in the directory.
+$ git reset 31f2bb1
+
+# Moves the current branch tip backward to the specified commit
+# and makes the working dir match (deletes uncommitted changes and all commits
+# after the specified commit).
+$ git reset --hard 31f2bb1
+```
+
+### reflog (dikkat)
+
+Reflog, verilen zaman içinde,default olarak 90 gündür, yaptığın git komutlarını listeler.
+
+Bu sana beklemediğin şekilde yanlış giden komutları geriye çevirme şansı verir.
+(mesela, eğer bir rebase uygulamanı kırdıysa)
+
+Şu şekilde yapıbilirsin:
+
+1. `git reflog` rebase için tüm git komutlarını listele
+
+```
+38b323f HEAD@{0}: rebase -i (finish): returning to refs/heads/feature/add_git_reflog
+38b323f HEAD@{1}: rebase -i (pick): Clarify inc/dec operators
+4fff859 HEAD@{2}: rebase -i (pick): Update java.html.markdown
+34ed963 HEAD@{3}: rebase -i (pick): [yaml/en] Add more resources (#1666)
+ed8ddf2 HEAD@{4}: rebase -i (pick): pythonstatcomp spanish translation (#1748)
+2e6c386 HEAD@{5}: rebase -i (start): checkout 02fb96d
+```
+2. Nereye reset'leyeceğini seç, şu durumda `2e6c386` veya `HEAD@{5}`
+3. 'git reset --hard HEAD@{5}' bu repo'nu seçilen head'e eşitler
+4. Rebase'e yeniden başlayabilir veya onu yalnız bırakabilirsin.
+
+[Ek Okuma.](https://git-scm.com/docs/git-reflog)
+
+### revert
+
+Revert commit'leri geri almada kullanılır. Projenin durumunu önceki bir noktaya
+alan reset ile karıştırılmamalıdır. Revert, belirtilen commit'in tersine yeni bir
+commit ekleyecektir.
+
+```bash
+# Revert a specified commit
+$ git revert <commit>
+```
+
+### rm
+
+git add'in tersine, git rm çalışma ağacından dosyaları kaldırır.
+
+```bash
+# remove HelloWorld.c
+$ git rm HelloWorld.c
+
+# Remove a file from a nested dir
+$ git rm /pather/to/the/file/HelloWorld.c
+```
+
+## Daha Fazla Bilgi
+
+* [tryGit - Git'i öğrenmek için eğlenceli interaktif bir yol](http://try.github.io/levels/1/challenges/1)
+
+* [Git Dallanmayı Öğren - Git'i web üzerinde öğrenmek için en görsel ve interaktif yol](http://learngitbranching.js.org/)
+
+* [Udemy Git Tutorial: Kapsayıcı bir kılavuz](https://blog.udemy.com/git-tutorial-a-comprehensive-guide/)
+
+* [Git Immersion - Git'in temelinden başlayan bir tur](http://gitimmersion.com/)
+
+* [git-scm - Video Tutorial](http://git-scm.com/videos)
+
+* [git-scm - Dökümantasyon](http://git-scm.com/docs)
+
+* [Atlassian Git - Tutorial & Workflow](https://www.atlassian.com/git/)
+
+* [SalesForce Kopya Kağıdı](http://res.cloudinary.com/hy4kyit2a/image/upload/SF_git_cheatsheet.pdf)
+
+* [GitGuys](http://www.gitguys.com/)
+
+* [Git - Basit bir kılavuz](http://rogerdudler.github.io/git-guide/index.html)
+
+* [Pro Git](http://www.git-scm.com/book/en/v2)
+
+* [Yeni başlayanlar için Git ve Github](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners)
diff --git a/zh-cn/python3-cn.html.markdown b/zh-cn/python3-cn.html.markdown
index 76455a46..211ce0c5 100644
--- a/zh-cn/python3-cn.html.markdown
+++ b/zh-cn/python3-cn.html.markdown
@@ -568,13 +568,14 @@ def double_numbers(iterable):
yield i + i
# 生成器只有在需要时才计算下一个值。它们每一次循环只生成一个值,而不是把所有的
-# 值全部算好。这意味着double_numbers不会生成大于15的数字。
+# 值全部算好。
#
# range的返回值也是一个生成器,不然一个1到900000000的列表会花很多时间和内存。
#
# 如果你想用一个Python的关键字当作变量名,可以加一个下划线来区分。
range_ = range(1, 900000000)
# 当找到一个 >=30 的结果就会停
+# 这意味着 `double_numbers` 不会生成大于30的数。
for i in double_numbers(range_):
print(i)
if i >= 30: