summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.markdown33
-rw-r--r--brainfuck.html.markdown32
-rw-r--r--c.html.markdown2
-rw-r--r--de-de/elixir-de.html.markdown417
-rw-r--r--de-de/javascript-de.html.markdown32
-rw-r--r--es-es/csharp-es.html.markdown631
-rw-r--r--fr-fr/python-fr.html.markdown491
-rw-r--r--go.html.markdown19
-rw-r--r--javascript.html.markdown5
-rw-r--r--ko-kr/clojure-kr.html.markdown383
-rw-r--r--ko-kr/python-kr.html.markdown4
-rw-r--r--lua.html.markdown15
-rw-r--r--matlab.html.markdown17
-rw-r--r--neat.html.markdown299
-rw-r--r--objective-c.html.markdown12
-rw-r--r--php.html.markdown29
-rw-r--r--pt-br/erlang-pt.html.markdown253
-rw-r--r--pt-br/go-pt.html.markdown308
-rw-r--r--pt-pt/git-pt.html.markdown414
-rw-r--r--r.html.markdown2
-rw-r--r--ro-ro/python-ro.html.markdown489
-rw-r--r--ruby-ecosystem.html.markdown6
-rw-r--r--ruby.html.markdown51
-rw-r--r--tr-tr/c-tr.html.markdown4
-rw-r--r--tr-tr/php-tr.html.markdown18
-rw-r--r--zh-cn/perl-cn.html.markdown151
26 files changed, 4040 insertions, 77 deletions
diff --git a/README.markdown b/README.markdown
index fe72df6c..dc379a9b 100644
--- a/README.markdown
+++ b/README.markdown
@@ -12,12 +12,24 @@ Make a new file, send a pull request, and if it passes muster I'll get it up pro
Remember to fill in the "contributors" fields so you get credited
properly!
-### Contributing
+## Contributing
All contributions welcome, from the tiniest typo to a brand new article. Translations
in all languages are welcome (or, for that matter, original articles in any language).
+Send a pull request or open an issue any time of day or night.
-#### Style Guidelines
+**Please tag your issues pull requests with [language/lang-code] at the beginning**
+**(e.g. [python/en] for english python).** This will help everyone pick out things they
+care about.
+
+### Style Guidelines
+
+* **Keep lines under 80 chars**
+* **Prefer example to exposition**
+* **Eschew surplusage**
+* **Use utf-8**
+
+Long version:
* Try to keep **line length in code blocks to 80 characters or fewer**, or they'll overflow
and look odd.
@@ -29,9 +41,9 @@ in all languages are welcome (or, for that matter, original articles in any lang
to keep articles succinct and scannable. We all know how to use google here.
* For translations (or english articles with non-ASCII characters), please make sure your file is
- utf-8 encoded.
+ utf-8 encoded, and try to leave out the byte-order-mark at the start of the file. (`:set nobomb` in vim)
-#### Header configuration
+### Header configuration
The actual site uses Middleman to generate HTML files from these markdown ones. Middleman, or at least
the custom scripts underpinning the site, required that some key information be defined in the header.
@@ -47,6 +59,19 @@ Other fields:
For non-english articles, *filename* should have a language-specific suffix.
* **lang**: For translations, the human language this article is in. For categorization, mostly.
+Here's an example header for an esperanto translation of Ruby:
+
+```yaml
+---
+language: ruby
+filename: learnruby-epo.ruby
+contributors:
+ - ["Doktor Esperanto", "http://example.com/"]
+ - ["Someone else", "http://someoneelseswebsite.com/"]
+lang: ep-ep
+---
+```
+
## License
Contributors retain copyright to their work, and can request removal at any time.
diff --git a/brainfuck.html.markdown b/brainfuck.html.markdown
index 2b7ce4db..9282381f 100644
--- a/brainfuck.html.markdown
+++ b/brainfuck.html.markdown
@@ -1,11 +1,12 @@
---
language: brainfuck
contributors:
- - ["Prajit Ramachandran", "http://prajitr.github.io"]
+ - ["Prajit Ramachandran", "http://prajitr.github.io/"]
+ - ["Mathias Bynens", "http://mathiasbynens.be/"]
---
-Brainfuck is an extremely minimal programming language (just 8 commands) and
-is Turing complete.
+Brainfuck (not capitalized except at the start of a sentence) is an extremely
+minimal Turing-complete programming language with just 8 commands.
```
Any character not "><+-.,[]" (excluding quotation marks) is ignored.
@@ -27,7 +28,7 @@ There are eight commands:
[ and ] form a while loop. Obviously, they must be balanced.
-Let's look at some basic Brainfuck programs.
+Let's look at some basic brainfuck programs.
++++++ [ > ++++++++++ < - ] > +++++ .
@@ -45,21 +46,18 @@ print cell #2's value. 65 is 'A' in ASCII, so 'A' is printed to the terminal.
, [ > + < - ] > .
-This program reads a character from the user input, copies the character into
-another cell, and prints out the same character.
-
-, reads in a character from the user into cell #1. Then we start a loop. Move
-to cell #2, increment the value at cell #2, move back to cell #1, and decrement
-the value at cell #1. This continues on until cell #1 is 0, and cell #2 holds
-cell #1's old value. Because we're on cell #1 at the end of the loop, move to
-cell #2, and then print out the value in ASCII.
+This program reads a character from the user input and copies the character into
+cell #1. Then we start a loop. Move to cell #2, increment the value at cell #2,
+move back to cell #1, and decrement the value at cell #1. This continues on
+until cell #1 is 0, and cell #2 holds cell #1's old value. Because we're on
+cell #1 at the end of the loop, move to cell #2, and then print out the value
+in ASCII.
Also keep in mind that the spaces are purely for readibility purposes. You
-could just as easily write it as
+could just as easily write it as:
,[>+<-]>.
-
Try and figure out what this program does:
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
@@ -73,7 +71,7 @@ problem: at the end of the inner loop, cell #2 is zero. To solve this problem,
we also increment cell #4, and then recopy cell #4 into cell #2.
```
-And that's Brainfuck. Not that hard, eh? For fun, you can write your own
-Brainfuck programs, or you can write a Brainfuck interpreter in another
+And that's brainfuck. Not that hard, eh? For fun, you can write your own
+brainfuck programs, or you can write a brainfuck interpreter in another
language. The interpreter is fairly simple to implement, but if you're a
-masochist, trying writing a Brainfuck interpreter... in Brainfuck.
+masochist, try writing a brainfuck interpreter… in brainfuck.
diff --git a/c.html.markdown b/c.html.markdown
index 3acf1a4d..12f862bc 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -294,7 +294,7 @@ int main() {
printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer));
// => Prints "8, 4" on a typical 64-bit system
- // To retreive the value at the address a pointer is pointing to,
+ // To retrieve the value at the address a pointer is pointing to,
// put * in front to de-reference it.
// Note: yes, it may be confusing that '*' is used for _both_ declaring a
// pointer and dereferencing it.
diff --git a/de-de/elixir-de.html.markdown b/de-de/elixir-de.html.markdown
new file mode 100644
index 00000000..5f89e1f5
--- /dev/null
+++ b/de-de/elixir-de.html.markdown
@@ -0,0 +1,417 @@
+---
+language: elixir
+contributors:
+ - ["Joao Marques", "http://github.com/mrshankly"]
+ - ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"]
+filename: learnelixir-de.ex
+---
+
+Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll
+kompatibel mit Erlang, verfügt aber über eine freundlichere Syntax und bringt
+viele Features mit.
+
+```ruby
+
+# Einzeilige Kommentare werden mit der Raute gesetzt.
+
+# Es gibt keine mehrzeiligen Kommentare;
+# es ist aber problemlos möglich mehrere einzeilige Kommentare hintereinander
+# zu setzen (so wie hier).
+
+# Mit 'iex' ruft man die Elixir-Shell auf.
+# Zum kompilieren von Modulen dient der Befehl 'elixirc'.
+
+# Beide Befehle sollten als Umgebungsvariable gesetzt sein, wenn Elixir korrekt
+# installiert wurde.
+
+## ---------------------------
+## -- Basistypen
+## ---------------------------
+
+# Es gibt Nummern:
+3 # Integer
+0x1F # Integer
+3.0 # Float
+
+# Atome, das sind Literale, sind Konstanten mit Namen. Sie starten mit einem
+# ':'.
+:hello # Atom
+
+# Außerdem gibt es Tupel, deren Werte im Arbeitsspeicher vorgehalten werden.
+{1,2,3} # Tupel
+
+# Die Werte innerhalb eines Tupels können mit der 'elem'-Funktion ausgelesen
+# werden:
+elem({1, 2, 3}, 0) # => 1
+
+# Listen sind als verkettete Listen implementiert.
+[1, 2, 3] # list
+
+# Auf Kopf und Rest einer Liste kann wie folgt zugegriffen werden:
+[ kopf | rest ] = [1,2,3]
+kopf # => 1
+rest # => [2, 3]
+
+# In Elixir, wie auch in Erlang, kennzeichnet '=' ein 'pattern matching'
+# (Musterabgleich) und keine Zuweisung.
+# Das heißt, dass die linke Seite auf die rechte Seite 'abgeglichen' wird.
+# Auf diese Weise kann im Beispiel oben auf Kopf und Rest der Liste zugegriffen
+# werden.
+
+# Ein Musterabgleich wird einen Fehler werfen, wenn die beiden Seiten nicht
+# zusammenpassen.
+# Im folgenden Beispiel haben die Tupel eine unterschiedliche Anzahl an
+# Elementen:
+{a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
+
+# Es gibt außerdem 'binaries',
+<<1,2,3>> # binary.
+
+# Strings und 'char lists'
+"hello" # String
+'hello' # Char-Liste
+
+# ... und mehrzeilige Strings
+"""
+Ich bin ein
+mehrzeiliger String.
+"""
+#=> "Ich bin ein\nmehrzeiliger String.\n"
+
+# Alles Strings werden in UTF-8 enkodiert:
+"héllò" #=> "héllò"
+
+# Eigentlich sind Strings in Wahrheit nur binaries und 'char lists' einfach
+# Listen.
+<<?a, ?b, ?c>> #=> "abc"
+[?a, ?b, ?c] #=> 'abc'
+
+# In Elixir gibt `?a` den ASCII-Integer für den Buchstaben zurück.
+?a #=> 97
+
+# Um Listen zu verbinden gibt es den Operator '++', für binaries nutzt man '<>'
+[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
+'hello ' ++ 'world' #=> 'hello world'
+
+<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
+"hello " <> "world" #=> "hello world"
+
+## ---------------------------
+## -- Operatoren
+## ---------------------------
+
+# Einfache Arithmetik
+1 + 1 #=> 2
+10 - 5 #=> 5
+5 * 2 #=> 10
+10 / 2 #=> 5.0
+
+# In Elixir gibt der Operator '/' immer einen Float-Wert zurück.
+
+# Für Division mit ganzzahligen Ergebnis gibt es 'div'
+div(10, 2) #=> 5
+
+# Um den Rest der ganzzahligen Division zu erhalten gibt es 'rem'
+rem(10, 3) #=> 1
+
+# Natürlich gibt es auch Operatoren für Booleans: 'or', 'and' und 'not'. Diese
+# Operatoren erwarten einen Boolean als erstes Argument.
+true and true #=> true
+false or true #=> true
+# 1 and true #=> ** (ArgumentError) argument error
+
+# Elixir bietet auch '||', '&&' und '!', die Argumente jedweden Typs
+# akzeptieren. Alle Werte außer 'false' und 'nil' werden zu wahr evaluiert.
+1 || true #=> 1
+false && 1 #=> false
+nil && 20 #=> nil
+
+!true #=> false
+
+# Für Vergleiche gibt es die Operatoren `==`, `!=`, `===`, `!==`, `<=`, `>=`,
+# `<` und `>`
+1 == 1 #=> true
+1 != 1 #=> false
+1 < 2 #=> true
+
+# '===' und '!==' sind strikter beim Vergleich von Integern und Floats:
+1 == 1.0 #=> true
+1 === 1.0 #=> false
+
+# Es ist außerdem möglich zwei verschiedene Datentypen zu vergleichen:
+1 < :hello #=> true
+
+# Die gesamte Ordnung über die Datentypen ist wie folgt definiert:
+# number < atom < reference < functions < port < pid < tuple < list < bitstring
+
+# Um Joe Armstrong zu zitieren: "The actual order is not important, but that a
+# total ordering is well defined is important."
+
+## ---------------------------
+## -- Kontrollstrukturen
+## ---------------------------
+
+# Es gibt die `if`-Verzweigung
+if false do
+ "Dies wird nie jemand sehen..."
+else
+ "...aber dies!"
+end
+
+# ...und ebenso `unless`
+unless true do
+ "Dies wird nie jemand sehen..."
+else
+ "...aber dies!"
+end
+
+# Du erinnerst dich an 'pattern matching'? Viele Kontrollstrukturen in Elixir
+# arbeiten damit.
+
+# 'case' erlaubt es uns Werte mit vielerlei Mustern zu vergleichen.
+case {:one, :two} do
+ {:four, :five} ->
+ "Das wird nicht passen"
+ {:one, x} ->
+ "Das schon und außerdem wird es ':two' dem Wert 'x' zuweisen."
+ _ ->
+ "Dieser Fall greift immer."
+end
+
+# Es ist eine übliche Praxis '_' einen Wert zuzuweisen, sofern dieser Wert
+# nicht weiter verwendet wird.
+# Wenn wir uns zum Beispiel nur für den Kopf einer Liste interessieren:
+[kopf | _] = [1,2,3]
+kopf #=> 1
+
+# Für bessere Lesbarkeit können wir auch das Folgende machen:
+[kopf | _rest] = [:a, :b, :c]
+kopf #=> :a
+
+# Mit 'cond' können diverse Bedingungen zur selben Zeit überprüft werden. Man
+# benutzt 'cond' statt viele if-Verzweigungen zu verschachteln.
+cond do
+ 1 + 1 == 3 ->
+ "Ich werde nie aufgerufen."
+ 2 * 5 == 12 ->
+ "Ich auch nicht."
+ 1 + 2 == 3 ->
+ "Aber ich!"
+end
+
+# Es ist üblich eine letzte Bedingung einzufügen, die immer zu wahr evaluiert.
+cond do
+ 1 + 1 == 3 ->
+ "Ich werde nie aufgerufen."
+ 2 * 5 == 12 ->
+ "Ich auch nicht."
+ true ->
+ "Aber ich! (dies ist im Grunde ein 'else')"
+end
+
+# 'try/catch' wird verwendet um Werte zu fangen, die zuvor 'geworfen' wurden.
+# Das Konstrukt unterstützt außerdem eine 'after'-Klausel die aufgerufen wird,
+# egal ob zuvor ein Wert gefangen wurde.
+try do
+ throw(:hello)
+catch
+ nachricht -> "#{nachricht} gefangen."
+after
+ IO.puts("Ich bin die 'after'-Klausel.")
+end
+#=> Ich bin die 'after'-Klausel.
+# ":hello gefangen"
+
+## ---------------------------
+## -- Module und Funktionen
+## ---------------------------
+
+# Anonyme Funktionen (man beachte den Punkt)
+square = fn(x) -> x * x end
+square.(5) #=> 25
+
+# Anonyme Funktionen unterstützen auch 'pattern' und 'guards'. Guards erlauben
+# es die Mustererkennung zu justieren und werden mit dem Schlüsselwort 'when'
+# eingeführt:
+f = fn
+ x, y when x > 0 -> x + y
+ x, y -> x * y
+end
+
+f.(1, 3) #=> 4
+f.(-1, 3) #=> -3
+
+# Elixir bietet zahlreiche eingebaute Funktionen. Diese sind im gleichen
+# Geltungsbereich ('scope') verfügbar.
+is_number(10) #=> true
+is_list("hello") #=> false
+elem({1,2,3}, 0) #=> 1
+
+# Mehrere Funktionen können in einem Modul gruppiert werden. Innerhalb eines
+# Moduls ist es möglich mit dem Schlüsselwort 'def' eine Funktion zu
+# definieren.
+defmodule Math do
+ def sum(a, b) do
+ a + b
+ end
+
+ def square(x) do
+ x * x
+ end
+end
+
+Math.sum(1, 2) #=> 3
+Math.square(3) #=> 9
+
+# Um unser einfaches Mathe-Modul zu kompilieren muss es unter 'math.ex'
+# gesichert werden. Anschließend kann es mit 'elixirc' im Terminal aufgerufen
+# werden: elixirc math.ex
+
+# Innerhalb eines Moduls definieren wir private Funktionen mit 'defp'. Eine
+# Funktion, die mit 'def' erstellt wurde, kann von anderen Modulen aufgerufen
+# werden; eine private Funktion kann nur lokal angesprochen werden.
+defmodule PrivateMath do
+ def sum(a, b) do
+ do_sum(a, b)
+ end
+
+ defp do_sum(a, b) do
+ a + b
+ end
+end
+
+PrivateMath.sum(1, 2) #=> 3
+# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
+
+# Auch Funktionsdeklarationen unterstützen 'guards' und Mustererkennung:
+defmodule Geometry do
+ def area({:rectangle, w, h}) do
+ w * h
+ end
+
+ def area({:circle, r}) when is_number(r) do
+ 3.14 * r * r
+ end
+end
+
+Geometry.area({:rectangle, 2, 3}) #=> 6
+Geometry.area({:circle, 3}) #=> 28.25999999999999801048
+# Geometry.area({:circle, "not_a_number"})
+#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
+
+# Wegen der Unveränderlichkeit von Variablen ist Rekursion ein wichtiger
+# Bestandteil von Elixir.
+defmodule Recursion do
+ def sum_list([head | tail], acc) do
+ sum_list(tail, acc + head)
+ end
+
+ def sum_list([], acc) do
+ acc
+ end
+end
+
+Recursion.sum_list([1,2,3], 0) #=> 6
+
+# Elixir-Module unterstützen Attribute. Es gibt eingebaute Attribute, ebenso
+# ist es möglich eigene Attribute hinzuzufügen.
+defmodule MyMod do
+ @moduledoc """
+ Dies ist ein eingebautes Attribut in einem Beispiel-Modul
+ """
+
+ @my_data 100 # Dies ist ein selbst-definiertes Attribut.
+ IO.inspect(@my_data) #=> 100
+end
+
+## ---------------------------
+## -- 'Records' und Ausnahmebehandlung
+## ---------------------------
+
+# 'Records' sind im Grunde Strukturen, die es erlauben einem Wert einen eigenen
+# Namen zuzuweisen.
+defrecord Person, name: nil, age: 0, height: 0
+
+joe_info = Person.new(name: "Joe", age: 30, height: 180)
+#=> Person[name: "Joe", age: 30, height: 180]
+
+# Zugriff auf den Wert von 'name'
+joe_info.name #=> "Joe"
+
+# Den Wert von 'age' überschreiben
+joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180]
+
+# Der 'try'-Block wird zusammen mit dem 'rescue'-Schlüsselwort dazu verwendet,
+# um Ausnahmen beziehungsweise Fehler zu behandeln.
+try do
+ raise "Irgendein Fehler."
+rescue
+ RuntimeError -> "Laufzeit-Fehler gefangen."
+ _error -> "Und dies fängt jeden Fehler."
+end
+
+# Alle Ausnahmen haben das Attribut 'message'
+try do
+ raise "ein Fehler"
+rescue
+ x in [RuntimeError] ->
+ x.message
+end
+
+## ---------------------------
+## -- Nebenläufigkeit
+## ---------------------------
+
+# Elixir beruht auf dem Aktoren-Model zur Behandlung der Nebenläufigkeit. Alles
+# was man braucht um in Elixir nebenläufige Programme zu schreiben sind drei
+# Primitive: Prozesse erzeugen, Nachrichten senden und Nachrichten empfangen.
+
+# Um einen neuen Prozess zu erzeugen nutzen wir die 'spawn'-Funktion, die
+# wiederum eine Funktion als Argument entgegen nimmt.
+f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
+spawn(f) #=> #PID<0.40.0>
+
+# 'spawn' gibt eine pid (einen Identifikator des Prozesses) zurück. Diese kann
+# nun verwendet werden, um Nachrichten an den Prozess zu senden. Um
+# zu senden nutzen wir den '<-' Operator. Damit das alles Sinn macht müssen wir
+# in der Lage sein Nachrichten zu empfangen. Dies wird mit dem
+# 'receive'-Mechanismus sichergestellt:
+defmodule Geometry do
+ def area_loop do
+ receive do
+ {:rectangle, w, h} ->
+ IO.puts("Area = #{w * h}")
+ area_loop()
+ {:circle, r} ->
+ IO.puts("Area = #{3.14 * r * r}")
+ area_loop()
+ end
+ end
+end
+
+# Kompiliere das Modul, starte einen Prozess und gib die 'area_loop' Funktion
+# in der Shell mit, etwa so:
+pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
+
+# Sende eine Nachricht an die 'pid', die ein Muster im 'receive'-Ausdruck
+# erfüllt:
+pid <- {:rectangle, 2, 3}
+#=> Area = 6
+# {:rectangle,2,3}
+
+pid <- {:circle, 2}
+#=> Area = 12.56000000000000049738
+# {:circle,2}
+
+# Die Shell selbst ist ein Prozess und mit dem Schlüsselwort 'self' kann man
+# die aktuelle pid herausfinden.
+self() #=> #PID<0.27.0>
+
+```
+
+## Referenzen und weitere Lektüre
+
+* [Getting started guide](http://elixir-lang.org/getting_started/1.html) auf der [elixir Website](http://elixir-lang.org)
+* [Elixir Documentation](http://elixir-lang.org/docs/master/)
+* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) von Fred Hebert
+* "Programming Erlang: Software for a Concurrent World" von Joe Armstrong \ No newline at end of file
diff --git a/de-de/javascript-de.html.markdown b/de-de/javascript-de.html.markdown
index 56a41af0..d767815e 100644
--- a/de-de/javascript-de.html.markdown
+++ b/de-de/javascript-de.html.markdown
@@ -1,9 +1,9 @@
---
-language: JavaScript
+language: javascript
contributors:
- ["Adam Brenecki", "http://adam.brenecki.id.au"]
- ["ggb", "http://www.ideen-und-soehne.de"]
-filename: learnjavascript.js
+filename: learnjavascript-de.js
lang: de-de
---
@@ -104,8 +104,8 @@ false;
// Es gibt außerdem die Werte 'null' und 'undefined'
null; // wird verwendet um einen vorsätzlich gewählten 'Nicht'-Wert anzuzeigen
undefined; // wird verwendet um anzuzeigen, dass der Wert (aktuell) nicht
- // verfügbar ist (obwohl genau genommen undefined selbst einen Wert
- // darstellt)
+ // verfügbar ist (obwohl genau genommen undefined selbst einen Wert
+ // darstellt)
// false, null, undefined, NaN, 0 und "" sind 'falsy', d. h. alles andere ist
// wahr. Man beachte, dass 0 falsch und "0" wahr ist, obwohl 0 == "0".
@@ -255,9 +255,9 @@ i; // = 5 - nicht undefined, wie man es von einer Sprache erwarten würde, die
(function(){
var temporary = 5;
// Auf eine Variable im globalen Geltungsbereich kann zugegriffen werden,
- // sofern sie im globalen Objekt definiert ist (in einem Webbrowser ist
- // dies immer das 'window'-Objekt, in anderen Umgebungen, bspw. Node.js,
- // kann das anders aussehen).
+ // sofern sie im globalen Objekt definiert ist (in einem Webbrowser ist
+ // dies immer das 'window'-Objekt, in anderen Umgebungen, bspw. Node.js,
+ // kann das anders aussehen).
window.permanent = 10;
})();
temporary; // wirft einen ReferenceError
@@ -274,13 +274,13 @@ function sayHelloInFiveSeconds(name){
}
setTimeout(inner, 5000);
// setTimeout wird asynchron ausgeführt. Also wird sayHelloInFiveSeconds
- // sofort verlassen und setTimeout wird die innere Funktion 'im nachhinein'
- // aufrufen. Dennoch: Weil sayHelloInFiveSeconds eine Hülle um die innere
- // Funktion bildet, hat die innere Funktion immer noch Zugriff auf die
- // Variable prompt.
+ // sofort verlassen und setTimeout wird die innere Funktion 'im nachhinein'
+ // aufrufen. Dennoch: Weil sayHelloInFiveSeconds eine Hülle um die innere
+ // Funktion bildet, hat die innere Funktion immer noch Zugriff auf die
+ // Variable prompt.
}
sayHelloInFiveSeconds("Adam"); // wird nach 5 Sekunden ein Popup mit der
- // Nachricht "Hello, Adam!" öffnen.
+ // Nachricht "Hello, Adam!" öffnen.
///////////////////////////////////
// 5. Mehr über Objekte, Konstruktoren und Prototypen
@@ -423,14 +423,14 @@ String.prototype.firstCharacter = function(){
// allen Umgebungen verfügbar ist - wir können sie dennoch verwenden, mit einem
// 'polyfill':
if (Object.create === undefined){ // überschreib nichts, was eventuell bereits
- // existiert
+ // existiert
Object.create = function(proto){
// erstelle einen vorübergehenden Konstruktor mit dem richtigen
- // Prototypen
+ // Prototypen
var Constructor = function(){};
Constructor.prototype = proto;
// verwende es dann, um ein neues Objekt mit einem passenden
- // Prototypen zurückzugeben
+ // Prototypen zurückzugeben
return new Constructor();
}
}
@@ -446,4 +446,4 @@ Dieses Tutorial hat nur die Sprache JavaScript vorgestellt; um mehr über den E
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) ist eine tiefgehende Einführung in die kontra-intuitiven Parts der Sprache.
-Zusätzlich zu direkten Beiträgen zu diesem Artikel ist der Inhalt in Anlehnung an Louie Dinh's Python-Tutorial auf dieser Seite und das [JS Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) des Mozilla Developer Network entstanden. \ No newline at end of file
+Zusätzlich zu direkten Beiträgen zu diesem Artikel ist der Inhalt in Anlehnung an Louie Dinh's Python-Tutorial auf dieser Seite und das [JS Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) des Mozilla Developer Network entstanden.
diff --git a/es-es/csharp-es.html.markdown b/es-es/csharp-es.html.markdown
new file mode 100644
index 00000000..7d1a1201
--- /dev/null
+++ b/es-es/csharp-es.html.markdown
@@ -0,0 +1,631 @@
+---
+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
+---
+
+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/fr-fr/python-fr.html.markdown b/fr-fr/python-fr.html.markdown
new file mode 100644
index 00000000..2f10e410
--- /dev/null
+++ b/fr-fr/python-fr.html.markdown
@@ -0,0 +1,491 @@
+---
+langage: python
+
+contributeurs:
+ - ["Louie Dinh", "http://ldinh.ca"]
+
+traducteurs:
+ - ["Sylvain Zyssman", "https://github.com/sylzys"]
+
+fichier: learnpython.py
+
+---
+
+Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des langages de programmation les plus populaires.
+Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiquement du pseudo-code exécutable.
+
+Vos retours sont grandement appréciés. Vous pouvez me contacter sur Twitter [@louiedinh](http://twitter.com/louiedinh) ou par e-mail: louiedinh [at] [google's email service]
+
+NB: Cet artice s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x
+Vous pourrez bientôt trouver un article pour Python 3!
+
+```python
+# Une ligne simple de commentaire commence par un dièse
+""" Les lignes de commenatires multipes peuvent être écrites
+ en utilisant 3 guillemets ("), et sont souvent utilisées
+ pour les commentaires
+"""
+
+####################################################
+## 1. Types Primaires et Opérateurs
+####################################################
+
+# Les nombres
+3 #=> 3
+
+# Les calculs produisent les résultats mathématiques escomptés
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# La division est un peu spéciale. C'est une division d'entiers, et Python arrondi le résultat par défaut automatiquement.
+5 / 2 #=> 2
+
+# Pour corriger ce problème, on utilise les float.
+2.0 # Voici un float
+11.0 / 4.0 #=> 2.75 ahhh... beaucoup mieux
+
+# Forcer la priorité avec les parenthèses
+(1 + 3) * 2 #=> 8
+
+# Les valeurs booléenes sont de type primitif
+True
+False
+
+# Pour la négation, on utilise "not"
+not True #=> False
+not False #=> True
+
+# Pour l'égalité, ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# L'inégalité est symbolisée par !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# D'autres comparateurs
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# On peut enchaîner les comparateurs !
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Les chaînes de caractères sont créées avec " ou '
+"C'est une chaîne."
+'C'est aussi une chaîne.'
+
+# On peut aussi les "additioner" !
+"Hello " + "world!" #=> "Hello world!"
+
+# Une chaîne peut être traitée comme une liste de caractères
+"C'est une chaîne"[0] #=> 'C'
+
+# % peut être utilisé pour formatter des chaîne, comme ceci:
+"%s can be %s" % ("strings", "interpolated")
+
+# Une autre manière de formatter les chaînes de caractères est d'utiliser la méthode 'format'
+# C'est la méthode à privilégier
+"{0} peut être {1}".format("La chaîne", "formattée")
+# On peut utiliser des mot-clés au lieu des chiffres.
+"{name} veut manger des {food}".format(name="Bob", food="lasagnes")
+
+# None est un objet
+None #=> None
+
+# Ne pas utiliser le symbole d'inégalité "==" pour comparer des objet à None
+# Il faut utiliser "is"
+"etc" is None #=> False
+None is None #=> True
+
+# L'opérateur 'is' teste l'identité de l'objet.
+# Ce n'est pas très utilisé avec les types primitifs, mais cela peut être très utile
+# lorsque l'on utilise des objets.
+
+# None, 0, et les chaînes de caractères vides valent False.
+# Toutes les autres valeurs valent True
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Variables et Collections
+####################################################
+
+# Afficher du texte, c'est facile
+print "Je suis Python. Enchanté!"
+
+
+# Il n'y a pas besoin de déclarer les variables avant de les assigner.
+some_var = 5 # La convention veut que l'on utilise des minuscules_avec_underscores
+some_var #=> 5
+
+# Accéder à une variable non assignée lève une exception
+# Voyez les structures de contrôle pour en apprendre plus sur la gestion des exceptions.
+some_other_var # Lève une exception
+
+# 'if' peut être utilisé comme expression
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Listes
+li = []
+# On peut remplir liste dès l'instanciation
+other_li = [4, 5, 6]
+
+# On ajoute des éléments avec 'append'
+li.append(1) #li contient [1]
+li.append(2) #li contient [1, 2]
+li.append(4) #li contient [1, 2, 4]
+li.append(3) #li contient [1, 2, 4, 3]
+
+# Et on les supprime avec 'pop'
+li.pop() #=> 3 et li contient [1, 2, 4]
+# Remettons-le dans la liste
+li.append(3) # li contient [1, 2, 4, 3] de nouveau.
+
+# On accède aux éléments d'une liste comme à ceux un tableau.
+li[0] #=> 1
+# Le dernier élément
+li[-1] #=> 3
+
+# Accèder aux indices hors limite lève une exception
+li[4] # Lève un 'IndexError'
+
+# On peut accèder à des rangs de valeurs avec la syntaxe "slice"
+# (C'est un rang de type 'fermé/ouvert' pour les plus matheux)
+li[1:3] #=> [2, 4]
+# Sans spécifier de début de rang
+li[2:] #=> [4, 3]
+# Sans spécifier de fin de rang
+li[:3] #=> [1, 2, 4]
+
+# Retirer un élément spécifique dee la liste avec "del"
+del li[2] # li contient [1, 2, 3]
+
+# On peut additionner des listes entre elles
+li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li et other_li existent toujours à part entière
+
+# Concaténer des listes avec "extend()"
+li.extend(other_li) # li vaut maintenant [1, 2, 3, 4, 5, 6]
+
+# Vérifier l'existence d'un élément dans une liste avec "in"
+1 in li #=> True
+
+# Récupérer la longueur avec "len()"
+len(li) #=> 6
+
+
+# Les "tuples" sont comme des listes, mais sont immuables.
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # Lève un 'TypeError'
+
+# Mais vous pouvez faire tout ceci sur les tuples:
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Vous pouvez "dé-packager" les tuples (ou les listes) dans des variables
+a, b, c = (1, 2, 3) # a vaut maintenant 1, b vaut maintenant 2 and c vaut maintenant 3
+# Sans parenthèses, un tuple est créé par défaut
+d, e, f = 4, 5, 6
+# Voyez maintenant comme il est facile d'inverser 2 valeurs
+e, d = d, e # d is now 5 and e is now 4
+
+
+# Dictionnaires
+empty_dict = {}
+# Un dictionnaire pré-rempli
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Trouver des valeurs avec []
+filled_dict["one"] #=> 1
+
+# Récupérer toutes les clés sous forme de liste avec "keys()"
+filled_dict.keys() #=> ["three", "two", "one"]
+# Note - l'ordre des clés du dictionnaire n'est pas garanti.
+# Vos résultats peuvent différer de ceux ci-dessus.
+
+# Récupérer toutes les valeurs sous forme de liste avec "values()"
+filled_dict.values() #=> [3, 2, 1]
+# Note - Même remarque qu'au-dessus concernant l'ordre des valeurs.
+
+# Vérifier l'existence d'une clé dans le dictionnaire avec "in"
+"one" in filled_dict #=> True
+1 in filled_dict #=> False
+
+# Chercher une clé non existante lève une 'KeyError'
+filled_dict["four"] # KeyError
+
+# Utiliser la méthode "get()" pour éviter 'KeyError'
+filled_dict.get("one") #=> 1
+filled_dict.get("four") #=> None
+# La méthode get() prend un argument par défaut quand la valeur est inexistante
+filled_dict.get("one", 4) #=> 1
+filled_dict.get("four", 4) #=> 4
+
+# La méthode "setdefault()" permet d'ajouter de manière sécuris une paire clé-valeur dans le dictionnnaire
+filled_dict.setdefault("five", 5) #filled_dict["five"] vaut 5
+filled_dict.setdefault("five", 6) #filled_dict["five"] is toujours 5
+
+
+# Les sets stockent ... des sets
+empty_set = set()
+# On initialise un "set()" avec tout un tas de valeurs
+some_set = set([1,2,2,3,4]) # some_set vaut maintenant set([1, 2, 3, 4])
+
+# Depuis Python 2.7, {} peut être utilisé pour déclarer un 'set'
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Ajouter plus d'éléments au set
+filled_set.add(5) # filled_set contient maintenant {1, 2, 3, 4, 5}
+
+# Intersection de sets avec &
+other_set = {3, 4, 5, 6}
+filled_set & other_set #=> {3, 4, 5}
+
+# Union de sets avec |
+filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+
+# Différence de sets avec -
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# Vérifier l'existence d'une valeur dans un set avec "in"
+2 in filled_set #=> True
+10 in filled_set #=> False
+
+
+####################################################
+## 3. Structure de contrôle
+####################################################
+
+# Initialisons une variable
+some_var = 5
+
+# Voici une condition 'if'. L'indentation est significative en Python !
+# Affiche "some_var est inférieur à 10"
+if some_var > 10:
+ print "some_var est supérieur à 10."
+elif some_var < 10: # La clause elif est optionnelle
+ print "some_var iinférieur à 10."
+else: # La clause else également
+ print "some_var vaut 10."
+
+
+"""
+Les boucles "for" permettent d'itérer sur les listes
+Affiche:
+ chien : mammifère
+ chat : mammifère
+ souris : mammifère
+"""
+for animal in ["chien", "chat", "souris"]:
+ # On peut utiliser % pour l'interpolation des chaînes formattées
+ print "%s : mammifère" % animal
+
+"""
+"range(number)" retourne une liste de nombres
+de 0 au nombre donné
+Affiche:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+Les boucles "while" boucle jusqu'à ce que leur condition ne soit plus vraie
+Affiche:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Raccourci pour x = x + 1
+
+# Gérer les exceptions avec un bloc try/except
+
+# Fonctionne pour Python 2.6 et ultérieur:
+try:
+ # Utiliser "raise" pour lever une exception
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # Pass ne prend pas d'arguments. Généralement, on gère l'erreur ici.
+
+
+####################################################
+## 4. Fonctions
+####################################################
+
+# Utiliser "def" pour créer une nouvelle fonction
+def add(x, y):
+ print "x vaut %s et y vaur %s" % (x, y)
+ return x + y # Renvoi de valeur avec 'return'
+
+# Appeller une fonction avec des paramètres
+add(5, 6) #=> Affichet "x is 5 et y vaut 6" et renvoie 11
+
+# Une autre manière d'appeller une fonction, avec les arguments
+add(y=6, x=5) # Les arguments peuvent venir dans n'importe quel ordre.
+
+# On peut définir une foncion qui prend un nombre variable de paramètres
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# On peut également définir une fonction qui prend un nombre
+# variable d'arguments
+def keyword_args(**kwargs):
+ return kwargs
+
+# Appelons-là et voyons ce qu'il se passe
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# On peut faire les deux à la fois si on le souhaite
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) affiche:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# En appellant les fonctions, on peut faire l'inverse des paramètres / arguments !
+# Utiliser * pour développer les paramètres, et ** pour développer les arguments
+params = (1, 2, 3, 4)
+args = {"a": 3, "b": 4}
+all_the_args(*args) # equivaut à foo(1, 2, 3, 4)
+all_the_args(**kwargs) # equivaut à foo(a=3, b=4)
+all_the_args(*args, **kwargs) # equivaut à foo(1, 2, 3, 4, a=3, b=4)
+
+# Python a des fonctions de première classe
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Mais également des fonctions anonymes
+(lambda x: x > 2)(3) #=> True
+
+# On trouve aussi des fonctions intégrées plus évoluées
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# On peut utiliser la syntaxe des liste pour construire les "maps" et les "filters"
+[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]
+
+####################################################
+## 5. Classes
+####################################################
+
+# Une classe est un objet
+class Human(object):
+
+ # Un attribut de classe. Il est partagé par toutes les instances de cette classe.
+ species = "H. sapiens"
+
+ # Initialiseur basique
+ def __init__(self, name):
+ # Assigne le paramètre à l'attribut de l'instance de classe.
+ self.name = name
+
+ # Une méthode de l'instance. Toutes les méthodes prennent "self" comme 1er paramètre.
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # Une méthode de classe est partagée par toutes les instances.
+ # On les appelle avec le nom de la classe en premier paramètre
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Une méthode statique est appellée sans référence à une classe ou à une instance
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Instancier une classe
+i = Human(name="Ian")
+print i.say("hi") # Affiche "Ian: hi"
+
+j = Human("Joel")
+print j.say("hello") #Affiche "Joel: hello"
+
+# Appeller notre méthode de classe
+i.get_species() #=> "H. sapiens"
+
+# Changer les attributs partagés
+Human.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# Appeller la méthode statique
+Human.grunt() #=> "*grunt*"
+
+
+####################################################
+## 6. Modules
+####################################################
+
+# On peut importer des modules
+import math
+print math.sqrt(16) #=> 4
+
+# Et récupérer des fonctions spécifiques d'un module
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Récuperer toutes les fonctions d'un module
+# Attention, ce n'est pas recommandé.
+from math import *
+
+# On peut raccourcir le nom d'un module
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Les modules Python sont juste des fichiers Python ordinaires.
+# On peut écrire ses propres modules et les importer.
+# Le nom du module doit être le même que le nom du fichier.
+
+# On peut trouver quelle fonction et attributs déterminent un module
+import math
+dir(math)
+
+
+```
+
+## Prêt à aller plus loin?
+
+### En ligne gratuitement
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Format papier
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/go.html.markdown b/go.html.markdown
index 4db76a49..eec03845 100644
--- a/go.html.markdown
+++ b/go.html.markdown
@@ -1,4 +1,4 @@
----
+---
name: Go
category: language
language: Go
@@ -46,7 +46,7 @@ func main() {
}
// Functions have parameters in parentheses.
-// If there are no parameters, empty parens are still required.
+// If there are no parameters, empty parentheses are still required.
func beyondHello() {
var x int // Variable declaration. Variables must be declared before use.
x = 3 // Variable assignment.
@@ -71,7 +71,7 @@ func learnTypes() {
can include line breaks.` // same string type
// non-ASCII literal. Go source is UTF-8.
- g := 'Σ' // rune type, an alias for uint32, holds a UTF-8 code point
+ g := 'Σ' // rune type, an alias for uint32, holds a unicode code point
f := 3.14195 // float64, an IEEE-754 64-bit floating point number
c := 3 + 4i // complex128, represented internally with two float64s
@@ -251,7 +251,7 @@ func learnConcurrency() {
fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator.
cs := make(chan string) // another channel, this one handles strings.
- cc := make(chan chan string) // a channel of channels.
+ cc := make(chan chan string) // a channel of string channels.
go func() { c <- 84 }() // start a new goroutine just to send a value
go func() { cs <- "wordy" }() // again, for cs this time
// Select has syntax like a switch statement but each case involves
@@ -259,7 +259,7 @@ func learnConcurrency() {
// that are ready to communicate.
select {
case i := <-c: // the value received can be assigned to a variable
- fmt.Println("it's a", i)
+ fmt.Printf("it's a %T", i)
case <-cs: // or the value received can be discarded
fmt.Println("it's a string")
case <-cc: // empty channel, not ready for communication.
@@ -294,8 +294,9 @@ There you can follow the tutorial, play interactively, and read lots.
The language definition itself is highly recommended. It's easy to read
and amazingly short (as language definitions go these days.)
-On the reading list for students of Go is the source code to the standard
-library. Comprehensively documented, it demonstrates the best of readable
-and understandable Go, Go style, and Go idioms. Click on a function name
-in the documentation and the source code comes up!
+On the reading list for students of Go is the [source code to the standard
+library](http://golang.org/src/pkg/). Comprehensively documented, it
+demonstrates the best of readable and understandable Go, Go style, and Go
+idioms. Or you can click on a function name in [the
+documentation](http://golang.org/pkg/) and the source code comes up!
diff --git a/javascript.html.markdown b/javascript.html.markdown
index 1dd6e2be..bc2a973a 100644
--- a/javascript.html.markdown
+++ b/javascript.html.markdown
@@ -1,7 +1,8 @@
---
language: javascript
-author: Adam Brenecki
-author_url: http://adam.brenecki.id.au
+contributors:
+ - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+filename: javascript.js
---
Javascript was created by Netscape's Brendan Eich in 1995. It was originally
diff --git a/ko-kr/clojure-kr.html.markdown b/ko-kr/clojure-kr.html.markdown
new file mode 100644
index 00000000..1d9e53cd
--- /dev/null
+++ b/ko-kr/clojure-kr.html.markdown
@@ -0,0 +1,383 @@
+---
+language: clojure
+filename: learnclojure-kr.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["netpyoung", "http://netpyoung.github.io/"]
+lang: ko-kr
+---
+
+Clojure는 Java 가상머신을 위해 개발된 Lisp 계통의 언어입니다
+이는 Common Lisp보다 순수 [함수형 프로그래밍](https://en.wikipedia.org/wiki/Functional_programming)을 더욱 강조했으며,
+상태를 있는 그대로 다루기 위해 다양한 [STM](https://en.wikipedia.org/wiki/Software_transactional_memory) 을 지원하는 프로그램들을 갖췄습니다.
+
+이를 조합하여, 병행처리(concurrent processing)를 매우 단순하게 처리할 수 있으며,
+대게 자동으로 처리될 수 있도록 만들 수 있습니다.
+
+(Clojure 1.2 이상의 버전이 필요로 합니다.)
+
+
+```clojure
+; 주석은 세미콜론(;)으로 시작합니다.
+
+; Clojure는 "폼(forms)"으로 구성되었으며,
+; 폼은 괄호로 감싸져있으며, 공백으로 구분된 것들이 나열된 것입니다.
+;
+; clojure의 reader는 첫번째로 오는 것을
+; 함수 혹은 매크로를 호출하는 것, 그리고 나머지를 인자라고 가정합니다.
+
+; namespace를 지정하기 위해, 파일에서 우선적으로 호출해야될 것은 ns입니다.
+(ns learnclojure)
+
+; 간단한 예제들:
+
+; str 은 인자로 받은 것들을 하나의 문자열로 만들어줍니다.
+(str "Hello" " " "World") ; => "Hello World"
+
+; 직관적인 수학 함수들을 갖고 있습니다.
+(+ 1 1) ; => 2
+(- 2 1) ; => 1
+(* 1 2) ; => 2
+(/ 2 1) ; => 2
+
+; = 로 동일성을 판별할 수 있습니다.
+(= 1 1) ; => true
+(= 2 1) ; => false
+
+; 논리연산을 위한 not 역시 필요합니다.
+(not true) ; => false
+
+; 중첩된 폼(forms)은 기대한대로 동작합니다.
+(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+
+; 타입
+;;;;;;;;;;;;;
+
+; Clojure는 부울(boolean), 문자열, 숫자를 위해 Java의 object 타입을 이용합니다.
+; `class` 를 이용하여 이를 확인할 수 있습니다.
+(class 1) ; 정수는 기본적으로 java.lang.Long입니다.
+(class 1.); 소수는 java.lang.Double입니다.
+(class ""); 문자열은 쌍따옴표로 감싸져 있으며, java.lang.String입니다.
+(class false) ; 부울값은 java.lang.Boolean입니다.
+(class nil); nil은 "null"값입니다.
+
+; 데이터 리스트 자체를 만들고자 한다면,
+; '를 이용하여 평가(evaluate)되지 않도록 막아야 합니다.
+'(+ 1 2) ; => (+ 1 2)
+; (quote (+ 1 2)) 를 줄여서 쓴것
+
+; quote 가 된 리스트를 평가할 수 도 있습니다.
+(eval '(+ 1 2)) ; => 3
+
+; 컬렉션(Collections) & 시퀀스(Sequences)
+;;;;;;;;;;;;;;;;;;;
+
+; 리스트(List)는 연결된(linked-list) 자료구조이며, 벡터(Vector)는 배열이 뒤로붙는(array-backed) 자료구조입니다.
+; 리스트와 벡터 모두 java 클래스입니다!
+(class [1 2 3]); => clojure.lang.PersistentVector
+(class '(1 2 3)); => clojure.lang.PersistentList
+
+; 간단하게 (1 2 3)로 리스트를 나타낼 수 있지만,
+; reader가 함수라고 여기지 못하게 quote(')를 해줘야 합니다.
+; 따라서, (list 1 2 3)는 '(1 2 3)와 같습니다.
+
+; "컬렉션"은 단순하게 데이터의 그룹입니다.
+; 리스트와 벡터 모두 컬렉션입니다:
+(coll? '(1 2 3)) ; => true
+(coll? [1 2 3]) ; => true
+
+; "시퀀스" (seq) 는 데이터 리스트를 추상적으로 기술한 것입니다.
+; 리스트는 시퀀스입니다.
+(seq? '(1 2 3)) ; => true
+(seq? [1 2 3]) ; => false
+
+; 시퀀스는 접근하고자 하는 항목만 제공해주면 됩니다.
+; 따라서, 시퀀스는 lazy 할 수 있습니다 -- 무한하게 늘어나는 것을 정의할 수 있습니다:
+(range 4) ; => (0 1 2 3)
+(range) ; => (0 1 2 3 4 ...) (an infinite series)
+(take 4 (range)) ; (0 1 2 3)
+
+; cons 를 이용하여 리스트나 벡터의 시작부에 항목을 추가할 수 있습니다.
+(cons 4 [1 2 3]) ; => (4 1 2 3)
+(cons 4 '(1 2 3)) ; => (4 1 2 3)
+
+; conj 는 컬렉션에 가장 효율적인 방식으로 항목을 추가합니다.
+; 리스트는 시작부분에 삽입하고, 벡터는 끝부분에 삽입합니다.
+(conj [1 2 3] 4) ; => [1 2 3 4]
+(conj '(1 2 3) 4) ; => (4 1 2 3)
+
+; concat 을 이용하여 리스트와 벡터를 서로 합칠 수 있습니다.
+(concat [1 2] '(3 4)) ; => (1 2 3 4)
+
+; filter, map 을 이용하여 컬렉션을 다룰 수 있습니다.
+(map inc [1 2 3]) ; => (2 3 4)
+(filter even? [1 2 3]) ; => (2)
+
+; reduce 를 이용하여 줄여나갈 수 있습니다.
+(reduce + [1 2 3 4])
+; = (+ (+ (+ 1 2) 3) 4)
+; => 10
+
+; reduce 는 초기 값을 인자로 취할 수 도 있습니다.
+(reduce conj [] '(3 2 1))
+; = (conj (conj (conj [] 3) 2) 1)
+; => [3 2 1]
+
+; 함수
+;;;;;;;;;;;;;;;;;;;;;
+
+; fn 을 이용하여 함수를 만들 수 있습니다 .
+; 함수는 항상 마지막 문장을 반환합니다.
+(fn [] "Hello World") ; => fn
+
+; (정의한 것을 호출하기 위해선, 괄호가 더 필요합니다.)
+((fn [] "Hello World")) ; => "Hello World"
+
+; def 를 이용하여 var 를 만들 수 있습니다.
+(def x 1)
+x ; => 1
+
+; var 에 함수를 할당시켜보겠습니다.
+(def hello-world (fn [] "Hello World"))
+(hello-world) ; => "Hello World"
+
+; defn 을 이용하여 짧게 쓸 수 도 있습니다.
+(defn hello-world [] "Hello World")
+
+; [] 는 함수의 인자 목록을 나타냅니다.
+(defn hello [name]
+ (str "Hello " name))
+(hello "Steve") ; => "Hello Steve"
+
+; 약자(shorthand)를 써서 함수를 만들 수 도 있습니다:
+(def hello2 #(str "Hello " %1))
+(hello2 "Fanny") ; => "Hello Fanny"
+
+; 함수가 다양한 인자를 받도록 정의할 수 도 있습니다.
+(defn hello3
+ ([] "Hello World")
+ ([name] (str "Hello " name)))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+
+; 함수는 여러 인자를 시퀀스로 취할 수 있습니다.
+(defn count-args [& args]
+ (str "You passed " (count args) " args: " args))
+(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
+
+; 개별적으로 받는 것과, 시퀀스로 취하는 것을 같이 쓸 수 도 있습니다.
+(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"
+
+
+; 맵(Maps)
+;;;;;;;;;;
+
+; 해쉬맵(hash map)과 배열맵(array map)은 공통된 인터페이스를 공유합니다.
+; 해쉬맵은 찾기가 빠르지만, 키의 순서가 유지되지 않습니다.
+(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
+(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
+
+; 배열맵은 여러 연산을 거쳐 자연스레 해쉬맵이 됩니다.
+; 만일 이게 커진다 하더라도, 걱정할 필요가 없습니다.
+
+; 맵은 해쉬가 가능한 타입이라면 어떠한 것이든 키로써 활용이 가능하지만, 보통 키워드를 이용하는 것이 가장 좋습니다.
+; 키워드(Keyword)는 문자열과 비슷하지만, 보다 효율적인 면이 있습니다.
+(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}
+
+; 여기서, 쉽표가 공백으로 취급되며, 아무 일도 하지 않는다는 것을 주목하시기 바랍니다.
+
+; 맵에서 값을 얻어오기 위해선, 함수로써 맵을 호출해야 합니다.
+(stringmap "a") ; => 1
+(keymap :a) ; => 1
+
+; 키워드 역시 맵에서 함수를 얻어올 때 사용할 수 있습니다!
+(:b keymap) ; => 2
+
+; 하지만, 문자열로는 하면 안됩니다.
+;("a" stringmap)
+; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+
+; 없는 값을 얻어오고자 하면, nil이 반환됩니다.
+(stringmap "d") ; => nil
+
+; assoc 를 이용하여 해쉬맵에 새로운 키를 추가할 수 있습니다.
+(def newkeymap (assoc keymap :d 4))
+newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
+
+; 하지만, 변경할 수 없는(immutable) clojure 타입이라는 것을 기억해야 합니다!
+keymap ; => {:a 1, :b 2, :c 3}
+
+; dissoc 를 이용하여 키를 제거할 수 있습니다.
+(dissoc keymap :a :b) ; => {:c 3}
+
+; 쎗(Set:집합)
+;;;;;;
+
+(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
+(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
+
+; conj 로 항목을 추가할 수 있습니다.
+(conj #{1 2 3} 4) ; => #{1 2 3 4}
+
+; disj 로 제거할 수 도 있습니다.
+(disj #{1 2 3} 1) ; => #{2 3}
+
+; 존재하는지 확인할 목적으로, 쎗을 함수로 사용할 수 도 있습니다.
+(#{1 2 3} 1) ; => 1
+(#{1 2 3} 4) ; => nil
+
+; clojure.sets 네임스페이스(namespace)에는 더 많은 함수들이 있습니다.
+
+; 유용한 폼(forms)
+;;;;;;;;;;;;;;;;;
+
+; clojure에선, if 와 매크로(macro)를 가지고,
+; 다른 여러 논리 연산들을 만들 수 있습니다.
+(if false "a" "b") ; => "b"
+(if false "a") ; => nil
+
+; let 을 이용하여 임시적으로 바인딩(binding)을 구축할 수 있습니다.
+(let [a 1 b 2]
+ (> a b)) ; => false
+
+; do 로 문단을 묶을 수 도 있습니다.
+(do
+ (print "Hello")
+ "World") ; => "World" (prints "Hello")
+
+; 함수는 암시적으로 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")
+
+; let 역시 그러합니다.
+(let [name "Urkel"]
+ (print "Saying hello to " name)
+ (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
+
+; 모듈(Modules)
+;;;;;;;;;;;;;;;
+
+; "use" 를 이용하여 module에 있는 모든 함수들을 얻어올 수 있습니다.
+(use 'clojure.set)
+
+; 이제 쎗(set:집합)연산을 사용 할 수 있습니다.
+(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
+(difference #{1 2 3} #{2 3 4}) ; => #{1}
+
+; 함수들 중에 일 부분만을 가져올 수 도 있습니다.
+(use '[clojure.set :only [intersection]])
+
+; require 를 이용하여 모듈을 import할 수 있습니다.
+(require 'clojure.string)
+
+; / 를 이용하여 모듈에 있는 함수를 호출 할 수 있습니다.
+; 여기, clojure.string 라는 모듈에, blank? 라는 함수가 있습니다.
+(clojure.string/blank? "") ; => true
+
+; import시, 모듈에 짧은 이름을 붙여줄 수 있습니다.
+(require '[clojure.string :as str])
+(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
+; (#"" denotes a regular expression literal)
+
+; :require 를 이용하여, 네임스페이스에서 require 를 사용할 수 있습니다.
+; 아레와 같은 방법을 이용하면, 모듈을 quote하지 않아도 됩니다.
+(ns test
+ (:require
+ [clojure.string :as str]
+ [clojure.set :as set]))
+
+; Java
+;;;;;;;;;;;;;;;;;
+
+; Java는 유용한 많은 표준 라이브러리를 가지고 있으며,
+; 이를 어떻게 활용할 수 있는지 알아보도록 하겠습니다.
+
+; import 로 java 모듈을 불러올 수 있습니다.
+(import java.util.Date)
+
+; ns 와 함께 import 를 할 수 도 있습니다.
+(ns test
+ (:import java.util.Date
+ java.util.Calendar))
+
+; 새로운 인스턴스를 만들기 위해선, 클래스 이름 끝에 "."을 찍습니다.
+(Date.) ; <a date object>
+
+; . 을 이용하여 메소드를 호출할 수 있습니다.
+; 아니면, 줄여서 ".메소드"로도 호출 할 수 있습니다.
+(. (Date.) getTime) ; <a timestamp>
+(.getTime (Date.)) ; exactly the same thing.
+
+; / 를 이용하여 정적메소드를 호출 할 수 있습니다.
+(System/currentTimeMillis) ; <a timestamp> (system is always present)
+
+; doto 를 이용하여 상태가 변하는(mutable) 클래스들을 좀 더 편하게(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 는 clojure가 영구적인(persistent) 상태를 다루는 방식입니다.
+; clojure가 이용하는 몇몇 자료형(construct)이 있습니다.
+
+; 가장 단순한 것은 atom 입니다. 초기 값을 넣어보도록 하겠습니다.
+(def my-atom (atom {}))
+
+; swap! 으로 atom을 갱신(update)할 수 있습니다!
+; swap! 은 함수를 인자로 받아, 그 함수에 대해 현재 atom에 들어있는 값을 첫번째 인자로,
+; 나머지를 두번째 인자로 하여 호출합니다.
+(swap! my-atom assoc :a 1) ; Sets my-atom to the result of (assoc {} :a 1)
+(swap! my-atom assoc :b 2) ; Sets my-atom to the result of (assoc {:a 1} :b 2)
+
+; '@' 를 이용하여 atom을 역참조(dereference)하여 값을 얻을 수 있습니다.
+my-atom ;=> Atom<#...> (atom 객체가 반환됩니다.)
+@my-atom ; => {:a 1 :b 2}
+
+; 여기 atom을 이용한 단순한 카운터가 있습니다.
+(def counter (atom 0))
+(defn inc-counter []
+ (swap! counter inc))
+
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+
+@counter ; => 5
+
+; STM을 구성하는 다른 것들에는 ref 와 agent 가 있습니다.
+; Refs: http://clojure.org/refs
+; Agents: http://clojure.org/agents
+```
+
+### 읽어볼거리
+
+부족한 것이 많았지만, 다행히도 채울 수 있는 것들이 많이 있습니다.
+
+Clojure.org에 많은 문서들이 보관되어 있습니다:
+[http://clojure.org/](http://clojure.org/)
+
+Clojuredocs.org는 core 함수들에 대해 다양한 예제와 문서를 보유하고 있습니다:
+[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
+
+4Clojure는 clojure/FP 스킬을 올릴 수 있는 좋은 길입니다:
+[http://www.4clojure.com/](http://www.4clojure.com/)
+
+Clojure-doc.org는 많고 많은 문서들을 보유하고 있습니다:
+[http://clojure-doc.org/](http://clojure-doc.org/)
diff --git a/ko-kr/python-kr.html.markdown b/ko-kr/python-kr.html.markdown
index a131e9a2..ed377a99 100644
--- a/ko-kr/python-kr.html.markdown
+++ b/ko-kr/python-kr.html.markdown
@@ -3,7 +3,7 @@ language: python
category: language
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
-filename: learnpython.py
+filename: learnpython-ko.py
translators:
- ["wikibook", "http://wikibook.co.kr"]
lang: ko-kr
@@ -481,4 +481,4 @@ dir(math)
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20) \ No newline at end of file
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/lua.html.markdown b/lua.html.markdown
index 7325a1cf..369de908 100644
--- a/lua.html.markdown
+++ b/lua.html.markdown
@@ -125,6 +125,9 @@ f = function (x) return x * x end
-- And so are these:
local function g(x) return math.sin(x) end
+local g = function(x) return math.xin(x) end
+-- Equivalent to local function g(x)..., except referring
+-- to g in the function body won't work as expected.
local g; g = function (x) return math.sin(x) end
-- the 'local g' decl makes g-self-references ok.
@@ -133,6 +136,10 @@ local g; g = function (x) return math.sin(x) end
-- Calls with one string param don't need parens:
print 'hello' -- Works fine.
+-- Calls with one table param don't need parens
+-- either (more on tables below):
+print {} -- Works fine too.
+
----------------------------------------------------
-- 3. Tables.
@@ -203,7 +210,7 @@ f2 = {a = 2, b = 3}
metafraction = {}
function metafraction.__add(f1, f2)
- sum = {}
+ local sum = {}
sum.b = f1.b * f2.b
sum.a = f1.a * f2.b + f2.a * f1.b
return sum
@@ -266,7 +273,7 @@ eatenBy = myFavs.animal -- works! thanks, metatable
Dog = {} -- 1.
function Dog:new() -- 2.
- newObj = {sound = 'woof'} -- 3.
+ local newObj = {sound = 'woof'} -- 3.
self.__index = self -- 4.
return setmetatable(newObj, self) -- 5.
end
@@ -301,7 +308,7 @@ mrDog:makeSound() -- 'I say woof' -- 8.
LoudDog = Dog:new() -- 1.
function LoudDog:makeSound()
- s = self.sound .. ' ' -- 2.
+ local s = self.sound .. ' ' -- 2.
print(s .. s .. s)
end
@@ -322,7 +329,7 @@ seymour:makeSound() -- 'woof woof woof' -- 4.
-- If needed, a subclass's new() is like the base's:
function LoudDog:new()
- newObj = {}
+ local newObj = {}
-- set up newObj
self.__index = self
return setmetatable(newObj, self)
diff --git a/matlab.html.markdown b/matlab.html.markdown
index 507e9c85..3bcc4bbc 100644
--- a/matlab.html.markdown
+++ b/matlab.html.markdown
@@ -250,7 +250,22 @@ eig(A) %Eigenvalues and eigenvectors of A
isempty(A) % Tests if array is empty
isequal(A, B) %Tests equality of two arrays
numel(A) %Number of elements in matrix
-
+triu(x) % Returns the upper triangular part of x
+tril(x) % Returns the lower triangular part of x
+cross(A,B) % Returns the cross product of the vectors A and B
+dot(A,B) % Returns the scalar product of the vectors A and B. A and B must be vectors of the same length.
+transpose(A) % Returns the transpose of A
+
+% Common vector functions
+max %largest component
+min %smallest component
+length %length of a vector
+sort %sort in ascending order
+sum %sum of elements
+prod %product of elements
+median %median value
+mean %mean value
+std %standard deviation
```
diff --git a/neat.html.markdown b/neat.html.markdown
new file mode 100644
index 00000000..6a319a7d
--- /dev/null
+++ b/neat.html.markdown
@@ -0,0 +1,299 @@
+---
+
+language: neat
+contributors:
+ - ["Feep", "https://github.com/FeepingCreature"]
+filename: LearnNeat.nt
+
+---
+
+Neat is basically a smaller version of D1 with some experimental syntax and a focus on terseness without losing the basic C-like syntax.
+
+[Read more here.](https://github.com/FeepingCreature/fcc/wiki)
+
+```D
+// single line comments start with //
+/*
+ multiline comments look like this
+*/
+/+
+ or this
+ /+ these can be nested too, same as D +/
++/
+
+// Module name. This has to match the filename/directory.
+module LearnNeat;
+
+// Make names from another module visible in this one.
+import std.file;
+// You can import multiple things at once.
+import std.math, std.util;
+// You can even group up imports!
+import std.(process, socket);
+
+// Global functions!
+void foo() { }
+
+// Main function, same as in C.
+// string[] == "array of strings".
+// "string" is just an alias for char[],
+void main(string[] args) {
+ // Call functions with "function expression".
+ writeln "Hello World";
+ // You can do it like in C too... if you really want.
+ writeln ("Hello World");
+ // Declare a variable with "type identifier"
+ string arg = ("Hello World");
+ writeln arg;
+ // (expression, expression) forms a tuple.
+ // There are no one-value tuples though.
+ // So you can always use () in the mathematical sense.
+ // (string) arg; <- is an error
+
+ /*
+ byte: 8 bit signed integer
+ char: 8 bit UTF-8 byte component.
+ short: 16 bit signed integer
+ int: 32 bit signed integer
+ long: 64 bit signed integer
+
+ float: 32 bit floating point
+ double: 64 bit floating point
+ real: biggest native size floating point (80 bit on x86).
+
+ bool: true or false
+ */
+ int a = 5;
+ bool b = true;
+ // as in C, && and || are short-circuit evaluating.
+ b = b && false;
+ assert(b == false);
+ // "" are "format strings". So $variable will be substituted at runtime
+ // with a formatted version of the variable.
+ writeln "$a";
+ // This will just print $a.
+ writeln `$a`;
+ // you can format expressions with $()
+ writeln "$(2+2)";
+ // Note: there is no special syntax for characters.
+ char c = "a";
+ // Cast values by using type: expression.
+ // There are three kinds of casts:
+ // casts that just specify conversions that would be happening automatically
+ // (implicit casts)
+ float f = float:5;
+ float f2 = 5; // would also work
+ // casts that require throwing away information or complicated computation -
+ // those must always be done explicitly
+ // (conversion casts)
+ int i = int:f;
+ // int i = f; // would not work!
+ // and, as a last attempt, casts that just reinterpret the raw data.
+ // Those only work if the types have the same size.
+ string s = "Hello World";
+ // Arrays are (length, pointer) pairs.
+ // This is a tuple type. Tuple types are (type, type, type).
+ // The type of a tuple expression is a tuple type. (duh)
+ (int, char*) array = (int, char*): s;
+ // You can index arrays and tuples using the expression[index] syntax.
+ writeln "pointer is $(array[1]) and length is $(array[0])";
+ // You can slice them using the expression[from .. to] syntax.
+ // Slicing an array makes another array.
+ writeln "$(s[0..5]) World";
+ // Alias name = expression gives the expression a name.
+ // As opposed to a variable, aliases do not have an address
+ // and can not be assigned to. (Unless the expression is assignable)
+ alias range = 0 .. 5;
+ writeln "$(s[range]) World";
+ // You can iterate over ranges.
+ for int i <- range {
+ write "$(s[i])";
+ }
+ writeln " World";
+ // Note that if "range" had been a variable, it would be 'empty' now!
+ // Range variables can only be iterated once.
+ // The syntax for iteration is "expression <- iterable".
+ // Lots of things are iterable.
+ for char c <- "Hello" { write "$c"; }
+ writeln " World";
+ // For loops are "for test statement";
+ alias test = char d <- "Hello";
+ for test write "$d";
+ writeln " World\t\x05"; // note: escapes work
+ // Pointers: function the same as in C, btw. The usual.
+ // Do note: the pointer star sticks with the TYPE, not the VARIABLE!
+ string* p;
+ assert(p == null); // default initializer
+ p = &s;
+ writeln "$(*p)";
+ // Math operators are (almost) standard.
+ int x = 2 + 3 * 4 << 5;
+ // Note: XOR is "xor". ^ is reserved for exponentiation (once I implement that).
+ int y = 3 xor 5;
+ int z = 5;
+ assert(z++ == 5);
+ assert(++z == 7);
+ writeln "x $x y $y z $z";
+ // As in D, ~ concatenates.
+ string hewo = "Hello " ~ "World";
+ // == tests for equality, "is" tests for identity.
+ assert (hewo == s);
+ assert !(hewo is s);
+ // same as
+ assert (hewo !is s);
+
+ // Allocate arrays using "new array length"
+ int[] integers = new int[] 10;
+ assert(integers.length == 10);
+ assert(integers[0] == 0); // zero is default initializer
+ integers = integers ~ 5; // This allocates a new array!
+ assert(integers.length == 11);
+
+ // This is an appender array.
+ // Instead of (length, pointer), it tracks (capacity, length, pointer).
+ // When you append to it, it will use the free capacity if it can.
+ // If it runs out of space, it reallocates - but it will free the old array automatically.
+ // This makes it convenient for building arrays.
+ int[auto~] appender;
+ appender ~= 2;
+ appender ~= 3;
+ appender.free(); // same as {mem.free(appender.ptr); appender = null;}
+
+ // Scope variables are automatically freed at the end of the current scope.
+ scope int[auto~] someOtherAppender;
+ // This is the same as:
+ int[auto~] someOtherAppender2;
+ onExit { someOtherAppender2.free; }
+
+ // You can do a C for loop too
+ // - but why would you want to?
+ for (int i = 0; i < 5; ++i) { }
+ // Otherwise, for and while are the same.
+ while int i <- 0..4 {
+ assert(i == 0);
+ break; // continue works too
+ } then assert(false); // if we hadn't break'd, this would run at the end
+ // This is the height of loopdom - the produce-test-consume loop.
+ do {
+ int i = 5;
+ } while (i == 5) {
+ assert(i == 5);
+ break; // otherwise we'd go back up to do {
+ }
+
+ // This is a nested function.
+ // Nested functions can access the surrounding function.
+ string returnS() { return s; }
+ writeln returnS();
+
+ // Take the address of a function using &
+ // The type of a global function is ReturnType function(ParameterTypeTuple).
+ void function() foop = &foo;
+
+ // Similarly, the type of a nested function is ReturnType delegate(ParameterTypeTuple).
+ string delegate() returnSp = &returnS;
+ writeln returnSp();
+ // Class member functions and struct member functions also fit into delegate variables.
+ // In general, delegates are functions that carry an additional context pointer.
+ // ("fat pointers" in C)
+
+ // Allocate a "snapshot" with "new delegate".
+ // Snapshots are not closures! I used to call them closures too,
+ // but then my Haskell-using friends yelled at me so I had to stop.
+ // The difference is that snapshots "capture" their surrounding context
+ // when "new" is used.
+ // This allows things like this
+ int delegate(int) add(int a) {
+ int add_a(int b) { return a + b; }
+ // This does not work - the context of add_a becomes invalid
+ // when add returns.
+ // return &add_a;
+ // Instead:
+ return new &add_a;
+ }
+ int delegate(int) dg = add 2;
+ assert (dg(3) == 5);
+ // or
+ assert (((add 2) 3) == 5);
+ // or
+ assert (add 2 3 == 5);
+ // add can also be written as
+ int delegate(int) add2(int a) {
+ // this is an implicit, nameless nested function.
+ return new λ(int b) { return a + b; }
+ }
+ // or even
+ auto add3(int a) { return new λ(int b) -> a + b; }
+ // hahahaaa
+ auto add4 = λ(int a) -> new λ(int b) -> a + b;
+ assert(add4 2 3 == 5);
+ // If your keyboard doesn't have a λ (you poor sod)
+ // you can use \ too.
+ auto add5 = \(int a) -> new \(int b) -> a + b;
+ // Note!
+ auto nestfun = λ() { } // There is NO semicolon needed here!
+ // "}" can always substitute for "};".
+ // This provides syntactic consistency with built-in statements.
+
+
+ // This is a class.
+ // Note: almost all elements of Neat can be used on the module level
+ // or just as well inside a function.
+ class C {
+ int a;
+ void writeA() { writeln "$a"; }
+ // It's a nested class - it exists in the context of main().
+ // so if you leave main(), any instances of C become invalid.
+ void writeS() { writeln "$s"; }
+ }
+ C cc = new C;
+ // cc is a *reference* to C. Classes are always references.
+ cc.a = 5; // Always used for property access.
+ auto ccp = &cc;
+ (*ccp).a = 6;
+ // or just
+ ccp.a = 7;
+ cc.writeA();
+ cc.writeS(); // to prove I'm not making things up
+ // Interfaces work same as in D, basically. Or Java.
+ interface E { void doE(); }
+ // Inheritance works same as in D, basically. Or Java.
+ class D : C, E {
+ override void writeA() { writeln "hahahahaha no"; }
+ override void doE() { writeln "eeeee"; }
+ // all classes inherit from Object. (toString is defined in Object)
+ override string toString() { return "I am a D"; }
+ }
+ C cd = new D;
+ // all methods are always virtual.
+ cd.writeA();
+ E e = E:cd; // dynamic class cast!
+ e.doE();
+ writeln "$e"; // all interfaces convert to Object implicitly.
+
+ // Templates!
+ // Templates are parameterized namespaces, taking a type as a parameter.
+ template Templ(T) {
+ alias hi = 5, hii = 8;
+ // Templates always have to include something with the same name as the template
+ // - this will become the template's _value_.
+ // Static ifs are evaluated statically, at compile-time.
+ // Because of this, the test has to be a constant expression,
+ // or something that can be optimized to a constant.
+ static if (types-equal (T, int)) {
+ alias Templ = hi;
+ } else {
+ alias Templ = hii;
+ }
+ }
+ assert(Templ!int == 5);
+ assert(Templ!float == 8);
+}
+```
+
+## Topics Not Covered
+
+ * Extended iterator types and expressions
+ * Standard library
+ * Conditions (error handling)
+ * Macros
diff --git a/objective-c.html.markdown b/objective-c.html.markdown
index 9e9f43e7..1ed0ed58 100644
--- a/objective-c.html.markdown
+++ b/objective-c.html.markdown
@@ -80,7 +80,7 @@ int main (int argc, const char * argv[])
NSLog(@"%f", piFloat);
NSNumber *piDoubleNumber = @3.1415926535;
- piDouble = [piDoubleNumber doubleValue];
+ double piDouble = [piDoubleNumber doubleValue];
NSLog(@"%f", piDouble);
// BOOL literals
@@ -160,7 +160,7 @@ int main (int argc, const char * argv[])
int jj;
for (jj=0; jj < 4; jj++)
{
- NSLog(@"%d,", jj++);
+ NSLog(@"%d,", jj);
} // => prints "0,"
// "1,"
// "2,"
@@ -223,7 +223,7 @@ int main (int argc, const char * argv[])
// }
// -/+ (type) Method declarations;
// @end
-@interface MyClass : NSObject <MyCustomProtocol>
+@interface MyClass : NSObject <MyProtocol>
{
int count;
id data;
@@ -241,14 +241,14 @@ int main (int argc, const char * argv[])
+ (NSString *)classMethod;
// - for instance method
-- (NSString *)instanceMethodWithParmeter:(NSString *)string;
+- (NSString *)instanceMethodWithParameter:(NSString *)string;
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
@end
// Implement the methods in an implementation (MyClass.m) file:
-@implementation UserObject
+@implementation MyClass
// Call when the object is releasing
- (void)dealloc
@@ -271,7 +271,7 @@ int main (int argc, const char * argv[])
return [[self alloc] init];
}
-- (NSString *)instanceMethodWithParmeter:(NSString *)string
+- (NSString *)instanceMethodWithParameter:(NSString *)string
{
return @"New string";
}
diff --git a/php.html.markdown b/php.html.markdown
index 0caa07b6..1952d833 100644
--- a/php.html.markdown
+++ b/php.html.markdown
@@ -107,7 +107,7 @@ echo 'This string ' . 'is concatenated';
/********************************
* Constants
*/
-
+
// A constant is defined by using define()
// and can never be changed during runtime!
@@ -143,7 +143,7 @@ echo $array[0]; // => "One"
$array[] = 'Four';
// Remove element from array
-unset($array[3]);
+unset($array[3]);
/********************************
* Output
@@ -455,8 +455,10 @@ class MyClass
// Static variables and their visibility
public static $publicStaticVar = 'publicStatic';
- private static $privateStaticVar = 'privateStatic'; // Accessible within the class only
- protected static $protectedStaticVar = 'protectedStatic'; // Accessible from the class and subclasses
+ // Accessible within the class only
+ private static $privateStaticVar = 'privateStatic';
+ // Accessible from the class and subclasses
+ protected static $protectedStaticVar = 'protectedStatic';
// Properties must declare their visibility
public $property = 'public';
@@ -476,14 +478,15 @@ class MyClass
print 'MyClass';
}
- //final keyword would make a function unoverridable
+ //final keyword would make a function unoverridable
final function youCannotOverrideMe()
{
}
/*
-Declaring class properties or methods as static makes them accessible without needing an instantiation of the class.
-A property declared as static can not be accessed with an instantiated class object (though a static method can).
+ * Declaring class properties or methods as static makes them accessible without
+ * needing an instantiation of the class. A property declared as static can not
+ * be accessed with an instantiated class object (though a static method can).
*/
public static function myStaticMethod()
@@ -674,10 +677,14 @@ $cls = new SomeOtherNamespace\MyClass();
## More Information
-Visit the [official PHP documentation](http://www.php.net/manual/) for reference and community input.
+Visit the [official PHP documentation](http://www.php.net/manual/) for reference
+and community input.
-If you're interested in up-to-date best practices, visit [PHP The Right Way](http://www.phptherightway.com/).
+If you're interested in up-to-date best practices, visit
+[PHP The Right Way](http://www.phptherightway.com/).
-If you're coming from a language with good package management, check out [Composer](http://getcomposer.org/).
+If you're coming from a language with good package management, check out
+[Composer](http://getcomposer.org/).
-For common standards, visit the PHP Framework Interoperability Group's [PSR standards](https://github.com/php-fig/fig-standards).
+For common standards, visit the PHP Framework Interoperability Group's
+[PSR standards](https://github.com/php-fig/fig-standards).
diff --git a/pt-br/erlang-pt.html.markdown b/pt-br/erlang-pt.html.markdown
new file mode 100644
index 00000000..6a86aafc
--- /dev/null
+++ b/pt-br/erlang-pt.html.markdown
@@ -0,0 +1,253 @@
+---
+language: erlang
+filename: learnerlang-pt.erl
+contributors:
+ - ["Giovanni Cappellotto", "http://www.focustheweb.com/"]
+ - ["Guilherme Heuser Prestes", "http://twitter.com/gprestes"]
+lang: pt-br
+---
+
+```erlang
+% Símbolo de porcento começa comentários de uma linha.
+
+%% Dois caracteres de porcento devem ser usados para comentar funções.
+
+%%% Três caracteres de porcento devem ser usados para comentar módulos.
+
+% Nós usamos três tipos de pontuação em Erlang.
+% Vírgulas (`,`) separam argumentos em chamadas de função, construtores de
+% dados, e padrões.
+% Pontos finais (`.`) separam totalmente funções e expressões no prompt.
+% Ponto e vírgulas (`;`) separam cláusulas. Nós encontramos cláusulas em
+% vários contextos: definições de função e em expressões com `case`, `if`,
+% `try..catch` e `receive`.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 1. Variáveis e casamento de padrões.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Num = 42. % Todos nomes de variáveis devem começar com uma letra maiúscula.
+
+% Erlang tem atribuição única de variáveis, se você tentar atribuir um valor
+% diferente à variável `Num`, você receberá um erro.
+Num = 43. % ** exception error: no match of right hand side value 43
+
+% Na maioria das linguagens, `=` denota um comando de atribuição. Em Erlang, no
+% entanto, `=` denota uma operação de casamento de padrão. `Lhs = Rhs` realmente
+% significa isso: avalia o lado direito (Rhs), e então casa o resultado com o
+% padrão no lado esquerdo (Lhs).
+Num = 7 * 6.
+
+% Número de ponto flutuante.
+Pi = 3.14159.
+
+% Átomos são usados para representar diferentes valores constantes não
+% numéricos. Átomos começam com letras minúsculas seguidas por uma sequência de
+% caracteres alfanuméricos ou sinais de subtraço (`_`) ou arroba (`@`).
+Hello = hello.
+OtherNode = example@node.
+
+% Átomos com valores alfanuméricos podem ser escritos colocando aspas por fora
+% dos átomos.
+AtomWithSpace = 'some atom with space'.
+
+% Tuplas são similares a structs em C.
+Point = {point, 10, 45}.
+
+% Se nós queremos extrair alguns valores de uma tupla, nós usamos o operador `=`.
+{point, X, Y} = Point. % X = 10, Y = 45
+
+% Nós podemos usar `_` para ocupar o lugar de uma variável que não estamos interessados.
+% O símbolo `_` é chamado de variável anônima. Ao contrário de variáveis regulares,
+% diversas ocorrências de _ no mesmo padrão não precisam se amarrar ao mesmo valor.
+Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
+{_, {_, {_, Who}, _}, _} = Person. % Who = joe
+
+% Nós criamos uma lista colocando valores separados por vírgula entre colchetes.
+% Cada elemento de uma lista pode ser de qualquer tipo.
+% O primeiro elemento de uma lista é a cabeça da lista. Se removermos a cabeça
+% da lista, o que sobra é chamado de cauda da lista.
+ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
+
+% Se `T` é uma lista, então `[H|T]` também é uma lista, com cabeça `H` e cauda `T`.
+% A barra vertical (`|`) separa a cabeça de uma lista de sua cauda.
+% `[]` é uma lista vazia.
+% Podemos extrair elementos de uma lista com uma operação de casamento de
+% padrão. Se temos uma lista não-vazia `L`, então a expressão `[X|Y] = L`, onde
+% `X` e `Y` são variáveis desamarradas, irá extrair a cabeça de uma lista para
+% `X` e a cauda da lista para `Y`.
+[FirstThing|OtherThingsToBuy] = ThingsToBuy.
+% FirstThing = {apples, 10}
+% OtherThingsToBuy = {pears, 6}, {milk, 3}
+
+% Não existe o tipo string em Erlang. Strings são somente listas de inteiros.
+% Strings são representadas dentro de aspas duplas (`"`).
+Name = "Hello".
+[72, 101, 108, 108, 111] = "Hello".
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 2. Programação sequencial.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Módulos são a unidade básica de código em Erlang. Todas funções que
+% escrevemos são armazenadas em módulos. Módulos são armazenados em arquivos
+% com extensão `.erl`.
+% Módulos devem ser compilados antes que o código possa ser rodado. Um módulo
+% compilado tem a extensão `.beam`.
+-module(geometry).
+-export([area/1]). % lista de funções exportadas de um módulo.
+
+% A função `area` consiste de duas cláusulas. As cláusulas são separadas por um
+% ponto e vírgula, e a cláusula final é terminada por um ponto final.
+% Cada cláusula tem uma cabeça em um corpo; a cabeça consiste de um nome de
+% função seguido por um padrão (entre parêntesis), e o corpo consiste de uma
+% sequência de expressões, que são avaliadas se o padrão na cabeça é um par bem
+% sucedido dos argumentos da chamada. Os padrões são casados na ordem que
+% aparecem na definição da função.
+area({rectangle, Width, Ht}) -> Width * Ht;
+area({circle, R}) -> 3.14159 * R * R.
+
+% Compila o código no arquivo geometry.erl.
+c(geometry). % {ok,geometry}
+
+% Nós precisamos incluir o nome do módulo junto com o nome da função de maneira
+% a identificar exatamente qual função queremos chamar.
+geometry:area({rectangle, 10, 5}). % 50
+geometry:area({circle, 1.4}). % 6.15752
+
+% Em Erlang, duas funções com o mesmo nome e diferentes aridades (números de
+% argumentos) no mesmo módulo representam funções totalmente diferentes.
+-module(lib_misc).
+-export([sum/1]). % exporta a função `sum` de aridade 1 aceitando um argumento: lista de inteiros.
+sum(L) -> sum(L, 0).
+sum([], N) -> N;
+sum([H|T], N) -> sum(T, H+N).
+
+% Funs são funções "anônimas". Elas são chamadas desta maneira por que elas não
+% têm nome. No entanto podem ser atribuídas a variáveis.
+Double = fun(X) -> 2*X end. % `Double` aponta para uma função anônima com referência: #Fun<erl_eval.6.17052888>
+Double(2). % 4
+
+% Funções aceitam funs como seus argumentos e podem retornar funs.
+Mult = fun(Times) -> ( fun(X) -> X * Times end ) end.
+Triple = Mult(3).
+Triple(5). % 15
+
+% Compreensão de lista são expressões que criam listas sem precisar usar funs,
+% maps, ou filtros.
+% A notação `[F(X) || X <- L]` significa "a lista de `F(X)` onde `X` é tomada
+% da lista `L`."
+L = [1,2,3,4,5].
+[2*X || X <- L]. % [2,4,6,8,10]
+% Uma compreensão de lista pode ter geradores e filtros que selecionam
+% subconjuntos dos valores gerados.
+EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
+
+% Sentinelas são contruções que podemos usar para incrementar o poder de
+% casamento de padrão. Usando sentinelas, podemos executar testes simples e
+% comparações nas variáveis em um padrão.
+% Você pode usar sentinelas nas cabeças das definições de função onde eles são
+% introduzidos pela palavra-chave `when`, ou você pode usá-los em qualquer
+% lugar na linguagem onde uma expressão é permitida.
+max(X, Y) when X > Y -> X;
+max(X, Y) -> Y.
+
+% Um sentinela é uma série de expressões sentinelas, separadas por
+% vírgulas (`,`).
+% O sentinela `GuardExpr1, GuardExpr2, ..., GuardExprN` é verdadeiro se todas
+% expressões sentinelas `GuardExpr1, GuardExpr2, ...` forem verdadeiras.
+is_cat(A) when is_atom(A), A =:= cat -> true;
+is_cat(A) -> false.
+is_dog(A) when is_atom(A), A =:= dog -> true;
+is_dog(A) -> false.
+
+% Uma `sequência sentinela` é um sentinela ou uma série de sentinelas separados
+% por ponto e vírgula (`;`). A sequência sentinela `G1; G2; ...; Gn` é
+% verdadeira se pelo menos um dos sentinelas `G1, G2, ...` for verdadeiro.
+is_pet(A) when is_dog(A); is_cat(A) -> true;
+is_pet(A) -> false.
+
+% Registros provêem um método para associar um nome com um elemento particular
+% em uma tupla.
+% Definições de registro podem ser incluídas em arquivos fonte Erlang ou em
+% arquivos com extensão `.hrl`, que então são incluídos em arquivos fonte Erlang.
+-record(todo, {
+ status = reminder, % Default value
+ who = joe,
+ text
+}).
+
+% Nós temos que ler definições de registro no prompt antes que possamos definir
+% um registro. Nós usamos a função de prompt `rr` (abreviação de read records)
+% para fazer isso.
+rr("records.hrl"). % [todo]
+
+% Criando e atualizando registros:
+X = #todo{}.
+% #todo{status = reminder, who = joe, text = undefined}
+X1 = #todo{status = urgent, text = "Fix errata in book"}.
+% #todo{status = urgent, who = joe, text = "Fix errata in book"}
+X2 = X1#todo{status = done}.
+% #todo{status = done,who = joe,text = "Fix errata in book"}
+
+% Expressões `case`.
+% A função `filter` retorna uma lista de todos elementos `X` em uma lista `L`
+% para qual `P(X)` é verdadeiro.
+filter(P, [H|T]) ->
+ case P(H) of
+ true -> [H|filter(P, T)];
+ false -> filter(P, T)
+ end;
+filter(P, []) -> [].
+filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4]
+
+% Expressões `if`.
+max(X, Y) ->
+ if
+ X > Y -> X;
+ X < Y -> Y;
+ true -> nil;
+ end.
+
+% Aviso: pelo menos um dos sentinelas na expressão `if` deve retornar
+% verdadeiro; Caso contrário, uma exceção será levantada.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 3. Exceções.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Exceções são levantadas pelo sistema quando erros internos são encontrados ou
+% explicitamente em código pela chamada `throw(Exception)`, `exit(Exception)`
+% ou `erlang:error(Exception)`.
+generate_exception(1) -> a;
+generate_exception(2) -> throw(a);
+generate_exception(3) -> exit(a);
+generate_exception(4) -> {'EXIT', a};
+generate_exception(5) -> erlang:error(a).
+
+% Erlang tem dois métodos para capturar uma exceção. Uma é encapsular a chamada
+% para a função que levanta uma exceção dentro de uma expressão `try...catch`.
+catcher(N) ->
+ try generate_exception(N) of
+ Val -> {N, normal, Val}
+ catch
+ throw:X -> {N, caught, thrown, X};
+ exit:X -> {N, caught, exited, X};
+ error:X -> {N, caught, error, X}
+ end.
+
+% O outro é encapsular a chamada em uma expressão `catch`. Quando você captura
+% uma exceção, é convertida em uma tupla que descreve o erro.
+catcher(N) -> catch generate_exception(N).
+
+```
+
+## Referências
+
+* ["Learn You Some Erlang for great good!"](http://learnyousomeerlang.com/)
+* ["Programming Erlang: Software for a Concurrent World" by Joe Armstrong](http://pragprog.com/book/jaerlang2/programming-erlang)
+* [Erlang/OTP Reference Documentation](http://www.erlang.org/doc/)
+* [Erlang - Programming Rules and Conventions](http://www.erlang.se/doc/programming_rules.shtml)
+
diff --git a/pt-br/go-pt.html.markdown b/pt-br/go-pt.html.markdown
new file mode 100644
index 00000000..41a02c37
--- /dev/null
+++ b/pt-br/go-pt.html.markdown
@@ -0,0 +1,308 @@
+---
+name: Go
+category: language
+language: Go
+filename: learngo-pt.go
+lang: pt-pt
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+translators:
+ - ["Nuno Antunes", "https://github.com/ntns"]
+---
+
+A linguagem Go foi criada a partir da necessidade de ver trabalho feito. Não
+é a última moda em ciências da computação, mas é a mais recente e mais rápida
+forma de resolver os problemas do mundo real.
+
+Tem conceitos familiares de linguagens imperativas com tipagem estática. É
+rápida a compilar e rápida a executar, acrescentando mecanismos de concorrência
+fáceis de entender para tirar partido dos CPUs multi-core de hoje em dia, e tem
+recursos para ajudar com a programação em larga escala.
+
+Go vem com uma biblioteca padrão exaustiva e uma comunidade entusiasta.
+
+```go
+// Comentário de uma linha
+/* Comentário de
+ várias linhas */
+
+// A cláusula package aparece no início de cada arquivo.
+// Main é um nome especial declarando um executável ao invés de uma biblioteca.
+package main
+
+// A cláusula Import declara os pacotes referenciados neste arquivo.
+import (
+ "fmt" // Um pacote da biblioteca padrão da linguagem Go
+ "net/http" // Sim, um servidor web!
+ "strconv" // Conversão de Strings
+)
+
+// Definição de uma função. Main é especial. É o ponto de entrada para o
+// programa executável. Goste-se ou não, a linguagem Go usa chavetas.
+func main() {
+ // A função Println envia uma linha para stdout.
+ // É necessário qualifica-la com o nome do pacote, fmt.
+ fmt.Println("Olá Mundo!")
+
+ // Chama outra função dentro deste pacote.
+ beyondHello()
+}
+
+// As funções declaram os seus parâmetros dentro de parênteses. Se a função
+// não receber quaisquer parâmetros, é obrigatório usar parênteses vazios.
+func beyondHello() {
+ var x int // Declaração de variável. Tem de ser declarada antes de usar.
+ x = 3 // Atribuição de variável.
+ // Declarações "curtas" usam := para inferir o tipo, declarar e atribuir.
+ y := 4
+ sum, prod := learnMultiple(x, y) // a função retorna dois valores
+ fmt.Println("soma:", sum, "produto:", prod)
+ learnTypes() // continuar a aprender!
+}
+
+// As funções podem receber parâmetros e retornar (vários!) valores.
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // retorna dois valores
+}
+
+// Alguns tipos e literais básicos.
+func learnTypes() {
+ // Declarações "curtas" geralmente servem para o que pretendemos.
+ s := "Aprender Go!" // tipo string
+
+ s2 := `Uma string em "bruto"
+pode incluir quebras de linha.` // mesmo tipo string
+
+ // literal não-ASCII. A linguagem Go utiliza de raiz a codificação UTF-8.
+ g := 'Σ' // tipo rune, um alias para uint32, que contém um código unicode
+
+ f := 3.14195 // float64, número de vírgula flutuante de 64bit (IEEE-754)
+ c := 3 + 4i // complex128, representado internamente com dois float64s
+
+ // Declaração de variáveis, com inicialização.
+ var u uint = 7 // inteiro sem sinal, tamanho depende da implementação do Go
+ var pi float32 = 22. / 7
+
+ // Sintaxe de conversão de tipo, com declaração "curta".
+ n := byte('\n') // byte é um alias para uint8
+
+ // Os arrays têm tamanho fixo e definido antes da compilação.
+ var a4 [4]int // um array de 4 ints, inicializado com ZEROS
+ a3 := [...]int{3, 1, 5} // um array de 3 ints, inicializado como mostrado
+
+ // As slices têm tamanho dinâmico. Os arrays e as slices têm cada um as
+ // suas vantagens mas o uso de slices é muito mais comum.
+ s3 := []int{4, 5, 9} // compare com a3. sem reticências aqui
+ s4 := make([]int, 4) // aloca uma slice de 4 ints, inicializada com ZEROS
+ var d2 [][]float64 // declaração apenas, nada é alocado
+ bs := []byte("uma slice") // sintaxe de conversão de tipos
+
+ p, q := learnMemory() // learnMemory retorna dois apontadores para int.
+ fmt.Println(*p, *q) // * segue um apontador. isto imprime dois ints.
+
+ // Os maps são um tipo de matriz associativa, semelhante aos tipos hash
+ // ou dictionary que encontramos noutras linguagens.
+ m := map[string]int{"três": 3, "quatro": 4}
+ m["um"] = 1
+
+ // As variáveis não usadas são um erro em Go.
+ // O traço inferior permite "usar" uma variável, mas descarta o seu valor.
+ _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
+ // Enviar para o stdout conta como utilização de uma variável.
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl()
+}
+
+// A linguagem Go é totalmente garbage collected. Tem apontadores mas não
+// permite que os apontadores sejam manipulados com aritmética. Pode-se cometer
+// um erro com um apontador nulo, mas não por incrementar um apontador.
+func learnMemory() (p, q *int) {
+ // A função retorna os valores p e q, que são do tipo apontador para int.
+ p = new(int) // a função new aloca memória, neste caso para um int.
+ // O int alocado é inicializado com o valor 0, p deixa de ser nil.
+ s := make([]int, 20) // alocar 20 ints como um único bloco de memória
+ s[3] = 7 // atribui o valor 7 a um deles
+ r := -2 // declarar outra variável local
+ return &s[3], &r // & obtém o endereço de uma variável.
+}
+
+func expensiveComputation() int {
+ return 1e6
+}
+
+func learnFlowControl() {
+ // As instruções if exigem o uso de chavetas, e não requerem parênteses.
+ if true {
+ fmt.Println("eu avisei-te")
+ }
+ // A formatação do código-fonte é "estandardizada" através do comando
+ // da linha de comandos "go fmt."
+ if false {
+ // reclamar
+ } else {
+ // exultar
+ }
+ // Preferir o uso de switch em vez de ifs em cadeia.
+ x := 1
+ switch x {
+ case 0:
+ case 1:
+ // os cases não fazem "fall through"
+ case 2:
+ // esta linha só é executada se e só se x=2
+ }
+ // Tal como a instrução if, a instrução for não usa parênteses.
+ for x := 0; x < 3; x++ { // x++ é uma instrução, nunca uma expressão
+ fmt.Println("iteração", x)
+ }
+ // note que, x == 1 aqui.
+
+ // A instrução for é a única para ciclos, mas assume várias formas.
+ for { // ciclo infinito
+ break // brincadeirinha
+ continue // nunca executado
+ }
+ // O uso de := numa instrução if permite criar uma variável local,
+ // que existirá apenas dentro do bloco if.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // As funções podem ser closures.
+ xBig := func() bool {
+ return x > 100 // referencia x, declarado acima da instrução switch.
+ }
+ fmt.Println("xBig:", xBig()) // true (1e6 é o último valor de x)
+ x /= 1e5 // agora temos x == 10
+ fmt.Println("xBig:", xBig()) // false
+
+ // Quando for mesmo necessário, pode usar o velho goto.
+ goto love
+love:
+
+ learnInterfaces() // Mais coisas interessantes chegando!
+}
+
+// Define Stringer como uma interface consistindo de um método, String.
+type Stringer interface {
+ String() string
+}
+
+// Define pair como uma struct com dois campos ints chamados x e y.
+type pair struct {
+ x, y int
+}
+
+// Define um método para o tipo pair. O tipo pair implementa agora a
+// interface Stringer.
+func (p pair) String() string { // p é chamado de "receptor"
+ // Sprintf é outra função pública no pacote fmt.
+ // Uso de pontos para referenciar os campos de p.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // Uma struct pode ser inicializada com os valores dos seus campos dentro
+ // de chavetas, seguindo a mesma ordem com que os campos foram definidos.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // chama o método String de p, que tem tipo pair.
+ var i Stringer // declara i do tipo interface Stringer.
+ i = p // válido, porque pair implementa Stringer
+ // Chama o método String de i, que tem tipo Stringer. Mesmo que acima.
+ fmt.Println(i.String())
+
+ // As funções no pacote fmt chamam o método String para pedir a um objecto
+ // uma representação textual de si mesmo.
+ fmt.Println(p) // mesmo que acima. Println chama o método String.
+ fmt.Println(i) // mesmo que acima.
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // ", ok" forma idiomática usada para saber se algo funcionou ou não.
+ m := map[int]string{3: "três", 4: "quatro"}
+ if x, ok := m[1]; !ok { // ok vai ser false porque 1 não está no map m.
+ fmt.Println("ninguem lá")
+ } else {
+ fmt.Print(x) // x seria o valor, se 1 estivesse no map.
+ }
+ // Um valor de erro comunica mais informação sobre o problema.
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ descarta o valor
+ // imprime "strconv.ParseInt: parsing "non-int": invalid syntax"
+ fmt.Println(err)
+ }
+ // Vamos revisitar as interfaces um pouco mais tarde. Entretanto,
+ learnConcurrency()
+}
+
+// c é um channel, um objecto para comunicação concurrency-safe.
+func inc(i int, c chan int) {
+ c <- i + 1 // <- é operador "enviar" quando um channel aparece à esquerda.
+}
+
+// Vamos usar a função inc para incrementar números de forma concorrente.
+func learnConcurrency() {
+ // A mesma função make usada anteriormente para alocar uma slice.
+ // Make aloca e inicializa slices, maps, e channels.
+ c := make(chan int)
+ // Inicia três goroutines concorrentes. Os números serão incrementados de
+ // forma concorrente, talvez em paralelo se a máquina for capaz e estiver
+ // configurada correctamente. As três goroutines enviam para o mesmo canal.
+ go inc(0, c) // go é a instrução para iniciar uma goroutine.
+ go inc(10, c)
+ go inc(-805, c)
+ // Lê três resultados do channel c e imprime os seus valores.
+ // Não se pode dizer em que ordem os resultados vão chegar!
+ fmt.Println(<-c, <-c, <-c) // channel na direita, <- é operador "receptor".
+
+ cs := make(chan string) // outro channel, este lida com strings.
+ cc := make(chan chan string) // channel que lida com channels de strings.
+ go func() { c <- 84 }() // inicia uma goroutine para enviar um valor
+ go func() { cs <- "palavroso" }() // outra vez, para o channel cs desta vez
+ // A instrução select tem uma sintaxe semelhante à instrução switch mas
+ // cada caso envolve uma operação com channels. Esta instrução seleciona,
+ // de forma aleatória, um caso que esteja pronto para comunicar.
+ select {
+ case i := <-c: // o valor recebido pode ser atribuído a uma variável
+ fmt.Printf("é um %T", i)
+ case <-cs: // ou o valor recebido pode ser descartado
+ fmt.Println("é uma string")
+ case <-cc: // channel vazio, não se encontra pronto para comunicar.
+ fmt.Println("não aconteceu")
+ }
+ // Neste ponto um valor foi recebido de um dos channels c ou cs. Uma das
+ // duas goroutines iniciadas acima completou, a outra continua bloqueada.
+
+ learnWebProgramming() // Go faz. Você quer faze-lo também.
+}
+
+// Basta apenas uma função do pacote http para iniciar um servidor web.
+func learnWebProgramming() {
+ // O primeiro parâmetro de ListenAndServe é o endereço TCP onde escutar.
+ // O segundo parâmetro é uma interface, especificamente http.Handler.
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // não ignorar erros
+}
+
+// Tornar pair um http.Handler ao implementar o seu único método, ServeHTTP.
+func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // Servir dados com um método de http.ResponseWriter
+ w.Write([]byte("Aprendeu Go em Y minutos!"))
+}
+```
+
+## Leitura Recomendada
+
+A principal fonte de informação é o [web site oficial Go](http://golang.org/).
+Lá é possível seguir o tutorial, experimentar de forma iterativa, e ler muito.
+
+A própria especificação da linguagem é altamente recomendada. É fácil de ler e
+incrivelmente curta (em relação ao que é habitual hoje em dia).
+
+Na lista de leitura para os aprendizes de Go deve constar o [código fonte da
+biblioteca padrão](http://golang.org/src/pkg/). Exaustivamente documentado, é
+a melhor demonstração de código fácil de ler e de perceber, do estilo Go, e da
+sua escrita idiomática. Ou então clique no nome de uma função na [documentação]
+(http://golang.org/pkg/) e veja o código fonte aparecer!
+
diff --git a/pt-pt/git-pt.html.markdown b/pt-pt/git-pt.html.markdown
new file mode 100644
index 00000000..213f1ad3
--- /dev/null
+++ b/pt-pt/git-pt.html.markdown
@@ -0,0 +1,414 @@
+---
+category: tool
+tool: git
+lang: pt-pt
+filename: LearnGit.txt
+contributors:
+ - ["Rafael Jegundo", "http://rafaeljegundo.github.io/"]
+---
+
+Git é um sistema distribuido de gestão para código fonte e controlo de versões.
+
+Funciona através de uma série de registos de estado do projecto e usa esse
+registo para permitir funcionalidades de versionamento e gestão de código
+fonte.
+
+## Conceitos de versionamento
+
+### O que é controlo de versões
+
+Controlo de versões (*source control*) é um processo de registo de alterações
+a um ficheiro ou conjunto de ficheiros ao longo do tempo.
+
+### Controlo de versões: Centralizado VS Distribuido
+
+* Controlo de versões centralizado foca-se na sincronização, registo e *backup*
+de ficheiros.
+* Controlo de versões distribuido foca-se em partilhar alterações. Cada
+alteração é associada a um *id* único.
+* Sistemas distribuidos não têm estrutura definida. É possivel ter um sistema
+centralizado ao estilo SVN usando git.
+
+[Informação adicional (EN)](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
+
+### Porquê usar git?
+
+* Permite trabalhar offline.
+* Colaborar com outros é fácil!
+* Criar *branches* é fácil!
+* Fazer *merge* é fácil!
+* Git é rápido.
+* Git é flexivel.
+
+## Git - Arquitectura
+
+
+### Repositório
+
+Um conjunto de ficheiros, directórios, registos históricos, *commits* e
+referências. Pode ser imaginado como uma estrutura de dados de código fonte
+com a particularidade de cada elemento do código fonte permitir acesso ao
+histórico das suas alterações, entre outras coisas.
+
+Um repositório git é constituido pelo directório .git e a *working tree*
+
+### Directório .git (componente do repositório)
+
+O repositório .git contém todas as configurações, *logs*, *branches*,
+referências e outros.
+
+[Lista detalhada (EN)](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
+
+### *Working Tree* (componente do repositório)
+
+Isto é basicamente os directórios e ficheiros do repositório. É frequentemente
+referido como o directório do projecto.
+
+### *Index* (componente do directório .git)
+
+O *Index* é a camada de interface no git. Consistente num elemento que separa
+o directório do projecto do repositório git. Isto permite aos programadores um
+maior controlo sobre o que é registado no repositório git.
+
+### *Commit*
+
+Um *commit** de git é um registo de um cojunto de alterações ou manipulações
+no nos ficheiros do projecto.
+Por exemplo, ao adicionar cinco ficheiros e remover outros 2, estas alterações
+serão gravadas num *commit* (ou registo). Este *commit* pode então ser enviado
+para outros repositórios ou não!
+
+### *Branch*
+
+Um *branch* é essencialmente uma referência que aponta para o último *commit*
+efetuado. à medida que são feitos novos commits, esta referência é atualizada
+automaticamente e passa a apontar para o commit mais recente.
+
+### *HEAD* e *head* (componentes do directório .git)
+
+*HEAD* é a referência que aponta para o *branch* em uso. Um repositório só tem
+uma *HEAD* activa.
+*head* é uma referência que aponta para qualquer *commit*. Um repositório pode
+ter um número indefinido de *heads*
+
+### Recursos conceptuais (EN)
+
+* [Git para Cientistas de Computação](http://eagain.net/articles/git-for-computer-scientists/)
+* [Git para Designers](http://hoth.entp.com/output/git_for_designers.html)
+
+## Comandos
+
+### *init*
+
+Cria um repositório Git vazio. As definições, informação guardada e outros do
+repositório git são guardados num directório (pasta) denominado ".git".
+
+```bash
+$ git init
+```
+
+### *config*
+
+Permite configurar as definições, sejam as definições do repositório, sistema
+ou configurações globais.
+
+```bash
+# Imprime & Define Algumas Variáveis de Configuração Básicas (Global)
+$ git config --global user.email
+$ git config --global user.name
+
+$ git config --global user.email "MyEmail@Zoho.com"
+$ git config --global user.name "My Name"
+```
+
+[Aprenda Mais Sobre git config. (EN)](http://git-scm.com/docs/git-config)
+
+### help
+
+Para aceder rapidamente a um guia extremamente detalhada sobre cada comando.
+Ou para dar apenas uma lembraça rápida de alguma semântica.
+
+```bash
+# Ver rapidamente os comandos disponiveis
+$ git help
+
+# Ver todos os comandos disponiveis
+$ git help -a
+
+# Requerer *help* sobre um comando especifico - manual de utilizador
+# git help <command_here>
+$ git help add
+$ git help commit
+$ git help init
+```
+
+### status
+
+Apresenta as diferenças entre o ficheiro *index* (no fundo a versão corrente
+do repositório) e o *commit* da *HEAD* atual.
+
+
+```bash
+# Apresenta o *branch*, ficheiros não monitorizados, alterações e outras
+# difereças
+$ git status
+
+# Para aprender mais detalhes sobre git *status*
+$ git help status
+```
+
+### add
+
+Adiciona ficheiros ao repositório corrente. Se os ficheiros novos não forem
+adicionados através de `git add` ao repositório, então eles não serão
+incluidos nos commits!
+
+```bash
+# adiciona um ficheiro no directório do project atual
+$ git add HelloWorld.java
+
+# adiciona um ficheiro num sub-directório
+$ git add /path/to/file/HelloWorld.c
+
+# permite usar expressões regulares!
+$ git add ./*.java
+```
+
+### branch
+
+Gere os *branches*. É possível ver, editar, criar e apagar branches com este
+comando.
+
+```bash
+# listar *branches* existentes e remotos
+$ git branch -a
+
+# criar um novo *branch*
+$ git branch myNewBranch
+
+# apagar um *branch*
+$ git branch -d myBranch
+
+# alterar o nome de um *branch*
+# git branch -m <oldname> <newname>
+$ git branch -m myBranchName myNewBranchName
+
+# editar a descrição de um *branch*
+$ git branch myBranchName --edit-description
+```
+
+### checkout
+
+Atualiza todos os ficheiros no directório do projecto de forma a ficarem iguais
+à versão do index ou do *branch* especificado.
+
+```bash
+# Checkout de um repositório - por predefinição para o branch master
+$ git checkout
+# Checkout de um branch especifico
+$ git checkout branchName
+# Cria um novo branch e faz checkout para ele.
+# Equivalente a: "git branch <name>; git checkout <name>"
+$ git checkout -b newBranch
+```
+
+### clone
+
+Clona ou copia um repositório existente para um novo directório. Também
+adiciona *branches* de monitorização remota para cada *branch* no repositório
+clonado o que permite enviar alterações para um *branch* remoto.
+
+```bash
+# Clona learnxinyminutes-docs
+$ git clone https://github.com/adambard/learnxinyminutes-docs.git
+```
+
+### commit
+
+Guarda o conteudo atual do index num novo *commit*. Este *commit* contém
+as alterações feitas e a mensagem criada pelo utilizador.
+
+```bash
+# commit com uma mensagem
+$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
+```
+
+### diff
+
+Apresenta as diferenças entre um ficheiro no repositório do projecto, *index*
+e *commits*
+
+```bash
+# Apresenta a diferença entre o directório atual e o index
+$ git diff
+
+# Apresenta a diferença entre o index e os commits mais recentes
+$ git diff --cached
+
+# Apresenta a diferença entre o directório atual e o commit mais recente
+$ git diff HEAD
+```
+
+### grep
+
+Permite procurar facilmente num repositório
+
+Configurações opcionais:
+
+```bash
+# Obrigado a Travis Jeffery por estas
+# Define a apresentação de números de linha nos resultados do grep
+$ git config --global grep.lineNumber true
+
+# Torna os resultados da pesquisa mais fáceis de ler, agrupando-os
+$ git config --global alias.g "grep --break --heading --line-number"
+```
+
+```bash
+# Pesquisa por "variableName" em todos os ficheiros de java
+$ git grep 'variableName' -- '*.java'
+
+# Pesquisa por uma linha que contém "arrayListName" e "add" ou "remove"
+$ git grep -e 'arrayListName' --and \( -e add -e remove \)
+```
+
+Google é teu amigo; para mais exemplos:
+[Git Grep Ninja (EN)](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
+
+### log
+
+Apresenta commits do repositório.
+
+```bash
+# Apresenta todos os commits
+$ git log
+
+# Apresenta X commits
+$ git log -n 10
+
+# Apresenta apenas commits de merge
+$ git log --merges
+```
+
+### merge
+
+"Merge" (junta) as alterações de commits externos com o *branch* atual.
+
+```bash
+# Junta o branch especificado com o atual
+$ git merge branchName
+
+# Para gerar sempre um commit ao juntar os branches
+$ git merge --no-ff branchName
+```
+
+### mv
+
+Alterar o nome ou mover um ficheiro.
+
+```bash
+# Alterar o nome de um ficheiro
+$ git mv HelloWorld.c HelloNewWorld.c
+
+# Mover um ficheiro
+$ git mv HelloWorld.c ./new/path/HelloWorld.c
+
+# Forçar a alteração de nome ou mudança local
+# "existingFile" já existe no directório, será sobre-escrito.
+$ git mv -f myFile existingFile
+```
+
+### pull
+
+Puxa alterações de um repositório e junta-as com outro branch
+
+```bash
+# Atualiza o repositório local, juntando as novas alterações
+# do repositório remoto 'origin' e branch 'master'
+# git pull <remote> <branch>
+# git pull => aplica a predefinição => git pull origin master
+$ git pull origin master
+
+# Juntar alterações do branch remote e fazer rebase commits do branch
+# no repositório local, como: "git pull <remote> <branch>, git rebase <branch>"
+$ git pull origin master --rebase
+```
+
+### push
+
+Enviar e juntar alterações de um branch para o seu branch correspondente
+num repositório remoto.
+
+```bash
+# Envia e junta as alterações de um repositório local
+# para um remoto denominado "origin" no branch "master".
+# git push <remote> <branch>
+# git push => aplica a predefinição => git push origin master
+$ git push origin master
+```
+
+### rebase (cautela!)
+
+Pega em todas as alterações que foram registadas num branch e volta a
+aplicá-las em outro branch.
+*Não deve ser feito rebase de commits que foram enviados para um repositório
+público*
+
+```bash
+# Faz Rebase de experimentBranch para master
+# git rebase <basebranch> <topicbranch>
+$ git rebase master experimentBranch
+```
+
+[Additional Reading (EN).](http://git-scm.com/book/en/Git-Branching-Rebasing)
+
+### reset (cautela!)
+
+Restabelece a HEAD atual ao estado definido. Isto permite reverter *merges*,
+*pulls*, *commits*, *adds* e outros. É um comando muito poderoso mas também
+perigoso se não há certeza quanto ao que se está a fazer.
+
+```bash
+# Restabelece a camada intermediária dr registo para o último
+# commit (o directório fica sem alterações)
+$ git reset
+
+# Restabelece a camada intermediária de registo para o último commit, e
+# sobre-escreve o projecto atual
+$ git reset --hard
+
+# Move a head do branch atual para o commit especificado, sem alterar o projecto.
+# todas as alterações ainda existem no projecto
+$ git reset 31f2bb1
+
+# Inverte a head do branch atual para o commit especificado
+# fazendo com que este esteja em sintonia com o directório do projecto
+# Remove alterações não registadas e todos os commits após o commit especificado
+$ git reset --hard 31f2bb1
+```
+
+### rm
+
+O oposto de git add, git rm remove ficheiros do branch atual.
+
+```bash
+# remove HelloWorld.c
+$ git rm HelloWorld.c
+
+# Remove um ficheiro de um sub-directório
+$ git rm /pather/to/the/file/HelloWorld.c
+```
+
+## Informação complementar (EN)
+
+* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
+
+* [git-scm - Video Tutorials](http://git-scm.com/videos)
+
+* [git-scm - Documentation](http://git-scm.com/docs)
+
+* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/)
+
+* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
+
+* [GitGuys](http://www.gitguys.com/)
diff --git a/r.html.markdown b/r.html.markdown
index 03aa1dd2..9c17e8ca 100644
--- a/r.html.markdown
+++ b/r.html.markdown
@@ -298,7 +298,7 @@ if (4 > 3) {
# Defined like so:
jiggle <- function(x) {
- x+ rnorm(x, sd=.1) #add in a bit of (controlled) noise
+ x = x + rnorm(1, sd=.1) #add in a bit of (controlled) noise
return(x)
}
diff --git a/ro-ro/python-ro.html.markdown b/ro-ro/python-ro.html.markdown
new file mode 100644
index 00000000..36ea78ec
--- /dev/null
+++ b/ro-ro/python-ro.html.markdown
@@ -0,0 +1,489 @@
+---
+language: python
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["Ovidiu Ciule", "https://github.com/ociule"] lang: ro-ro filename: python-ro.html.markdown
+filename: learnpython-ro.py
+---
+
+Python a fost creat de Guido Van Rossum la începutul anilor '90. Python a devenit astăzi unul din
+cele mai populare limbaje de programare. M-am indrăgostit de Python pentru claritatea sa sintactică.
+Python este aproape pseudocod executabil.
+
+Opinia dumneavoastră este binevenită! Puteţi sa imi scrieţi la [@ociule](http://twitter.com/ociule) sau ociule [at] [google's email service]
+
+Notă: Acest articol descrie Python 2.7, dar este util şi pentru Python 2.x. O versiune Python 3 va apărea
+în curând, în limba engleză mai întâi.
+
+```python
+# Comentariile pe o singură linie încep cu un caracter diez.
+""" Şirurile de caractere pe mai multe linii pot fi încadrate folosind trei caractere ", şi sunt des
+ folosite ca şi comentarii pe mai multe linii.
+"""
+
+####################################################
+## 1. Operatori şi tipuri de date primare
+####################################################
+
+# Avem numere
+3 #=> 3
+
+# Matematica se comportă cum ne-am aştepta
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# Împărţirea este un pic surprinzătoare. Este de fapt împărţire pe numere întregi şi rotunjeşte
+# automat spre valoarea mai mică
+5 / 2 #=> 2
+
+# Pentru a folosi împărţirea fără rest avem nevoie de numere reale
+2.0 # Acesta e un număr real
+11.0 / 4.0 #=> 2.75 ahhh ... cum ne aşteptam
+
+# Ordinea operaţiilor se poate forţa cu paranteze
+(1 + 3) * 2 #=> 8
+
+# Valoriile boolene sunt şi ele valori primare
+True
+False
+
+# Pot fi negate cu operatorul not
+not True #=> False
+not False #=> True
+
+# Egalitatea este ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# Inegalitate este !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# Comparaţii
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# Comparaţiile pot fi inlănţuite!
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Şirurile de caractere pot fi încadrate cu " sau '
+"Acesta e un şir de caractere."
+'Şi acesta este un şir de caractere.'
+
+# Şirurile de caractere pot fi adăugate!
+"Hello " + "world!" #=> "Hello world!"
+
+# Un şir de caractere poate fi folosit ca o listă
+"Acesta e un şir de caractere"[0] #=> 'A'
+
+# Caracterul % (procent) poate fi folosit pentru a formata şiruri de caractere :
+"%s pot fi %s" % ("şirurile", "interpolate")
+
+# O metodă mai nouă de a formata şiruri este metoda "format"
+# Este metoda recomandată
+"{0} pot fi {1}".format("şirurile", "formatate")
+# Puteţi folosi cuvinte cheie dacă nu doriţi sa număraţi
+"{nume} vrea să mănânce {fel}".format(nume="Bob", fel="lasagna")
+
+# "None", care reprezintă valoarea nedefinită, e un obiect
+None #=> None
+
+# Nu folosiţi operatorul == pentru a compara un obiect cu None
+# Folosiţi operatorul "is"
+"etc" is None #=> False
+None is None #=> True
+
+# Operatorul "is" testeaza dacă obiectele sunt identice.
+# Acastă operaţie nu e foarte folositoare cu tipuri primare,
+# dar e foarte folositoare cu obiecte.
+
+# None, 0, şi şiruri de caractere goale sunt evaluate ca si fals, False.
+# Toate celelalte valori sunt adevărate, True.
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Variabile şi colecţii
+####################################################
+
+# Printarea este uşoară
+print "Eu sunt Python. Încântat de cunoştinţă!"
+
+
+# Nu este nevoie sa declari variabilele înainte de a le folosi
+o_variabila = 5 # Convenţia este de a folosi caractere_minuscule_cu_underscore
+o_variabila #=> 5
+
+# Dacă accesăm o variabilă nefolosită declanşăm o excepţie.
+# Vezi secţiunea Control de Execuţie pentru mai multe detalii despre excepţii.
+alta_variabila # Declanşează o eroare de nume
+
+# "If" poate fi folosit într-o expresie.
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Listele sunt folosite pentru colecţii
+li = []
+# O listă poate avea valori de la început
+alta_li = [4, 5, 6]
+
+# Se adaugă valori la sfârşitul lister cu append
+li.append(1) #li e acum [1]
+li.append(2) #li e acum [1, 2]
+li.append(4) #li e acum [1, 2, 4]
+li.append(3) #li este acum [1, 2, 4, 3]
+# Se şterg de la sfarşit cu pop
+li.pop() #=> 3 şi li e acum [1, 2, 4]
+# Să o adaugăm înapoi valoarea
+li.append(3) # li e din nou [1, 2, 4, 3]
+
+# Putem accesa valorile individuale dintr-o listă cu operatorul index
+li[0] #=> 1
+# Valoarea speciala -1 pentru index accesează ultima valoare
+li[-1] #=> 3
+
+# Dacă depaşim limitele listei declanşăm o eroare IndexError
+li[4] # Declanşează IndexError
+
+# Putem să ne uităm la intervale folosind sintaxa de "felii"
+# În Python, intervalele sunt închise la început si deschise la sfârşit.
+li[1:3] #=> [2, 4]
+# Fără început
+li[2:] #=> [4, 3]
+# Fără sfarşit
+li[:3] #=> [1, 2, 4]
+
+# Putem şterge elemente arbitrare din lista cu operatorul "del" care primeşte indexul lor
+del li[2] # li e acum [1, 2, 3]
+
+# Listele pot fi adăugate
+li + alta_li #=> [1, 2, 3, 4, 5, 6] - Notă: li si alta_li nu sunt modificate!
+
+# Concatenăm liste cu "extend()"
+li.extend(alta_li) # Acum li este [1, 2, 3, 4, 5, 6]
+
+# Se verifică existenţa valorilor in lista cu "in"
+1 in li #=> True
+
+# Şi lungimea cu "len()"
+len(li) #=> 6
+
+
+# Tuplele sunt ca şi listele dar imutabile
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # Declanşează TypeError
+
+# Pot fi folosite ca şi liste
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Tuplele pot fi despachetate
+a, b, c = (1, 2, 3) # a este acum 1, b este acum 2 şi c este acum 3
+# Tuplele pot fi folosite şi fără paranteze
+d, e, f = 4, 5, 6
+# Putem inversa valori foarte uşor!
+e, d = d, e # d este acum 5 şi e este acum 4
+
+
+# Dicţionarele stochează chei şi o valoare pentru fiecare cheie
+dict_gol = {}
+# Şi un dicţionar cu valori
+dict_cu_valori = {"unu": 1, "doi": 2, "trei": 3}
+
+# Căutaţi valori cu []
+dict_cu_valori["unu"] #=> 1
+
+# Obţinem lista cheilor cu "keys()"
+dict_cu_valori.keys() #=> ["trei", "doi", "unu"]
+# Notă - ordinea cheilor obţinute cu keys() nu este garantată.
+# Puteţi obţine rezultate diferite de exemplul de aici.
+
+# Obţinem valorile cu values()
+dict_cu_valori.values() #=> [3, 2, 1]
+# Notă - aceeaşi ca mai sus, aplicată asupra valorilor.
+
+# Verificăm existenţa unei valori cu "in"
+"unu" in dict_cu_valori #=> True
+1 in dict_cu_valori #=> False
+
+# Accesarea unei chei care nu exista declanşează o KeyError
+dict_cu_valori["four"] # KeyError
+
+# Putem folosi metoda "get()" pentru a evita KeyError
+dict_cu_valori.get("one") #=> 1
+dict_cu_valori.get("four") #=> None
+# Metoda get poate primi ca al doilea argument o valoare care va fi returnată
+# când cheia nu este prezentă.
+dict_cu_valori.get("one", 4) #=> 1
+dict_cu_valori.get("four", 4) #=> 4
+
+# "setdefault()" este o metodă pentru a adăuga chei-valori fără a le modifica, dacă cheia există deja
+dict_cu_valori.setdefault("five", 5) #dict_cu_valori["five"] este acum 5
+dict_cu_valori.setdefault("five", 6) #dict_cu_valori["five"] exista deja, nu este modificată, tot 5
+
+
+# Set este colecţia mulţime
+set_gol = set()
+# Putem crea un set cu valori
+un_set = set([1,2,2,3,4]) # un_set este acum set([1, 2, 3, 4]), amintiţi-vă ca mulţimile garantează unicatul!
+
+# În Python 2.7, {} poate fi folosit pentru un set
+set_cu_valori = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Putem adăuga valori cu add
+set_cu_valori.add(5) # set_cu_valori este acum {1, 2, 3, 4, 5}
+
+# Putem intersecta seturi
+alt_set = {3, 4, 5, 6}
+set_cu_valori & alt_set #=> {3, 4, 5}
+
+# Putem calcula uniunea cu |
+set_cu_valori | alt_set #=> {1, 2, 3, 4, 5, 6}
+
+# Diferenţa între seturi se face cu -
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# Verificăm existenţa cu "in"
+2 in set_cu_valori #=> True
+10 in set_cu_valori #=> False
+
+
+####################################################
+## 3. Controlul Execuţiei
+####################################################
+
+# O variabilă
+o_variabila = 5
+
+# Acesta este un "if". Indentarea este importanta în python!
+# Printează "o_variabila este mai mică ca 10"
+if o_variabila > 10:
+ print "o_variabila e mai mare ca 10."
+elif o_variabila < 10: # Clauza elif e opţională.
+ print "o_variabila este mai mică ca 10."
+else: # Şi else e opţional.
+ print "o_variabila este exact 10."
+
+
+"""
+Buclele "for" pot fi folosite pentru a parcurge liste
+Vom afişa:
+ câinele este un mamifer
+ pisica este un mamifer
+ şoarecele este un mamifer
+"""
+for animal in ["câinele", "pisica", "şoarecele"]:
+ # Folosim % pentru a compune mesajul
+ print "%s este un mamifer" % animal
+
+"""
+"range(număr)" crează o lista de numere
+de la zero la numărul dat
+afişează:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+While repetă pana când condiţia dată nu mai este adevărată.
+afişează:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Prescurtare pentru x = x + 1
+
+# Recepţionăm excepţii cu blocuri try/except
+
+# Acest cod e valid in Python > 2.6:
+try:
+ # Folosim "raise" pentru a declanşa o eroare
+ raise IndexError("Asta este o IndexError")
+except IndexError as e:
+ pass # Pass nu face nimic. În mod normal aici ne-am ocupa de eroare.
+
+
+####################################################
+## 4. Funcţii
+####################################################
+
+# Folosim "def" pentru a defini funcţii
+def add(x, y):
+ print "x este %s şi y este %s" % (x, y)
+ return x + y # Funcţia poate returna valori cu "return"
+
+# Apelăm funcţia "add" cu parametrii
+add(5, 6) #=> Va afişa "x este 5 şi y este 6" şi va returna 11
+
+# Altă cale de a apela funcţii: cu parametrii numiţi
+add(y=6, x=5) # Ordinea parametrilor numiţi nu contează
+
+# Putem defini funcţii care primesc un număr variabil de parametrii nenumiţi
+# Aceşti parametrii nenumiţi se cheamă si poziţinali
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# Şi putem defini funcţii care primesc un număr variabil de parametrii numiţi
+def keyword_args(**kwargs):
+ return kwargs
+
+# Hai să vedem cum merge
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# Se pot combina
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) va afişa:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Când apelăm funcţii, putem face inversul args/kwargs!
+# Folosim * pentru a expanda tuple şi ** pentru a expanda kwargs.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # echivalent cu foo(1, 2, 3, 4)
+all_the_args(**kwargs) # echivalent cu foo(a=3, b=4)
+all_the_args(*args, **kwargs) # echivalent cu foo(1, 2, 3, 4, a=3, b=4)
+
+# În Python, funcţiile sunt obiecte primare
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Funcţiile pot fi anonime
+(lambda x: x > 2)(3) #=> True
+
+# Există funcţii de ordin superior (care operează pe alte funcţii) predefinite
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# Putem folosi scurtături de liste pentru a simplifica munca cu map si filter
+[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]
+
+####################################################
+## 5. Clase
+####################################################
+
+# Moştenim object pentru a crea o nouă clasă
+class Om(object):
+
+ # Acesta este un atribut al clasei. Va fi moştenit de toate instanţele.
+ species = "H. sapiens"
+
+ # Constructor (mai degrabă, configurator de bază)
+ def __init__(self, nume):
+ # Valoarea parametrului este stocată in atributul instanţei
+ self.nume = nume
+
+ # Aceasta este o metoda a instanţei.
+ # Toate metodele primesc "self" ca si primul argument.
+ def spune(self, mesaj):
+ return "%s: %s" % (self.nume, mesaj)
+
+ # O metodă a clasei. Este partajată de toate instanţele.
+ # Va primi ca si primul argument clasa căreia îi aparţine.
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # O metoda statica nu primeste un argument automat.
+ @staticmethod
+ def exclama():
+ return "*Aaaaaah*"
+
+
+# Instanţiem o clasă
+i = Om(nume="Ion")
+print i.spune("salut") # afişează: "Ion: salut"
+
+j = Om("George")
+print j.spune("ciau") # afişează George: ciau"
+
+# Apelăm metoda clasei
+i.get_species() #=> "H. sapiens"
+
+# Modificăm atributul partajat
+Om.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# Apelăm metoda statică
+Om.exclama() #=> "*Aaaaaah*"
+
+
+####################################################
+## 6. Module
+####################################################
+
+# Pentru a folosi un modul, trebuie importat
+import math
+print math.sqrt(16) #=> 4
+
+# Putem importa doar anumite funcţii dintr-un modul
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Putem importa toate funcţiile dintr-un modul, dar nu este o idee bună
+# Nu faceţi asta!
+from math import *
+
+# Numele modulelor pot fi modificate la import, de exemplu pentru a le scurta
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Modulele python sunt pur şi simplu fişiere cu cod python.
+# Puteţi sa creaţi modulele voastre, şi sa le importaţi.
+# Numele modulului este acelasi cu numele fişierului.
+
+# Cu "dir" inspectăm ce funcţii conţine un modul
+import math
+dir(math)
+
+
+```
+
+## Doriţi mai mult?
+
+### Gratis online, în limba engleză
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Cărţi, în limba engleză
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/ruby-ecosystem.html.markdown b/ruby-ecosystem.html.markdown
index c2a2087b..d186f712 100644
--- a/ruby-ecosystem.html.markdown
+++ b/ruby-ecosystem.html.markdown
@@ -121,9 +121,9 @@ dependency graph to resolve.
# Testing
-Testing is a large of ruby culture. Ruby comes with its own Unit-style testing
-framework called minitest (Or TestUnit for ruby version 1.8.x). There are many
-testing libraries with different goals.
+Testing is a large part of ruby culture. Ruby comes with its own Unit-style
+testing framework called minitest (Or TestUnit for ruby version 1.8.x). There
+are many testing libraries with different goals.
* TestUnit - Ruby 1.8's built-in "Unit-style" testing framework
* minitest - Ruby 1.9/2.0's built-in testing framework
diff --git a/ruby.html.markdown b/ruby.html.markdown
index 80682682..b9ba83cb 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -403,4 +403,55 @@ end
Human.bar # 0
Doctor.bar # nil
+module ModuleExample
+ def foo
+ 'foo'
+ end
+end
+
+# Including modules binds the methods to the object instance
+# Extending modules binds the methods to the class instance
+
+class Person
+ include ModuleExample
+end
+
+class Book
+ extend ModuleExample
+end
+
+Person.foo # => NoMethodError: undefined method `foo' for Person:Class
+Person.new.foo # => 'foo'
+Book.foo # => 'foo'
+Book.new.foo # => NoMethodError: undefined method `foo'
+
+# Callbacks when including and extending a module are executed
+
+module ConcernExample
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+ end
+
+ module ClassMethods
+ def bar
+ 'bar'
+ end
+ end
+
+ module InstanceMethods
+ def qux
+ 'qux'
+ end
+ end
+end
+
+class Something
+ include ConcernExample
+end
+
+Something.bar # => 'bar'
+Something.qux # => NoMethodError: undefined method `qux'
+Something.new.bar # => NoMethodError: undefined method `bar'
+Something.new.qux # => 'qux'
```
diff --git a/tr-tr/c-tr.html.markdown b/tr-tr/c-tr.html.markdown
index 50bca246..128901de 100644
--- a/tr-tr/c-tr.html.markdown
+++ b/tr-tr/c-tr.html.markdown
@@ -95,6 +95,10 @@ int main() {
// is not evaluated (except VLAs (see below)).
// The value it yields in this case is a compile-time constant.
int a = 1;
+
+ // size_t bir objeyi temsil etmek için kullanılan 2 byte uzunluğundaki bir
+ // işaretsiz tam sayı tipidir
+
size_t size = sizeof(a++); // a++ is not evaluated
printf("sizeof(a++) = %zu where a = %d\n", size, a);
// prints "sizeof(a++) = 4 where a = 1" (on a 32-bit architecture)
diff --git a/tr-tr/php-tr.html.markdown b/tr-tr/php-tr.html.markdown
index 94bc31ff..c5576fd7 100644
--- a/tr-tr/php-tr.html.markdown
+++ b/tr-tr/php-tr.html.markdown
@@ -67,6 +67,9 @@ $float = 1.234;
$float = 1.2e3;
$float = 7E-10;
+// Değişken Silmek
+unset($int1)
+
// Aritmetik
$sum = 1 + 1; // 2
$difference = 2 - 1; // 1
@@ -183,6 +186,13 @@ $y = 0;
echo $x; // => 2
echo $z; // => 0
+// Dump'lar değişkenin tipi ve değerini yazdırır
+var_dump($z); // int(0) yazdırılacaktır
+
+// Print'ler ise değişkeni okunabilir bir formatta yazdıracaktır.
+print_r($array); // Çıktı: Array ( [0] => One [1] => Two [2] => Three )
+
+
/********************************
* Mantık
*/
@@ -478,10 +488,18 @@ class MyClass
print 'MyClass';
}
+ //final anahtar kelimesi bu metodu override edilemez yapacaktır.
final function youCannotOverrideMe()
{
}
+/*
+Bir sınıfın özelliğini ya da metodunu statik yaptığınız takdirde sınıfın bir
+objesini oluşturmadan bu elemana erişebilirsiniz. Bir özellik statik tanımlanmış
+ise obje üzerinden bu elemana erişilemez. (Statik metodlar öyle değildir.)
+*/
+
+
public static function myStaticMethod()
{
print 'I am static';
diff --git a/zh-cn/perl-cn.html.markdown b/zh-cn/perl-cn.html.markdown
new file mode 100644
index 00000000..8f99ccbf
--- /dev/null
+++ b/zh-cn/perl-cn.html.markdown
@@ -0,0 +1,151 @@
+---
+name: perl
+category: language
+language: perl
+filename: learnperl.pl
+contributors:
+ - ["Korjavin Ivan", "http://github.com/korjavin"]
+translators:
+ - ["Yadong Wen", "https://github.com/yadongwen"]
+---
+
+Perl 5是一个功能强大、特性齐全的编程语言,有25年的历史。
+
+Perl 5可以在包括便携式设备和大型机的超过100个平台上运行,既适用于快速原型构建,也适用于大型项目开发。
+
+```perl
+# 单行注释以#号开头
+
+
+#### Perl的变量类型
+
+# 变量以$号开头。
+# 合法变量名以英文字母或者下划线起始,
+# 后接任意数目的字母、数字或下划线。
+
+### Perl有三种主要的变量类型:标量、数组和哈希。
+
+## 标量
+# 标量类型代表单个值:
+my $animal = "camel";
+my $answer = 42;
+
+# 标量类型值可以是字符串、整型或浮点类型,Perl会根据需要自动进行类型转换。
+
+## 数组
+# 数组类型代表一列值:
+my @animals = ("camel", "llama", "owl");
+my @numbers = (23, 42, 69);
+my @mixed = ("camel", 42, 1.23);
+
+
+
+## 哈希
+# 哈希类型代表一个键/值对的集合:
+
+my %fruit_color = ("apple", "red", "banana", "yellow");
+
+# 可以使用空格和“=>”操作符更清晰的定义哈希:
+
+my %fruit_color = (
+ apple => "red",
+ banana => "yellow",
+ );
+# perldata中有标量、数组和哈希更详细的介绍。 (perldoc perldata).
+
+# 可以用引用构建更复杂的数据类型,比如嵌套的列表和哈希。
+
+#### 逻辑和循环结构
+
+# Perl有大多数常见的逻辑和循环控制结构
+
+if ( $var ) {
+ ...
+} elsif ( $var eq 'bar' ) {
+ ...
+} else {
+ ...
+}
+
+unless ( condition ) {
+ ...
+ }
+# 上面这个比"if (!condition)"更可读。
+
+# 有Perl特色的后置逻辑结构
+print "Yow!" if $zippy;
+print "We have no bananas" unless $bananas;
+
+# while
+ while ( condition ) {
+ ...
+ }
+
+
+# for和foreach
+for ($i = 0; $i <= $max; $i++) {
+ ...
+ }
+
+foreach (@array) {
+ print "This element is $_\n";
+ }
+
+
+#### 正则表达式
+
+# Perl对正则表达式有深入广泛的支持,perlrequick和perlretut等文档有详细介绍。简单来说:
+
+# 简单匹配
+if (/foo/) { ... } # 如果 $_ 包含"foo"逻辑为真
+if ($a =~ /foo/) { ... } # 如果 $a 包含"foo"逻辑为真
+
+# 简单替换
+
+$a =~ s/foo/bar/; # 将$a中的foo替换为bar
+$a =~ s/foo/bar/g; # 将$a中所有的foo替换为bar
+
+
+#### 文件和输入输出
+
+# 可以使用“open()”函数打开文件用于输入输出。
+
+open(my $in, "<", "input.txt") or die "Can't open input.txt: $!";
+open(my $out, ">", "output.txt") or die "Can't open output.txt: $!";
+open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
+
+# 可以用"<>"操作符读取一个打开的文件句柄。 在标量语境下会读取一行,
+# 在列表环境下会将整个文件读入并将每一行赋给列表的一个元素:
+
+my $line = <$in>;
+my @lines = <$in>;
+
+#### 子程序
+
+# 写子程序很简单:
+
+sub logger {
+ my $logmessage = shift;
+ open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
+ print $logfile $logmessage;
+}
+
+# 现在可以像内置函数一样调用子程序:
+
+logger("We have a logger subroutine!");
+
+
+```
+
+#### 使用Perl模块
+
+Perl模块提供一系列特性来帮助你避免重新发明轮子,CPAN是下载模块的好地方( http://www.cpan.org/ )。Perl发行版本身也包含很多流行的模块。
+
+perlfaq有很多常见问题和相应回答,也经常有对优秀CPAN模块的推荐介绍。
+
+#### 深入阅读
+
+ - [perl-tutorial](http://perl-tutorial.org/)
+ - [www.perl.com的learn站点](http://www.perl.org/learn.html)
+ - [perldoc](http://perldoc.perl.org/)
+ - 以及 perl 内置的: `perldoc perlintro`