diff options
Diffstat (limited to 'de-de')
-rw-r--r-- | de-de/clojure-macros-de.html.markdown | 161 | ||||
-rw-r--r-- | de-de/elm-de.html.markdown | 376 | ||||
-rw-r--r-- | de-de/perl-de.html.markdown | 4 | ||||
-rw-r--r-- | de-de/processing-de.html.markdown | 498 | ||||
-rw-r--r-- | de-de/pug-de.html.markdown | 208 | ||||
-rw-r--r-- | de-de/ruby-de.html.markdown | 782 | ||||
-rw-r--r-- | de-de/vim-de.html.markdown | 282 |
7 files changed, 1956 insertions, 355 deletions
diff --git a/de-de/clojure-macros-de.html.markdown b/de-de/clojure-macros-de.html.markdown new file mode 100644 index 00000000..088a29a8 --- /dev/null +++ b/de-de/clojure-macros-de.html.markdown @@ -0,0 +1,161 @@ +--- +language: "clojure macros" +filename: learnclojuremacros-de.clj +contributors: + - ["Adam Bard", "http://adambard.com/"] +translators: + - ["Dennis Keller", "https://github.com/denniskeller"] +lang: de-de +--- + +Wie mit allen Lisps besitzt auch Clojure die inhärente [Homoikonizität](https://en.wikipedia.org/wiki/Homoiconic), +die dir den vollen Zugang der Sprache gibt, um + Code-Generierungsroutinen zu schreiben. Diese werden "Macros" genannt. +Macros geben dir eine leistungsarke Möglichkeit, die Sprache +an deine Bedürfnisse anzupassen. + +Sei aber vorsichtig, es wird als schlechter Stil angesehen, wenn du +ein Macro schreibst, obwohl eine Funktion genausogut funktionieren würde. +Verwende nur dann ein Macro, wenn du Kontrolle darüber brauchst, wann oder ob Argumente in einer Form evaluiert werden. + +Wenn du mit Clojure vertraut sein möchtest, stelle sicher, dass du alles in [Clojure in Y Minutes](/docs/clojure/) verstehst. + +```clojure +;; Definiere ein Macro mit defmacro. Dein Macro sollte eine Liste zurückgeben, +;; die als Clojure Code evaluiert werden kann. +;; +;; Dieses Macro ist das Gleiche, als ob du (reverse "Hallo Welt") geschrieben +;; hättest +(defmacro my-first-macro [] + (list reverse "Hallo Welt")) + +;; Inspiziere das Ergebnis eines Macros mit macroexpand oder macroexpand-1. +;; +;; Beachte, dass der Aufruf zitiert sein muss. +(macroexpand '(my-first-macro)) +;; -> (#<core$reverse clojure.core$reverse@xxxxxxxx> "Hallo Welt") + +;; Du kannst das Ergebnis von macroexpand direkt auswerten. +(eval (macroexpand '(my-first-macro))) +; -> (\t \l \e \W \space \o \l \l \a \H) + +;; Aber du solltest diese prägnante und funktionsähnliche Syntax verwenden: +(my-first-macro) ; -> (\t \l \e \W \space \o \l \l \a \H) + +;; Du kannst es dir leichter machen, indem du die Zitiersyntax verwendest +;; um Listen in ihren Makros zu erstellen: +(defmacro my-first-quoted-macro [] + '(reverse "Hallo Welt")) + +(macroexpand '(my-first-quoted-macro)) +;; -> (reverse "Hallo Welt") +;; Beachte, dass reverse nicht mehr ein Funktionsobjekt ist, sondern ein Symbol + +;; Macros können Argumente haben. +(defmacro inc2 [arg] + (list + 2 arg)) + +(inc2 2) ; -> 4 + +;; Aber wenn du versuchst das mit einer zitierten Liste zu machen wirst du +;; einen Fehler bekommen, weil das Argument auch zitiert sein wird. +;; Um dies zu umgehen, bietet Clojure einee Art und Weise Macros zu zitieren: ` +;; In ` kannst du ~ verwenden um in den äußeren Bereich zu kommen. +(defmacro inc2-quoted [arg] + `(+ 2 ~arg)) + +(inc2-quoted 2) + +;; Du kannst die normalen destruktuierungs Argumente verwenden. Expandiere +;; Listenvariablen mit ~@. +(defmacro unless [arg & body] + `(if (not ~arg) + (do ~@body))) ; Erinnere dich an das do! + +(macroexpand '(unless true (reverse "Hallo Welt"))) +;; -> +;; (if (clojure.core/not true) (do (reverse "Hallo Welt"))) + +;; (unless) evaluiert und gibt body zurück, wenn das erste Argument falsch ist. +;; Andernfalls gibt es nil zurück + +(unless true "Hallo") ; -> nil +(unless false "Hallo") ; -> "Hallo" + +;; Die Verwendung Macros ohne Sorgfalt kann viel Böses auslösen, indem es +;; deine Variablen überschreibt +(defmacro define-x [] + '(do + (def x 2) + (list x))) + +(def x 4) +(define-x) ; -> (2) +(list x) ; -> (2) + +;; Um das zu verhindern kannst du gensym verwenden um einen eindeutigen +;; Identifikator zu bekommen +(gensym 'x) ; -> x1281 (oder etwas Ähnliches) + +(defmacro define-x-safely [] + (let [sym (gensym 'x)] + `(do + (def ~sym 2) + (list ~sym)))) + +(def x 4) +(define-x-safely) ; -> (2) +(list x) ; -> (4) + +;; Du kannst # innerhalb von ` verwenden um für jedes Symbol automatisch +;; ein gensym zu erstellen +(defmacro define-x-hygienically [] + `(do + (def x# 2) + (list x#))) + +(def x 4) +(define-x-hygienically) ; -> (2) +(list x) ; -> (4) + +;; Es ist üblich, Hilfsfunktionen mit Macros zu verwenden. Lass uns einige +;; erstellen, die uns helfen , eine (dumme) arithmetische Syntax +;; zu unterstützen +(declare inline-2-helper) +(defn clean-arg [arg] + (if (seq? arg) + (inline-2-helper arg) + arg)) + +(defn apply-arg + "Bekomme die Argumente [x (+ y)], gebe (+ x y) zurück" + [val [op arg]] + (list op val (clean-arg arg))) + +(defn inline-2-helper + [[arg1 & ops-and-args]] + (let [ops (partition 2 ops-and-args)] + (reduce apply-arg (clean-arg arg1) ops))) + +;; Wir können es sofort testen, ohne ein Macro zu erstellen +(inline-2-helper '(a + (b - 2) - (c * 5))) ; -> (- (+ a (- b 2)) (* c 5)) + +; Allerdings, brauchen wir ein Macro, wenn wir es zur Kompilierungszeit +; ausführen wollen +(defmacro inline-2 [form] + (inline-2-helper form)) + +(macroexpand '(inline-2 (1 + (3 / 2) - (1 / 2) + 1))) +; -> (+ (- (+ 1 (/ 3 2)) (/ 1 2)) 1) + +(inline-2 (1 + (3 / 2) - (1 / 2) + 1)) +; -> 3 (eigentlich, 3N, da die Zahl zu einem rationalen Bruch mit / umgewandelt wird) +``` + +### Weiterführende Literatur + +[Macros schreiben](http://www.braveclojure.com/writing-macros/) + +[Offiziele Docs](http://clojure.org/macros) + +[Wann verwendet man Macros?](https://lispcast.com/when-to-use-a-macro/) diff --git a/de-de/elm-de.html.markdown b/de-de/elm-de.html.markdown new file mode 100644 index 00000000..08832327 --- /dev/null +++ b/de-de/elm-de.html.markdown @@ -0,0 +1,376 @@ +--- +language: Elm +filename: learnelm.elm +contributors: + - ["Max Goldstein", "http://maxgoldste.in/"] +translators: + - ["waynee95", "https://waynee95.me"] +lang: de-de +--- + +Elm ist eine pure funktionale Programmiersprache. Mit Elm werden GUIs +(grafische Benutzeroberfläche) für Webanwendungen erstellt. Durch die statische +Typisierung kann Elm viele Fehler schon bei der Kompilierung abfangen. Ein +Hauptmerkmal von Elm sind die ausführlichen und gut erklärten Fehlermeldungen. + +```haskell +-- Einzeilige Kommentare beginnen mit 2 Bindestrichen. +{- So wird ein mehrzeiliger Kommentar angelegt. +{- Diese können auch verschachtelt werden. -} +-} + +{-- Die Grundlagen --} + +-- Arithmetik +1 + 1 -- 2 +8 - 1 -- 7 +10 * 2 -- 20 + +-- Zahlen ohne Punkt sind entweder vom Typ Int oder Float. +33 / 2 -- 16.5 mit Division von Gleitkommazahlen +33 // 2 -- 16 mit ganzzahliger Division + +-- Exponenten +5 ^ 2 -- 25 + +-- Boolsche Werte +not True -- False +not False -- True +1 == 1 -- True +1 /= 1 -- False +1 < 10 -- True + +-- Strings (Zeichenketten) und Zeichen +"Das hier ist ein String." +'a' -- Zeichen + +-- Strings können konkateniert werden. +"Hello " ++ "world!" -- "Hello world!" + +{-- Listen und Tupel --} + +-- Jedes Element einer Liste muss vom gleichen Typ sein. Listen sind homogen. +["the", "quick", "brown", "fox"] +[1, 2, 3, 4, 5] +-- Das zweite Beispiel kann man auch mit Hilfe der "range" Funktion schreiben. +List.range 1 5 + +-- Listen werden genauso wie Strings konkateniert. +List.range 1 5 ++ List.range 6 10 == List.range 1 10 -- True + +-- Mit dem "cons" Operator lässt sich ein Element an den Anfang einer Liste anfügen. +0 :: List.range 1 5 -- [0, 1, 2, 3, 4, 5] + +-- Die Funktionen "head" und "tail" haben als Rückgabewert den "Maybe" Typ. +-- Dadurch wird die Fehlerbehandlung von fehlenden Elementen explizit, weil +-- man immer mit jedem möglichen Fall umgehen muss. +List.head (List.range 1 5) -- Just 1 +List.tail (List.range 1 5) -- Just [2, 3, 4, 5] +List.head [] -- Nothing +-- List.funktionsName bedeutet, dass diese Funktion aus dem "List"-Modul stammt. + +-- Tupel sind heterogen, jedes Element kann von einem anderen Typ sein. +-- Jedoch haben Tupel eine feste Länge. +("elm", 42) + +-- Das Zugreifen auf Elemente eines Tupels geschieht mittels den Funktionen +-- "first" und "second". +Tuple.first ("elm", 42) -- "elm" +Tuple.second ("elm", 42) -- 42 + +-- Das leere Tupel, genannt "Unit", wird manchmal als Platzhalter verwendet. +-- Es ist das einzige Element vom Typ "Unit". +() + +{-- Kontrollfluss --} + +-- Eine If-Bedingung hat immer einen Else-Zweig und beide Zweige müssen den +-- gleichen Typ haben. +if powerLevel > 9000 then + "WHOA!" +else + "meh" + +-- If-Bedingungen können verkettet werden. +if n < 0 then + "n is negative" +else if n > 0 then + "n is positive" +else + "n is zero" + +-- Mit dem Mustervergleich (pattern matching) kann man bestimmte Fälle direkt +-- behandeln. +case aList of + [] -> "matches the empty list" + [x]-> "matches a list of exactly one item, " ++ toString x + x::xs -> "matches a list of at least one item whose head is " ++ toString x +-- Mustervergleich geht immer von oben nach unten. Würde man [x] als letztes +-- platzieren, dann würde dieser Fall niemals getroffen werden, weil x:xs diesen +-- Fall schon mit einschließt (xs ist in dem Fall die leere Liste). + +-- Mustervergleich an einem Maybe Typ. +case List.head aList of + Just x -> "The head is " ++ toString x + Nothing -> "The list was empty." + +{-- Funktionen --} + +-- Die Syntax für Funktionen in Elm ist minimal. Hier werden Leerzeichen anstelle +-- von runden oder geschweiften Klammern verwendet. Außerdem gibt es kein "return" +-- Keyword. + +-- Eine Funktion wird durch ihren Namen, einer Liste von Parametern gefolgt von +-- einem Gleichheitszeichen und dem Funktionskörper angegeben. +multiply a b = + a * b + +-- Beim Aufruf der Funktion (auch Applikation genannt) werden die Argumente ohne +-- Komma übergeben. +multiply 7 6 -- 42 + +-- Partielle Applikation einer Funktion (Aufrufen einer Funktion mit fehlenden +-- Argumenten). Hierbei entsteht eine neue Funktion, der wir einen Namen geben. +double = + multiply 2 + +-- Konstanten sind Funktionen ohne Parameter. +answer = + 42 + +-- Funktionen, die Funktionen als Parameter haben, nennt man Funktionen höherer +-- Ordnung. In funktionalen Programmiersprachen werden Funktionen als "first-class" +-- behandelt. Man kann sie als Argument übergeben, als Rückgabewert einer Funktion +-- zurückgeben oder einer Variable zuweisen. +List.map double (List.range 1 4) -- [2, 4, 6, 8] + +-- Funktionen können auch als anonyme Funktion (Lambda-Funktionen) übergeben werden. +-- Diese werden mit einem Blackslash eingeleitet, gefolgt von allen Argumenten. +-- Die Funktion "\a -> a * 2" beschreibt die Funktion f(x) = x * 2. +List.map (\a -> a * 2) (List.range 1 4) -- [2, 4, 6, 8] + +-- Mustervergleich kann auch in der Funktionsdefinition verwendet werden. +-- In diesem Fall hat die Funktion ein Tupel als Parameter. (Beachte: Hier +-- werden die Werte des Tupels direkt ausgepackt. Dadurch kann man auf die +-- Verwendung von "first" und "second" verzichten.) +area (width, height) = + width * height + +area (6, 7) -- 42 + +-- Mustervergleich auf Records macht man mit geschweiften Klammern. +-- Bezeichner (lokale Variablen) werden mittels dem "let" Keyword angelegt. +-- (Mehr zu Records weiter unten!) +volume {width, height, depth} = + let + area = width * height + in + area * depth + +volume { width = 3, height = 2, depth = 7 } -- 42 + +-- Rekursive Funktion +fib n = + if n < 2 then + 1 + else + fib (n - 1) + fib (n - 2) + +List.map fib (List.range 0 8) -- [1, 1, 2, 3, 5, 8, 13, 21, 34] + +-- Noch eine rekursive Funktion (Nur ein Beispiel, verwende stattdessen immer +-- List.length!) +listLength aList = + case aList of + [] -> 0 + x::xs -> 1 + listLength xs + +-- Funktionsapplikation hat die höchste Präzedenz, sie binden stärker als Operatoren. +-- Klammern bietet die Möglichkeit der Bevorrangung. +cos (degrees 30) ^ 2 + sin (degrees 30) ^ 2 -- 1 +-- Als erstes wird die Funktion "degrees" mit dem Wert 30 aufgerufen. +-- Danach wird das Ergenis davon den Funktionen "cos", bzw. "sin" übergeben. +-- Dann wird das Ergebnis davon mit 2 quadriert und als letztes werden diese +-- beiden Werte dann addiert. + +{-- Typen und Typ Annotationen --} + +-- Durch Typinferenz kann der Compiler jeden Typ genau bestimmen. Man kann diese +-- aber auch manuell selber angeben (guter Stil!). +-- Typen beginnen immer mit eine Großbuchstaben. Dabei liest man "x : Typ" als +-- "x" ist vom Typ "Typ". +-- Hier ein paar übliche Typen: +5 : Int +6.7 : Float +"hello" : String +True : Bool + +-- Funktionen haben ebenfalls einen Typ. Dabei ist der ganz rechte Typ der +-- Rückgabetyp der Funktion und alle anderen sind die Typen der Parameter. +not : Bool -> Bool +round : Float -> Int + +-- Es ist guter Stil immer den Typ anzugeben, da diese eine Form von Dokumentation +-- sind. Außerdem kann so der Compiler genauere Fehlermeldungen geben. +double : Int -> Int +double x = x * 2 + +-- Funktionen als Parameter werden durch Klammern angegeben. Die folgende Funktion +-- ist nicht auf einen Typ festgelegt, sondern enthält Typvariablen (beginnend +-- mit Kleinbuchstaben). Die konkreten Typen werden erst bei Anwendung der +-- Funktion festgelegt. "List a" bedeutet, dass es sich um eine Liste mit +-- Elementen vom Typ "a" handelt. +List.map : (a -> b) -> List a -> List b + +-- Es gibt drei spezielle kleingeschriebene Typen: "number", "comparable" und +-- "appendable". +add : number -> number -> number +add x y = x + y -- funktioniert mit Ints und Floats. + +max :: comparable -> comparable -> comparable +max a b = if a > b then a else b -- funktioniert mit Typen, die vergleichbar sind. + +append :: appendable -> appendable -> appendable +append xs ys = xs ++ ys -- funktioniert mit Typen, die konkatenierbar sind. + +append "hello" "world" -- "helloworld" +append [1,1,2] [3,5,8] -- [1,1,2,3,5,8] + +{-- Eigene Datentypen erstellen --} + +-- Ein "Record" ist ähnlich wie ein Tupel, nur das jedes Feld einen Namne hat. +-- Dabei spielt die Reihenfolge keine Rolle. +{ x = 3, y = 7 } + +-- Um auf Werte eines Records zuzugreifen, benutzt man einen Punkt gefolgt +-- von dem Namen des Feldes. +{ x = 3, y = 7 }.x -- 3 + +-- Oder mit einer Zugriffsfunktion, welche aus einem Punkt und dem Feldnamen besteht. +.y { x = 3, y = 7 } -- 7 + +-- Wert eines Feldes ändern. (Achtung: Das Feld muss aber vorher schon vorhanden sein!) +{ person | + name = "George" } + +-- Mehrere Felder aufeinmal ändern unter Verwendung des alten Wertes. +{ particle | + position = particle.position + particle.velocity, + velocity = particle.velocity + particle.acceleration } + +-- Du kannst ein Record auch als Typ Annotation verwenden. +-- (Beachte: Ein Record Typ benutzt einen Doppelpunkt und ein Record Wert benutzt +-- ein Gleichheitszeichen!) +origin : { x : Float, y : Float, z : Float } +origin = + { x = 0, y = 0, z = 0 } + +-- Durch das "type" Keyword kann man einem existierenden Typen einen Namen geben. +type alias Point3D = + { x : Float, y : Float, z : Float } + +-- Der Name kann dann als Konstruktor verwendet werden. +otherOrigin : Point3D +otherOrigin = + Point3D 0 0 0 + +-- Aber es ist immernoch der selbe Typ, da es nur ein Alias ist! +origin == otherOrigin -- True + +-- Neben den Records gibt es auch noch so genannte Summentypen. +-- Ein Summentyp hat mehrere Konstruktoren. +type Direction = + North | South | East | West + +-- Ein Konstruktor kann außerdem noch andere Typen enthalten. Rekursion ist +-- auch möglich. +type IntTree = + Leaf | Node Int IntTree IntTree + +-- Diese können auch als Typ Annotation verwendet werden. +root : IntTree +root = + Node 7 Leaf Leaf + +-- Außerdem können auch Typvariablen verwendet werden in einem Konstruktor. +type Tree a = + Leaf | Node a (Tree a) (Tree a) + +-- Beim Mustervergleich kann man auf die verschiedenen Konstruktoren matchen. +leftmostElement : Tree a -> Maybe a +leftmostElement tree = + case tree of + Leaf -> Nothing + Node x Leaf _ -> Just x + Node _ subtree _ -> leftmostElement subtree + +{-- Module und Imports --} + +-- Die Kernbibliotheken und andere Bibliotheken sind in Module aufgeteilt. +-- Für große Projekte können auch eigene Module erstellt werden. + +-- Eine Modul beginnt mit ganz oben. Ohne diese Angabe befindet man sich +-- automatisch im Modul "Main". +module Name where + +-- Ohne genaue Angabe von Exports wird alles exportiert. Es können aber alle +-- Exporte explizit angegeben werden. +module Name (MyType, myValue) where + +-- Importiert das Modul "Dict". Jetzt kann man Funktionen mittels "Dict.insert" +-- aufrufen. +import Dict + +-- Importiert das "Dict" Modul und den "Dict" Typ. Dadurch muss man nicht "Dict.Dict" +-- verwenden. Man kann trotzdem noch Funktionen des Moduls aufrufen, wie "Dict.insert". +import Dict exposing (Dict) + +-- Abkürzung für den Modulnamen. Aufrufen der Funktionen mittels "C.funktionsName". +import Graphics.Collage as C + +{-- Kommandozeilen Programme --} + +-- Eine Elm-Datei kompilieren. +$ elm make MyFile.elm + +-- Beim ersten Aufruf wird Elm die "core" Bibliotheken installieren und eine +-- "elm-package.json"-Datei anlegen, die alle Informationen des Projektes +-- speichert. + +-- Der Reactor ist ein Server, welche alle Dateinen kompiliert und ausführt. +$ elm reactor + +-- Starte das REPL (read-eval-print-loop). +$ elm repl + +-- Bibliotheken werden durch den Github-Nutzernamen und ein Repository identifiziert. +-- Installieren einer neuen Bibliothek. +$ elm package install elm-lang/html +-- Diese wird der elm-package.json Datei hinzugefügt. + +-- Zeigt alle Veränderungen zwischen zwei bestimmten Versionen an. +$ elm package diff elm-lang/html 1.1.0 2.0.0 +-- Der Paketmanager von Elm erzwingt "semantic versioning"! +``` + +Elm ist eine besonders kleine Programmiersprache. Jetzt hast du genug Wissen an +deiner Seite, um dich in fast jedem Elm Code zurecht zu finden. + +Noch ein paar weitere hilfreiche Ressourcen (in Englisch): + +- Die [Elm Homepage](http://elm-lang.org/). Dort findest du: + + - [Anleitung zur Installierung von Elm](http://elm-lang.org/install) + - [Dokumentation](http://elm-lang.org/docs), sowie eine [Referenz zur Syntax](http://elm-lang.org/docs/syntax) + - Viele hilfreiche [Beispiele](http://elm-lang.org/examples) + +- Dokumentation der [Elm Kernbibliotheken](http://package.elm-lang.org/packages/elm-lang/core/latest/). Insbesondere: + + - [Basics](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics) (standardmäßig importiert) + - [Maybe](http://package.elm-lang.org/packages/elm-lang/core/latest/Maybe) sowie [Result](http://package.elm-lang.org/packages/elm-lang/core/latest/Result) (benutzt für Fehlerbehandlung) + - Datenstrukturen, wie [List](http://package.elm-lang.org/packages/elm-lang/core/latest/List), [Array](http://package.elm-lang.org/packages/elm-lang/core/latest/Array), [Dict](http://package.elm-lang.org/packages/elm-lang/core/latest/Dict), und [Set](http://package.elm-lang.org/packages/elm-lang/core/latest/Set) + - JSON [encoding](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Encode) und [decoding](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode) + +- [Die Elm Architektur](https://github.com/evancz/elm-architecture-tutorial#the-elm-architecture). + +- Die [Elm mailing list](https://groups.google.com/forum/#!forum/elm-discuss). diff --git a/de-de/perl-de.html.markdown b/de-de/perl-de.html.markdown index fd8fb3c4..13c00b01 100644 --- a/de-de/perl-de.html.markdown +++ b/de-de/perl-de.html.markdown @@ -8,9 +8,9 @@ translators: lang: de-de --- -Perl 5 ist eine sehr mächtige, funktionsreiche Programmiersprache mit über 25 Jahren Entwicklungsgeschichte. +Perl ist eine sehr mächtige, funktionsreiche Programmiersprache mit über 25 Jahren Entwicklungsgeschichte. -Perl 5 läuft auf über 100 Platformen von portablen Geräten bis hin zu Mainframes. Perl 5 ist geeignet für Rapid-Prototyping und auch groß angelegte Entwicklungs-Projekte. +Perl läuft auf über 100 Platformen von portablen Geräten bis hin zu Mainframes. Perl ist geeignet für Rapid-Prototyping und auch groß angelegte Entwicklungs-Projekte. ```perl # Einzeilige Kommentare beginnen mit dem # Symbol. diff --git a/de-de/processing-de.html.markdown b/de-de/processing-de.html.markdown new file mode 100644 index 00000000..42ae2233 --- /dev/null +++ b/de-de/processing-de.html.markdown @@ -0,0 +1,498 @@ +--- +language: processing +filename: learnprocessing.pde +contributors: + - ["Phone Thant Ko", "http://github.com/phonethantko"] + - ["Divay Prakash", "https://github.com/divayprakash"] +translators: + - ["caminsha", "https://github.com/caminsha"] +filename: processing-de.md +lang: de-de +--- + +## Einführung + +Processing ist eine Programmiersprache, welche es ermöglicht, digitale Kunst +und multimediale Inhalte zu erstellen. Mit Processing können Personen ohne +Programmiererfahrung die Grundlagen der Computerprogrammierung in einem +visuellen Kontext erlernen. + +Obwohl Processing von Java beeinflusst wurde und auf Java basiert, ist die Syntax +sowohl von Java als auch Javascript beeinflusst worden. Weitere Informationen +sind [hier](https://processing.org/reference/) zu finden. + +Die Programmiersprache wird statisch programmiert und kommt mit einer eigenen +offiziellen IDE, damit die Programme kompiliert und ausgeführt werden können. + +``` +/* ------------ + Mehrzeilige Kommentare werden so gemacht +*/ + +// Einzeilige Kommentare funktionieren so // + +/* + Da Processing von Java abstammt, ist die Syntax für Kommentare gleich + wie bei Java (wie du vielleicht oben bemerkt hast)! + Mehrzeilige Kommentare werden wie hier umschloßen. +*/ + +/* ------------------------------------------------- + Schreiben und Ausführen von Processing Programmen + ------------------------------------------------- +*/ + +// In Processing ist der Startpunkt eines Programms die Funktion `setup()` +// mit dem Rückgabetyp `void`. +// Beachte: Die Syntax ist derjenigen von C++ ziemlich ähnlich. +void setup() { + // Dies gibt beim Ausführen "Hallo Welt!" auf der Konsole aus. + println("Hallo Welt!"); // eine weitere Sprache mit einem Semikolon am Ende. +} + +// Normalerweise wird der Code für statische Elemente innerhalb der Methode +// `setup()` geschrieben, da diese lediglich einmal ausgeführt wird. +// Dies kann zum Beispiel das Setzen der Hintergrundfarbe oder das Bestimmen +// der Canvas-Größe sein. +background(color); // Setze die Hintergrundfarbe +size(width, height, [renderer]); // bestimme die Canvasgröße mit dem optionalen + // Parameter `renderer`. +// Du wirst innerhalb dieses Dokuments noch weitere Parameter sehen. + +// Wenn du möchstest, dass Code unendlich oft ausgeführt wird, so muss dieser +// Code innerhalb der `draw()`-Methode stehen. +// `draw()` muss existieren, wenn du möchtest, dass das Programm durchgehend +// läuft. Die `draw()`-Methode darf nur einmal vorkommen. + +int i = 0; +void draw() { + // Dieser Codeblock wird ausgeführt bis er gestoppt wird. + print(i); + i++; // Inkrement-Operator +} + +// Da wir nun wissen, wie man ein funktionierendes Skript erstellen kann und wie +// dieses ausgeführt wird, fahren wir mit den unterschiedlichen Datentypen und +// Collections weiter, welche in Processing unterstützt werden. + +/* ------------------------------------------------- + Datentypen und Collections + ------------------------------------------------- +*/ + +// Gemäß den Angaben in der Processingreferenz, unterstützt Processing die +// folgenden acht primitiven Datentypen: +boolean booleanValue = true; // Boolean +byte byteValueOfA = 23; // Byte +char charValueOfA = 'A'; // Char (einzelnes Zeichen) +color colorValueOfWhiteM = color(255, 255, 255); // Farben (angegeben durch die + // `color()`-Methode) +color colorValueOfWhiteH = #FFFFFF; // Farbe (angegeben mit der Hexadezimal- + // schreibweise.) +int intValue = 5; // Integer (ganze Zahl) +long longValue = 2147483648L; // "L" wird hinzugefügt, um es als `long` zu + // markieren. +float floatValue = 1.12345; // Float (32-Bit Gleitkommazahl) +double doubleValue = 1.12345D // Double (64-Bit Gleitkommazahl) + +//BEACHTE! +// Auch wenn es die Datentypen "long" und "double" gibt und auch funktionieren, +// verwenden Processing-Funktionen diese Datentypen nicht. Das bedeutet, dass +// diese zu "int" resp. "float" konvertiert werden müssen. +// Dies geschieht, indem man `(int)` oder `(float)` vor die Variable schreibt, +// bevor diese einer Funktion übergeben werden. + +// Es gibt eine ganze Reiher zusammengesetzter Datentypen, welche in Processing +// gebraucht werden können. Um Zeit zu sparen, gehen wir in diesem Tutorial +// lediglich die wichtigsten durch. + +// String +// Während der Datentyp `char` einfache Anzührungszeichen (' ') braucht, haben +// Strings doppelte Anführungszeichen (" "). +String sampleString = "Hallo, Processing!"; +// Strings können auch durch ein Array von `char`s erstellt werden. +// Wir werden Arrays gleich anschauen. +char source = {'H', 'A', 'L', 'L', 'O'}; +String stringFromSource = new String(source); // HALLO +// Wie auch in Java können in Processing Strings auch zusammengefügt werden +// mit dem +-Operator. +print("Hallo " + "Welt!"); // => Hallo Welt! + + +// Arrays +// In Processing können Arrays jeden Datentypen beinhalten, sogar Objekte. +// Da Arrays ähnlich wie Objekte sind, müssen diese mit dem Schlüsselwort `new` +// erstellt werden. +int[] intArray = new int[5]; +int[] intArrayWithValues = {1, 2, 3} // Arrays können auch mit Daten gefüllt + // werden. +// ArrayList +// Die Funktionen einer ArrayList sind ähnlich wie die eines Arrays und können +// auch jegliche Datentypen beinhalten. Der einzige Unterschied zwischen Arrays +// und `ArrayList`s ist, dass eine `ArrayList` die Größe dynamisch anpassen kann, +// da es eine Implementierung des "List" Interface in Java ist. +ArrayList<Integer> intArrayList = new ArrayList<Integer>(); + +// Objekte +// Da Processing auf Java basiert, unterstützt Processing die Objektorientierte +// Programmierung. Dies bedeutet, dass du grundsätzlich jegliche Datentypen +// selber erstellen kannst und diese nach deinen Bedürfnissen manipulieren kannst. +// Selbstverständlich muss eine Klasse definiert werden bevor du ein Objekt +// davon instanzieren kannst. +// Format: ClassName InstanceName +SomeRandomClass myObject // hier musst du das Objekt später instazieren +// Hier wird das Objekt direkt instanziert: +SomeRandomClass myObjectInstantiated = new SomeRandomClass(); + +// Processing hat noch weitere Collections (wie zum Beispiel Dictionaries und +// Listen). Aus Einfachheitsgründen wird dies in diesem Tutorial weggelassen. + +/* ------------------------------------------------- + Mathematik + ------------------------------------------------- +*/ + +// Arithmetik +1 + 1 // => 2 +2 -1 // => 1 +2 * 3 // => 6 +3 / 2 // => 1 +3.0 / 2 // => 1.5 +3.0 % 2 // => 1.0 (Modulo) + +// Processing beinhaltet auch einige Funktionen, welche mathematische +// Operationen vereinfachen +float f = sq(3); // Quadrat => f = 9.0 +float p = pow(3, 3); // Potenz => p = 27.0 +int a = abs(-13); // Absolute Zahl => a = 13 +int r1 = round(3.1); // Runden => r1 = 3 +int r2 = round(3.7); // Runden => r2 = 4 +int sr = sqrt(25); // Quadratwurzel => sr = 5.0 + +// Vektoren +// Processing bietet eine einfache Möglichkeit an, mit Vektoren zu arbeiten mit +// der Klasse PVector. Die Klasse kann zwei- und dreidimensionale Vektoren +// darstellen und bietet Methoden an, welche nützlich sein können für Matrizen- +// Operationen. Weitere Informationen findest du hier: +// (https://processing.org/reference/PVector.html) + +// Trigonometrie +// Processing unterstützt auch trigonometrische Operationen mit Hilfe dieser +// Funktionen: `sin()`, `cos()`, `tan()`, `asin()`, `atan()`. Für die einfache +// Konvertierung gibt es außerdem noch die Funktionen `degrees()` und `radians()`. +// Die trigonometrischen Funktionen rechnen mit dem Winkelmaß Radian, wodurch +// die Gradzahlen zuerst konvertiert werden müssen. +float one = sin(PI/2); // => one = 1.0 +// Wie du vielleicht bemerkt hast, existieren einige Konstanten für trigo- +// metrische Operationen; `PI`, `HALF_PI`, `QUARTER_PI` und so weiter ... + +/* ------------------------------------------------- + Kontrollstrukturen + ------------------------------------------------- +*/ + +// Bedingte Anweisungen +// Bedinge Anweisungen werden gleich wie in Java geschrieben. +if (author.getAppearence().equals("hot")) { + print("Narzissmus vom Feinsten!") +} else { + // Du kannst hier weitere Bedingungen prüfen. + print("Irgendetwas ist falsch hier!"); +} +// Für die `if`-Anweisungen gibt es auch eine Kurzschreibweise +// Dies sind sogenannte ternäre Operatoren. +int i = 3; +String value = (i > 5) ? "Groß" : "Klein"; // => "Klein" + +// Die Switch-Case-Anweisung kann verwendet werden, um mehrere Bedingungen +// zu prüfen. +// Wichtig ist, dass nach jeder Bedingung ein `break`-Statement verwendet wird, +// sonst werden alle folgenden ausgeführt und es wird nicht mehr überprüft, ob +// die Bedingung wahr ist. +int value = 2; +switch(value) { + case 0: + print("Auf keinen Fall!"); // Dies wird nicht ausgeführt. + break; // Geht zum nächsten Statement und prüft dieses + case 1: + print("Wir kommen näher..."); // Auch dies wird nicht ausgeführt + break; + case 2: + print("Bravo!"); // Dies wird ausgeführt. + break; + default: + print("Nicht gefunden."); // Diese Zeile wird ausgeführt, wenn keine + // der anderen Operatoren wahr sind. + break; +} + +// Wiederholungen +// For-Schleifen - Auch hier ist die Syntax wieder gleich wie in Java +for(int i = 0; i < 5; i++) { + print(i); // Gibt die Zahlen 0 bis 4 aus. +} + +// While-Statements +int j = 3; +while(j > 0) { + print(j); + j--; // Dies ist wichtig, dass der Code nicht unendlich lange läuft. +} + +// `loop()` | `noloop()` | `redraw()` | `exit()` +// Dies sind spezifische Funktionen, welche in Processing verwendet werden +// können, um den Programmablauf zu steuern. +loop(); // erlaubt es der `draw()`-Methode immer zu laufen, während +noloop(); // dies nur für einmal erlaubt. +redraw(); // führt die `draw()`-Methode noch einmal aus. +exit(); // Diese Methode stoppt das Programm. Dies kann nützlich sein, wenn die + // Methode `draw()` immer läuft. +``` + +## Mit Processing zeichnen + +Da du nun die Grundsätze der Programmiersprache verstanden hast, schauen wir +uns nun das Beste an Processing an - Das Zeichnen! + +``` + +/* ------------------------------------------------- + Figuren + ------------------------------------------------- +*/ + +// 2D-Figuren + +// Punkte +point(x,y); // im zweidimensionalen Raum +point(x, y, z); // im dreidimensionalen Raum +// Diese Befehle zeichnen einen Punkt an der Koordinate. + +// Linien +line(x1, y1, x2, y2); // im zweidimensionalen Raum +// Dies zeichnet eine Linie, welche durch die zwei Punkte (x1, y1) und (x2, y2) +// definiert wird. +line(x1, y1, z1, x2, y2, z2); // im dreidimensionalen Raum +// Analog wird hier eine Linie gezeichnet mit drei Punkten + +// Dreieck +triangle(x1, y1, x2, y2, x3, y3); +// Zeichnet ein Dreieck, welches als Eckpunkte die drei Koordinaten hat. + +// Rechteck +rect(a, b, c, d, [r]); // Mit dem optionalen Parameter kann der Winkel aller + // vier Ecken definiert werden +rect(a, b, c, d, [tl, tr, br, bl]); // Mit weiteren optionalen Parametern kann + // jeder Winkel des Rechtecks definiert werden. +// Dies zeichnet ein Quadrat mit der Koordinate {a, b} als linke obere Ecke +// die Parameter c und d sind für die Breite und Höhe. + +// Vierecke +quad(x, y, x2, y2, x3, y3, x4, y4); +// Dies zeichnet ein Viereck, welches die einzelnen Koordinaten als Eckpunkte hat. + +// Ellipse +ellipse(x, y, width, height); +// Zeichnet eine Ellipse beim Punkt {x. y}. Die Breite und die Höhe werden durch +// die Parameter width und height definiert. + +// Arc +arc(x, y, width, height, start, stop, [mode]); +// Die ersten vier Parameter sollten selbsterklärend sein. +// start und end definieren die Winkel, bei welchen `arc` starten resp. enden +// (in Radians) +// Der optionale Parameter `mode` definiert, ob der Kreisbogen gefüllt wird +// oder nicht. +// Die möglichen Optionen für `mode` sind: PIE, CHORD und OPEN. + +// Kurven +// Processing bietet zwei mögliche Kurven an, welche verwendet werden können. +// Da es hier darum geht, dass es möglichst simpel ist, werden hier keine +// weiteren Details genannt. Wenn du Kurven in deinem Programm verwenden möchtest, +// sind die folgenden Links empfehlenswert: +// https://processing.org/reference/curve_.html +// https://processing.org/reference/bezier_.html + + +// 3D-Figuren + +// Der dreidimensionale Raum kann aktiviert werden, indem man den Renderer- +// Parameter in der Methode `size()` zu "P3D" setzt. +size(width, height, P3D); +// Im dreidimensionalen Raum müssen die Koordinaten übersetzt werden, damit +// diese korrekt gerendert werden. + +// Box +box(size); // Würfel mit der Seitenlänge `size` +box(w, h, d); // Quader definiert durch Breite, Höhe und Tiefe + +// Kugel +sphere(radius); // Die Größe wird definiert durch den Parameter `radius` +// Der Mechanismus hinter dem Rendern von Kugeln wurde durch mosaikartige +// Dreiecke implementiert. +// Mit der folgenden Funktion ist es möglich, zu bestimmen wie detailliert die +// Kugel gerendert wird. +// spereDetail(res); +// Weitere Informationen sind hier zu finden: (https://processing.org/reference/sphereDetail_.html) + +// Unregelmäßige Figuren +// Was ist, wenn du etwas zeichnen möchtest, was nicht durch Processing-Funktionen +// abgedeckt ist? +// Es ist möglich, die Funktionen `beginShape()`, `endShape()` und `vertex(x,y) +// zu verwenden. +// Weitere Informationen findest du hier: (https://processing.org/reference/beginShape_.html) +// Du kannst selber gemachte Formen auch verwenden mit der PShape-Klasse. +// Informationen zu PShape gibt es hier: (https://processing.org/reference/PShape.html) + +/* ------------------------------------------------- + Transformationen + ------------------------------------------------- +*/ + +// Tranformationen sind nützlich, um ständig zu wissen, wo die Koordinaten und +// die Ecken einer Form sind, welche du gezeichnet hast. Grundsätzlich sind dies +// Matrizenoperationen. `pushMatrix()`, `popMatrix()` und `translate()`. +pushMatrix(); // Speichert das aktuelle Koordinatensystem auf dem Stack + // alle Transformationen werden hier angewendet. +popMatrix(); // Stellt das gespeicherte Koordinatensystem wieder her. +// Wenn du diese Funktionen verwendest, kann das Koordinatensystem gespeichert +// und visualisiert werden, ohne dass es Konflikte gibt. + +// Translate +translate(x,y); // Setzt den Ursprung zu diesem Punkt. +translate(x, y, z); // Pendant zu der oberen Funktion im dreidimensionalen Raum + +// Rotationen +rotate(angle); // Rotiere, um den Betrag, welcher spezifiert wurde. +// Es gibt drei Pendants im dreidimensionalen Raum. +// Namentlich sind dies: `rotateX(angle)`, `rotateY(angle)` und `rotateZ(angle)` + +// Skalierung +scale(s); // Skaliert das Koordinatensystem (entweder erweitern oder verkleinern) + +/* ------------------------------------------------- + Styling und Texturen + ------------------------------------------------- +*/ + +// Farben +// Wie ich zuvor schon erklärt habe, kann die Hintergrundfarbe mit der Funktion +// `background()` definiert werden. Außerdem ist es möglich, dass man zuerst +// eine Farbe definiert und diese erst danach der Funktion übergeben wird. +color c = color(255, 255, 255); // WEISS! +// Standardmäßig verwendet Processing das RGB-Farbschema, aber dies kann +// zu HSB konfiguriert werden, indem die Funktion `colorMode()` verwendet wird. +// Weitere Informationen findest du hier: (https://processing.org/reference/colorMode_.html) +background(c); // Ab jetzt ist der Hintergrund in weiß. +// Du kannst die Funktion `fill()` verwenden, um die Farbe auszuwählen, mit +// welcher die Formen ausgefüllt werden. +// Dies muss konfiguriert werden bevor Formen und Figuren gezeichnet werden. +fill(color(0, 0, 0)); +// Wenn du nur die Farbe der Umrandungen definieren möchtest, kannst du die +// Funktion `stroke()` verwenden. +stroke(255, 255, 0, 200); // Linienfarbe wird zu gelb mit einer höheren + // Transparenz geändert. + +// Bilder +// Processing kann Bilder rendern und diese unterschiedlich verwenden. Die +// meisten Bilder sind im Datentyp `PImage` gespeichert. +filter(shader); // Processing unterstützt mehrere Filter-Funktionen, damit + // Bilder verändert werden können. +texture(image); // PImage kann als Argument, weiteren Funktionen übergeben + // werden, um die Figuren zu "Text" zu machen. +``` + +Wenn du weitere Dinge mit Processing kennenlernen willst, dann gibt es unzählige +Dinge, welche du mit Processing machen kannst. Das Rendern von Modellen, +Schattierungen und viele mehr. Für ein kurzes Tutorial bietet Processing zu viel, +daher verweise ich dich, falls du interessiert bist, auf die offizielle +Dokumentaion. + +``` +// Bevor wir weiterfahren, werde ich einige Aspekte zum Importieren von +// Bibliotheken und Paketen sagen, damit du Processing erweitern kannst.. + +/* ------------------------------------------------- + Import + ------------------------------------------------- +*/ + +// Die Macht von Processing kann besser veranschaulicht werden, wenn wir +// Bibliotheken und Pakete importieren. +// Die Import-Anweisung kann wie unten geschrieben zu Beginn des Quelltextes +// geschrieben werden. +import processing.something.*; +``` + +## Beispielprogramm + +Lass uns ein Beispiel von openprocessing.org ansehen, welches verdeutlicht, +was man in Processing mit nur wenigen Zeilen Code machen kann. + +Kopiere den nachfolgenden Code in deine Processing IDE. + +``` +// Disclaimer: Ich habe das Porgramm nicht selbst geschriben. Diese Skizze +// stammt aus openprocessing, allerdings soll dieses Programm zeigen, wie wenig +// Zeilen Code notwendig sind, um etwas Cooles zu machen. +// Abgerufen von: (https://www.openprocessing.org/sketch/559769) + +float theta; +float a; +float col; +float num; + +void setup() { + size(600,600); +} + +void draw() { + background(#F2F2F2); + translate(width/2, height/2); + theta = map(sin(millis()/1000.0), -1, 1, 0, PI/6); + + float num=6; + for (int i=0; i<num; i++) { + a =350; + rotate(TWO_PI/num); + branch(a); + } +} + +void branch(float len) { + col=map(len, 0, 90, 150, 255); + fill(col, 0, 74); + stroke (col, 0, 74); + line(0, 0, 0, -len); + ellipse(0, -len, 3, 3); + len*=0.7; + + if (len>30) { + pushMatrix(); + translate(0, -30); + rotate(theta); + branch(len); + popMatrix(); + + pushMatrix(); + translate(0, -30); + rotate(-theta); + branch(len); + popMatrix(); + } +} +``` + +Processing ist einfach zu erlernen und ist vorallem nützlich, um Multimedia- +Inhalte (auch in 3D) zu erstellen ohne viel Code zu schreiben. Es ist so einfach +gehalten, dass man den Code durchlesen kann und man versteht den Programmablauf +bereits. + +Wenn du externe Bibliotheken, Pakete oder eigene Klassen einbindest, kann ein +Programm, welches mit Processing geschrieben wurde, durchaus auch kompliziert +werden. + +## Einige nützliche Links + +- [Processing Webseite](http://processing.org) +- [Processing Sketches](http://openprocessing.org) diff --git a/de-de/pug-de.html.markdown b/de-de/pug-de.html.markdown new file mode 100644 index 00000000..c86494ce --- /dev/null +++ b/de-de/pug-de.html.markdown @@ -0,0 +1,208 @@ +--- +language: Pug +contributors: + - ["Michael Warner", "https://github.com/MichaelJGW"] +filename: lernepug-de.pug +translators: + - ["denniskeller", "https://github.com/denniskeller"] +lang: de-de +--- + +## Erste Schritte mit Pug + +Pug ist eine kleine Sprache, die zu HTML kompiliert. Sie hat eine +saubere Syntax mit zusätzlichen Funktionen wie if Anweisungen und Schleifen. +Sie kann auch als serverseitige Templatingsprache für Serversprachen +wie NodeJS verwendet werden. + +### Die Sprache +```pug + +//- Einzeilenkommentar + +//- Mehrzeiliger + Kommentar + +//- ---TAGS--- +//- Grundlagen +div +//- <div></div> +h1 +//- <h1></h1> +mein-benutzerdefiniertesTag +//- <mein-benutzerdefiniertesTag></mein-benutzerdefiniertesTag> + +//- Geschwister +div +div +//- <div></div> + <div></div> + +//- Kind +div + div +//- <div> + <div></div> + </div> + +//- Text +h1 Hallo Welt +//- <h1>Hallo Welt</h1> + +//- Multizeilentext +div. + Hallo + Welt +//- <div> + Hallo + Welt + </div> + +//- ---ATTRIBUTE--- +div(class="meine-klasse" id="meine-id" mein-benutzerdefiniertes-attr="data" enabled) +//- <div class="meine-klasse" id="meine-id" mein-benutzerdefiniertes-attr="data" enabled></div> + +//- Kurzhand +span.meine-klasse +//- <span class="meine-klasse"></span> +.meine-klasse +//- <div class="meine-klasse"></div> +div#meine-id +//- <div id="meine-id"></div> +div#meine-id.meine-klasse +//- <div class="meine-klasse" id="meine-id"></div> + + +//- ---JS--- +- const sprache = "pug"; + +//- Multizeilen JS +- + const srache = "pug"; + const cool = true; + +//- JS Klassen +- const meineKlasse = ['class1', 'class2', 'class3'] +div(class=meineKlasse) +//- <div class="class1 class2 class3"></div> + +//- JS Stil +- const meineStile = {'color':'white', 'background-color':'blue'} +div(styles=meineStile) +//- <div styles="{"color":"white","background-color":"blue"}"></div> + +//- JS Attributte +- const meineAttribute = {"src": "foto.png", "alt": "meine Bilder"} +img&attributes(meineAttribute) +//- <img src="foto.png" alt="meine Bilder"> +- let deaktiviert = false +input(type="text" disabled=deaktiviert) +//- <input type="text"> +- deaktiviert = true +input(type="text" disabled=deaktiviert) +//- <input type="text" disabled> + +//- JS Templating +- const name = "Bob"; +h1 Hi #{name} +h1= name +//- <h1>Hi Bob</h1> +//- <h1>Bob</h1> + +//- ---Schleifen--- + +//- 'each' und 'for' machen das Selbe. Wir werden nur 'each' verwenden. + +each value, i in [1,2,3] + p=value +//- + <p>1</p> + <p>2</p> + <p>3</p> + +each value, index in [1,2,3] + p=value + '-' + index +//- + <p>1-0</p> + <p>2-1</p> + <p>3-2</p> + +each value in [] + p=value +//- + +each value in [] + p=value +else + p Keine Werte sind hier + +//- <p>Keine Werte sind hier</p> + +//- ---BEDINGUNGEN--- + +- const zahl = 5 +if zahl < 5 + p zahl ist kleiner als 5 +else if zahl > 5 + p zahl ist größer als 5 +else + p zahl ist 5 +//- <p>zahl ist 5</p> + +- const bestellungsStatus = "Ausstehend"; +case bestellungsStatus + when "Ausstehend" + p.warn Deine Bestellung steht noch aus + when "Abgeschlossen" + p.success Bestellung ist abgeschlossen. + when -1 + p.error Ein Fehler ist aufgetreten + default + p kein Bestellprotokoll gefunden +//- <p class="warn">Deine Bestellung steht noch aus</p> + +//- --INCLUDE-- +//- File path -> "includes/nav.png" +h1 Firmenname +nav + a(href="index.html") Home + a(href="about.html") Über uns + +//- Dateipfad -> "index.png" +html + body + include includes/nav.pug +//- + <html> + <body> + <h1>Firmenname</h1> + <nav><a href="index.html">Home</a><a href="about.html">Über uns</a></nav> + </body> + </html> + +//- Importiere JS und CSS +script + include scripts/index.js +style + include styles/theme.css + +//- ---MIXIN--- +mixin basic() + div Hallo ++basic("Bob") +//- <div>Hallo</div> + +mixin comment(name, kommentar) + div + span.comment-name= name + div.comment-text= kommentar ++comment("Bob", "Das ist super") +//- <div>Hallo</div> + +``` + + +### Zusätzliche Ressourcen +- [The Site](https://pugjs.org/) +- [The Docs](https://pugjs.org/api/getting-started.html) +- [Github Repo](https://github.com/pugjs/pug) diff --git a/de-de/ruby-de.html.markdown b/de-de/ruby-de.html.markdown index e14603cd..8025a8c0 100644 --- a/de-de/ruby-de.html.markdown +++ b/de-de/ruby-de.html.markdown @@ -1,5 +1,6 @@ --- language: ruby +filename: ruby-de.rb contributors: - ["David Underwood", "http://theflyingdeveloper.com"] - ["Joel Walden", "http://joelwalden.net"] @@ -11,602 +12,677 @@ contributors: - ["Dzianis Dashkevich", "https://github.com/dskecse"] - ["Levi Bostian", "https://github.com/levibostian"] - ["Rahil Momin", "https://github.com/iamrahil"] + - ["Gabriel Halley", "https://github.com/ghalley"] + - ["Persa Zula", "http://persazula.com"] + - ["Jake Faris", "https://github.com/farisj"] + - ["Corey Ward", "https://github.com/coreyward"] + - ["Jannik Siebert", "https://github.com/janniks"] + - ["Keith Miyake", "https://github.com/kaymmm"] translators: - ["Christian Albrecht", "https://github.com/coastalchief"] - ["Dennis Keller", "https://github.com/denniskeller"] -filename: ruby-de.rb + - ["Paul Götze", "https://gitub.com/paulgoetze"] lang: de-de --- -# Dies ist ein Kommentar +```ruby +# Das ist ein Kommentar =begin -Dies sind multi-line -Kommentare. Niemand benutzt -die wirklich. +Das ist ein mehrzeiliger Kommentar. +Die Anfangszeile muss mit "=begin" beginnen +und die Endzeile muss mit "=end" beginnen. + +Alternativ kannst du jede Zeile in einem +mehrzeiligen Kommentar mit dem # Zeichen beginnen. =end -# Objekte - Alles ist ein Objekt +# In Ruby ist (fast) alles ein Objekt. +# Das schließt Zahlen ein... +3.class #=> Integer -## Zahlen sind Objekte -``` -3.class #=> Fixnum -3.to_s #=> "3" -``` +# ...und Zeichenketten (Strings)... +"Hallo".class #=> String -### Simple Arithmetik -``` +# ...und sogar Methoden! +"Hallo".method(:class).class #=> Method + +# Simple Arithmetik 1 + 1 #=> 2 8 - 1 #=> 7 10 * 2 #=> 20 35 / 5 #=> 7 -2**5 #=> 32 -``` +2 ** 5 #=> 32 +5 % 3 #=> 2 -// Arithmetik ist aber eigentlich nur syntaktischer Zucker -// um eine Methode eines Objekt aufzurufen -``` +# Bitweise Operatoren +3 & 5 #=> 1 +3 | 5 #=> 7 +3 ^ 5 #=> 6 + +# Arithmetik ist aber eigentlich nur syntaktischer Zucker +# um eine Methode eines Objekts aufzurufen 1.+(3) #=> 4 10.* 5 #=> 50 -``` +100.methods.include?(:/) #=> true -## Special values sind Objekte -``` -nil # Nothing to see here -true # truth -false # falsehood +## Spezielle Werte sind Objekte +nil # Equivalent zu null in anderen Sprachen +true # Wahrheitswert +false # Falschheitswert nil.class #=> NilClass true.class #=> TrueClass false.class #=> FalseClass -``` -## Objektvergleiche -### Gleicheit -``` +# Gleicheit 1 == 1 #=> true 2 == 1 #=> false -``` -### Ungleichheit -``` + +# Ungleichheit 1 != 1 #=> false 2 != 1 #=> true -``` -### Neben false selbst, nil ist ein anderer 'falsey' Wert -``` -!nil #=> true -!false #=> true -!0 #=> false -``` -### Weitere Vergleiche -``` + +# Neben false selbst, ist nil der einzige andere +# zu Falsch evaluierende Wert + +!!nil #=> false +!!false #=> false +!!0 #=> true +!!"" #=> true + +# Weitere Vergleiche 1 < 10 #=> true 1 > 10 #=> false 2 <= 2 #=> true 2 >= 2 #=> true -``` + +# Kombinierter Vergleichsoperator (gibt `1` zurück wenn das erste Argument +# größer ist, und `-1`, wenn das zweite Argument größer ist, sonst `0`) +1 <=> 10 #=> -1 (1 < 10) +10 <=> 1 #=> 1 (10 > 1) +1 <=> 1 #=> 0 (1 == 1) + ### Logische Operatoren -``` true && false #=> false true || false #=> true -!true #=> false -``` -Es gibt alternative Versionen der logischen Operatoren mit niedrigerer -Wertigkeit. Diese werden meistens bei Flow-Control eingesetzt, um -verschiedenen Ausdrücke zu verketten bis einer true oder false zurück -liefert. +# Es gibt alternative Versionen der logischen Operatoren mit niedrigerer +# Wertigkeit. Diese werden meistens zur Flusskontrolle eingesetzt, um +# verschiedenen Ausdrücke zu verketten bis einer true oder false zurück +# liefert. -#### and -##### `do_something_else` wird nur ausgewertet wenn `do_something` true ist. +# `do_something_else` wird nur ausgewertet wenn `do_something` true ist. do_something() and do_something_else() - -#### or -#####`log_error` wird nur ausgewertet wenn `do_something` false ist. +# `log_error` wird nur ausgewertet wenn `do_something` false ist. do_something() or log_error() -## Strings sind Objekte -``` -'I am a string'.class #=> String -"I am a string too".class #=> String +# String Interpolation +placeholder = 'Ruby' +"Ich kann in #{placeholder} Platzhalter mit doppelten Anführungszeichen füllen." +#=> "Ich kann in Ruby Platzhalter mit doppelten Anführungszeichen füllen." -platzhalter = 'Ruby' -"Ich kann in #{placeholder} Platzhalter mit doppelten Anführungsstrichen füllen." -``` -Einfache Anführungszeichen sollten bevorzugt werden. -Doppelte Anführungszeichen führen interne Berechnungen durch. +# Du kannst Strings mit `+` verbinden, nicht jedoch mit anderen Typen +'hallo ' + 'Welt' #=> "hallo Welt" +'Hallo ' + 3 #=> TypeError: no implicit conversion of Integer into String +'hallo ' + 3.to_s #=> "hallo 3" +"hallo #{3}" #=> "hallo 3" + +# ...oder Strings mit Operatoren kombinieren +'hallo ' * 3 #=> "hallo hallo hallo " + +# ...oder Strings an andere Strings anhängen +'hallo' << ' Welt' #=> "hallo Welt" + +# Du kannst Text mit einer neuen Zeile am Ende ausgeben +puts "Ich gebe Text aus!" +#=> Ich gebe Text aus! +#=> nil + +# ...oder Text ohne einen Zeilenumbruch ausgeben +print "Ich gebe Text aus!" +#=> "Ich gebe Text aus!" => nil -### Strings können verbunden werden, aber nicht mit Zahlen -``` -'hello ' + 'world' #=> "hello world" -'hello ' + 3 #=> TypeError: can't convert Fixnum into String -``` -#### Zahl muss in String konvertiert werden -``` -'hello ' + 3.to_s #=> "hello 3" -``` -### Text ausgeben -``` -puts "I'm printing!" -``` # Variablen -## Zuweisungen -### Diese Zuweisung gibt den zugeordneten Wert zurück -``` x = 25 #=> 25 x #=> 25 -``` -### Damit funktionieren auch mehrfache Zuweisungen -``` + +# Beachte, dass Zuweisungen den zugewiesenen Wert zurückgeben. +# D.h. du kannst mehrfache Zuweisungen machen. + x = y = 10 #=> 10 x #=> 10 y #=> 10 -``` -## Benennung -### Konvention ist snake_case -``` + +# Nutze snake_case für Variablennamen. snake_case = true -``` -### Benutze verständliche Variablennamen -``` -path_to_project_root = '/good/name/' -path = '/bad/name/' -``` -# Symbols (sind auch Objekte) -Symbols sind unveränderliche, wiederverwendbare Konstanten, welche intern -als integer repräsentiert werden. Sie werden häufig anstelle von Strings -verwendet, um sinnvoll Werte zu übermitteln. -Symbols werden mit dem Doppelpunkt gekennzeichnet. -``` +# Nutze verständliche Variablennamen. +path_to_project_root = '/guter/Name/' +m = '/schlechter/Name/' + + +# Symbole sind unveränderliche, wiederverwendbare Konstanten, welche intern +# als Integer repräsentiert werden. Sie werden häufig anstelle von Strings +# verwendet, um semantisch sinnvoll Werte zu übermitteln. +# Symbols werden mit dem Doppelpunkt gekennzeichnet. + :pending.class #=> Symbol + status = :pending + status == :pending #=> true + status == 'pending' #=> false + status == :approved #=> false -``` + +# Strings können in Symbole konvertiert werden und umgekehrt. +status.to_s #=> "pending" +"argon".to_sym #=> :argon + # Arrays -## Ein Array anlegen -``` +# Das ist ein Array. array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] -``` -## Array können verschiedene Typen beinhalten -``` +# Array können verschiedene Typen beinhalten [1, 'hello', false] #=> [1, "hello", false] -``` -## Wie bei arithmetischen Ausdrücken auch wird beim Zugriff auf -## [0] eigentlich die Methode [] des Array Objekts aufgerufen. -``` -array.[] 0 #=> 1 -array.[] 12 #=> nil -``` +## Arrays könnenindiziert werden. -## Arrays können von vorne indiziert werden -``` +# Von vorne... array[0] #=> 1 +array.first #=> 1 array[12] #=> nil -``` -## Arrays können von hinten indiziert werden -``` +# ...oder von hinten... array[-1] #=> 5 -``` +array.last #=> 5 -## Arrays können mit Start Index und Länge indiziert werden -``` +# ...oder mit einem Startindex und einer Länge... array[2, 3] #=> [3, 4, 5] -``` -## Arrays können mit einer Range indiziert werden -``` +# ...oder mit einem Range... array[1..3] #=> [2, 3, 4] -``` -## Einen Wert hinzufügen -``` +# Du kanns ein Array umkehren. +# Gib ein neues Array mit umgkehrten Werten zurück +[1,2,3].reverse #=> [3,2,1] + +# Kehre ein Array an Ort und Stelle um, um die Variable mit den +# umgekehrten Werten zu aktualisieren. +a = [1,2,3] +a.reverse! #=> a==[3,2,1] wegen des Aufrufs von reverse mit Ausrufezeichens ('!') + +# Wie bei der Arithmetik, ist Zugriff mit [index] nur +# syntaktischer Zucker für den Aufruf der `[]` Methode auf dem Objekt. +array.[] 0 #=> 1 +array.[] 12 #=> nil + +# Du kannst Werte zu einem Array hinzufügen... array << 6 #=> [1, 2, 3, 4, 5, 6] +# Oder so array.push(6) #=> [1, 2, 3, 4, 5, 6] -``` -## Testen, ob ein Element schon vorhanden ist -``` +# ...und testen ob ein Element schon vorhanden ist array.include?(1) #=> true -``` -# Hashes -Hashes sind das Hauptfeature um Key/Values zu speichern +# Hashes sind Rubys Hauptdatenstruktur for Schlüssel/Wert Paare. +# Hashes werden durch geschweifte Klammern gekennzeichnet. +hash = { 'Farbe' => 'grün', 'Nummer' => 5 } -## Ein Hash anlegen -``` -hash = { 'color' => 'green', 'number' => 5 } -hash.keys #=> ['color', 'number'] -``` +hash.keys #=> ['farbe', 'nummer'] -## Wert per key herausfinden -``` -hash['color'] #=> 'green' -hash['number'] #=> 5 -hash['nothing here'] #=> nil -// Fragen an einen Hash nach einem Schlüssel, der nicht existiert, ruft nil hervor: -``` +# Hashes can be quickly looked up by key. +hash['Farbe'] #=> "grün" +hash['Nummer'] #=> 5 -## Symbols können auch keys sein -``` -new_hash = { defcon: 3, action: true } -new_hash.keys #=> [:defcon, :action] -``` +# Abfragen eines nicht vorhandenen Schlüssels, gibt nil zurück. +hash['nicht vorhanden'] #=> nil -## Testen ob ein Key oder ein Value existiert -``` -new_hash.has_key?(:defcon) #=> true -new_hash.has_value?(3) #=> true -``` +# Wenn du Symbole als Schlüssel in einem Hash verwendest, kannst du +# eine alternative Syntax verwenden. +hash = { :defcon => 3, :action => true } +hash.keys #=> [:defcon, :action] -### Tipp: Arrays und Hashes sind Enumerable -### Und haben gemeinsame, hilfreiche Methoden wie: -### each, map, count, and more +hash = { defcon: 3, action: true } +hash.keys #=> [:defcon, :action] + +# Testen ob ein Schlüssel oder Wert im Hash existiert +hash.key?(:defcon) #=> true +hash.value?(3) #=> true + +# Tipp: Arrays und Hashes sind Enumerables! +# Sie haben viele nützliche Methoden gemein, wie each, map, count, und andere. # Kontrolstrukturen -## if -``` + +# Bedingungen if true - 'if statement' + 'wenn Bedingung' elsif false - 'else if, optional' + 'sonst wenn, optional' else - 'else, also optional' + 'sonst, auch optional' end -``` -## for - Allerdings werden for Schleifen nicht oft vewendet. -``` -for counter in 1..5 - puts "iteration #{counter}" -end -``` -## Stattdessen: "each" Methode und einen Bloch übergeben -Ein Block ist ein Codeteil, den man einer Methode übergeben kann -Ähnelt stark lambdas, anonymen Funktionen oder Closures in anderen -Programmiersprachen. -``` +# Wenn eine Kontrollstruktur keinen Code-Block, sondern einen einzigen +# Ausdruck ausführt, dann kannst du die nachgestellte if-Notation verwenden +warnings = ['Nachname fehlt', 'Adresse zu kurz'] +puts("Vorhandene Warnungen:\n" + warnings.join("\n")) if !warnings.empty? + +# Formuliere die Bedingung um, wenn sich `unless` besser liest als `if` +puts("Vorhandene Warnungen:\n" + warnings.join("\n")) unless warnings.empty? + +# Schleifen +# Traditionell ist das Benutzen von `for` Schleifen in Ruby eher unüblich. +# Stattdessen werden diese mit Hilfe von Enumerables implementiert, was mit +# dem Aufrufen von `each` einhergeht. (1..5).each do |counter| - puts "iteration #{counter}" + puts "Iteration #{counter}" +end + +# Was in etwa das selbe ist wie Folgendes (selten in Ruby zu sehen). +for counter in 1..5 + puts "Iteration #{counter}" end -``` -Die each Methode einer Range führt den Block für jedes Element der Range aus. +# Das `do |variable| ... end` Konstrukt wird `block` genannt. +# Blocks sind vergleichbar mit Lambdas, anonymen Funktionen +# oder Closures in anderen Programmiersprachen. +# Sie können als Objekte übergeben, aufgerufen oder als Methoden +# zugewiesen werden. -Dem Block wird ein "counter" parameter übergeben. +# Die `each` Methode eines Ranges führt den Block einmal für jedes +# Element des Ranges aus. +# Dem Block wird eine counter Variable als Parameter übergeben. -### Den Block kann man auch in geschweiften Klammern schreiben -``` -(1..5).each { |counter| puts "iteration #{counter}" } -``` +# Du kannst einen Block auch mit geschweiften Klammern schreiben. +(1..5).each { |counter| puts "Iteration #{counter}" } -### Each kann auch über den Inhalt von Datenstrukturen iterieren -``` +# Each kann auch über den Inhalt von Datenstrukturen iterieren. array.each do |element| - puts "#{element} is part of the array" + puts "#{element} is Teil des Arrays" end + hash.each do |key, value| - puts "#{key} is #{value}" + puts "#{key} ist #{value}" +end + +# Um auf den Laufindex zuzugreifen kannst du `each_with_index` verwenden +# und eine index Variable definieren. +array.each_with_index do |element, index| + puts "#{element} ist Nummer #{index} im Array" end counter = 1 while counter <= 5 do - puts "iteration #{counter}" + puts "Iteration #{counter}" counter += 1 end -``` +#=> Iteration 1 +#=> Iteration 2 +#=> Iteration 3 +#=> Iteration 4 +#=> Iteration 5 + +# Es gibt einige andere hilfreiche Schleifenfunktionen in Ruby. +# Wie etwa 'map', 'reduce', 'inject' und viele andere mehr. +# Map zum Beispiel iteriert über das Array, führt für jedes Element +# die Anweisungen aus, +# die im Block definiert sind und gibt ein völlig neues Array zurück. +array = [1,2,3,4,5] +doubled = array.map do |element| + element * 2 +end +puts doubled +#=> [2,4,6,8,10] +puts array +#=> [1,2,3,4,5] -## case -``` +# Case Konstruct grade = 'B' case grade when 'A' - puts 'Way to go kiddo' + puts 'So wird’s gemacht' when 'B' - puts 'Better luck next time' + puts 'Viel Glück beim nächsten Mal' when 'C' - puts 'You can do better' + puts 'Das kannst du besser' when 'D' - puts 'Scraping through' + puts 'Gerade so durch' when 'F' - puts 'You failed!' + puts 'Durchgefallen!' else - puts 'Alternative grading system, eh?' + puts 'Anderes Bewertungssystem, was?' end -=> "Better luck next time" -``` +#=> "Viel Glück beim nächsten Mal" -### Case können auch ranges -``` +# Case kann auch Ranges benutzen grade = 82 case grade when 90..100 - puts 'Hooray!' + puts 'Hurra!' when 80...90 - puts 'OK job' + puts 'OK gemacht' else - puts 'You failed!' + puts 'Durchgefallen!' end -=> "OK job" -``` +#=> "OK gemacht" -# Exception handling: -``` +# Fehlerbehandlung begin - # code here that might raise an exception - raise NoMemoryError, 'You ran out of memory.' + # Code der einen Fehler wirft... + raise NoMemoryError, 'Dein Speicher ist voll.' rescue NoMemoryError => exception_variable - puts 'NoMemoryError was raised', exception_variable + puts 'NoMemoryError ist aufgetreten', exception_variable rescue RuntimeError => other_exception_variable - puts 'RuntimeError was raised now' + puts 'RuntimeError ist aufgetreten' else - puts 'This runs if no exceptions were thrown at all' + puts 'Das wird ausgeführt, wenn keine Fehler geworfen wurden' ensure - puts 'This code always runs no matter what' + puts 'Dieser Code wird immer ausgeführt, egal was vorher passiert' end -``` -# Funktionen -``` + +# Methoden + def double(x) x * 2 end -``` -## Funktionen (und Blocks) -## geben implizit den Wert des letzten Statements zurück -``` + +# Methoden (und Blocks) geben implizit den Wert des letzten Anweisung zurück. double(2) #=> 4 -``` -### Klammern sind optional wenn das Ergebnis nicht mehrdeutig ist -``` +# Klammern sind optional wenn die Anweisung dadurch nicht mehrdeutig wird. double 3 #=> 6 + double double 3 #=> 12 + def sum(x, y) x + y end -``` -### Methoden Parameter werden per Komma getrennt -``` +# Die Argumente einer Methode werden durch ein Komma getrennt. sum 3, 4 #=> 7 + sum sum(3, 4), 5 #=> 12 -``` -## yield -### Alle Methoden haben einen impliziten, optionalen block Parameter -### Dieser wird mit dem Schlüsselword "yield" aufgerufen -``` +# yield +# Alle Methoden haben implizit einen optionalen block Parameter. +# Dieser kann durch das Schlüsselwort 'yield' ausgeführt werden. def surround puts '{' yield puts '}' end -surround { puts 'hello world' } -``` -## Einen Block kann man auch einer Methoden übergeben -### "&" kennzeichnet die Referenz zum übergebenen Block -``` +surround { puts 'hallo Welt' } + +#=> { +#=> hallo Welt +#=> } + +# Blocks können in ein 'Proc' Objekt umgewandelt werden. +# Dieses ist eine Art Container um den Block und erlaubt ihn an eine +# andere Methode zu übergeben, ihn in einen anderen Gültigkeitsbereicht +# einzubinden oder ihn andersweitig zu verändern. +# Am häufigsten findet man dies bei Parameterlisten von Methoden, in Form +# eines letzten '&block' Parameters, der den Block – wenn es einen gibt – +# entgegen nimmt und ihn in ein 'Proc' umwandelt. Die Benennung '&block' ist +# hier nur eine Konvention; es würde genauso mit '&pineapple' funktionieren. def guests(&block) - block.call 'some_argument' + block.class #=> Proc + block.call(4) end -``` -### Eine Liste von Parametern kann man auch übergeben, -### Diese wird in ein Array konvertiert -### "*" kennzeichnet dies. -``` +# Die 'call' Methode eines Proc ist ganz ähnlich zum Aufruf von 'yield', wenn +# ein Block vorhanden ist. Die Argumente, die 'call' übergeben werden, werden +# als Argumente and den Block weitergereicht. + +guests { |n| "Du hast #{n} Gäste." } +# => "Du hast 4 Gäste." + +# Du kannst eine Liste von Argumenten übergeben, die dann in ein Array +# umgewandelt werden. Dafür gibt es den splat-Operator (`*`). def guests(*array) array.each { |guest| puts guest } end -``` + +# Destrukturierung + +# Ruby destrukturiert Arrays automatisch beim Zuweisen mehrerer Variablen. +a, b, c = [1, 2, 3] +a #=> 1 +b #=> 2 +c #=> 3 + +# In manchen Fällen will man den splat-Operator (`*`) verwenden um ein Array in +# eine Liste zu destrukturieren. +ranked_competitors = ["John", "Sally", "Dingus", "Moe", "Marcy"] + +def best(first, second, third) + puts "Gewinner sind #{first}, #{second} und #{third}." +end + +best *ranked_competitors.first(3) #=> Gewinner sind John, Sally and Dingus. + +# Der splat-Operator kann auch in Parametern verwendet werden. +def best(first, second, third, *others) + puts "Gewinner sind #{first}, #{second} und #{third}." + puts "Es gab #{others.count} andere Teilnehmer." +end + +best *ranked_competitors +#=> Gewinner sind John, Sally und Dingus. +#=> Es gab 2 andere Teilnehmer. + +# Per Konvention enden alle Methoden, die einen Wahrheitswert zurück geben, mit einem +# Fragezeichen. +5.even? #=> false +5.odd? #=> true + +# Wenn ein Methodenname mit einem Ausrufezeichen endet, dann tut diese Methode +# per Konvention etwas Destruktives, wie z.B. das aufrufende Objekt zu +# verändern. +# Viele Mehtoden haben eine !-Version um eine direkte Änderung zu machen und +# eine Nicht-!-Version, die ein neues Objekt mit den Veränderungen zurück gibt. +company_name = "Dunder Mifflin" +company_name.upcase #=> "DUNDER MIFFLIN" +company_name #=> "Dunder Mifflin" +# Diesmal verändern wir company_name direkt. +company_name.upcase! #=> "DUNDER MIFFLIN" +company_name #=> "DUNDER MIFFLIN" + # Klassen -## Werden mit dem class Schlüsselwort definiert -``` + +# Du kannst eine Klasse mit dem Schlüsselwort 'class' definieren. class Human -``` -### Konstruktor bzw. Initializer -``` + # Eine Klassenvariable. Sie wird von allen Instanzen einer Klasse geteilt. + @@species = 'H. sapiens' + + # Konstruktor bzw. Initializer def initialize(name, age = 0) - # Assign the argument to the "name" instance variable for the instance + # Weise das Argument der Instanzvariable 'name' zu. @name = name - # If no age given, we will fall back to the default in the arguments list. + # Wenn kein 'age' angegeben wurde wird der Standartwert aus der Argumentenlist verwendet. @age = age end -``` -### setter Methode -``` + # Setter Methode def name=(name) @name = name end -``` -### getter Methode -``` + + # Getter Methode def name @name end -``` -#### getter können mit der attr_accessor Methode vereinfacht definiert werden -``` + # Getter & Setter können auch kürzer mit der attr_accessor Methode erstellt werden. attr_accessor :name - # Getter/setter methods can also be created individually like this + + # Getter & Setter Methoden können auch einzeln erstellt werden. attr_reader :name attr_writer :name - # A class method uses self to distinguish from instance methods. - # It can only be called on the class, not an instance. + + # Eine Klassenmethode unterscheidet sich durch ein 'self' von einer + # Instanzmethode. + # Sie kann nur auf der Klasse und nicht auf einer Instanz der Klasse + # aufgerufen werden. def self.say(msg) puts msg end + def species @@species end end -``` -## Eine Klasse instanziieren -``` +# Instanziieren einer Klasse jim = Human.new('Jim Halpert') dwight = Human.new('Dwight K. Schrute') -``` -## Methodenaufrufe -``` +# Du kannst die Methoden des erstellten Objekts aufrufen. jim.species #=> "H. sapiens" jim.name #=> "Jim Halpert" jim.name = "Jim Halpert II" #=> "Jim Halpert II" jim.name #=> "Jim Halpert II" dwight.species #=> "H. sapiens" dwight.name #=> "Dwight K. Schrute" -``` -## Eine Klassenmethode aufrufen -``` +# Aufrufen einer Klassenmethode Human.say('Hi') #=> "Hi" -``` -## Variable Gültigkeit -### Variablen die mit "$" starten, gelten global -``` -$var = "I'm a global var" +# Der Gültigkeitsbereich einer Variablen wird durch ihren Namen definiert. +# Variablen, die mit $ beginnen sind global gültig. +$var = "Ich bin eine globale Variable" defined? $var #=> "global-variable" -``` -### Variablen die mit "@" starten, gelten für die Instanz -``` -@var = "I'm an instance var" +# Variablen, die mit @ beginnen, sind innerhalb einer Instanz gültig. +@var = "Ich bin eine Instanzvariable" defined? @var #=> "instance-variable" -``` -### Variablen die mit "@@" starten, gelten für die Klasse -``` -@@var = "I'm a class var" +# Variablen, die mit @@ beginnen, sind für die Klasse gültig. +@@var = "Ich bin eine Klassenvariable" defined? @@var #=> "class variable" -``` -### Variablen die mit einem Großbuchstaben anfangen, sind Konstanten -``` -Var = "I'm a constant" +# Variablen, die mit einem Großbuchstaben beginnen, sind Konstanten +Var = "Ich bin eine Konstante" defined? Var #=> "constant" -``` -## Class ist auch ein Objekt -### Hat also auch Instanzvariablen -### Eine Klassenvariable wird innerhalb der Klasse und Ableitungen geteilt. +# Class ist in Ruby auch ein Objekt. Deshalb kann eine Klasse Instanzvariablen +# haben. Eine Klassenvariable wird zwischen der Klasse und all ihren +# Ableitungen geteilt. -### Basis Klasse -``` +# Basis Klasse class Human @@foo = 0 + def self.foo @@foo end + def self.foo=(value) @@foo = value end end -``` -### Abgeleitete Klasse -``` +# Abgeleitete Klasse class Worker < Human end -Human.foo # 0 -Worker.foo # 0 -Human.foo = 2 # 2 -Worker.foo # 2 -``` -### Eine Klasseninstanzvariable wird nicht geteilt -``` +Human.foo #=> 0 +Worker.foo #=> 0 + +Human.foo = 2 +Worker.foo #=> 2 + +# Ableitungen einer Klasse haben keinen Zugriff auf eine Eine Klassen-Instanzvariable. class Human @bar = 0 + def self.bar @bar end + def self.bar=(value) @bar = value end end -``` -``` + class Doctor < Human end -``` -``` -Human.bar # 0 -Doctor.bar # nil -``` -``` + +Human.bar #=> 0 +Doctor.bar #=> nil + module ModuleExample def foo 'foo' end end -``` -### Module einbinden, heisst ihre Methoden an die Instanzen der Klasse zu binden -### Module erweitern, heisst ihre Mothden an die Klasse selbst zu binden -``` + +# Ein Einbinden (include) eines Moduls bindet seine Methoden an die Instanzen +# der Klasse. +# Ein Erweitern (extend) eines Moduls bindet seine Methoden an die Klasse +# selbst. 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 werden ausgeführt, wenn ein Modul eingebunden oder erweitert wird -``` - 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 + +Person.foo #=> NoMethodError: undefined method `foo' for Person:Class +Person.new.foo #=> "foo" +Book.foo #=> "foo" +Book.new.foo #=> NoMethodError: undefined method `foo' + + +# Callbacks werden ausgeführt, wenn ein Modul eingebunden oder erweitert wird. +module ConcernExample + def self.included(base) + base.extend(ClassMethods) + base.send(:include, InstanceMethods) + end + + module ClassMethods + def bar + 'bar' end end - class Something - include ConcernExample + + module InstanceMethods + def qux + 'qux' + end end -``` -``` -Something.bar # => 'bar' -Something.qux # => NoMethodError: undefined method `qux' -Something.new.bar # => NoMethodError: undefined method `bar' -Something.new.qux # => 'qux' +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" ``` -## Weiterführende Hinweise +## Weitere Links -//EN +_(z.T. auf Englisch)_ -- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338) - A variant of this reference with in-browser challenges. -- [Official Documentation](http://www.ruby-doc.org/core-2.1.1/) +- [Offizielle Ruby Website](https://www.ruby-lang.org/de/) +- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338) - Eine Variante dieses Dokuments mit in-Browser Challenges. +- [RubyMonk](https://rubymonk.com/) - Lerne Ruby mit einer Reihe interaktiver Tutorials. +- [Offizielle Dokumentation](http://ruby-doc.org/core) - [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/) -- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - An older [free edition](http://ruby-doc.com/docs/ProgrammingRuby/) is available online. -- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - A community-driven Ruby coding style guide. +- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - Eine ältere [freie Ausgabe](http://ruby-doc.com/docs/ProgrammingRuby/) ist online verfügbar. +- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - Ein von der Community erstellter Ruby coding style guide. +- [Try Ruby](http://tryruby.org) - Lerne die Grundlagen der Ruby Programmiersprache, interaktiv im Browser. diff --git a/de-de/vim-de.html.markdown b/de-de/vim-de.html.markdown new file mode 100644 index 00000000..8abf9a14 --- /dev/null +++ b/de-de/vim-de.html.markdown @@ -0,0 +1,282 @@ +--- +category: tool +tool: vim +lang: de-de +contributors: + - ["RadhikaG", "https://github.com/RadhikaG"] +translators: + - ["caminsha", "https://github.com/caminsha"] +filename: LearnVim-de.txt +--- + + +[Vim](http://www.vim.org) +(Vi IMproved) ist ein Klon von vi, dem bekannten Editor für Unix. Es ist ein +Texteditor, welcher mit Fokus auf Geschwindigkeit und Prouktivität entwickelt +wurde. +Vim hat viele Keybindings für ein schnelles navigieren und schnelles bearbeiten +einer Datei. + +## Grundlagen, um in Vim zu navigieren + +``` + vim <filename> # Öffne <filename> in Vim + :help <topic> # Open up built-in help docs about <topic> if any exists + :help <topic> # Öffne die eingebaute Hilfe zum Thema <topic>, wenn + # es existiert + :q # Schließe vim + :w # Speichere diese Datei + :wq # Speichere diese Datei und schließe vim + ZZ # Speichere diese Datei und schließe vim + :q! # Schließe vim ohne die Datei zu speichern + # ! *zwingt* die Ausführung von :q, + # daher wird die Datei nicht gespeichert. + ZQ # Beende vim ohne die Datei zu speichern + :x # Speichere die Datei und beende vim + # Dies ist eine kürzere Version von :wq + + u # Änderung rückgängig machen + CTRL+R # Änderung wiederherstellen + + h # Den Cursor um ein Zeichen nach links bewegen + j # Den Cursor eine Zeile nach unten bewegen + k # Den Cursor eine Zeile nach oben bewegen + l # Den Cursor um ein Zeichen nach rechts bewegen + + Ctrl+B # Gehe eine Bildschirmanzeige zurück + Ctrl+F # Gehe eine Bildschirmanzeige vorwärts + Ctrl+D # Gehe eine halbe Bildschirmanzeige vorwärts + Ctrl+U # Gehe eine halbe Bildschirmanzeige zurück + + # Navigieren innerhalb einer Zeile + + 0 # Navigiere zum Anfang der Zeile + $ # Navigiere zum Ende der Zeile + ^ # Navigiere zum ersten Zeichen, welches kein Leerzeichen ist + + # Im Text suchen + + /word # Hebt alle Ergebnisse nach dem Cursor hervor + ?word # Hebt alle Ergebnisse vor dem Cursor hervor + n # Bewegt den Cursor zum nächsten Ergebnis nach der Suche + N # Bewegt den Cursor zum vorherigen Ergebnis der Suche + + :%s/foo/bar/g # Ersetze "foo" durch "bar" in allen Zeilen + :s/foo/bar/g # Ersetze "foo" durch "bar" in der aktuellen Zeile + :%s/\n/\r/g # Ersetze das newline-Zeichen bei allen Zeilen durch + # ein carriage return + + # Zu einzelnen Zeichen springen + + f<character> # Springe vorwärts und auf dem Zeichen <character> + t<character> # Springe vorwärts und lande vor dem Zeichen <character> + + # Zum Beispiel, + f< # Springe vorwärts und lande auf < + t< # Springe vorwärts und lande vor < + + # Wortweise navigieren + + w # Springe um ein Wort vorwärts + b # Gehe ein Wort zurück + e # Springe zum Ende des aktuellen Wortes + + # Weitere Befehle, um zu navigieren + + gg # Gehe an den Start der Datei + G # Gehe an das Ende der Datei + :NUM # Springe zur Zeile NUM (NUM kann eine beliebige Zahl sein) + H # Navigiere zum Start der aktuellen Bildschirmanzeige + M # Navigiere in die Mitte der aktuellen Bildschirmanzeige + L # Navigiere an das Ende der aktuellen Bildschirmanzeige +``` + +## Hilfsdokumente: + +Vim hat eine eingebaute Dokumentation, welche mit `:help <topic>` aufgerufen +werden kann. +Zum Beispiel öffnet `:help navigation` die Dokumentation über das Navigieren + +`:help` kann auch ohne ein Argument verwendet werden. Dies zeigt den Standard- +Hilfsdialog an, welcher den Start mit vim einfacher macht. +that aims to make getting started with vim more approachable! + +## Modi: + +Vim basiert auf dem Konzept von **modes**. + +- Command Mode - Vim startet in diesem Modus, hier kann man navigieren und Befehle eingeben +- Insert Mode - Wird verwendet, um Änderungen in der Datei zu machen. +- Visual Mode - Wird verwendet, um Text zu markieren und Operationen durchzuführen +- Ex Mode - Wird verwendet, um im ':'-Prompt Befehle einzugeben + +``` + i # Führt vim in den Insert Mode, vor der Cursorposition + a # Führt vim in den Insert Mode, nach der Cursorposition + v # Führt vim in den Visual Mode + : # Führt vim in den Ex Mode + <esc> # Führt zurück in den Command Mode, egal in welchem Mode + # man sich gerade befindet. + + # Kopieren und einfügen von Text + + y # Kopiere alles, was im Moment ausgewählt ist + yy # Kopiert die aktuelle Zeile + d # Löscht alles, was im Moment ausgewählt ist + dd # Löscht die aktuelle Zeile + p # Fügt den kopierten Text nach dem Cursor ein + P # Fügt den kopierten Text vor dem Cursor ein + x # Löscht das Zeichen unter dem Cursor +``` + +## Die 'Grammatik' von Vim + +Vim kann als Satz von Kommandos angesehen werden, welche im Format +'Verb-Modifier-Noun' sind. Hierbei gilt: + +- Verb - die Aktion, du machen willst +- Modifier - wie die Aktion gemacht wird +- Noun - das Objekt, auf welchem die Aktion ausgeführt wird. + +Einige wichtige Beispiele von 'Verb', 'Modifier' und 'Nouns': + +``` + # 'Verb' + + d # löschen + c # ändern + y # kopieren + v # visuelles auswählen + + # 'Modifiers' + + i # innerhalb + a # außerhalb + NUM # Nummer (NUM kann irgendeine Zahl sein) + f # Sucht nach etwas und landet darauf + t # Sucht nach etwas und stoppt davor + / # Suche eine Zeichenfolge ab dem Cursor + ? # Suche eine Zeichenfolge vor dem Cursor + + # 'Nouns' + + w # Wort + s # Satz + p # Abschnitt + b # Block + + # Beispielsätze resp. Kommandos + + d2w # lösche zwei Wörter + cis # Ändere innerhalb des Satzes. + yip # Kopiere innerhalb des Abschnitts (kopiere den Abschnitt, + # in welchem du bist) + ct< # Ändere bis zur spitzen Klammer + # Ändere den Text von deiner aktuellen Cursorposition bis + # zur nächsten spitzen Klammer + d$ # Lösche bis zum Ende der Zeile +``` + +## Einige Shortcuts und Tricks + +``` + > # Rücke die Auswahl um einen Block ein + < # Lösche eine Einrückung der Auswahl + :earlier 15m # Stellt das Dokument so wieder her, wie es vor 15 + # Minuten war + :later 15m # den oberen Befehl rückgängig machen + ddp # Vertauschen zweier aufeinanderfolgenden Zeilen + # Zuerst dd, dann p + . # Wiederhole die vorherige Aktion + :w !sudo tee % # Speichere die Datei als Root + :set syntax=c # Stelle das Syntax-Highlighting für 'C' ein + :sort # Alle Zeilen sortieren + :sort! # Alle Zeilen rückwärts sortieren + :sort u # Alle Zeilen sortieren und Duplikate entfernen + ~ # Umschalten der Groß-/Kleinschreibung des ausgewählten Textes + u # Ausgewählten Text zu Kleinschreibung ändern + U # Ausgewählten Text zu Großschreibung ändern + + # Text-Folding (Textfaltung) + zf # Erstelle eine Faltung des ausgewählten Textes + zo # Öffne die aktuelle Faltung + zc # Schließe die aktuelle Faltung + zR # Öffne alle Faltungen + zM # Schließe alle Faltungen +``` + +## Makros + +Makros sind grundsätzlich einfach aufgezeichnete Aktionen +Wenn du mit dem Aufnehmen eines Makros beginnst, werden **alle** Aktionen und +Kommandos, welche du braucht, aufgenommen bis die Aufnahme gestoppt wird. +Wenn du ein Makro ausführst, werden exakt die gleichen Schritte gemacht. + +``` + qa # Starte das Aufnehmen des Makros 'a' + q # Beende das Aufnehmen + @a # Führe das Makro 'a' aus +``` + +### Konfigurieren mit ~/.vimrc + +Die Datei .vimrc kann verwendet werden, um Vim beim Starten zu konfigurieren + +Hier ist eine Beispiel ~/.vimrc Datei: + +``` +" Beispiel ~/.vimrc + +" Erforderlich für vim, dass es iMproved ist. +set nocompatible + +" Bestimme den Dateityp anhand des Namens, um ein intelligentes Einrücken etc. +" zu ermöglichen +filetype indent plugin on + +" Aktiviere das Syntax-Highlighting +syntax on + +" Bessere Kommandozeilen-Vervollständigung +set wildmenu + +" Verwende die Suche ohne die Berücksichtigung der Groß-/Kleinschreibung, außer +" wenn mit Großbuchstaben gesucht wird. +set ignorecase +set smartcase + +" Wenn eine neue Zeile erstellt wird und kein Dateispezifisches Einrücken +" aktiviert ist, behält die neue Zeile die gleiche Einrückung wie die aktuelle +" Zeile +set autoindent + +" Zeige links die Zeilennummern an +set number + +" Einrückungsoptionen, ändere diese nach deinen Vorlieben + +" Anzahl sichtbarer Leerzeichen bei einem TAB +set tabstop=4 + +" Anzahl der Leerzeichen während des Bearbeitens bei einem TAB +set softtabstop=4 + +" Anzahl der Einrückungstiefe bei den Operationen (>> und <<) +set shiftwidth=4 + +" Konvertiere TABs zu Leerzeichen +set expandtab + +" Enable intelligent tabbing and spacing for indentation and alignment +" Aktiviere intelligente Tabs und Leerzeichen bei der Einrückung und Ausrichtung +set smarttab +``` + +### Verweise + +- [Vim | Homepage](http://www.vim.org/index.php) +- In der Shell eingeben: `vimtutor` +- [Ein vim Tutorial und Primer, englisch](https://danielmiessler.com/study/vim/) +- [Deutsches Arch Linux Wiki](https://wiki.archlinux.de/title/Vim) +- [Arch Linux Wiki, englisch (dafür ausführlicher)](https://wiki.archlinux.org/index.php/Vim) +- [What are the dark corners of Vim your mom never told you about? (Stack Overflow thread)](http://stackoverflow.com/questions/726894/what-are-the-dark-corners-of-vim-your-mom-never-told-you-about) |