diff options
Diffstat (limited to 'de-de')
| -rw-r--r-- | de-de/bash-de.html.markdown | 4 | ||||
| -rw-r--r-- | de-de/git-de.html.markdown | 14 | ||||
| -rw-r--r-- | de-de/go-de.html.markdown | 1 | ||||
| -rw-r--r-- | de-de/hack-de.html.markdown | 322 | ||||
| -rw-r--r-- | de-de/haml-de.html.markdown | 156 | ||||
| -rw-r--r-- | de-de/lua-de.html.markdown | 426 | ||||
| -rw-r--r-- | de-de/make-de.html.markdown | 260 | ||||
| -rw-r--r-- | de-de/markdown-de.html.markdown | 10 | ||||
| -rw-r--r-- | de-de/tcl-de.html.markdown | 475 | 
9 files changed, 1658 insertions, 10 deletions
| diff --git a/de-de/bash-de.html.markdown b/de-de/bash-de.html.markdown index 541d28bb..654fcdd4 100644 --- a/de-de/bash-de.html.markdown +++ b/de-de/bash-de.html.markdown @@ -92,12 +92,12 @@ echo "immer ausgeführt" || echo "Nur ausgeführt wenn der erste Befehl fehlschl  echo "immer ausgeführt" && echo "Nur ausgeführt wenn der erste Befehl Erfolg hat"  # Um && und || mit if statements zu verwenden, braucht man mehrfache Paare eckiger Klammern: -if [ $NAME == "Steve" ] && [ $Alter -eq 15 ] +if [ "$NAME" == "Steve" ] && [ "$Alter" -eq 15 ]  then      echo "Wird ausgeführt wenn $NAME gleich 'Steve' UND $Alter gleich 15."  fi -if [ $Name == "Daniya" ] || [ $Name == "Zach" ] +if [ "$Name" == "Daniya" ] || [ "$Name" == "Zach" ]  then      echo "Wird ausgeführt wenn $NAME gleich 'Daniya' ODER $NAME gleich 'Zach'."  fi diff --git a/de-de/git-de.html.markdown b/de-de/git-de.html.markdown index dea329d5..61f7bb67 100644 --- a/de-de/git-de.html.markdown +++ b/de-de/git-de.html.markdown @@ -33,6 +33,7 @@ Eine Versionsverwaltung erfasst die Änderungen einer Datei oder eines Verzeichn  * Ist offline einsetzbar.  * Einfache Kollaboration!  * Branching ist einfach! +* Branching ist schnell!  * Merging ist einfach!  * Git ist schnell.  * Git ist flexibel. @@ -53,11 +54,11 @@ Das .git-Verzeichnis enthält alle Einstellung, Logs, Branches, den HEAD und meh  ### Arbeitsverzeichnis (Teil des Repositorys) -Dies sind die Verzeichnisse und Dateien in deinem Repository. +Dies sind die Verzeichnisse und Dateien in deinem Repository, also z.B. dein Programmcode.  ### Index (Teil des .git-Verzeichnisses) -Der Index ist die die Staging-Area von Git. Es ist im Grunde eine Ebene, die Arbeitsverzeichnis vom Repository trennt. Sie gibt Entwicklern mehr Einfluss darüber, was ins Git-Repository eingeht. +Der Index ist die Staging-Area von Git. Es ist im Grunde eine Ebene, die Arbeitsverzeichnis vom Repository trennt. Sie gibt Entwicklern mehr Einfluss darüber, was ins Git-Repository eingeht.  ### Commit @@ -84,7 +85,7 @@ Ein *head* ist ein Pointer, der auf einen beliebigen Commit zeigt.  Ein Reposito  ### init -Erstelle ein leeres Git-Repository. Die Einstellungen, gespeicherte Informationen und mehr zu diesem Git-Repository werden in einem Verzeichnis namens *.git* angelegt. +Erstelle ein leeres Git-Repository im aktuellen Verzeichnis. Die Einstellungen, gespeicherte Informationen und mehr zu diesem Git-Repository werden in einem Verzeichnis namens *.git* angelegt.  ```bash  $ git init @@ -180,6 +181,8 @@ Bringt alle Dateien im Arbeitsverzeichnis auf den Stand des Index oder des angeg  ```bash  # Ein Repo auschecken - wenn nicht anders angegeben ist das der master  $ git checkout +# Eine Datei auschecken - sie befindet sich dann auf dem aktuellen Stand im Repository +$ git checkout /path/to/file  # Einen bestimmten Branch auschecken  $ git checkout branchName  # Erstelle einen neuen Branch und wechsle zu ihm. Wie: "git branch <name>; git checkout <name>" @@ -217,6 +220,9 @@ $ git diff --cached  # Unterschiede zwischen deinem Arbeitsverzeichnis und dem aktuellsten Commit anzeigen  $ git diff HEAD + +# Unterschiede zwischen dem Index und dem aktuellsten Commit (betrifft nur Dateien im Index) +$ git diff --staged  ```  ### grep @@ -374,3 +380,5 @@ $ git rm /pather/to/the/file/HelloWorld.c  * [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)  * [GitGuys](http://www.gitguys.com/) + +* [gitflow - Ein Modell um mit Branches zu arbeiten](http://nvie.com/posts/a-successful-git-branching-model/) diff --git a/de-de/go-de.html.markdown b/de-de/go-de.html.markdown index 94f48e65..dca88f01 100644 --- a/de-de/go-de.html.markdown +++ b/de-de/go-de.html.markdown @@ -4,6 +4,7 @@ filename: learngo-de.go  contributors:      - ["Joseph Adams", "https://github.com/jcla1"]      - ["Dennis Keller", "https://github.com/denniskeller"] +translators:      - ["Jerome Meinke", "https://github.com/jmeinke"]  lang: de-de  --- diff --git a/de-de/hack-de.html.markdown b/de-de/hack-de.html.markdown new file mode 100644 index 00000000..42428130 --- /dev/null +++ b/de-de/hack-de.html.markdown @@ -0,0 +1,322 @@ +--- +language: Hack +lang: de-de +contributors: +    - ["Stephen Holdaway", "https://github.com/stecman"] +    - ["David Lima", "https://github.com/davelima"] +translators: +    - ["Jerome Meinke", "https://github.com/jmeinke"] +filename: learnhack-de.hh +--- + +Hack ist eine von Facebook neu entwickelte Programmiersprache auf Basis von PHP. +Sie wird von der HipHop Virtual Machine (HHVM) ausgeführt. Die HHVM kann +aufgrund der Ähnlichkeit der Programmiersprachen nicht nur Hack, sondern auch +PHP-Code ausführen. Der wesentliche Unterschied zu PHP besteht in der statischen +Typisierung der Sprache, die eine wesentlich höhere Performance erlaubt. + + +Hier werden nur Hack-spezifische Eigenschaften beschrieben. Details über PHP's +Syntax findet man im [PHP Artikel](http://learnxinyminutes.com/docs/php/) dieser +Seite. + +```php +<?hh + +// Hack-Syntax ist nur für Dateien aktiv, die mit dem <?hh Prefix starten. +// Der <?hh Prefix kann nicht wie <?php mit HTML gemischt werden. +// Benutzung von "<?hh //strict" aktiviert den Strikt-Modus des Type-Checkers. + + +// Typisierung für Funktions-Argumente +function repeat(string $word, int $count) +{ +    $word = trim($word); +    return str_repeat($word . ' ', $count); +} + +// Typisierung für Rückgabewerte +function add(...$numbers) : int +{ +    return array_sum($numbers); +} + +// Funktionen ohne Rückgabewert, werden mit "void" typisiert +function truncate(resource $handle) : void +{ +    // ... +} + +// Typisierung unterstützt die explizit optionale Ein- / Ausgabe von "null" +function identity(?string $stringOrNull) : ?string +{ +    return $stringOrNull; +} + +// Typisierung von Klassen-Eigenschaften +class TypeHintedProperties +{ +    public ?string $name; + +    protected int $id; + +    private float $score = 100.0; + +    // Hack erfordert es, dass typisierte Eigenschaften (also "non-null") +    // einen Default-Wert haben oder im Konstruktor initialisiert werden. +    public function __construct(int $id) +    { +        $this->id = $id; +    } +} + + +// Kurzgefasste anonyme Funktionen (lambdas) +$multiplier = 5; +array_map($y ==> $y * $multiplier, [1, 2, 3]); + + +// Weitere, spezielle Felder (Generics) +// Diese kann man sich als ein zugreifbares Interface vorstellen +class Box<T> +{ +    protected T $data; + +    public function __construct(T $data) { +        $this->data = $data; +    } + +    public function getData(): T { +        return $this->data; +    } +} + +function openBox(Box<int> $box) : int +{ +    return $box->getData(); +} + + +// Formen +// +// Hack fügt das Konzept von Formen hinzu, wie struct-ähnliche arrays +// mit einer typ-geprüften Menge von Schlüsseln +type Point2D = shape('x' => int, 'y' => int); + +function distance(Point2D $a, Point2D $b) : float +{ +    return sqrt(pow($b['x'] - $a['x'], 2) + pow($b['y'] - $a['y'], 2)); +} + +distance( +    shape('x' => -1, 'y' => 5), +    shape('x' => 2, 'y' => 50) +); + + +// Typen-Definition bzw. Aliasing +// +// Hack erlaubt es Typen zu definieren und sorgt somit für bessere Lesbarkeit +newtype VectorArray = array<int, Vector<int>>; + +// Ein Tupel mit zwei Integern +newtype Point = (int, int); + +function addPoints(Point $p1, Point $p2) : Point +{ +    return tuple($p1[0] + $p2[0], $p1[1] + $p2[1]); +} + +addPoints( +    tuple(1, 2), +    tuple(5, 6) +); + + +// Erstklassige Aufzählungen (enums) +enum RoadType : int +{ +    Road = 0; +    Street = 1; +    Avenue = 2; +    Boulevard = 3; +} + +function getRoadType() : RoadType +{ +    return RoadType::Avenue; +} + + +// Automatische Erstellung von Klassen-Eigenschaften durch Konstruktor-Argumente +// +// Wiederkehrende Definitionen von Klassen-Eigenschaften können durch die Hack- +// Syntax vermieden werden. Hack erlaubt es die Klassen-Eigenschaften über +// Argumente des Konstruktors zu definieren. +class ArgumentPromotion +{ +    public function __construct(public string $name, +                                protected int $age, +                                private bool $isAwesome) {} +} + +class WithoutArgumentPromotion +{ +    public string $name; + +    protected int $age; + +    private bool $isAwesome; + +    public function __construct(string $name, int $age, bool $isAwesome) +    { +        $this->name = $name; +        $this->age = $age; +        $this->isAwesome = $isAwesome; +    } +} + + +// Kooperatives Multitasking +// +// Die Schlüsselworte "async" and "await" führen Multitasking ein. +// Achtung, hier werden keine Threads benutzt, sondern nur Aktivität getauscht. +async function cooperativePrint(int $start, int $end) : Awaitable<void> +{ +    for ($i = $start; $i <= $end; $i++) { +        echo "$i "; + +        // Geben anderen Tasks die Möglichkeit aktiv zu werden +        await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0); +    } +} + +// Die Ausgabe von folgendem Code ist "1 4 7 2 5 8 3 6 9" +AwaitAllWaitHandle::fromArray([ +    cooperativePrint(1, 3), +    cooperativePrint(4, 6), +    cooperativePrint(7, 9) +])->getWaitHandle()->join(); + + +// Attribute +// +// Attribute repräsentieren eine Form von Metadaten für Funktionen. +// Hack bietet Spezial-Attribute, die nützliche Eigenschaften mit sich bringen. + +// Das __Memoize Attribut erlaubt es die Ausgabe einer Funktion zu cachen. +<<__Memoize>> +function doExpensiveTask() : ?string +{ +    return file_get_contents('http://example.com'); +} + +// Der Funktionsrumpf wird im Folgenden nur ein einziges mal ausgeführt: +doExpensiveTask(); +doExpensiveTask(); + + +// Das __ConsistentConstruct Attribut signalisiert dem type-checker, dass +// die Funktionsdeklaration von __construct für alle Unterklassen dieselbe ist. +<<__ConsistentConstruct>> +class ConsistentFoo +{ +    public function __construct(int $x, float $y) +    { +        // ... +    } + +    public function someMethod() +    { +        // ... +    } +} + +class ConsistentBar extends ConsistentFoo +{ +    public function __construct(int $x, float $y) +    { +        // Der Type-checker erzwingt den Aufruf des Eltern-Klassen-Konstruktors +        parent::__construct($x, $y); + +        // ... +    } + +    // Das __Override Attribut ist ein optionales Signal an den Type-Checker, +    // das erzwingt, dass die annotierte Methode die Methode der Eltern-Klasse +    // oder des Traits verändert. +    <<__Override>> +    public function someMethod() +    { +        // ... +    } +} + +class InvalidFooSubclass extends ConsistentFoo +{ +    // Wenn der Konstruktor der Eltern-Klasse nicht übernommen wird, +    // wird der Type-Checker einen Fehler ausgeben: +    // +    //  "This object is of type ConsistentBaz. It is incompatible with this object +    //   of type ConsistentFoo because some of their methods are incompatible" +    // +    public function __construct(float $x) +    { +        // ... +    } + +    // Auch bei der Benutzung des __Override Attributs für eine nicht veränderte +    // Methode wird vom Type-Checker eine Fehler ausgegeben: +    // +    //  "InvalidFooSubclass::otherMethod() is marked as override; no non-private +    //   parent definition found or overridden parent is defined in non-<?hh code" +    // +    <<__Override>> +    public function otherMethod() +    { +        // ... +    } +} + +// Ein Trait ist ein Begriff aus der objektorientierten Programmierung und +// beschreibt eine wiederverwendbare Sammlung von Methoden und Attributen, +// ähnlich einer Klasse. + +// Anders als in PHP können Traits auch als Schnittstellen (Interfaces) +// implementiert werden und selbst Schnittstellen implementieren. +interface KittenInterface +{ +    public function play() : void; +} + +trait CatTrait implements KittenInterface +{ +    public function play() : void +    { +        // ... +    } +} + +class Samuel +{ +    use CatTrait; +} + + +$cat = new Samuel(); +$cat instanceof KittenInterface === true; // True + +``` + +## Weitere Informationen + +Die Hack [Programmiersprachen-Referenz](http://docs.hhvm.com/manual/de/hacklangref.php) +erklärt die neuen Eigenschaften der Sprache detailliert auf Englisch. Für +allgemeine Informationen kann man auch die offizielle Webseite [hacklang.org](http://hacklang.org/) +besuchen. + +Die offizielle Webseite [hhvm.com](http://hhvm.com/) bietet Infos zum Download +und zur Installation der HHVM. + +Hack's [nicht-untersützte PHP Syntax-Elemente](http://docs.hhvm.com/manual/en/hack.unsupported.php) +werden im offiziellen Handbuch beschrieben. diff --git a/de-de/haml-de.html.markdown b/de-de/haml-de.html.markdown new file mode 100644 index 00000000..7272b365 --- /dev/null +++ b/de-de/haml-de.html.markdown @@ -0,0 +1,156 @@ +--- +language: haml +filename: learnhaml-de.haml +contributors: +  - ["Simon Neveu", "https://github.com/sneveu"] +  - ["Sol Bekic", "https://github.com/S0lll0s"] +lang: de-de +--- + +Haml ist eine Markup- und Templatingsprache, aufgesetzt auf Ruby, mit der HTML Dokumente einfach beschrieben werden können. + +Haml vermindert Wiederholung und Fehleranfälligkeit, indem es Tags basierend auf der Markup-Struktur schließt und schachtelt. +Dadurch ergibt sich kurzes, präzises und logisches Markup. + +Haml kann außerhalb eines Ruby-projekts verwendet werden. Mit dem installierten Haml gem kann man das Terminal benutzen um Haml zu HTML umzuwandeln: + +$ haml input_file.haml output_file.html + + +```haml +/ ------------------------------------------- +/ Einrückung +/ ------------------------------------------- + +/ +  Einrückung ist ein wichtiges Element des Haml Syntax, deswegen ist es +  wichtig ein konsequentes Schema zu verwenden. Meistens werden zwei spaces +  verwendet, solange die Einrückungen das gleiche Schema verfolgen können +  aber auch andere Breiten und Tabs verwendet werden + + +/ ------------------------------------------- +/ Kommentare +/ ------------------------------------------- + +/ Kommentare beginnen mit einem Slash + +/ +  Mehrzeilige Kommentare werden eingerückt und mit einem Slash +  eingeführt + +-# Diese Zeile ist ein "stummes" Kommentar, es wird nicht mitgerendert + + +/ ------------------------------------------- +/ HTML Elemente +/ ------------------------------------------- + +/ Tags werden durch ein Prozentzeichen und den Tagnamen erzeugt +%body +  %header +    %nav + +/ Die Zeilen oben würden folgendes ergeben: +  <body> +    <header> +      <nav></nav> +    </header> +  </body> + +/ Text kann direkt nach dem Tagnamen eingefügt werden: +%h1 Headline copy + +/ Mehrzeilige Inhalte müssen stattdessen eingerückt werden: +%p  +  This is a lot of content that we could probably split onto two +  separate lines. + +/  +  HTML kann mit &= escaped werden. So werden HTML-sensitive Zeichen +  enkodiert. Zum Beispiel: + +%p +  &= "Ja & Nein" + +/ würde 'Ja & Nein' ergeben + +/ HTML kann mit != dekodiert werden: +%p +  != "so schreibt man ein Paragraph-Tag: <p></p>" + +/ ...was 'This is how you write a paragraph tag <p></p>' ergeben würde + +/ CSS Klassen können mit '.classname' an Tags angehängt werden: +%div.foo.bar + +/ oder über einen Ruby Hash: +%div{:class => 'foo bar'} + +/ Das div Tag wird standardmäßig verwendet, divs können also verkürzt werden: +.foo + +/ andere Attribute können über den Hash angegeben werden: +%a{:href => '#', :class => 'bar', :title => 'Bar'} + +/ Booleesche Attribute können mit 'true' gesetzt werden: +%input{:selected => true} + +/ data-Attribute können in einem eigenen Hash im :data key angegeben werden: +%div{:data => {:attribute => 'foo'}} + + +/ ------------------------------------------- +/ Verwendung von Ruby +/ ------------------------------------------- + +/ Mit dem = Zeichen können Ruby-werte evaluiert und als Tag-text verwendet werden: + +%h1= book.name + +%p +  = book.author +  = book.publisher + + +/ Code nach einem Bindestrich wird ausgeführt aber nicht gerendert: +- books = ['book 1', 'book 2', 'book 3'] + +/ So können zum Beispiel auch Blöcke verwendet werden: +- books.shuffle.each_with_index do |book, index| +  %h1= book + +  if book do +    %p This is a book + +/ +  Auch hier werden wieder keine End-Tags benötigt! +  Diese ergeben sich aus der Einrückung. + + +/ ------------------------------------------- +/ Inline Ruby / Ruby Interpolation +/ ------------------------------------------- + +/ Ruby variablen können mit #{} in Text interpoliert werden: +%p dein bestes Spiel ist #{best_game} + + +/ ------------------------------------------- +/ Filter +/ ------------------------------------------- + +/ +  Mit dem Doppelpinkt können Haml Filter benutzt werden. +  Zum Beispiel gibt es den :javascript Filter, mit dem inline JS +  geschrieben werden kann: + +:javascript +  console.log('Dies ist ein <script>'); + +``` + +## Weitere Resourcen + +- [What is HAML?](http://haml.info/) - Eine gute Einleitung auf der Haml homepage (englisch) +- [Official Docs](http://haml.info/docs/yardoc/file.REFERENCE.html) - Die offizielle Haml Referenz (englisch) diff --git a/de-de/lua-de.html.markdown b/de-de/lua-de.html.markdown new file mode 100644 index 00000000..83f8506c --- /dev/null +++ b/de-de/lua-de.html.markdown @@ -0,0 +1,426 @@ +--- +language: Lua +contributors: +    - ["Tyler Neylon", "http://tylerneylon.com/"] +translators: +    - ["Martin Schimandl", "https://github.com/Git-Jiro"] +filename: learnlua-de.lua +lang: de-de +--- + +```lua +-- Zwei Gedankenstriche starten ein einzeiliges Kommentar. + +--[[ +     Fügt man zwei '[' und ']' hinzu, +     erzeugt man einen mehrzeiligen Kommentar. +--]] +-------------------------------------------------------------------------------- +-- 1. Variablen und Fluß-Kontrolle. +-------------------------------------------------------------------------------- + +num = 42  -- Alle Nummern sind vom Typ: Double. +-- Werd nicht nervös, 64-Bit Double haben 52 Bits zum Speichern von exakten +-- Ganzzahlen; Maschinen-Genauigkeit ist kein Problem für Ganzzahlen kleiner als  +-- 52 Bit. + +s = 'walternate'  -- Zeichenketten sind unveränderlich, wie bei Python. +t = "Doppelte Anführungszeichen sind auch OK" +u = [[ Doppelte eckige Klammern +       beginnen und beenden +       mehrzeilige Zeichenketten.]] +t = nil  -- Undefineren von t; Lua hat einen Garbage Collection. + +-- Blöcke werden durch Schlüsselwörter wie do/end markiert: +while num < 50 do +  num = num + 1  -- Es gibt Keine Operatoren wie ++ oder += +end + +-- If Bedingungen: +if num > 40 then +  print('over 40') +elseif s ~= 'walternate' then  -- ~= bedeutet ungleich +  -- Gleichheits-Check == wie bei Python; OK für Zeichenketten. +  io.write('not over 40\n')  -- Standard ist stdout. +else +  -- Variablen sind standardmäßig global. +  thisIsGlobal = 5  -- Camel case ist üblich. + +  -- So macht man eine Variable lokal: +  local line = io.read()  -- Lies die nächste Zeile von stdin. + +  -- Zeichenketten zusammenführen mit dem .. Operator: +  print('Winter is coming, ' .. line) +end + +-- Undefinierte Variablen geben nil zurück. +-- Das ist kein Fehler: +foo = anUnknownVariable  -- Nun ist foo = nil. + +aBoolValue = false + +-- Nur nil und false sind unwahr; 0 and '' sind wahr! +if not aBoolValue then print('was false') end + +-- 'or' und 'and' sind "kurz-geschlossen". Das ist so ähnlich wie der a?b:c +-- operator in C/js: +-- in C/js: +ans = aBoolValue and 'yes' or 'no'  --> 'no' + +karlSum = 0 +for i = 1, 100 do  -- Ein Bereich inkludiert beide Enden. +  karlSum = karlSum + i +end + +-- Verwende "100, 1, -1" als Breich für Countdowns: +fredSum = 0 +for j = 100, 1, -1 do fredSum = fredSum + j end + +-- Im Allgemeinen besteht ein Bereich aus: Anfang, Ende, [, Schrittweite]. + +-- Ein anderes Schleifen-Konstrukt: +repeat +  print('Der Weg der Zukunft') +  num = num - 1 +until num == 0 + +-------------------------------------------------------------------------------- +-- 2. Funktionen. +-------------------------------------------------------------------------------- + +function fib(n) +  if n < 2 then return n end +  return fib(n - 2) + fib(n - 1) +end + +-- Closures und anonyme Funktionen sind ok: +function adder(x) +  -- Die zurückgegebene Funktion wird erzeugt wenn addr aufgerufen wird und merkt +  -- sich den Wert von x: +  return function (y) return x + y end +end +a1 = adder(9) +a2 = adder(36) +print(a1(16))  --> 25 +print(a2(64))  --> 100 + +-- Rückgabewerte, Funktions-Aufrufe und Zuweisungen funktionieren alle mit +-- Listen die nicht immer gleich lang sein müssen. Überzählige Empfänger +-- bekommen nil; überzählige Sender werden ignoriert. + +x, y, z = 1, 2, 3, 4 +-- Nun ist x = 1, y = 2, z = 3, und 4 wird ignoriert. + +function bar(a, b, c) +  print(a, b, c) +  return 4, 8, 15, 16, 23, 42 +end + +x, y = bar('zaphod')  --> prints "zaphod  nil nil" +-- Nun ist x = 4, y = 8, die Werte 15..42 werden ignoriert. + +-- Funktionen sind erste Klasse, und können lokal oder global sein. +-- Das ist alles das Gleiche: +function f(x) return x * x end +f = function (x) return x * x end + +-- Das auch: +local function g(x) return math.sin(x) end +local g = function(x) return math.sin(x) end +-- Äquivalent zu local function g(x)..., außer das Referenzen auf g im +-- Funktions-Körper nicht wie erwartet funktionieren. +local g; g  = function (x) return math.sin(x) end +-- Die Deklaration 'local g' macht Selbst-Referenzen auf g OK. + +-- Nebenbei gesagt, Trigonometrie-Funktionen verwenden Radianten. + +-- Funktionsaufrufe mit nur einem Zeichenketten-Parameter brauch keine runden +-- Klammern. +print 'hello'  -- Funktioniert wunderbar. + +-- Funktionsaufrufe mit einem Tabellen-Parameter brauchen auch keine runden +-- Klammern. Mehr zu Tabellen kommt später. +print {} -- Funktioniert auch wunderbar. + +-------------------------------------------------------------------------------- +-- 3. Tabellen. +-------------------------------------------------------------------------------- + +-- Tabellen sind die einzige zusammengesetzte Struktur in Lua. Sie sind +-- assoziative Arrays. Sie sind so ähnlich wie PHP arrays oder JavaScript +-- Objekte. Sie sind Hash-Lookup-Dictionaries die auch als Listen verwendet +-- werden können. + +-- Verwenden von Tabellen als Dictionaries oder Maps: + +-- Dict-Literale haben standardmäßig Zeichenketten als Schlüssel: +t = {key1 = 'value1', key2 = false} + +-- Zeichenketten-Schlüssel verwenden eine JavaScript ähnliche Punkt-Notation. +print(t.key1)  -- Ausgabe 'value1'. +t.newKey = {}  -- Neues Schlüssel/Wert-Paar hinzufügen. +t.key2 = nil   -- key2 aus der Tabelle entfernen. + +-- Literale notation für jeden (nicht-nil) Wert als Schlüssel: +u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'} +print(u[6.28])  -- Ausgabe "tau" + +-- Schlüssel-Vergleiche funktionieren per Wert für Nummern und Zeichenketten, +-- aber über die Identität bei Tabellen. +a = u['@!#']  -- Nun ist a = 'qbert'. +b = u[{}]     -- Wir würden 1729 erwarten, aber es ist nil: +-- b = nil weil der Lookup fehlschlägt. Er schlägt Fehl, weil der Schlüssel +-- den wir verwendet haben nicht das gleiche Objekt ist das wir verwendet +-- haben um den original Wert zu speichern. Zahlen und Zeichnkette sind daher +-- die praktischeren Schlüssel. + +-- Eine Funktion mit nur einem Tabellen-Parameter benötigt keine Klammern. +function h(x) print(x.key1) end +h{key1 = 'Sonmi~451'}  -- Ausgabe 'Sonmi~451'. + +for key, val in pairs(u) do  -- Tabellen-Iteration. +  print(key, val) +end + +-- _G ist eine spezielle Tabelle die alles Globale enthält. +print(_G['_G'] == _G)  -- Ausgabe 'true'. + +-- Verwenden von Tabellen als Listen/Arrays: + +-- Listen-Literale verwenden implizit Ganzzahlen als Schlüssel: +v = {'value1', 'value2', 1.21, 'gigawatts'} +for i = 1, #v do  -- #v ist die Größe von v für Listen. +  print(v[i])  -- Indices beginnen mit 1 !! SO VERRÜCKT! +end +-- Eine 'Liste' ist kein echter Typ. v ist nur eine Tabelle mit fortlaufenden +-- Ganzzahlen als Schlüssel, die behandelt wird wie eine Liste. + +-------------------------------------------------------------------------------- +-- 3.1 Metatabellen und Metamethoden +-------------------------------------------------------------------------------- + +-- Eine Tabelle kann eine Metatabelle haben. Diese verleiht ihr so etwas wie +-- Tabellen-Operator-Überladungs-Verhalten. Später sehen wir wie +-- Metatabellen js-prototypen artiges Verhalten unterstützen. + +f1 = {a = 1, b = 2}  -- Repräsentiert den Bruch a/b. +f2 = {a = 2, b = 3} + +-- Dies würde Fehlschlagen: +-- s = f1 + f2 + +metafraction = {} +function metafraction.__add(f1, f2) +  local sum = {} +  sum.b = f1.b * f2.b +  sum.a = f1.a * f2.b + f2.a * f1.b +  return sum +end + +setmetatable(f1, metafraction) +setmetatable(f2, metafraction) + +s = f1 + f2  -- Rufe __add(f1, f2) vom der Metatabelle von f1 auf. + +-- f1 und f2 haben keine Schlüssel für ihre Metatabellen, anders als bei js +-- Prototypen. Daher muss mithilfe von getmetatable(f1) darauf zugegriffen +-- werden. Eine Metatabelle ist wie eine normale Tabelle mit Schlüsseln die +-- Lua bekannt sind, so wie __add. + + +-- Die nächste Zeile schlägt fehl weil s keine Metatabelle hat: +-- t = s + s +-- Mihilfe von Klassen ähnlichen Mustern kann das gelöst werden. +-- Siehe weiter unten. + +-- Ein __index einer Metatabelle überlädt Punkt-Lookups: +defaultFavs = {animal = 'gru', food = 'donuts'} +myFavs = {food = 'pizza'} +setmetatable(myFavs, {__index = defaultFavs}) +eatenBy = myFavs.animal  -- Funktioniert dank Metatabelle! + +-------------------------------------------------------------------------------- +-- Direkte Tabellen-Lookups die fehlschlagen werden mithilfe von __index der +-- Metatabelle wiederholt. Das geschieht rekursiv. + +-- __index kann auch eine Funktion mit der Form function(tbl, key) sein. +-- Damit kann man Lookups weiter anpassen. + +-- Werte wie __index,add, .. werden Metamethoden genannt. +-- HIer eine vollständige Liste aller Metamethoden. + +-- __add(a, b)                     für a + b +-- __sub(a, b)                     für a - b +-- __mul(a, b)                     für a * b +-- __div(a, b)                     für a / b +-- __mod(a, b)                     für a % b +-- __pow(a, b)                     für a ^ b +-- __unm(a)                        für -a +-- __concat(a, b)                  für a .. b +-- __len(a)                        für #a +-- __eq(a, b)                      für a == b +-- __lt(a, b)                      für a < b +-- __le(a, b)                      für a <= b +-- __index(a, b)  <fn or a table>  für a.b +-- __newindex(a, b, c)             für a.b = c +-- __call(a, ...)                  für a(...) + +-------------------------------------------------------------------------------- +-- 3.2 Klassen-Artige Tabellen und Vererbung. +-------------------------------------------------------------------------------- + +-- Klassen sind in Lua nicht eingebaut. Es gibt verschieden Wege sie mithilfe +-- von Tabellen und Metatabellen zu erzeugen. + +-- Die Erklärund des Beispiels erfolgt unterhalb. + +Dog = {}                                   -- 1. + +function Dog:new()                         -- 2. +  local newObj = {sound = 'woof'}          -- 3. +  self.__index = self                      -- 4. +  return setmetatable(newObj, self)        -- 5. +end + +function Dog:makeSound()                   -- 6. +  print('I say ' .. self.sound) +end + +mrDog = Dog:new()                          -- 7. +mrDog:makeSound()  -- 'I say woof'         -- 8. + +-- 1. Dog verhält sich wie eine Klasse; Ist aber eine Tabelle. +-- 2. "function tablename:fn(...)" ist das gleiche wie +--    "function tablename.fn(self, ...)", Der : fügt nur ein Argument namens +--    self hinzu. Siehe 7 & 8 um zu sehen wie self seinen Wert bekommt. +-- 3. newObj wird eine Instanz von Dog. +-- 4. "self" ist die zu Instanzierende Klasse. Meistern ist self = Dog, aber +--    dies kann durch Vererbung geändert werden. newObj bekommt die Funktionen +--    von self wenn wir die Metatabelle von newObj und __index von self auf +--    self setzen. +-- 5. Zur Erinnerung: setmetatable gibt sein erstes Argument zurück. +-- 6. Der Doppelpunkt funktioniert wie bei 2, aber dieses Mal erwarten wir das +--    self eine Instanz ist und keine Klasse. +-- 7. Das Selbe wie Dog.new(Dog), also self = Dog in new(). +-- 8. Das Selbe wie mrDog.makeSound(mrDog); self = mrDog. + +-------------------------------------------------------------------------------- + +-- Vererbungs-Beispiel: + +LoudDog = Dog:new()                           -- 1. + +function LoudDog:makeSound() +  local s = self.sound .. ' '                 -- 2. +  print(s .. s .. s) +end + +seymour = LoudDog:new()                       -- 3. +seymour:makeSound()  -- 'woof woof woof'      -- 4. + +-------------------------------------------------------------------------------- +-- 1. LoudDog bekommt die Methoden und Variablen von Dog. +-- 2. self hat einen 'sound' Schlüssel von new(), siehe 3. +-- 3. Das Gleiche wie "LoudDog.new(LoudDog)", und umgewandelt zu "Dog.new(LoudDog)" +--    denn LoudDog hat keinen 'new' Schlüssel, aber "__index = Dog" steht in der +--    Metatabelle. +--    Ergebnis: Die Metatabelle von seymour ist LoudDog und "LoudDog.__index = Dog". +--    Daher ist seymour.key gleich seymour.key, LoudDog.key, Dog.key, je nachdem +--    welche Tabelle als erstes einen passenden Schlüssel hat. +-- 4. Der 'makeSound' Schlüssel wird in LoudDog gefunden: Das ist das Gleiche +--    wie "LoudDog.makeSound(seymour)". + +-- Wenn nötig, sieht new() einer Sub-Klasse genau so aus wie new() der +-- Basis-Klasse: +function LoudDog:new() +  local newObj = {} +  -- set up newObj +  self.__index = self +  return setmetatable(newObj, self) +end + +-------------------------------------------------------------------------------- +-- 4. Module. +-------------------------------------------------------------------------------- + + +--[[ Dieser Abschnitt ist auskommentiert damit der Rest des Skripts lauffähig +--   bleibt. +``` + +```lua +-- Angenommen mod.lua sieht so aus: +local M = {} + +local function sayMyName() +  print('Hrunkner') +end + +function M.sayHello() +  print('Why hello there') +  sayMyName() +end + +return M + +-- Eine andere Datei könnte die Funktionen in mod.lua so verwenden: +local mod = require('mod')  -- Führe mod.lua aus. + +-- require ist der Standard-Weg um Module zu inkludieren. +-- require verhält sich wie: (Wenn nicht gecached wird; siehe später) +local mod = (function () +  <Inhalt von mod.lua> +end)() +-- Es ist als ob mod.lua eine Funktion wäre, sodass lokale Variablen in +-- mod.lua ausserhalb unsichtbar sind. + +-- Das funktioniert weil mod hier das Gleiche wie M in mod.lua ist: +mod.sayHello()  -- Says hello to Hrunkner. + +-- Das ist Falsch: sayMyName existiert nur in mod.lua: +mod.sayMyName()  -- Fehler + +-- Der Rückgabe-Wert von require wird zwischengespeichert. Sodass Module nur +-- einmal abgearbeitet werden, auch wenn sie mit require öfters eingebunden +-- werden. + +-- Nehmen wir an mod2.lua enthält "print('Hi!')". +local a = require('mod2')  -- Ausgabe Hi! +local b = require('mod2')  -- Keine Ausgabe; a=b. + +-- dofile ist wie require aber ohne Zwischenspeichern. +dofile('mod2')  --> Hi! +dofile('mod2')  --> Hi! (läuft nochmal, nicht wie require) + +-- loadfile ladet eine lua Datei aber die Datei wird noch nicht abgearbeitet. +f = loadfile('mod2')  -- Sobald f() aufgerufen wird läuft mod2.lua. + +-- loadstring ist loadfile für Zeichenketten +g = loadstring('print(343)')  -- Gibt eine Funktion zurück.. +g()  -- Ausgabe 343; Vorher kam keine Ausgabe. + +--]] + +``` +## Referenzen + +Ich war so begeistert Lua zu lernen, damit ich Spiele mit <a href="http://love2d.org/">Love 2D game engine</a> programmieren konnte. + +Ich habe angefangen mit <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>. +Danach habe ich das offizielle Lua Buch gelesen: <a href="http://www.lua.org/pil/contents.html">Programming in Lua</a> + +Es kann auch hilfreich sein hier vorbeizuschauen: <a href="http://lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Lua short +reference</a> + +Wichtige Themen die hier nicht angesprochen wurden; die Standard-Bibliotheken: + +* <a href="http://lua-users.org/wiki/StringLibraryTutorial">string library</a> +* <a href="http://lua-users.org/wiki/TableLibraryTutorial">table library</a> +* <a href="http://lua-users.org/wiki/MathLibraryTutorial">math library</a> +* <a href="http://lua-users.org/wiki/IoLibraryTutorial">io library</a> +* <a href="http://lua-users.org/wiki/OsLibraryTutorial">os library</a> + +Übrigends, die gesamte Datei ist gültiges Lua. Speichere sie als learn.lua und +starte sie als "lua learn.lua" ! + +Die Erstfassung ist von tylerneylon.com, und ist auch hier verfügbar: <a href="https://gist.github.com/tylerneylon/5853042">github gist</a>. Viel Spaß mit Lua! diff --git a/de-de/make-de.html.markdown b/de-de/make-de.html.markdown new file mode 100644 index 00000000..22c14a69 --- /dev/null +++ b/de-de/make-de.html.markdown @@ -0,0 +1,260 @@ +---
 +language: make
 +contributors:
 +    - ["Robert Steed", "https://github.com/robochat"]
 +translators:
 +  - ["Martin Schimandl", "https://github.com/Git-Jiro"]
 +filename: Makefile-de
 +lang: de-de
 +---
 +
 +Eine Makefile definiert einen Graphen von Regeln um ein Ziel (oder Ziele)
 +zu erzeugen. Es dient dazu die geringste Menge an Arbeit zu verrichten um
 +ein Ziel in einklang mit dem Quellcode zu bringen. Make wurde berühmterweise
 +von Stuart Feldman 1976 übers Wochenende geschrieben. Make ist noch immer
 +sehr verbreitet (vorallem im Unix umfeld) obwohl es bereits sehr viel
 +Konkurrenz und Kritik zu Make gibt.
 +
 +Es gibt eine vielzahl an Varianten von Make, dieser Artikel beschäftig sich
 +mit der Version GNU Make. Diese Version ist standard auf Linux.
 +
 +```make
 +
 +# Kommentare können so geschrieben werden.
 +
 +# Dateien sollten Makefile heißen, denn dann können sie als `make <ziel>`
 +# aufgerufen werden. Ansonsten muss `make -f "dateiname" <ziel>` verwendet
 +# werden.
 +
 +# Warnung - Es sollten nur TABULATOREN zur Einrückung im Makefile verwendet
 +# werden. Niemals Leerzeichen!
 +
 +#-----------------------------------------------------------------------
 +# Grundlagen
 +#-----------------------------------------------------------------------
 +
 +# Eine Regel - Diese Regel wird nur abgearbeitet wenn die Datei file0.txt
 +# nicht existiert.
 +file0.txt:
 +	echo "foo" > file0.txt
 +	# Selbst Kommentare in der 'Rezept' Sektion werden an die Shell
 +	# weitergegeben. Versuche `make file0.txt` oder einfach `make`
 +	# die erste Regel ist die Standard-Regel.
 +
 +
 +# Diese Regel wird nur abgearbeitet wenn file0.txt aktueller als file1.txt ist.
 +file1.txt: file0.txt
 +	cat file0.txt > file1.txt
 +	# Verwende die selben Quoting-Regeln wie die Shell
 +	@cat file0.txt >> file1.txt
 +	# @ unterdrückt die Ausgabe des Befehls an stdout.
 +	-@echo 'hello'
 +	# - bedeutet das Make die Abarbeitung fortsetzt auch wenn Fehler passieren.
 +	# Versuche `make file1.txt` auf der Kommandozeile.
 +
 +# Eine Regel kann mehrere Ziele und mehrere Voraussetzungen haben.
 +file2.txt file3.txt: file0.txt file1.txt
 +	touch file2.txt
 +	touch file3.txt
 +
 +# Make wird sich beschweren wenn es mehrere Rezepte für die gleiche Regel gibt.
 +# Leere Rezepte zählen nicht und können dazu verwendet werden weitere 
 +# Voraussetzungen hinzuzufügen.
 +
 +#-----------------------------------------------------------------------
 +# Phony-Ziele
 +#-----------------------------------------------------------------------
 +
 +# Ein Phony-Ziel ist ein Ziel das keine Datei ist.
 +# Es wird nie aktuell sein, daher wird Make immer versuchen es abzuarbeiten
 +all: maker process
 +
 +# Es ist erlaubt Dinge ausserhalb der Reihenfolge zu deklarieren.
 +maker:
 +	touch ex0.txt ex1.txt
 +
 +# Um das Fehlschlagen von Phony-Regeln zu vermeiden wenn eine echte Datei den
 +# selben namen wie ein Phony-Ziel hat:
 +.PHONY: all maker process
 +# Das ist ein spezielles Ziel. Es gibt noch ein paar mehr davon.
 +
 +# Eine Regel mit einem Phony-Ziel als Voraussetzung wird immer abgearbeitet
 +ex0.txt ex1.txt: maker
 +
 +# Häufige Phony-Ziele sind: all make clean install ...
 +
 +#-----------------------------------------------------------------------
 +# Automatische Variablen & Wildcards
 +#-----------------------------------------------------------------------
 +
 +process: file*.txt	# Eine Wildcard um Dateinamen zu Vergleichen
 +	@echo $^	# $^ ist eine Variable die eine Liste aller
 +			# Voraussetzungen enthält.
 +	@echo $@	# Namen des Ziels ausgeben.
 +	#(Bei mehreren Ziel-Regeln enthält $@ den Verursacher der Abarbeitung
 +	#der Regel.)
 +	@echo $<	# Die erste Voraussetzung aus der Liste
 +	@echo $?	# Nur die Voraussetzungen die nicht aktuell sind.
 +	@echo $+	# Alle Voraussetzungen inklusive Duplikate (nicht wie Üblich)
 +	#@echo $|	# Alle 'order only' Voraussetzungen
 +
 +# Selbst wenn wir die Voraussetzungen der Regel aufteilen, $^ wird sie finden.
 +process: ex1.txt file0.txt
 +# ex1.txt wird gefunden werden, aber file0.txt wird dedupliziert.
 +
 +#-----------------------------------------------------------------------
 +# Muster
 +#-----------------------------------------------------------------------
 +
 +# Mit Mustern kann man make beibringen wie Dateien in andere Dateien
 +# umgewandelt werden.
 +
 +%.png: %.svg
 +	inkscape --export-png $^
 +
 +# Muster-Vergleichs-Regeln werden nur abgearbeitet wenn make entscheidet das Ziel zu
 +# erzeugen
 +
 +# Verzeichnis-Pfade werden normalerweise bei Muster-Vergleichs-Regeln ignoriert.
 +# Aber make wird versuchen die am besten passende Regel zu verwenden.
 +small/%.png: %.svg
 +	inkscape --export-png --export-dpi 30 $^
 +
 +# Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden die es
 +# findet.
 +%.png: %.svg
 +	@echo this rule is chosen
 +
 +# Allerdings wird make die erste Muster-Vergleicher-Regel verwenden die das
 +# Ziel erzeugen kann.
 +%.png: %.ps
 +	@echo this rule is not chosen if *.svg and *.ps are both present
 +
 +# Make hat bereits ein paar eingebaute Muster-Vergleichs-Regelen. Zum Beispiel
 +# weiß Make wie man aus *.c Dateien *.o Dateien erzeugt.
 +
 +# Ältere Versionen von Make verwenden möglicherweise Suffix-Regeln anstatt
 +# Muster-Vergleichs-Regeln.
 +.png.ps:
 +	@echo this rule is similar to a pattern rule.
 +
 +# Aktivieren der Suffix-Regel
 +.SUFFIXES: .png
 +
 +#-----------------------------------------------------------------------
 +# Variablen
 +#-----------------------------------------------------------------------
 +# auch Makros genannt.
 +
 +# Variablen sind im Grunde genommen Zeichenketten-Typen.
 +
 +name = Ted
 +name2="Sarah"
 +
 +echo:
 +	@echo $(name)
 +	@echo ${name2}
 +	@echo $name    # Das funktioniert nicht, wird als $(n)ame behandelt.
 +	@echo $(name3) # Unbekannte Variablen werden als leere Zeichenketten behandelt.
 +
 +# Es git 4 Stellen um Variablen zu setzen.
 +# In Reihenfolge der Priorität von höchster zu niedrigster:
 +# 1: Befehls-Zeilen Argumente
 +# 2: Makefile
 +# 3: Shell Umbebungs-Variablen - Make importiert diese automatisch.
 +# 3: MAke hat einige vordefinierte Variablen.
 +
 +name4 ?= Jean
 +# Setze die Variable nur wenn es eine gleichnamige Umgebungs-Variable noch
 +# nicht gibt.
 +
 +override name5 = David
 +# Verhindert das Kommando-Zeilen Argumente diese Variable ändern können.
 +
 +name4 +=grey
 +# Werte an eine Variable anhängen (inkludiert Leerzeichen).
 +
 +# Muster-Spezifische Variablen Werte (GNU Erweiterung).
 +echo: name2 = Sara # Wahr innerhalb der passenden Regel und auch innerhalb
 +	# rekursiver Voraussetzungen (ausser wenn es den Graphen zerstören
 +	# kann wenn es zu kompilizert wird!)
 +
 +# Ein paar Variablen die von Make automatisch definiert werden.
 +echo_inbuilt:
 +	echo $(CC)
 +	echo ${CXX)}
 +	echo $(FC)
 +	echo ${CFLAGS)}
 +	echo $(CPPFLAGS)
 +	echo ${CXXFLAGS}
 +	echo $(LDFLAGS)
 +	echo ${LDLIBS}
 +
 +#-----------------------------------------------------------------------
 +# Variablen 2
 +#-----------------------------------------------------------------------
 +
 +# Der erste Typ von Variablen wird bei jeder verwendung ausgewertet.
 +# Das kann aufwendig sein, daher exisitert ein zweiter Typ von Variablen.
 +# Diese werden nur einmal ausgewertet. (Das ist eine GNU make Erweiterung)
 +
 +var := hello
 +var2 ::=  $(var) hello
 +#:= und ::= sind äquivalent.
 +
 +# Diese Variablen werden prozedural ausgwertet (in der Reihenfolge in der sie
 +# auftauchen), die stehen daher im wiederspruch zum Rest der Sprache!
 +
 +# Das funktioniert nicht
 +var3 ::= $(var4) and good luck
 +var4 ::= good night
 +
 +#-----------------------------------------------------------------------
 +# Funktionen
 +#-----------------------------------------------------------------------
 +
 +# Make verfügt über eine vielzahl von Funktionen.
 +
 +sourcefiles = $(wildcard *.c */*.c)
 +objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
 +
 +# Das Format ist $(func arg0,arg1,arg2...)
 +
 +# Ein paar Beispiele
 +ls:	* src/*
 +	@echo $(filter %.txt, $^)
 +	@echo $(notdir $^)
 +	@echo $(join $(dir $^),$(notdir $^))
 +
 +#-----------------------------------------------------------------------
 +# Direktiven
 +#-----------------------------------------------------------------------
 +
 +# Inkludiere andere Makefile, sehr praktisch für platformspezifischen Code
 +include foo.mk
 +
 +sport = tennis
 +# Konditionale kompiliereung
 +report:
 +ifeq ($(sport),tennis)
 +	@echo 'game, set, match'
 +else
 +	@echo "They think it's all over; it is now"
 +endif
 +
 +# Es gibt auch ifneq, ifdef, ifndef
 +
 +foo = true
 +
 +ifdef $(foo)
 +bar = 'hello'
 +endif
 +```
 +
 +
 +### Mehr Resourcen
 +
 ++ [gnu make documentation](https://www.gnu.org/software/make/manual/)
 ++ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/)
 ++ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)
 +
 diff --git a/de-de/markdown-de.html.markdown b/de-de/markdown-de.html.markdown index 6a90980b..2c838660 100644 --- a/de-de/markdown-de.html.markdown +++ b/de-de/markdown-de.html.markdown @@ -56,7 +56,7 @@ __Genau wie dieser.__  **_Dieser auch!_**  *__Und dieser genau so!__* -<!-- In "Github Flavored Markdown", dem von Github verwendeten Dialekt / Parser, +<!-- In "GitHub Flavored Markdown", dem von GitHub verwendeten Dialekt / Parser,  gibt es auch noch durchgestrichenen Text: -->  ~~Dieser Text wird durchgestrichen dargestellt.~~ @@ -148,7 +148,7 @@ indem du eine Zeile mit vier Leerzeichen oder einem Tabulator einrückst -->  Hermann hatte nicht die leiseste Ahnung, was dieses `go_to()` bedeuten könnte! -<!-- In "Github Flavored Markdown" gibt es für Code nocheinmal eine +<!-- In "GitHub Flavored Markdown" gibt es für Code nocheinmal eine  besondere Syntax -->  \`\`\`ruby <!-- in "echt" musst du die Backslashes entfernen: ```ruby ! --> @@ -157,7 +157,7 @@ def foobar  end  \`\`\` <!-- hier auch keine Backslashes, nur ``` --> -<-- der obige Block muss nicht extra eingerückt werden, außerdem fügt Github +<-- der obige Block muss nicht extra eingerückt werden, außerdem fügt GitHub  Syntax-Highlighting für die nach dem ``` angegebene Sprache hinzu -->  <!-- Horizontale Linie (<hr />) --> @@ -233,7 +233,7 @@ Ich würde *diesen Teil gerne mit Sternen umschließen*, doch ohne dass er kursi  wird. Also mache ich folgendes: \*Ich umschließe diesen Text mit Sternen\*!  <!-- Tabellen --> -<!-- Tabellen gibt es bis jetzt nur in "Github Flavored Markdown". +<!-- Tabellen gibt es bis jetzt nur in "GitHub Flavored Markdown".  Zudem sind sie ziemlich mühselig, aber wenn du es wirklich wissen willst: -->  | Spalte1      | Spalte2  | Spalte3       | @@ -253,4 +253,4 @@ Ganz schön hässlich | vielleicht doch lieber | wieder aufhören  Mehr Informationen gibt es in [John Gruber's offiziellem Blog-Post](http://daringfireball.net/projects/markdown/syntax)  und bei Adam Pritchards [grandiosem Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). -Infos zu Github Flavored Markdown [gibt es hier](https://help.github.com/articles/github-flavored-markdown).
\ No newline at end of file +Infos zu GitHub Flavored Markdown [gibt es hier](https://help.github.com/articles/github-flavored-markdown).
\ No newline at end of file diff --git a/de-de/tcl-de.html.markdown b/de-de/tcl-de.html.markdown new file mode 100644 index 00000000..4f3b8820 --- /dev/null +++ b/de-de/tcl-de.html.markdown @@ -0,0 +1,475 @@ +--- +language: Tcl +contributors: +    - ["Poor Yorick", "http://pooryorick.com/"] +translators: +    - ["Martin Schimandl", "https://github.com/Git-Jiro"] +filename: learntcl-de.tcl +lang: de-de +--- + +Tcl wurde kreiert von [John Ousterhout](http://wiki.tcl.tk/John Ousterout) als +eine wiederverwendbare Script-Sprache für Chip-Design Werkzeuge die er kreiert +hat. Im Jahre 1997 wurde er mit dem [ACM Software System +Award](http://en.wikipedia.org/wiki/ACM_Software_System_Award) für Tcl +ausgezeichnet. Tcl kann sowohl als eingebettete Scipt-Sprache als auch als +allgemeine Programmier-Sprache verwendet werden. Tcl kann auch als portable +C-Bibliothek verwendet werden. Sogar in Fällen in denen die Script-Fähigkeiten +nicht nötig sind. Denn Tcl stellt Daten-Strukturen wie dynamische Zeichenketten, +Listen und Hash-Tabellen bereit. Die C-Bilbiothek stellt auch portable +Funktionen zur Verfügung: Laden von dynamischen Bibliotheken, Zeichenketten +formatierung und Code Konversion, Dateisystem Operationen, Netzwerk Operationen +und mehr. + + +Verschiedenste herausragende Fähigkeiten von Tcl: + +* Praktische Cross-Platform Netzwerk-API + +* Vollständig virtualisiertes Dateisystem + +* Stapelbare I/O Kanäle + +* Asynchron bis zum Kern + +* Vollständige Ko-Routinen + +* Robustes und einfach zu verwendendes Thread-Modell + + +Wenn Lisp ein Listen-Prozessor ist, dann ist TCl ein Zeichenketten-Prozessor. +Alle Werte sind Zeichenketten. Eine Liste ist ein Zeichenketten-Format. Eine +Prozedur-Definition ist ein Zeichenketten-Format. Um leistungsfähig zu sein, +werden Tcl-intern diese Zeichenketten in Strukutierter-Form gepuffert. Ein +Beispiel: Der "list" Befehl arbeitet mit diesen internen gepufferten  +Repräsentationen. Tcl kümmert sich selbständig darum die String-Repräsentationen +zu aktualisieren, falls dies im Skript benötigt werden sollten. Das Kopieren- +beim-Schreiben-Design von Tcl erlaubt es Skript-Authoren mit großen Daten- +Strukturen zu arbeiten ohne zuätzlichen Speicher-Overhead. Prozeduren werden +automatisch byte-kompiliert außer sie verwenden dynamsiche Befehle wie zum +Beispiel "uplevel", "upvar und "trace". + +Es ist eine freude in Tcl zu programmieren. Hacker-Typen werden gefallen daran +finden, wenn sie Lisp, Forth oder Smalltalk interessant finden. Tcl wird auch +Ingenieuren und Wissenshaftlern gefallen die nur den Job erledigen wollen, +und zwar mit Werkzeugen die sich ihrem Willen anpassen. Bei Tcl ist jegliche +funktionalität in Befehlen ausgeführt, selbst Dinge wie Schleifen und +Mathematische-Funktionen die bei anderen Sprachen normalerweise Teil der Syntax +sind. Das erlaubt Tcl in den Hintergrund von Domänen spezischen Sprachen zu +treten die das jeweilige Projekt gerade benötigt. Die Tcl-Syntax ist sehr +leichtgewichtig. Sie ist selbst leichtgewichtiger als die Syntax von Lisp. +Tcl steht dir einfach nicht im Weg. + + +```tcl +#! /bin/env tclsh + +################################################################################ +## 1. Richtlinien  +################################################################################ + +# Tcl ist nicht Bash oder C! Das muss gesagt werden, denn standard Shell-Quoting +# funktioniert fast mit Tcl. Daher glauben viele sie können diese Syntax für +# Tcl übernehmen. Am Beginn funktioniert das meist, führt aber schnell zu  +# Frustrationen wenn die Skripte komplexer werden. + +# Eckige-Klammern sind nur Quoting-Mechanismen, keine Code-Block-Konstruktoren +# und auch keine Listen-Konstruktoren. In Tcl gibt es diese beiden Dinge nicht. +# Eckige-Klammern werden verwendet um Spezial-Zeichen in Prozeduren zu escapen +# und in Zeichenketten die als Listen formattiert sind. + +################################################################################ +## 2. Syntax  +################################################################################ + +# Jede Zeile ist ein Befehl. Das erste Wort ist der Name des Befehls, jedes +# weitere Wort ist ein Argument des Befehls. Wörter sind begrenzt durch +# Leerzeichen. Da jedes Wort auch ein String ist, sind keine speziellen +# auszeichnungen wie Anführungs-Zeichen, Klammern oder Backslashes nötig. +# Selbst wenn Anführungs-Zeichen verwendet werden, denn sie sind ja keine +# String-Konstruktoren, sondern nur Escape-Zeichen. + +set greeting1 Sal  +set greeting2 ut +set greeting3 ations + + +# Strichpunkte begrenzen auch Befehle +set greeting1 Sal; set greeting2 ut; set greeting3 ations  + + +# Das Dollar-Zeichen zeigt eine Variablen-Substitution an. +set greeting $greeting1$greeting2$greeting3 + + +# Eckige-Klammern zeigen Befehls-Substitionen an. Das Ergebnis des Befehls wird an +# Stelle des Klammern-Ausdrucks eingefügt. Wenn man dem "set" Befehl nur den +# Namen einer Variablen übergibt, gibt er den Wert der Variablen zurück. +set greeting $greeting1$greeting2[set greeting3] + + +# Befehls-Substitution sollte eigentlich Script-Substitution heißen, denn ein +# komplettes Script, und nicht nur ein Befehl, kann zwischen die Eckigen-Klammern +# geschrieben werden. Der "incr" Befehl erhöht den Wert einer Variable um 1 +# und gibt den neuen Wert der Variable zurück. +set greeting $greeting[ +	incr i +	incr i +	incr i +] + + +# Der Backslash unterdrück die Bedeutung von Sonderzeichen +set amount \$16.42 + + +# Der Backslash macht bestimmte Zeichen zu Sonderzeichen +puts lots\nof\n\n\n\n\n\nnewlines + +# Ein Wort das in geschweiften Klammern eingeschlossen wurde ist von jeglichen +# speziellen Interpretationen ausgeschlossen. Eine Ausnahme bilden Backslashes +# vor geschweiften Klammern, hiermit wird die geschweifte Klammer von der Suche +# nach der schließenden geschweiften Klammer ausgeschlossen. +set somevar { +    Das ist ein literales $ Zeichen, diese geschweifte Klammer \} wird nicht +    als Ende interpretiert. +}  + + +# Bei einem Wort das in doppelten Anführungszeichen steht verlieren Leerzeichen +# ihre spezielle Bedeutung. +set name Neo +set greeting "Hallo, $name" + + +#Variablen-Namen können irgend eine Zeichenkette sein. +set {first name} New + + +# Die Geschweifte-Klammern-Form der Variablen-Substitution kann sehr komplexe +# Variblen-Namen handhaben. +set greeting "Hello, ${first name}" + + +# Der "set" Befehl kann immer anstatt einer Variablen-Substition verwendet +# werden. +set greeting "Hello, [set {first name}]" + + +# Mit dem Expansions-Operator "{*}" werden Wörter innerhalb eines Wortes wieder +# individuell als Teile des aktuellen Befehls behandelt. +set {*}{name Neo} + +# Ist Äquivalent zu +set name Neo + + +# Ein Array ist eine spezielle Varible die also Kontainer für andere Variablen +# dient. +set person(name) Neo +set person(gender) male +set greeting "Hello, $person(name)" + + +# Ein Namensraum enthält Befehle und Variablen +namespace eval people { +    namespace eval person1 { +        variable name Neo +    } +} + + +#Der volle Name einer Variablen beihaltet den/die umschließenden +# Namensraum/Namensräume begrenzt durch zwei Doppelpunkte. +set greeting "Hello $people::person1::name" +``` + +```tcl +################################################################################ +## 3. Einige Notizen  +################################################################################ + +# Jede weitere Funktion ist über Befehle implementiert. Von nun an kommt keine +# neue Syntax hinzu. Alles weitere das es über Tcl zu lernen gibt ist das +# Verhalten individueller Befehle und die bedeutung ihrer Argumente. + + +# Um einen Interpreter zu bekommen mit dem man nichts mehr machen kann, lösche +# einfach den globalen Namensraum. Das ist nicht sehr sinnvoll, zeigt aber die +# Natur von Tcl. +namespace delete :: + + +# Wegen des Verhaltens der Namens-Auflösung ist es sicherer den "variable" +# Befehl zu verwenden um in einem Namensraum einen Wert zu deklarieren oder +# zuzuweisen. Wenn eine Variable mit dem namen "name" bereits im globalen +# Namensraum existiert, bewirkt der "set" Befehl das der globalen Variable ein +# Wert zugewiesen wird, anstatt eine Variable im lokalen Namensraum zu erzeugen +namespace eval people { +    namespace eval person1 { +        variable name Neo +    } +} + + +# Es kann immer der vollständige Name einer Variable verwendet werden, falls +# gewünscht. +set people::person1::name Neo + + + +################################################################################ +## 4. Befehle  +################################################################################ + +# Berechnungen werde mit dem "expr" Befehl durchgeführt. +set a 3 +set b 4 +set c [expr {$a + $b}] + +# Since "expr" performs variable substitution on its own, brace the expression +# to prevent Tcl from performing variable substitution first.  See + +# Da der "expr" Befehl eigene Variablen-Substitutionen durchführt, setze den +# zu berechnenden Ausdruck in Eckige-Klammern. Das hindert Tcl daran Variablen- +# Substitutionen durchzuführen. Für Details siehe: +# "http://wiki.tcl.tk/Brace%20your%20#%20expr-essions" + + +# Der "expr" Befehl versteht Variablen- und Befehls-Substitutionen +set c [expr {$a + [set b]}] + + +# Der "expr" Befehl stellt Mathematische-Funktionen zur Verfügung. +set c [expr {pow($a,$b)}] + + +# Mathematische Operatoren sind als Befehle auch im Namensraum  +# ::tcl::mathop verfügbar. +::tcl::mathop::+ 5 3 + +# Befehle können aus anderen Namensräumen importiert werden. +namespace import ::tcl::mathop::+ +set result [+ 5 3] + + +# Neu Befehle werden mit dem "proc" Befehl gebildet. +proc greet name { +    return "Hello, $name!" +} + +#Es können mehrere Parameter spezifiziert werden. +proc greet {greeting name} { +    return "$greeting, $name!" +} + + +# Wie bereits erwähnt, geschwungene Klammern erzeugen keinen Code-Block. +# Jeder Wert, sogar das dritte Argument für den "proc" Befehl ist eine +# Zeichenkette. Der vorherige Befehl kann daher auch ohne +# geschwungene Klammern geschrieben werden: +proc greet greeting\ name return\ \"Hello,\ \$name! + + + +# Wenn der letzte Parameter der literale Wert "args" ist, sammelt dieser Wert +# alle übrigen Argumente des Befehls ein wenn dieser aufgerufen wird. +proc fold {cmd args} { +    set res 0 +    foreach arg $args { +        set res [$cmd $res $arg] +    } +} +fold ::tcl::mathop::* 5 3 3 ;# ->  45 + + +# Bedingte Ausführung ist auch als Befehl implementiert +if {3 > 4} { +    puts {This will never happen} +} elseif {4 > 4} { +    puts {This will also never happen} +} else { +    puts {This will always happen} +} + + +# Auch Schleifen sind Befehle. Das erste, zweite und dritte Argument des "for" +# Befehls wird als mathematischer Ausdruck behandelt. +for {set i 0} {$i < 10} {incr i} { +    set res [expr {$res + $i}] +} + + +# Das erste Argument des "while" Befehls wird auch als mathematischer Ausdruck +# behandelt. +set i 0 +while {$i < 10} { +    incr i 2 +} + + +# Eine Liste ist eine speziell formatierte Zeichenkette. Im einfachsten Fall +# genügen Leerzeichen als Trennzeichen zwischen den einzelnen Werten. +set amounts 10\ 33\ 18  +set amount [lindex $amounts 1] + + +# Geschwungene Klammern und Backslashes können verwendet werden um komplexe +# Werte in einer Liste zu formatieren. Eine Liste sieht aus wie ein Skript, +# allerdings verlieren verlieren Zeilenumbrüche und Doppelüunkte ihre  +# besondere Bedeutung. Diese Funktionalität macht Tcl homoikonisch. Die +# folgende Liste enhtält drei Elemente. +set values { + +    one\ two + +    {three four} + +    five\{six + +} + + +# Da Listen auch Zeichenketten sind, kann man Zeichenketten-Operationen auf +# ihnen anwenden. Allerdings mit dem Risiko die Formatierung der Liste zu +# beschädigen. +set values {one two three four} +set values [string map {two \{} $values] ;# $values is no-longer a \ +    properly-formatted listwell-formed list + + +# Der sicherste Weg korrekt formatierte Liste zu erzeugen, ist den "list" +# Befehl zu verwenden. +set values [list one \{ three four] +lappend values { } ;# Ein Leerzeichen als Element der Liste hinzufügen + + +# Mit "eval" können Werte als Skripts evaluiert weden. +eval { +    set name Neo +    set greeting "Hello, $name" +} + + +# Eine Liste kann immer an "eval" übergeben werden, solange die Liste einen +# einzigen Befehl entält. +eval {set name Neo} +eval [list set greeting "Hello, $name"] + + +# Daher: Wenn "eval" verwendet wird, verwende [list] um den gewünschten Befehl +# aufzubauen. +set command {set name} +lappend command {Archibald Sorbisol} +eval $command + + +# Es ist ein häufiger Fehler die Listen funktionen beim Aufbauen von Listen +# nicht zu verwenden. +set command {set name} +append command { Archibald Sorbisol} +eval $command ;# Hier passiert eine Fehler, denn der "set" Befehl hat nun zu \ +    viele Argumente {set name Archibald Sorbisol} + + +# Dieser Fehler kann auch leicht beim "subst" Befehl passieren. +set replacement {Archibald Sorbisol} +set command {set name $replacement} +set command [subst $command]  +eval $command ;# The same error as before: too many arguments to "set" in \ +    {set name Archibald Sorbisol} + + +# Die korrekte Vorgangsweise ist es den substituierten Wert mit dem "list" +# Befehl zu formatieren. +set replacement [list {Archibald Sorbisol}] +set command {set name $replacement} +set command [subst $command]  +eval $command + + +# Der "list" Befehl wird sehr häufig verwendet um Werte zu formatieren die +# in Tcl Skript Vorlagen substituiert werden. Es gibt dazu viele Beispiele, +# siehe unterhalb. + + +# Der "apply" Befehl evaluiert eine Zeichenkette als Befehl. +set cmd {{greeting name} { +    return "$greeting, $name!" +}} +apply $cmd Whaddup Neo + + +# Der "uplevel" Befehl evaluiert ein Skript in einem höher liegenden +Gültigkeitsbereich. +proc greet {} { +	uplevel {puts "$greeting, $name"} +} + +proc set_double {varname value} { +	if {[string is double $value]} { +		uplevel [list variable $varname $value] +	} else { +		error [list {not a double} $value] +	} +} + + +# Der "upvar" Befehl verknüpft eine Variable im aktuellen Gültigkeitsbereich +# mit einer Variable in einem höher liegenden Gültigkeitsbereich. +proc set_double {varname value} { +	if {[string is double $value]} { +		upvar 1 $varname var +		set var $value +	} else { +		error [list {not a double} $value] +	} +} + + +# Werde den eingebauten "while" Befehl los. +rename ::while {} + + +# Definieren einen neuen "while" Befehl mit hilfe des "proc" Befehls. +# Ausführlichere Fehler-Behandlung wird dem Leser als Übung überlassen. +proc while {condition script} { +    if {[uplevel 1 [list expr $condition]]} { +        uplevel 1 $script +        tailcall [namespace which while] $condition $script +    } +} + + +# Der "coroutine" Befehl erzeugt einen separaten Call-Stack, zusammen mit einem +# Befehl um diesem Call-Stack zu verwenden. Der "yield" Befehl unterbricht +# die Ausführung des aktuellen Call-Stacks. +proc countdown {} { +	#send something back to the initial "coroutine" command +	yield + +	set count 3  +	while {$count > 1} { +		yield [incr count -1] +	} +	return 0 +} +coroutine countdown1 countdown +coroutine countdown2 countdown +puts [countdown 1] ;# -> 2  +puts [countdown 2] ;# -> 2  +puts [countdown 1] ;# -> 1  +puts [countdown 1] ;# -> 0  +puts [coundown 1] ;# -> invalid command name "countdown1" +puts [countdown 2] ;# -> 1  + + +``` + +## Referenzen + +[Official Tcl Documentation](http://www.tcl.tk/man/tcl/) + +[Tcl Wiki](http://wiki.tcl.tk) + +[Tcl Subreddit](http://www.reddit.com/r/Tcl) | 
