diff options
author | Levi Bostian <levi.bostian@banno.com> | 2013-11-25 09:42:37 -0600 |
---|---|---|
committer | Levi Bostian <levi.bostian@banno.com> | 2013-11-25 09:42:37 -0600 |
commit | af6701904b459b16cf65709cd8c70fd2f5519457 (patch) | |
tree | 68cb4bf9ead32686f492e68528e9f0761e41c500 /es-es | |
parent | df3cc00f5233dac96c0e063d87d3552f493e25f6 (diff) | |
parent | d24c824d388669181eed99c3e94bb25c2914304a (diff) |
Fix conflict bash.
Diffstat (limited to 'es-es')
-rw-r--r-- | es-es/clojure-es.html.markdown | 393 | ||||
-rw-r--r-- | es-es/coffeescript-es.html.markdown | 4 | ||||
-rw-r--r-- | es-es/csharp-es.html.markdown | 632 | ||||
-rw-r--r-- | es-es/go-es.html.markdown | 301 | ||||
-rw-r--r-- | es-es/perl-es.html.markdown | 160 |
5 files changed, 1488 insertions, 2 deletions
diff --git a/es-es/clojure-es.html.markdown b/es-es/clojure-es.html.markdown new file mode 100644 index 00000000..150d0bb2 --- /dev/null +++ b/es-es/clojure-es.html.markdown @@ -0,0 +1,393 @@ +--- +language: clojure +filename: learnclojure-es.clj +contributors: + - ["Adam Bard", "http://adambard.com/"] +translators: + - ["Antonio Hernández Blas", "https://twitter.com/nihilipster"] + - ["Guillermo Vayá Pérez", "http://willyfrog.es"] +lang: es-es +--- + +Clojure es un lenguaje de la familia Lisp desarrollado sobre la Máquina Virtual +de Java. Tiene un énfasis mayor en la [programación funcional](https://es.wikipedia.org/wiki/Programación_funcional) pura +que Common Lisp, pero incluyendo la posibilidad de usar [SMT](https://es.wikipedia.org/wiki/Memoria_transacional) para manipular +el estado según se presente. + +Esta combinación le permite gestionar la concurrencia de manera muy sencilla +y a menudo automáticamente. + +(Necesitas la versión de Clojure 1.2 o posterior) + + +```clojure +; Los comentatios comienzan con punto y coma. + +; Clojure se escribe mediante "forms" (patrones), los cuales son +; listas de objectos entre paréntesis, separados por espacios en blanco. + +; El "reader" (lector) de Clojure asume que el primer objeto es una +; función o una macro que se va a llamar, y que el resto son argumentos. + +; El primer form en un archivo debe ser ns, para establecer el namespace (espacio de +; nombres) +(ns learnclojure) + +; Algunos ejemplos básicos: + +; str crea una cadena de caracteres a partir de sus argumentos +(str "Hello" " " "World") ; => "Hello World" + +; Las operaciones matemáticas son sencillas +(+ 1 1) ; => 2 +(- 2 1) ; => 1 +(* 1 2) ; => 2 +(/ 2 1) ; => 2 + +; La igualdad es = +(= 1 1) ; => true +(= 2 1) ; => false + +; También es necesaria la negación para las operaciones lógicas +(not true) ; => false + +; Cuando se anidan Los patrones, estos funcionan de la manera esperada +(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2 + +; Tipos +;;;;;;;;;;;;; + +; Clojure usa los tipos de objetos de Java para booleanos, strings (cadenas de +; caracteres) y números. +; Usa class para saber de qué tipo es. +(class 1); Los enteros son java.lang.Long por defecto +(class 1.); Los numeros en coma flotante son java.lang.Double +(class ""); Los strings van entre comillas dobles, y son +; son java.lang.String +(class false); Los Booleanos son java.lang.Boolean +(class nil); El valor "null" se escribe nil + +; Si quieres crear una lista de datos, precedela con una comilla +; simple para evitar su evaluación +'(+ 1 2) ; => (+ 1 2) +; (que es una abreviatura de (quote (+ 1 2)) ) + +; Puedes evaluar una lista precedida por comilla con eval +(eval '(+ 1 2)) ; => 3 + +; Colecciones & Secuencias +;;;;;;;;;;;;;;;;;;; + +; Las Listas están basadas en las listas enlazadas, mientras que los Vectores en +; arrays. +; ¡Los Vectores y las Listas también son clases de Java! +(class [1 2 3]); => clojure.lang.PersistentVector +(class '(1 2 3)); => clojure.lang.PersistentList + +; Una lista podría ser escrita como (1 2 3), pero debemos ponerle una +; comilla simple delante para evitar que el reader piense que es una función. +; Además, (list 1 2 3) es lo mismo que '(1 2 3) + +; Las "Colecciones" son solo grupos de datos +; Tanto las listas como los vectores son colecciones: +(coll? '(1 2 3)) ; => true +(coll? [1 2 3]) ; => true + +; Las "Secuencias" (seqs) son descripciones abstractas de listas de datos. +; Solo las listas son seqs. +(seq? '(1 2 3)) ; => true +(seq? [1 2 3]) ; => false + +; Una seq solo necesita proporcionar una entrada cuando es accedida. +; Así que, las seqs pueden ser perezosas -- pueden establecer series infinitas: +(range 4) ; => (0 1 2 3) +(range) ; => (0 1 2 3 4 ...) (una serie infinita) +(take 4 (range)) ; (0 1 2 3) + +; Usa cons para agregar un elemento al inicio de una lista o vector +(cons 4 [1 2 3]) ; => (4 1 2 3) +(cons 4 '(1 2 3)) ; => (4 1 2 3) + +; conj agregará un elemento a una colección en la forma más eficiente. +; Para listas, se añade al inicio. Para vectores, al final. +(conj [1 2 3] 4) ; => [1 2 3 4] +(conj '(1 2 3) 4) ; => (4 1 2 3) + +; Usa concat para concatenar listas o vectores +(concat [1 2] '(3 4)) ; => (1 2 3 4) + +; Usa filter y map para actuar sobre colecciones +(map inc [1 2 3]) ; => (2 3 4) +(filter even? [1 2 3]) ; => (2) + +; Usa reduce para combinar sus elementos +(reduce + [1 2 3 4]) +; = (+ (+ (+ 1 2) 3) 4) +; => 10 + +; reduce puede tener un argumento indicando su valor inicial. +(reduce conj [] '(3 2 1)) +; = (conj (conj (conj [] 3) 2) 1) +; => [3 2 1] + +; Funciones +;;;;;;;;;;;;;;;;;;;;; + +; Usa fn para crear nuevas funciones. Una función siempre devuelve +; su última expresión +(fn [] "Hello World") ; => fn + +; (Necesitas rodearlo con paréntesis para invocarla) +((fn [] "Hello World")) ; => "Hello World" + +; Puedes crear una var (variable) mediante def +(def x 1) +x ; => 1 + +; Asigna una función a una var +(def hello-world (fn [] "Hello World")) +(hello-world) ; => "Hello World" + +; Puedes defn como atajo para lo anterior +(defn hello-world [] "Hello World") + +; El [] es el vector de argumentos de la función. +(defn hello [name] + (str "Hello " name)) +(hello "Steve") ; => "Hello Steve" + +; Otra abreviatura para crear funciones es: +(def hello2 #(str "Hello " %1)) +(hello2 "Fanny") ; => "Hello Fanny" + +; Puedes tener funciones multi-variadic: funciones con un numero variable de +; argumentos +(defn hello3 + ([] "Hello World") + ([name] (str "Hello " name))) +(hello3 "Jake") ; => "Hello Jake" +(hello3) ; => "Hello World" + +; Las funciones pueden usar argumentos extras dentro de un seq utilizable en la función +(defn count-args [& args] + (str "You passed " (count args) " args: " args)) +(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)" + +; Y puedes mezclarlos con el resto de argumentos declarados de la función. +(defn hello-count [name & args] + (str "Hello " name ", you passed " (count args) " extra args")) +(hello-count "Finn" 1 2 3) +; => "Hello Finn, you passed 3 extra args" + + +; Mapas +;;;;;;;;;; + +; Mapas de Hash y mapas de arrays comparten una misma interfaz. Los mapas de Hash +; tienen búsquedas más rápidas pero no mantienen el orden de las claves. +(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap +(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap + +; Los mapas de arrays se convertidos en mapas de Hash en la mayoría de +; operaciones si crecen mucho, por lo que no debes preocuparte. + +; Los mapas pueden usar cualquier tipo para sus claves, pero generalmente las +; keywords (palabras clave) son lo habitual. +; Las keywords son parecidas a cadenas de caracteres con algunas ventajas de eficiencia +(class :a) ; => clojure.lang.Keyword + +(def stringmap {"a" 1, "b" 2, "c" 3}) +stringmap ; => {"a" 1, "b" 2, "c" 3} + +(def keymap {:a 1, :b 2, :c 3}) +keymap ; => {:a 1, :c 3, :b 2} + +; Por cierto, las comas son equivalentes a espacios en blanco y no hacen +; nada. + +; Recupera un valor de un mapa tratandolo como una función +(stringmap "a") ; => 1 +(keymap :a) ; => 1 + +; ¡Las keywords pueden ser usadas para recuperar su valor del mapa, también! +(:b keymap) ; => 2 + +; No lo intentes con strings. +;("a" stringmap) +; => Exception: java.lang.String cannot be cast to clojure.lang.IFn + +; Si preguntamos por una clave que no existe nos devuelve nil +(stringmap "d") ; => nil + +; Usa assoc para añadir nuevas claves a los mapas de Hash +(def newkeymap (assoc keymap :d 4)) +newkeymap ; => {:a 1, :b 2, :c 3, :d 4} + +; Pero recuerda, ¡los tipos de Clojure son inmutables! +keymap ; => {:a 1, :b 2, :c 3} + +; Usa dissoc para eliminar llaves +(dissoc keymap :a :b) ; => {:c 3} + +; Conjuntos +;;;;;; + +(class #{1 2 3}) ; => clojure.lang.PersistentHashSet +(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3} + +; Añade un elemento con conj +(conj #{1 2 3} 4) ; => #{1 2 3 4} + +; Elimina elementos con disj +(disj #{1 2 3} 1) ; => #{2 3} + +; Comprueba su existencia usando el conjunto como una función: +(#{1 2 3} 1) ; => 1 +(#{1 2 3} 4) ; => nil + +; Hay más funciones en el namespace clojure.sets + +; Patrones útiles +;;;;;;;;;;;;;;;;; + +; Las construcciones lógicas en clojure son macros, y presentan el mismo aspecto +; que el resto de forms. +(if false "a" "b") ; => "b" +(if false "a") ; => nil + +; Usa let para crear un binding (asociación) temporal +(let [a 1 b 2] + (> a b)) ; => false + +; Agrupa expresiones mediante do +(do + (print "Hello") + "World") ; => "World" (prints "Hello") + +; Las funciones tienen implicita la llamada a do +(defn print-and-say-hello [name] + (print "Saying hello to " name) + (str "Hello " name)) +(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff") + +; Y el let también +(let [name "Urkel"] + (print "Saying hello to " name) + (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel") + +; Módulos +;;;;;;;;;;;;;;; + +; Usa use para obtener todas las funciones del módulo +(use 'clojure.set) + +; Ahora podemos usar más operaciones de conjuntos +(intersection #{1 2 3} #{2 3 4}) ; => #{2 3} +(difference #{1 2 3} #{2 3 4}) ; => #{1} + +; Puedes escoger un subgrupo de funciones a importar, también +(use '[clojure.set :only [intersection]]) + +; Usa require para importar un módulo +(require 'clojure.string) + +; Usa / para llamar a las funciones de un módulo +; Aquí, el módulo es clojure.string y la función es blank? +(clojure.string/blank? "") ; => true + +; Puedes asignarle una abreviatura a un modulo al importarlo +(require '[clojure.string :as str]) +(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst." +; (#"" es una expresión regular) + +; Puedes usar require (y use, pero no lo hagas) desde un espacio de nombre +; usando :require, +; No necesitas preceder con comilla simple tus módulos si lo haces de esta +; forma. +(ns test + (:require + [clojure.string :as str] + [clojure.set :as set])) + +; Java +;;;;;;;;;;;;;;;;; + +; Java tiene una enorme librería estándar, por lo que resulta util +; aprender como interactuar con ella. + +; Usa import para cargar un módulo de java +(import java.util.Date) + +; Puedes importar desde un ns también. +(ns test + (:import java.util.Date + java.util.Calendar)) + +; Usa el nombre de la clase con un "." al final para crear una nueva instancia +(Date.) ; <un objeto Date> + +; Usa "." para llamar a métodos o usa el atajo ".método" +(. (Date.) getTime) ; <un timestamp> +(.getTime (Date.)) ; exactamente la misma cosa + +; Usa / para llamar métodos estáticos. +(System/currentTimeMillis) ; <un timestamp> (System siempre está presente) + +; Usa doto para hacer frente al uso de clases (mutables) más tolerable +(import java.util.Calendar) +(doto (Calendar/getInstance) + (.set 2000 1 1 0 0 0) + .getTime) ; => A Date. set to 2000-01-01 00:00:00 + +; STM +;;;;;;;;;;;;;;;;; + +; Software Transactional Memory es un mecanismo que usa clojure para gestionar +; el estado persistente. Hay unas cuantas construcciones en clojure que +; hacen uso de este mecanismo. + +; Un atom es el más sencillo. Se le da un valor inicial +(def my-atom (atom {})) + +; Actualiza un atom con swap! +; swap! toma una función y la llama con el valor actual del atom +; como su primer argumento, y cualquier argumento restante como el segundo +(swap! my-atom assoc :a 1) ; Establece my-atom al resultado de (assoc {} :a 1) +(swap! my-atom assoc :b 2) ; Establece my-atom al resultado de (assoc {:a 1} :b 2) + +; Usa '@' para no referenciar al atom sino para obtener su valor +my-atom ;=> Atom<#...> (Regresa el objeto Atom) +@my-atom ; => {:a 1 :b 2} + +; Un sencillo contador usando un atom sería +(def counter (atom 0)) +(defn inc-counter [] + (swap! counter inc)) + +(inc-counter) +(inc-counter) +(inc-counter) +(inc-counter) +(inc-counter) + +@counter ; => 5 + +; Otros forms que utilizan STM son refs y agents. +; Refs: http://clojure.org/refs +; Agents: http://clojure.org/agents +### Lectura adicional + +Ésto queda lejos de ser exhaustivo, pero espero que sea suficiente para que puedas empezar tu camino. + +Clojure.org tiene muchos artículos: +[http://clojure.org/](http://clojure.org/) + +Clojuredocs.org contiene documentación con ejemplos para la mayoría de +funciones principales (pertenecientes al core): +[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) + +4Clojure es una genial forma de mejorar tus habilidades con clojure/FP: +[http://www.4clojure.com/](http://www.4clojure.com/) + +Clojure-doc.org (sí, de verdad) tiene un buen número de artículos con los que iniciarse en Clojure: +[http://clojure-doc.org/](http://clojure-doc.org/) diff --git a/es-es/coffeescript-es.html.markdown b/es-es/coffeescript-es.html.markdown index 78bb9be5..6bf430e6 100644 --- a/es-es/coffeescript-es.html.markdown +++ b/es-es/coffeescript-es.html.markdown @@ -44,7 +44,7 @@ math = # "cube": function(x) { return x * square(x); } #} -# Símbolos: +# Número de argumentos variable: race = (winner, runners...) -> print winner, runners @@ -52,6 +52,6 @@ race = (winner, runners...) -> alert "I knew it!" if elvis? #=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); } -# Colecciones por comprensión: +# Listas: cubes = (math.cube num for num in list) #=> ... ``` diff --git a/es-es/csharp-es.html.markdown b/es-es/csharp-es.html.markdown new file mode 100644 index 00000000..ef26d8ce --- /dev/null +++ b/es-es/csharp-es.html.markdown @@ -0,0 +1,632 @@ +--- +language: c# +contributors: + - ["Irfan Charania", "https://github.com/irfancharania"] + - ["Max Yankov", "https://github.com/golergka"] +translators: + - ["Olfran Jiménez", "https://twitter.com/neslux"] +filename: LearnCSharp-es.cs +lang: es-es +--- + +C# es un lenguaje orientado a objetos elegante y de tipado seguro que +permite a los desarrolladores construir una variedad de aplicaciones +seguras y robustas que se ejecutan en el Framework .NET. + +[Lee más aquí.](http://msdn.microsoft.com/es-es/library/vstudio/z1zx9t92.aspx) + +```c# +// Los comentarios de una sola línea comienzan con // +/* +Los comentarios de múltiples líneas son de esta manera +*/ +/// <summary> +/// Este es un comentario de documentación XML +/// </summary> + +// Especifica el espacio de nombres que estará usando la aplicación +using System; +using System.Collections.Generic; + + +// Define un ambito para organizar el código en "paquetes" +namespace Learning +{ + // Cada archivo .cs debe contener al menos una clase con el mismo nombre que el archivo + // Se permite colocar cualquier nombre, pero no deberías por cuestiones de consistencia. + public class LearnCSharp + { + // Una aplicación de consola debe tener un método main como punto de entrada + public static void Main(string[] args) + { + // Usa Console.WriteLine para imprimir líneas + Console.WriteLine("Hello World"); + Console.WriteLine( + "Integer: " + 10 + + " Double: " + 3.14 + + " Boolean: " + true); + + // Para imprimir sin una nueva línea, usa Console.Write + Console.Write("Hello "); + Console.Write("World"); + + + /////////////////////////////////////////////////// + // Variables y Tipos + // + // Declara una variable usando <tipo> <nombre> + /////////////////////////////////////////////////// + + // Sbyte - Entero de 8 bits con signo + // (-128 <= sbyte <= 127) + sbyte fooSbyte = 100; + + // Byte - Entero de 8 bits sin signo + // (0 <= byte <= 255) + byte fooByte = 100; + + // Short - Entero de 16 bits con signo + // (-32,768 <= short <= 32,767) + short fooShort = 10000; + + // Ushort - Entero de 16 bits sin signo + // (0 <= ushort <= 65,535) + ushort fooUshort = 10000; + + // Integer - Entero de 32 bits con signo + // (-2,147,483,648 <= int <= 2,147,483,647) + int fooInt = 1; + + // Uinteger - Entero de 32 bits sin signo + // (0 <= uint <= 4,294,967,295) + uint fooUint = 1; + + // Long - Entero de 64 bits con signo + // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) + long fooLong = 100000L; + // L es usado para indicar que esta variable es de tipo long o ulong + // un valor sin este sufijo es tratado como int o uint dependiendo del tamaño. + + // Ulong - Entero de 64 bits sin signo + // (0 <= ulong <= 18,446,744,073,709,551,615) + ulong fooUlong = 100000L; + + // Float - Precisión simple de 32 bits. IEEE 754 Coma flotante + // Precisión: 7 dígitos + float fooFloat = 234.5f; + // f es usado para indicar que el valor de esta variable es de tipo float + // de otra manera sería tratado como si fuera de tipo double. + + // Double - Doble precisión de 32 bits. IEEE 754 Coma flotante + // Precisión: 15-16 dígitos + double fooDouble = 123.4; + + // Bool - true & false (verdadero y falso) + bool fooBoolean = true; + bool barBoolean = false; + + // Char - Un solo caracter Unicode de 16 bits + char fooChar = 'A'; + + // Strings + string fooString = "My string is here!"; + Console.WriteLine(fooString); + + // Formato de cadenas + string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2); + Console.WriteLine(fooFormattedString); + + // Formato de fechas + DateTime fooDate = DateTime.Now; + Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); + + // \n es un caracter de escape que comienza una nueva línea + string barString = "Printing on a new line?\nNo Problem!"; + Console.WriteLine(barString); + + // Puede ser escrito mejor usando el símbolo @ + string bazString = @"Here's some stuff + on a new line!"; + Console.WriteLine(bazString); + + // Las comillas deben ser escapadas + // usa \" para escaparlas + string quotedString = "some \"quoted\" stuff"; + Console.WriteLine(quotedString); + + // usa "" cuando las cadenas comiencen con @ + string quotedString2 = @"some MORE ""quoted"" stuff"; + Console.WriteLine(quotedString2); + + // Usa const o readonly para hacer las variables inmutables + // los valores const son calculados en tiempo de compilación + const int HOURS_I_WORK_PER_WEEK = 9001; + + // Tipos que aceptan valores NULL (Nullable) + // cualquier tipo de dato puede ser un tipo nulo añadiendole el sufijo ? + // <tipo>? <variable> = <valor> + int? nullable = null; + Console.WriteLine("Nullable variable: " + nullable); + + // Para usar valores nulos, tienes que usar la propiedad Value + // o usar conversión explícita + string? nullableString = "not null"; + Console.WriteLine("Nullable value is: " + nullableString.Value + " or: " + (string) nullableString ); + + // ?? is una manera corta de especificar valores por defecto + // en caso de que la variable sea null + int notNullable = nullable ?? 0; + Console.WriteLine("Not nullable variable: " + notNullable); + + // var - el compilador escogerá el tipo de dato más apropiado basado en el valor + var fooImplicit = true; + + /////////////////////////////////////////////////// + // Estructura de datos + /////////////////////////////////////////////////// + Console.WriteLine("\n->Data Structures"); + + // Arreglos + // El tamaño del arreglo debe decidirse al momento de la declaración + // El formato para declarar un arreglo es el siguiente: + // <tipo_de_dato>[] <nombre_variable> = new <tipo_de_dato>[<tamaño>]; + int[] intArray = new int[10]; + string[] stringArray = new string[1]; + bool[] boolArray = new bool[100]; + + // Otra forma de declarar e inicializar un arreglo + int[] y = { 9000, 1000, 1337 }; + + // Indexar arreglos - Acceder a un elemento + Console.WriteLine("intArray @ 0: " + intArray[0]); + + // Los arreglos son de índice cero y son mutables. + intArray[1] = 1; + Console.WriteLine("intArray @ 1: " + intArray[1]); // => 1 + + // Listas + // Las listas son usadas más frecuentemente que los arreglos ya que son más flexibles + // El formato para declarar una lista es el siguiente: + // List<tipo_de_dato> <nombre_variable> = new List<tipo_de_dato>(); + List<int> intList = new List<int>(); + List<string> stringList = new List<string>(); + + // Otra forma de declarar e inicializar una lista + List<int> z = new List<int> { 9000, 1000, 1337 }; + + // Indexar una lista - Acceder a un elemento + // Las listas son de índice cero y son mutables. + Console.WriteLine("z @ 0: " + z[2]); + + // Las listas no tienen valores por defecto; + // Un valor debe ser añadido antes de acceder al índice + intList.Add(1); + Console.WriteLine("intList @ 0: " + intList[0]); + + + // Otras estructuras de datos a chequear: + // + // Pilas/Colas + // Diccionarios + // Colecciones de sólo lectura + // Tuplas (.Net 4+) + + + /////////////////////////////////////// + // Operadores + /////////////////////////////////////// + Console.WriteLine("\n->Operators"); + + int i1 = 1, i2 = 2; // Modo corto para múltiples declaraciones + + // La aritmética es sencilla + Console.WriteLine("1+2 = " + (i1 + i2)); // => 3 + Console.WriteLine("2-1 = " + (i2 - i1)); // => 1 + Console.WriteLine("2*1 = " + (i2 * i1)); // => 2 + Console.WriteLine("1/2 = " + (i1 / i2)); // => 0 (0.5 truncated down) + + // Módulo + Console.WriteLine("11%3 = " + (11 % 3)); // => 2 + + // Operadores de comparación + Console.WriteLine("3 == 2? " + (3 == 2)); // => false + Console.WriteLine("3 != 2? " + (3 != 2)); // => true + Console.WriteLine("3 > 2? " + (3 > 2)); // => true + Console.WriteLine("3 < 2? " + (3 < 2)); // => false + Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true + Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true + + // Operadores a nivel de bits + /* + ~ Complemento a nivel de bits + << Desplazamiento a la izquierda con signo + >> Desplazamiento a la derecha con signo + >>> Desplazamiento a la derecha sin signo + & AND a nivel de bits + ^ XOR a nivel de bits + | OR a nivel de bits + */ + + // Incremento + int i = 0; + Console.WriteLine("\n->Inc/Dec-remento"); + Console.WriteLine(i++); //i = 1. Posincrementación + Console.WriteLine(++i); //i = 2. Preincremento + Console.WriteLine(i--); //i = 1. Posdecremento + Console.WriteLine(--i); //i = 0. Predecremento + + + /////////////////////////////////////// + // Estructuras de control + /////////////////////////////////////// + Console.WriteLine("\n->Control Structures"); + + // Las condiciones if son como en lenguaje c + int j = 10; + if (j == 10) + { + Console.WriteLine("I get printed"); + } + else if (j > 10) + { + Console.WriteLine("I don't"); + } + else + { + Console.WriteLine("I also don't"); + } + + // Operador ternario + // Un simple if/else puede ser escrito de la siguiente manera; + // <condición> ? <true> : <false> + string isTrue = (true) ? "True" : "False"; + Console.WriteLine("Ternary demo: " + isTrue); + + + // Bucle while + int fooWhile = 0; + while (fooWhile < 100) + { + //Console.WriteLine(fooWhile); + //Incrementar el contador + //Iterar 99 veces, fooWhile 0->99 + fooWhile++; + } + Console.WriteLine("fooWhile Value: " + fooWhile); + + // Bucle Do While + int fooDoWhile = 0; + do + { + //Console.WriteLine(fooDoWhile); + //Incrementar el contador + //Iterar 99 veces, fooDoWhile 0->99 + fooDoWhile++; + } while (fooDoWhile < 100); + Console.WriteLine("fooDoWhile Value: " + fooDoWhile); + + // Bucle For + int fooFor; + //Estructura del bucle for => for(<declaración_inicial>; <condición>; <incremento>) + for (fooFor = 0; fooFor < 10; fooFor++) + { + //Console.WriteLine(fooFor); + //Iterated 10 times, fooFor 0->9 + } + Console.WriteLine("fooFor Value: " + fooFor); + + // Switch Case + // El switch funciona con los tipos de datos byte, short, char e int + // También funciona con las enumeraciones (discutidos en in Tipos Enum), + // la clase string y algunas clases especiales que encapsulan + // tipos primitivos: Character, Byte, Short, Integer. + int month = 3; + string monthString; + switch (month) + { + case 1: + monthString = "January"; + break; + case 2: + monthString = "February"; + break; + case 3: + monthString = "March"; + break; + default: + monthString = "Some other month"; + break; + } + Console.WriteLine("Switch Case Result: " + monthString); + + + //////////////////////////////// + // Conversión de tipos de datos + //////////////////////////////// + + // Convertir datos + + // Convertir String a Integer + // esto generará una excepción al fallar la conversión + int.Parse("123");//retorna una versión entera de "123" + + // TryParse establece la variable a un tipo por defecto + // en este caso: 0 + int tryInt; + int.TryParse("123", out tryInt); + + // Convertir Integer a String + // La clase Convert tiene algunos métodos para facilitar las conversiones + Convert.ToString(123); + + /////////////////////////////////////// + // Clases y Funciones + /////////////////////////////////////// + + Console.WriteLine("\n->Classes & Functions"); + + // (Definición de la clase Bicycle (Bicicleta)) + + // Usar new para instanciar una clase + Bicycle trek = new Bicycle(); + + // Llamar a los métodos del objeto + trek.speedUp(3); // Siempre deberías usar métodos setter y métodos getter + trek.setCadence(100); + + // ToString es una convención para mostrar el valor del objeto. + Console.WriteLine("trek info: " + trek.ToString()); + + // Instanciar otra nueva bicicleta + Bicycle octo = new Bicycle(5, 10); + Console.WriteLine("octo info: " + octo.ToString()); + + // Instanciar un Penny Farthing (Biciclo) + PennyFarthing funbike = new PennyFarthing(1, 10); + Console.WriteLine("funbike info: " + funbike.ToString()); + + Console.Read(); + } // Fin del método main + + + } // Fin de la clase LearnCSharp + + // Puedes incluir otras clases en un archivo .cs + + + // Sintaxis para la declaración de clases: + // <public/private/protected> class <nombre_de_clase>{ + // //campos, constructores, funciones todo adentro de la clase. + // //las funciones son llamadas métodos como en java. + // } + + public class Bicycle + { + // Campos/Variables de la clase Bicycle + public int cadence; // Public: Accesible desde cualquier lado + private int _speed; // Private: Sólo es accesible desde dentro de la clase + protected int gear; // Protected: Accesible desde clases y subclases + internal int wheels; // Internal: Accesible en el ensamblado + string name; // Todo es privado por defecto: Sólo es accesible desde dentro de esta clase + + // Enum es un tipo valor que consiste un una serie de constantes con nombres + public enum Brand + { + AIST, + BMC, + Electra, + Gitane + } + // Definimos este tipo dentro de la clase Bicycle, por lo tanto es un tipo anidado + // El código afuera de esta clase debería referenciar este tipo como Bicycle.Brand + + public Brand brand; // Declaramos un tipo enum, podemos declarar un campo de este tipo + + // Los miembros estáticos pertenecen al tipo mismo, no a un objeto en específico. + static public int bicyclesCreated = 0; + // Puedes acceder a ellos sin referenciar ningún objeto: + // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated); + + // Los valores readonly (Sólo lectura) son establecidos en tiempo de ejecución + // sólo pueden ser asignados al momento de la declaración o dentro de un constructor + readonly bool hasCardsInSpokes = false; // privado de sólo lectura + + // Los constructores son una forma de crear clases + // Este es un constructor por defecto + private Bicycle() + { + gear = 1; + cadence = 50; + _speed = 5; + name = "Bontrager"; + brand = Brand.AIST; + bicyclesCreated++; + } + + // Este es un constructor específico (contiene argumentos) + public Bicycle(int startCadence, int startSpeed, int startGear, + string name, bool hasCardsInSpokes, Brand brand) + { + this.gear = startGear; // La palabra reservada "this" señala el objeto actual + this.cadence = startCadence; + this._speed = startSpeed; + this.name = name; // Puede ser útil cuando hay un conflicto de nombres + this.hasCardsInSpokes = hasCardsInSpokes; + this.brand = brand; + } + + // Los constructores pueden ser encadenados + public Bicycle(int startCadence, int startSpeed, Brand brand) : + this(startCadence, startSpeed, 0, "big wheels", true) + { + } + + // Sintaxis para Funciones: + // <public/private/protected> <tipo_retorno> <nombre_funcion>(<args>) + + // Las clases pueden implementar getters y setters para sus campos + // o pueden implementar propiedades + + // Sintaxis para la declaración de métodos: + // <ámbito> <tipo_retorno> <nombre_método>(<argumentos>) + public int GetCadence() + { + return cadence; + } + + // Los métodos void no requieren usar return + public void SetCadence(int newValue) + { + cadence = newValue; + } + + // La palabra reservada virtual indica que este método puede ser sobrescrito + public virtual void SetGear(int newValue) + { + gear = newValue; + } + + // Los parámetros de un método pueden tener valores por defecto. + // En este caso, los métodos pueden ser llamados omitiendo esos parámetros + public void SpeedUp(int increment = 1) + { + _speed += increment; + } + + public void SlowDown(int decrement = 1) + { + _speed -= decrement; + } + + // Propiedades y valores get/set + // Cuando los datos sólo necesitan ser accedidos, considera usar propiedades. + // Las propiedades pueden tener get, set o ambos + private bool _hasTassles; // variable privada + public bool HasTassles // acceso público + { + get { return _hasTassles; } + set { _hasTassles = value; } + } + + // Las propiedades pueden ser auto implementadas + public int FrameSize + { + get; + // Puedes especificar modificadores de acceso tanto para get como para set + // esto significa que sólo dentro de la clase Bicycle se puede modificar Framesize + private set; + } + + //Método para mostrar los valores de atributos de este objeto. + public override string ToString() + { + return "gear: " + gear + + " cadence: " + cadence + + " speed: " + _speed + + " name: " + name + + " cards in spokes: " + (hasCardsInSpokes ? "yes" : "no") + + "\n------------------------------\n" + ; + } + + // Los métodos también pueden ser estáticos. Puede ser útil para métodos de ayuda + public static bool DidWeCreateEnoughBycles() + { + // Dentro de un método esático, + // Sólo podemos hacer referencia a miembros estáticos de clases + return bicyclesCreated > 9000; + } // Si tu clase sólo necesita miembros estáticos, + // considera establecer la clase como static. + + } // fin de la clase Bicycle + + // PennyFarthing es una subclase de Bicycle + class PennyFarthing : Bicycle + { + // (Penny Farthings son las bicicletas con una rueda delantera enorme. + // No tienen engranajes.) + + // llamar al constructor de la clase padre + public PennyFarthing(int startCadence, int startSpeed) : + base(startCadence, startSpeed, 0, "PennyFarthing", true) + { + } + + public override void SetGear(int gear) + { + gear = 0; + } + + public override string ToString() + { + string result = "PennyFarthing bicycle "; + result += base.ToString(); // Llamar a la versión base del método + return reuslt; + } + } + + // Las interfaces sólo contienen las declaraciones + // de los miembros, sin la implementación. + interface IJumpable + { + void Jump(int meters); // todos los miembros de interfaces son implícitamente públicos + } + + interface IBreakable + { + // Las interfaces pueden contener tanto propiedades como métodos, campos y eventos + bool Broken { get; } + } + + // Las clases sólo heredan de alguna otra clase, pero pueden implementar + // cualquier cantidad de interfaces + class MountainBike : Bicycle, IJumpable, IBreakable + { + int damage = 0; + + public void Jump(int meters) + { + damage += meters; + } + + public void Broken + { + get + { + return damage > 100; + } + } + } +} // Fin del espacio de nombres + +``` + +## Temas no cubiertos + + * Flags + * Attributes + * Generics (T), Delegates, Func, Actions, lambda expressions + * Static properties + * Exceptions, Abstraction + * LINQ + * ASP.NET (Web Forms/MVC/WebMatrix) + * Winforms + * Windows Presentation Foundation (WPF) + + + +## Lecturas recomendadas + + * [DotNetPerls](http://www.dotnetperls.com) + * [C# in Depth](http://manning.com/skeet2) + * [Programming C#](http://shop.oreilly.com/product/0636920024064.do) + * [LINQ](http://shop.oreilly.com/product/9780596519254.do) + * [MSDN Library](http://msdn.microsoft.com/es-es/library/618ayhy6.aspx) + * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials) + * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials) + * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials) + * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) + + + +[Convenciones de código de C#](http://msdn.microsoft.com/es-es/library/vstudio/ff926074.aspx) diff --git a/es-es/go-es.html.markdown b/es-es/go-es.html.markdown new file mode 100644 index 00000000..434f6713 --- /dev/null +++ b/es-es/go-es.html.markdown @@ -0,0 +1,301 @@ +--- +name: Go +category: language +language: Go +filename: learngo.go +contributors: + - ["Sonia Keys", "https://github.com/soniakeys"] +translators: + - ["Adrian Espinosa", "http://www.adrianespinosa.com"] +lang: es-es + + +--- + +Go fue creado por la necesidad de hacer el trabajo rápidamente. No es la última +tendencia en informática, pero es la forma nueva y más rápida de resolver problemas reales. + +Tiene conceptos familiares de lenguajes imperativos con tipado estático. +Es rápido compilando y rápido al ejecutar, añade una concurrencia fácil de entender para las CPUs de varios núcleos de hoy en día, y tiene características que ayudan con la programación a gran escala. +Go viene con una librería estándar muy buena y una comunidad entusiasta. + +```go +// Comentario de una sola línea +/* Comentario + multi línea */ + +// La cláusula package aparece al comienzo de cada archivo fuente. +// Main es un nombre especial que declara un ejecutable en vez de una librería. +package main + +// La declaración Import declara los paquetes de librerías referenciados en este archivo. +import ( + "fmt" // Un paquete en la librería estándar de Go + "net/http" // Sí, un servidor web! + "strconv" // Conversiones de cadenas +) + +// Definición de una función. Main es especial. Es el punto de entrada para el ejecutable. +// Te guste o no, Go utiliza llaves. +func main() { + // Println imprime una línea a stdout. + // Cualificalo con el nombre del paquete, fmt. + fmt.Println("Hello world!") + + // Llama a otra función de este paquete. + beyondHello() +} + +// Las funciones llevan parámetros entre paréntesis. +// Si no hay parámetros, los paréntesis siguen siendo obligatorios. +func beyondHello() { + var x int // Declaración de una variable. Las variables se deben declarar antes de + // utilizarlas. + x = 3 // Asignación de variables. + // Declaración "corta" con := para inferir el tipo, declarar y asignar. + y := 4 + sum, prod := learnMultiple(x, y) // función devuelve dos valores + fmt.Println("sum:", sum, "prod:", prod) // simple salida + learnTypes() // < y minutes, learn more! +} + +// Las funciones pueden tener parámetros y (múltiples!) valores de retorno. +func learnMultiple(x, y int) (sum, prod int) { + return x + y, x * y // devolver dos valores +} + +// Algunos tipos incorporados y literales. +func learnTypes() { + // La declaración corta suele darte lo que quieres. + s := "Learn Go!" // tipo cadena + + s2 := ` Un tipo cadena "puro" puede incluir +saltos de línea.` // mismo tipo cadena + + // Literal no ASCII. Los fuentes de Go son UTF-8. + g := 'Σ' // tipo rune, un alias de uint32, alberga un punto unicode. + f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit + c := 3 + 4i // complex128, representado internamente por dos float64 + // Sintaxis Var con inicializadores. + var u uint = 7 // sin signo, pero la implementación depende del tamaño como en int + var pi float32 = 22. / 7 + + // Sintáxis de conversión con una declaración corta. + n := byte('\n') // byte es un alias de uint8 + + // Los Arrays tienen un tamaño fijo a la hora de compilar. + var a4 [4]int // un array de 4 ints, inicializados a 0 + a3 := [...]int{3, 1, 5} // un array de 3 ints, inicializados como se indica + + // Los Slices tienen tamaño dinámico. Los arrays y slices tienen sus ventajas + // y desventajas pero los casos de uso para los slices son más comunes. + s3 := []int{4, 5, 9} // Comparar con a3. No hay puntos suspensivos + s4 := make([]int, 4) // Asigna slices de 4 ints, inicializados a 0 + var d2 [][]float64 // solo declaración, sin asignación + bs := []byte("a slice") // sintaxis de conversión de tipo + + p, q := learnMemory() // declara p, q para ser un tipo puntero a int. + fmt.Println(*p, *q) // * sigue un puntero. Esto imprime dos ints. + + // Los Maps son arrays asociativos dinámicos, como los hash o diccionarios + // de otros lenguajes + m := map[string]int{"three": 3, "four": 4} + m["one"] = 1 + + // Las variables no utilizadas en Go producen error. + // El guión bajo permite "utilizar" una variable, pero descartar su valor. + _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs + // Esto cuenta como utilización de variables. + fmt.Println(s, c, a4, s3, d2, m) + + learnFlowControl() // vuelta al flujo +} + +// Go posee recolector de basura. Tiene puntero pero no aritmética de punteros. +// Puedes cometer un errores con un puntero nil, pero no incrementando un puntero. +func learnMemory() (p, q *int) { + // q y p tienen un tipo puntero a int. + p = new(int) // función incorporada que asigna memoria. + // La asignación de int se inicializa a 0, p ya no es nil. + s := make([]int, 20) // asigna 20 ints a un solo bloque de memoria. + s[3] = 7 // asignar uno de ellos + r := -2 // declarar otra variable local + return &s[3], &r // & toma la dirección de un objeto. +} + +func expensiveComputation() int { + return 1e6 +} + +func learnFlowControl() { + // La declaración If requiere llaves, pero no paréntesis. + if true { + fmt.Println("told ya") + } + // El formato está estandarizado por el comando "go fmt." + if false { + // pout + } else { + // gloat + } + // Utiliza switch preferiblemente para if encadenados. + x := 1 + switch x { + case 0: + case 1: + // los cases no se mezclan, no requieren de "break" + case 2: + // no llega + } + // Como if, for no utiliza paréntesis tampoco. + for x := 0; x < 3; x++ { // ++ es una sentencia + fmt.Println("iteration", x) + } + // x == 1 aqui. + + // For es la única sentencia de bucle en Go, pero tiene formas alternativas. + for { // bucle infinito + break // solo bromeaba! + continue // no llega + } + // Como en for, := en una sentencia if significa declarar y asignar primero, + // luego comprobar y > x. + if y := expensiveComputation(); y > x { + x = y + } + // Los literales de funciones son "closures". + xBig := func() bool { + return x > 100 // referencia a x declarada encima de la sentencia switch. + } + fmt.Println("xBig:", xBig()) // verdadero (la última vez asignamos 1e6 a x) + x /= 1e5 // esto lo hace == 10 + fmt.Println("xBig:", xBig()) // ahora es falso + + // Cuando lo necesites, te encantará. + goto love +love: + + learnInterfaces() // Buen material dentro de poco! +} + +// Define Stringer como un tipo interfaz con un método, String. +type Stringer interface { + String() string +} + +// Define pair como un struct con dos campos int, x e y. +type pair struct { + x, y int +} + +// Define un método del tipo pair. Pair ahora implementa Stringer. +func (p pair) String() string { // p se llama "recibidor" + // Sprintf es otra función pública del paquete fmt. + // La sintaxis con punto referencia campos de p. + return fmt.Sprintf("(%d, %d)", p.x, p.y) +} + +func learnInterfaces() { + // La sintaxis de llaves es un "literal struct". Evalúa a un struct + // inicializado. La sintaxis := declara e inicializa p a este struct. + p := pair{3, 4} + fmt.Println(p.String()) // llamar al método String de p, de tipo pair. + var i Stringer // declarar i como interfaz tipo Stringer. + i = p // válido porque pair implementa Stringer + // Llamar al metodo String de i, de tipo Stringer. Misma salida que arriba + fmt.Println(i.String()) + + // Las funciones en el paquete fmt llaman al método String para preguntar a un objeto + // por una versión imprimible de si mismo + fmt.Println(p) // salida igual que arriba. Println llama al método String. + fmt.Println(i) // salida igual que arriba. + + learnErrorHandling() +} + +func learnErrorHandling() { + // ", ok" forma utilizada para saber si algo funcionó o no. + m := map[int]string{3: "three", 4: "four"} + if x, ok := m[1]; !ok { // ok será falso porque 1 no está en el map. + fmt.Println("no one there") + } else { + fmt.Print(x) // x sería el valor, si estuviera en el map. + } + // Un valor de error comunica más información sobre el problema aparte de "ok". + if _, err := strconv.Atoi("non-int"); err != nil { // _ descarta el valor + // imprime "strconv.ParseInt: parsing "non-int": invalid syntax" + fmt.Println(err) + } + // Revisarmeos las interfaces más tarde. Mientras tanto, + learnConcurrency() +} + +// c es un canal, un objeto de comunicación de concurrencia segura. +func inc(i int, c chan int) { + c <- i + 1 // <- es el operador "enviar" cuando un canal aparece a la izquierda. +} + +// Utilizaremos inc para incrementar algunos números concurrentemente. +func learnConcurrency() { + // Misma función make utilizada antes para crear un slice. Make asigna e + // inicializa slices, maps, y channels. + c := make(chan int) + // Iniciar tres goroutines concurrentes. Los números serán incrementados + // concurrentemente, quizás en paralelo si la máquina es capaz y + // está correctamente configurada. Las tres envían al mismo channel. + go inc(0, c) // go es una sentencia que inicia una nueva goroutine. + go inc(10, c) + go inc(-805, c) + // Leer los tres resultados del channel e imprimirlos. + // No se puede saber en que orden llegarán los resultados! + fmt.Println(<-c, <-c, <-c) // channel a la derecha, <- es el operador "recibir". + + cs := make(chan string) // otro channel, este gestiona cadenas. + cc := make(chan chan string) // un channel de cadenas de channels. + go func() { c <- 84 }() // iniciar una nueva goroutine solo para enviar un valor. + go func() { cs <- "wordy" }() // otra vez, para cs en esta ocasión + // Select tiene una sintáxis parecida a la sentencia switch pero cada caso involucra + // una operacion de channels. Selecciona un caso de forma aleatoria de los casos + // que están listos para comunicarse. + select { + case i := <-c: // el valor recibido puede ser asignado a una variable + fmt.Printf("it's a %T", i) + case <-cs: // o el valor puede ser descartado + fmt.Println("it's a string") + case <-cc: // channel vacío, no está listo para la comunicación. + fmt.Println("didn't happen.") + } + // En este punto un valor fue devuelvto de c o cs. Uno de las dos + // goroutines que se iniciaron se ha completado, la otrá permancerá bloqueada. + + learnWebProgramming() // Go lo hace. Tu también quieres hacerlo. +} + +// Una simple función del paquete http inicia un servidor web. +func learnWebProgramming() { + // El primer parámetro de la direccinón TCP a la que escuchar. + // El segundo parámetro es una interfaz, concretamente http.Handler. + err := http.ListenAndServe(":8080", pair{}) + fmt.Println(err) // no ignorar errores +} + +// Haz pair un http.Handler implementando su único método, ServeHTTP. +func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Servir datos con un método de http.ResponseWriter + w.Write([]byte("You learned Go in Y minutes!")) +} +``` + +## Para leer más + +La raíz de todas las cosas de Go es la [web oficial de Go](http://golang.org/). +Ahí puedes seguir el tutorial, jugar interactivamente y leer mucho. + +La propia definición del lenguaje también está altamente recomendada. Es fácil de leer +e increíblemente corta (como otras definiciones de lenguajes hoy en día) + +En la lista de lectura de estudiantes de Go está el código fuente de la +librería estándar. Muy bien documentada, demuestra lo mejor de Go leíble, comprendible, +estilo Go y formas Go. Pincha en el nombre de una función en la documentación +y te aparecerá el código fuente! + diff --git a/es-es/perl-es.html.markdown b/es-es/perl-es.html.markdown new file mode 100644 index 00000000..4f0c26c1 --- /dev/null +++ b/es-es/perl-es.html.markdown @@ -0,0 +1,160 @@ +--- +name: perl +category: language +language: perl +filename: learnperl-es.pl +contributors: + - ["Korjavin Ivan", "http://github.com/korjavin"] +translators: + - ["Francisco Gomez", "http://github.com/frncscgmz"] +lang: es-es +--- + +Perl 5 es un lenguaje de programación altamente capaz, rico en características con mas de 25 años de desarrollo. + +Perl 5 corre en mas de 100 plataformas desde portales hasta mainframes y es adecuado para realizar prototipos rápidos hasta desarrollar proyectos a gran escala. + +```perl +# Comentarios de una sola linea con un carácter hash. + +#### Tipos de variables en Perl + +# Las variables comienzan con el símbolo $. +# Un nombre de variable valido empieza con una letra o un guión bajo, +# seguido por cualquier numero de letras, números o guiones bajos. + +### Perl tiene tres tipos principales de variables: escalares, arreglos y hashes. + +## Escalares +# Un escalar representa un solo valor: +my $animal = "camello"; +my $respuesta = 42; + +# Los valores escalares pueden ser cadenas de caracteres, números enteros o +# de punto flotante, Perl automáticamente los convertirá como sea requerido. + +## Arreglos +# Un arreglo representa una lista de valores: +my @animales = {"camello","llama","buho"}; +my @numeros = {23,42,69}; +my @mixto = {"camello",42,1.23}; + + + +## Hashes +# Un hash representa un conjunto de pares llave/valor: + +my %color_fruta = {"manzana","rojo","banana","amarillo"}; + +# Puedes usar un espacio en blanco y el operador "=>" para asignarlos mas +# fácilmente. + +my %color_fruta = ( + manzana => "rojo", + banana => "amarillo", + ); +# Los escalares, arreglos y hashes están mas documentados en perldata. (perldoc perldata). + +# Los tipos de datos mas complejos pueden ser construidos utilizando +# referencias, las cuales te permiten construir listas y hashes dentro +# de listas y hashes. + +#### Estructuras condicionales y de ciclos + +# Perl tiene la mayoría de las estructuras condicionales y de ciclos mas comunes. + +if ( $var ) { + ... +} elsif ( $var eq 'bar' ) { + ... +} else { + ... +} + +unless ( condicion ) { + ... + } +# Esto es proporcionado como una version mas fácil de leer que "if (!condición)" + +# La post condición al modo Perl +print "Yow!" if $zippy; +print "No tenemos bananas" unless $bananas; + +# while + while ( condicion ) { + ... + } + + +# for y foreach +for ($i = 0; $i <= $max; $i++) { + ... + } + +foreach (@array) { + print "Este elemento es $_\n"; + } + + +#### Expresiones regulares + +# El soporte de expresiones regulares en Perl es muy amplio y profundo, y es +# sujeto a una extensa documentación en perlrequick, perlretut, entre otros. +# Sin embargo, resumiendo: + +# Pareo simple +if (/foo/) { ... } # verdadero si $_ contiene "foo" +if ($a =~ /foo/) { ... } # verdadero si $a contiene "foo" + +# Substitución simple +$a =~ s/foo/bar/; # remplaza foo con bar en $a +$a =~ s/foo/bar/g; # remplaza TODAS LAS INSTANCIAS de foo con bar en $a + + +#### Archivos e I/O + +# Puedes abrir un archivo para obtener datos o escribirlos utilizando la +# función "open()". + +open(my $entrada, "<" "entrada.txt") or die "No es posible abrir entrada.txt: $!"; +open(my $salida, ">", "salida.txt") or die "No es posible abrir salida.txt: $!"; +open(my $log, ">>", "mi.log") or die "No es posible abrir mi.log: $!"; + +# Es posible leer desde un gestor de archivo abierto utilizando el operador "<>" +# operador. En contexto escalar leer una sola linea desde el gestor de +# archivo, y en contexto de lista leer el archivo completo en donde, asigna +# cada linea a un elemento de la lista. + +my $linea = <$entrada>; +my @lineas = <$entrada>; + +#### Escribiendo subrutinas + +# Escribir subrutinas es fácil: + +sub logger { + my $mensajelog = shift; + open my $archivolog, ">>", "mi.log" or die "No es posible abrir mi.log: $!"; + print $archivolog $mensajelog; +} + +# Ahora podemos utilizar la subrutina al igual que cualquier otra función +# incorporada: + +logger("Tenemos una subrutina logger!"); + + +``` + +#### Utilizando módulos Perl + +Los módulos en Perl proveen una gama de funciones que te pueden ayudar a evitar reinventar la rueda, estas pueden ser descargadas desde CPAN( http://www.cpan.org/ ). Algunos de los módulos mas populares ya están incluidos con la misma distribución de Perl. + +perlfaq contiene preguntas y respuestas relacionadas con muchas tareas comunes, y algunas veces provee sugerencias sobre buenos módulos CPAN para usar. + +#### Material de Lectura + + - [perl-tutorial](http://perl-tutorial.org/) + - [Aprende en www.perl.com](http://www.perl.org/learn.html) + - [perldoc](http://perldoc.perl.org/) + - y perl incorporado: `perldoc perlintro` |