mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 07:12:31 +03:00
Merge branch 'master' of https://github.com/adambard/learnxinyminutes-docs
This commit is contained in:
commit
6172fee1a4
@ -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.
|
||||
|
@ -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.
|
||||
|
417
de-de/elixir-de.html.markdown
Normal file
417
de-de/elixir-de.html.markdown
Normal file
@ -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
|
491
fr-fr/python-fr.html.markdown
Normal file
491
fr-fr/python-fr.html.markdown
Normal file
@ -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)
|
||||
|
@ -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!
|
||||
|
||||
|
@ -210,7 +210,19 @@ public class LearnJava {
|
||||
//Iterated 10 times, fooFor 0->9
|
||||
}
|
||||
System.out.println("fooFor Value: " + fooFor);
|
||||
|
||||
|
||||
// For Each Loop
|
||||
// An automatic iteration through an array or list of objects.
|
||||
int[] fooList = {1,2,3,4,5,6,7,8,9};
|
||||
//for each loop structure => for(<object> : <array_object>)
|
||||
//reads as: for each object in the array
|
||||
//note: the object type must match the array.
|
||||
|
||||
for( int bar : fooList ){
|
||||
//System.out.println(bar);
|
||||
//Iterates 9 times and prints 1-9 on new lines
|
||||
}
|
||||
|
||||
// Switch Case
|
||||
// A switch works with the byte, short, char, and int data types.
|
||||
// It also works with enumerated types (discussed in Enum Types),
|
||||
|
@ -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
|
||||
|
||||
|
||||
```
|
||||
|
299
neat.html.markdown
Normal file
299
neat.html.markdown
Normal file
@ -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
|
@ -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
|
||||
|
@ -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).
|
||||
|
253
pt-br/erlang-pt.html.markdown
Normal file
253
pt-br/erlang-pt.html.markdown
Normal file
@ -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)
|
||||
|
308
pt-br/go-pt.html.markdown
Normal file
308
pt-br/go-pt.html.markdown
Normal file
@ -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!
|
||||
|
414
pt-pt/git-pt.html.markdown
Normal file
414
pt-pt/git-pt.html.markdown
Normal file
@ -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/)
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
```
|
||||
|
151
zh-cn/perl-cn.html.markdown
Normal file
151
zh-cn/perl-cn.html.markdown
Normal file
@ -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`
|
Loading…
Reference in New Issue
Block a user