1
0
mirror of https://github.com/adambard/learnxinyminutes-docs.git synced 2025-08-06 14:56:54 +02:00

Convert \r\n to \n

This commit is contained in:
Boris Verkhovskiy
2024-04-04 00:27:01 -07:00
parent 4ab1be1be5
commit 818b8eec46
18 changed files with 6767 additions and 6767 deletions

View File

@@ -1,212 +1,212 @@
--- ---
category: tool category: tool
tool: amd tool: amd
contributors: contributors:
- ["Frederik Ring", "https://github.com/m90"] - ["Frederik Ring", "https://github.com/m90"]
filename: learnamd.js filename: learnamd.js
--- ---
## Getting Started with AMD ## Getting Started with AMD
The **Asynchronous Module Definition** API specifies a mechanism for defining The **Asynchronous Module Definition** API specifies a mechanism for defining
JavaScript modules such that the module and its dependencies can be asynchronously JavaScript modules such that the module and its dependencies can be asynchronously
loaded. This is particularly well suited for the browser environment where loaded. This is particularly well suited for the browser environment where
synchronous loading of modules incurs performance, usability, debugging, and synchronous loading of modules incurs performance, usability, debugging, and
cross-domain access problems. cross-domain access problems.
### Basic concept ### Basic concept
```javascript ```javascript
// The basic AMD API consists of nothing but two methods: `define` and `require` // The basic AMD API consists of nothing but two methods: `define` and `require`
// and is all about module definition and consumption: // and is all about module definition and consumption:
// `define(id?, dependencies?, factory)` defines a module // `define(id?, dependencies?, factory)` defines a module
// `require(dependencies, callback)` imports a set of dependencies and // `require(dependencies, callback)` imports a set of dependencies and
// consumes them in the passed callback // consumes them in the passed callback
// Let's start by using define to define a new named module // Let's start by using define to define a new named module
// that has no dependencies. We'll do so by passing a name // that has no dependencies. We'll do so by passing a name
// and a factory function to define: // and a factory function to define:
define('awesomeAMD', function(){ define('awesomeAMD', function(){
var isAMDAwesome = function(){ var isAMDAwesome = function(){
return true; return true;
}; };
// The return value of a module's factory function is // The return value of a module's factory function is
// what other modules or require calls will receive when // what other modules or require calls will receive when
// requiring our `awesomeAMD` module. // requiring our `awesomeAMD` module.
// The exported value can be anything, (constructor) functions, // The exported value can be anything, (constructor) functions,
// objects, primitives, even undefined (although that won't help too much). // objects, primitives, even undefined (although that won't help too much).
return isAMDAwesome; return isAMDAwesome;
}); });
// Now, let's define another module that depends upon our `awesomeAMD` module. // Now, let's define another module that depends upon our `awesomeAMD` module.
// Notice that there's an additional argument defining our // Notice that there's an additional argument defining our
// module's dependencies now: // module's dependencies now:
define('loudmouth', ['awesomeAMD'], function(awesomeAMD){ define('loudmouth', ['awesomeAMD'], function(awesomeAMD){
// dependencies will be passed to the factory's arguments // dependencies will be passed to the factory's arguments
// in the order they are specified // in the order they are specified
var tellEveryone = function(){ var tellEveryone = function(){
if (awesomeAMD()){ if (awesomeAMD()){
alert('This is sOoOo rad!'); alert('This is sOoOo rad!');
} else { } else {
alert('Pretty dull, isn\'t it?'); alert('Pretty dull, isn\'t it?');
} }
}; };
return tellEveryone; return tellEveryone;
}); });
// As we do know how to use define now, let's use `require` to // As we do know how to use define now, let's use `require` to
// kick off our program. `require`'s signature is `(arrayOfDependencies, callback)`. // kick off our program. `require`'s signature is `(arrayOfDependencies, callback)`.
require(['loudmouth'], function(loudmouth){ require(['loudmouth'], function(loudmouth){
loudmouth(); loudmouth();
}); });
// To make this tutorial run code, let's implement a very basic // To make this tutorial run code, let's implement a very basic
// (non-asynchronous) version of AMD right here on the spot: // (non-asynchronous) version of AMD right here on the spot:
function define(name, deps, factory){ function define(name, deps, factory){
// notice how modules without dependencies are handled // notice how modules without dependencies are handled
define[name] = require(factory ? deps : [], factory || deps); define[name] = require(factory ? deps : [], factory || deps);
} }
function require(deps, callback){ function require(deps, callback){
var args = []; var args = [];
// first let's retrieve all the dependencies needed // first let's retrieve all the dependencies needed
// by the require call // by the require call
for (var i = 0; i < deps.length; i++){ for (var i = 0; i < deps.length; i++){
args[i] = define[deps[i]]; args[i] = define[deps[i]];
} }
// satisfy all the callback's dependencies // satisfy all the callback's dependencies
return callback.apply(null, args); return callback.apply(null, args);
} }
// you can see this code in action here: http://jsfiddle.net/qap949pd/ // you can see this code in action here: http://jsfiddle.net/qap949pd/
``` ```
### Real-world usage with require.js ### Real-world usage with require.js
In contrast to the introductory example, `require.js` (the most popular AMD library) actually implements the **A** in **AMD**, enabling you to load modules and their dependencies asynchronously via XHR: In contrast to the introductory example, `require.js` (the most popular AMD library) actually implements the **A** in **AMD**, enabling you to load modules and their dependencies asynchronously via XHR:
```javascript ```javascript
/* file: app/main.js */ /* file: app/main.js */
require(['modules/someClass'], function(SomeClass){ require(['modules/someClass'], function(SomeClass){
// the callback is deferred until the dependency is loaded // the callback is deferred until the dependency is loaded
var thing = new SomeClass(); var thing = new SomeClass();
}); });
console.log('So here we are, waiting!'); // this will run first console.log('So here we are, waiting!'); // this will run first
``` ```
By convention, you usually store one module in one file. `require.js` can resolve module names based on file paths, so you don't have to name your modules, but can simply reference them using their location. In the example `someClass` is assumed to be in the `modules` folder, relative to your configuration's `baseUrl`: By convention, you usually store one module in one file. `require.js` can resolve module names based on file paths, so you don't have to name your modules, but can simply reference them using their location. In the example `someClass` is assumed to be in the `modules` folder, relative to your configuration's `baseUrl`:
* app/ * app/
* main.js * main.js
* modules/ * modules/
* someClass.js * someClass.js
* someHelpers.js * someHelpers.js
* ... * ...
* daos/ * daos/
* things.js * things.js
* ... * ...
This means we can define `someClass` without specifying a module id: This means we can define `someClass` without specifying a module id:
```javascript ```javascript
/* file: app/modules/someClass.js */ /* file: app/modules/someClass.js */
define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){ define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){
// module definition, of course, will also happen asynchronously // module definition, of course, will also happen asynchronously
function SomeClass(){ function SomeClass(){
this.method = function(){/**/}; this.method = function(){/**/};
// ... // ...
} }
return SomeClass; return SomeClass;
}); });
``` ```
To alter the default path mapping behavior use `requirejs.config(configObj)` in your `main.js`: To alter the default path mapping behavior use `requirejs.config(configObj)` in your `main.js`:
```javascript ```javascript
/* file: main.js */ /* file: main.js */
requirejs.config({ requirejs.config({
baseUrl : 'app', baseUrl : 'app',
paths : { paths : {
// you can also load modules from other locations // you can also load modules from other locations
jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min', jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min',
coolLibFromBower : '../bower_components/cool-lib/coollib' coolLibFromBower : '../bower_components/cool-lib/coollib'
} }
}); });
require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){ require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){
// a `main` file needs to call require at least once, // a `main` file needs to call require at least once,
// otherwise no code will ever run // otherwise no code will ever run
coolLib.doFancyStuffWith(helpers.transform($('#foo'))); coolLib.doFancyStuffWith(helpers.transform($('#foo')));
}); });
``` ```
`require.js`-based apps will usually have a single entry point (`main.js`) that is passed to the `require.js` script tag as a data-attribute. It will be automatically loaded and executed on pageload: `require.js`-based apps will usually have a single entry point (`main.js`) that is passed to the `require.js` script tag as a data-attribute. It will be automatically loaded and executed on pageload:
```html ```html
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>A hundred script tags? Never again!</title> <title>A hundred script tags? Never again!</title>
</head> </head>
<body> <body>
<script src="require.js" data-main="app/main"></script> <script src="require.js" data-main="app/main"></script>
</body> </body>
</html> </html>
``` ```
### Optimizing a whole project using r.js ### Optimizing a whole project using r.js
Many people prefer using AMD for sane code organization during development, but still want to ship a single script file in production instead of performing hundreds of XHRs on page load. Many people prefer using AMD for sane code organization during development, but still want to ship a single script file in production instead of performing hundreds of XHRs on page load.
`require.js` comes with a script called `r.js` (that you will probably run in node.js, although Rhino is supported too) that can analyse your project's dependency graph, and build a single file containing all your modules (properly named), minified and ready for consumption. `require.js` comes with a script called `r.js` (that you will probably run in node.js, although Rhino is supported too) that can analyse your project's dependency graph, and build a single file containing all your modules (properly named), minified and ready for consumption.
Install it using `npm`: Install it using `npm`:
```shell ```shell
$ npm install requirejs -g $ npm install requirejs -g
``` ```
Now you can feed it with a configuration file: Now you can feed it with a configuration file:
```shell ```shell
$ r.js -o app.build.js $ r.js -o app.build.js
``` ```
For our above example the configuration might look like: For our above example the configuration might look like:
```javascript ```javascript
/* file : app.build.js */ /* file : app.build.js */
({ ({
name : 'main', // name of the entry point name : 'main', // name of the entry point
out : 'main-built.js', // name of the file to write the output to out : 'main-built.js', // name of the file to write the output to
baseUrl : 'app', baseUrl : 'app',
paths : { paths : {
// `empty:` tells r.js that this should still be loaded from the CDN, using // `empty:` tells r.js that this should still be loaded from the CDN, using
// the location specified in `main.js` // the location specified in `main.js`
jquery : 'empty:', jquery : 'empty:',
coolLibFromBower : '../bower_components/cool-lib/coollib' coolLibFromBower : '../bower_components/cool-lib/coollib'
} }
}) })
``` ```
To use the built file in production, simply swap `data-main`: To use the built file in production, simply swap `data-main`:
```html ```html
<script src="require.js" data-main="app/main-built"></script> <script src="require.js" data-main="app/main-built"></script>
``` ```
An incredibly detailed [overview of build options](https://github.com/jrburke/r.js/blob/master/build/example.build.js) is available in the GitHub repo. An incredibly detailed [overview of build options](https://github.com/jrburke/r.js/blob/master/build/example.build.js) is available in the GitHub repo.
### Topics not covered in this tutorial ### Topics not covered in this tutorial
* [Loader plugins / transforms](http://requirejs.org/docs/plugins.html) * [Loader plugins / transforms](http://requirejs.org/docs/plugins.html)
* [CommonJS style loading and exporting](http://requirejs.org/docs/commonjs.html) * [CommonJS style loading and exporting](http://requirejs.org/docs/commonjs.html)
* [Advanced configuration](http://requirejs.org/docs/api.html#config) * [Advanced configuration](http://requirejs.org/docs/api.html#config)
* [Shim configuration (loading non-AMD modules)](http://requirejs.org/docs/api.html#config-shim) * [Shim configuration (loading non-AMD modules)](http://requirejs.org/docs/api.html#config-shim)
* [CSS loading and optimizing with require.js](http://requirejs.org/docs/optimization.html#onecss) * [CSS loading and optimizing with require.js](http://requirejs.org/docs/optimization.html#onecss)
* [Using almond.js for builds](https://github.com/jrburke/almond) * [Using almond.js for builds](https://github.com/jrburke/almond)
### Further reading: ### Further reading:
* [Official Spec](https://github.com/amdjs/amdjs-api/wiki/AMD) * [Official Spec](https://github.com/amdjs/amdjs-api/wiki/AMD)
* [Why AMD?](http://requirejs.org/docs/whyamd.html) * [Why AMD?](http://requirejs.org/docs/whyamd.html)
* [Universal Module Definition](https://github.com/umdjs/umd) * [Universal Module Definition](https://github.com/umdjs/umd)
### Implementations: ### Implementations:
* [require.js](http://requirejs.org) * [require.js](http://requirejs.org)
* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/) * [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/)
* [cujo.js](http://cujojs.com/) * [cujo.js](http://cujojs.com/)
* [curl.js](https://github.com/cujojs/curl) * [curl.js](https://github.com/cujojs/curl)
* [lsjs](https://github.com/zazl/lsjs) * [lsjs](https://github.com/zazl/lsjs)
* [mmd](https://github.com/alexlawrence/mmd) * [mmd](https://github.com/alexlawrence/mmd)

File diff suppressed because it is too large Load Diff

View File

@@ -1,423 +1,423 @@
--- ---
language: Elixir language: Elixir
contributors: contributors:
- ["Joao Marques", "http://github.com/mrshankly"] - ["Joao Marques", "http://github.com/mrshankly"]
translators: translators:
- ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"] - ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"]
filename: learnelixir-de.ex filename: learnelixir-de.ex
lang: de-de lang: de-de
--- ---
Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll
kompatibel mit Erlang, verfügt aber über eine freundlichere Syntax und bringt kompatibel mit Erlang, verfügt aber über eine freundlichere Syntax und bringt
viele Features mit. viele Features mit.
```ruby ```ruby
# Einzeilige Kommentare werden mit der Raute gesetzt. # Einzeilige Kommentare werden mit der Raute gesetzt.
# Es gibt keine mehrzeiligen Kommentare; # Es gibt keine mehrzeiligen Kommentare;
# es ist aber problemlos möglich mehrere einzeilige Kommentare hintereinander # es ist aber problemlos möglich mehrere einzeilige Kommentare hintereinander
# zu setzen (so wie hier). # zu setzen (so wie hier).
# Mit 'iex' ruft man die Elixir-Shell auf. # Mit 'iex' ruft man die Elixir-Shell auf.
# Zum kompilieren von Modulen dient der Befehl 'elixirc'. # Zum kompilieren von Modulen dient der Befehl 'elixirc'.
# Beide Befehle sollten als Umgebungsvariable gesetzt sein, wenn Elixir korrekt # Beide Befehle sollten als Umgebungsvariable gesetzt sein, wenn Elixir korrekt
# installiert wurde. # installiert wurde.
## --------------------------- ## ---------------------------
## -- Basistypen ## -- Basistypen
## --------------------------- ## ---------------------------
# Es gibt Nummern: # Es gibt Nummern:
3 # Integer 3 # Integer
0x1F # Integer 0x1F # Integer
3.0 # Float 3.0 # Float
# Für bessere Lesbarkeit des Codes können Unterstriche "_" als Trennzeichen verwendet werden # Für bessere Lesbarkeit des Codes können Unterstriche "_" als Trennzeichen verwendet werden
1_000_000 == 1000000 # Integer 1_000_000 == 1000000 # Integer
1_000.567 == 1000.567 # Float 1_000.567 == 1000.567 # Float
# Atome, das sind Literale, sind Konstanten mit Namen. Sie starten mit einem # Atome, das sind Literale, sind Konstanten mit Namen. Sie starten mit einem
# ':'. # ':'.
:hello # Atom :hello # Atom
# Außerdem gibt es Tupel, deren Werte im Arbeitsspeicher vorgehalten werden. # Außerdem gibt es Tupel, deren Werte im Arbeitsspeicher vorgehalten werden.
{1,2,3} # Tupel {1,2,3} # Tupel
# Die Werte innerhalb eines Tupels können mit der 'elem'-Funktion ausgelesen # Die Werte innerhalb eines Tupels können mit der 'elem'-Funktion ausgelesen
# werden: # werden:
elem({1, 2, 3}, 0) # => 1 elem({1, 2, 3}, 0) # => 1
# Listen sind als verkettete Listen implementiert. # Listen sind als verkettete Listen implementiert.
[1, 2, 3] # list [1, 2, 3] # list
# Auf Kopf und Rest einer Liste kann wie folgt zugegriffen werden: # Auf Kopf und Rest einer Liste kann wie folgt zugegriffen werden:
[ kopf | rest ] = [1,2,3] [ kopf | rest ] = [1,2,3]
kopf # => 1 kopf # => 1
rest # => [2, 3] rest # => [2, 3]
# In Elixir, wie auch in Erlang, kennzeichnet '=' ein 'pattern matching' # In Elixir, wie auch in Erlang, kennzeichnet '=' ein 'pattern matching'
# (Musterabgleich) und keine Zuweisung. # (Musterabgleich) und keine Zuweisung.
# Das heißt, dass die linke Seite auf die rechte Seite 'abgeglichen' wird. # Das heißt, dass die linke Seite auf die rechte Seite 'abgeglichen' wird.
# Auf diese Weise kann im Beispiel oben auf Kopf und Rest der Liste zugegriffen # Auf diese Weise kann im Beispiel oben auf Kopf und Rest der Liste zugegriffen
# werden. # werden.
# Ein Musterabgleich wird einen Fehler werfen, wenn die beiden Seiten nicht # Ein Musterabgleich wird einen Fehler werfen, wenn die beiden Seiten nicht
# zusammenpassen. # zusammenpassen.
# Im folgenden Beispiel haben die Tupel eine unterschiedliche Anzahl an # Im folgenden Beispiel haben die Tupel eine unterschiedliche Anzahl an
# Elementen: # Elementen:
{a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2} {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
# Es gibt außerdem 'binaries', # Es gibt außerdem 'binaries',
<<1,2,3>> # binary. <<1,2,3>> # binary.
# Strings und 'char lists' # Strings und 'char lists'
"hello" # String "hello" # String
'hello' # Char-Liste 'hello' # Char-Liste
# ... und mehrzeilige Strings # ... und mehrzeilige Strings
""" """
Ich bin ein Ich bin ein
mehrzeiliger String. mehrzeiliger String.
""" """
#=> "Ich bin ein\nmehrzeiliger String.\n" #=> "Ich bin ein\nmehrzeiliger String.\n"
# Alles Strings werden in UTF-8 enkodiert: # Alles Strings werden in UTF-8 enkodiert:
"héllò" #=> "héllò" "héllò" #=> "héllò"
# Eigentlich sind Strings in Wahrheit nur binaries und 'char lists' einfach # Eigentlich sind Strings in Wahrheit nur binaries und 'char lists' einfach
# Listen. # Listen.
<<?a, ?b, ?c>> #=> "abc" <<?a, ?b, ?c>> #=> "abc"
[?a, ?b, ?c] #=> 'abc' [?a, ?b, ?c] #=> 'abc'
# In Elixir gibt `?a` den ASCII-Integer für den Buchstaben zurück. # In Elixir gibt `?a` den ASCII-Integer für den Buchstaben zurück.
?a #=> 97 ?a #=> 97
# Um Listen zu verbinden gibt es den Operator '++', für binaries nutzt man '<>' # Um Listen zu verbinden gibt es den Operator '++', für binaries nutzt man '<>'
[1,2,3] ++ [4,5] #=> [1,2,3,4,5] [1,2,3] ++ [4,5] #=> [1,2,3,4,5]
'hello ' ++ 'world' #=> 'hello world' 'hello ' ++ 'world' #=> 'hello world'
<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>> <<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
"hello " <> "world" #=> "hello world" "hello " <> "world" #=> "hello world"
## --------------------------- ## ---------------------------
## -- Operatoren ## -- Operatoren
## --------------------------- ## ---------------------------
# Einfache Arithmetik # Einfache Arithmetik
1 + 1 #=> 2 1 + 1 #=> 2
10 - 5 #=> 5 10 - 5 #=> 5
5 * 2 #=> 10 5 * 2 #=> 10
10 / 2 #=> 5.0 10 / 2 #=> 5.0
# In Elixir gibt der Operator '/' immer einen Float-Wert zurück. # In Elixir gibt der Operator '/' immer einen Float-Wert zurück.
# Für Division mit ganzzahligen Ergebnis gibt es 'div' # Für Division mit ganzzahligen Ergebnis gibt es 'div'
div(10, 2) #=> 5 div(10, 2) #=> 5
# Um den Rest der ganzzahligen Division zu erhalten gibt es 'rem' # Um den Rest der ganzzahligen Division zu erhalten gibt es 'rem'
rem(10, 3) #=> 1 rem(10, 3) #=> 1
# Natürlich gibt es auch Operatoren für Booleans: 'or', 'and' und 'not'. Diese # Natürlich gibt es auch Operatoren für Booleans: 'or', 'and' und 'not'. Diese
# Operatoren erwarten einen Boolean als erstes Argument. # Operatoren erwarten einen Boolean als erstes Argument.
true and true #=> true true and true #=> true
false or true #=> true false or true #=> true
# 1 and true #=> ** (ArgumentError) argument error # 1 and true #=> ** (ArgumentError) argument error
# Elixir bietet auch '||', '&&' und '!', die Argumente jedweden Typs # Elixir bietet auch '||', '&&' und '!', die Argumente jedweden Typs
# akzeptieren. Alle Werte außer 'false' und 'nil' werden zu wahr evaluiert. # akzeptieren. Alle Werte außer 'false' und 'nil' werden zu wahr evaluiert.
1 || true #=> 1 1 || true #=> 1
false && 1 #=> false false && 1 #=> false
nil && 20 #=> nil nil && 20 #=> nil
!true #=> false !true #=> false
# Für Vergleiche gibt es die Operatoren `==`, `!=`, `===`, `!==`, `<=`, `>=`, # Für Vergleiche gibt es die Operatoren `==`, `!=`, `===`, `!==`, `<=`, `>=`,
# `<` und `>` # `<` und `>`
1 == 1 #=> true 1 == 1 #=> true
1 != 1 #=> false 1 != 1 #=> false
1 < 2 #=> true 1 < 2 #=> true
# '===' und '!==' sind strikter beim Vergleich von Integern und Floats: # '===' und '!==' sind strikter beim Vergleich von Integern und Floats:
1 == 1.0 #=> true 1 == 1.0 #=> true
1 === 1.0 #=> false 1 === 1.0 #=> false
# Es ist außerdem möglich zwei verschiedene Datentypen zu vergleichen: # Es ist außerdem möglich zwei verschiedene Datentypen zu vergleichen:
1 < :hello #=> true 1 < :hello #=> true
# Die gesamte Ordnung über die Datentypen ist wie folgt definiert: # Die gesamte Ordnung über die Datentypen ist wie folgt definiert:
# number < atom < reference < functions < port < pid < tuple < list < bitstring # number < atom < reference < functions < port < pid < tuple < list < bitstring
# Um Joe Armstrong zu zitieren: "The actual order is not important, but that a # Um Joe Armstrong zu zitieren: "The actual order is not important, but that a
# total ordering is well defined is important." # total ordering is well defined is important."
## --------------------------- ## ---------------------------
## -- Kontrollstrukturen ## -- Kontrollstrukturen
## --------------------------- ## ---------------------------
# Es gibt die `if`-Verzweigung # Es gibt die `if`-Verzweigung
if false do if false do
"Dies wird nie jemand sehen..." "Dies wird nie jemand sehen..."
else else
"...aber dies!" "...aber dies!"
end end
# ...und ebenso `unless` # ...und ebenso `unless`
unless true do unless true do
"Dies wird nie jemand sehen..." "Dies wird nie jemand sehen..."
else else
"...aber dies!" "...aber dies!"
end end
# Du erinnerst dich an 'pattern matching'? Viele Kontrollstrukturen in Elixir # Du erinnerst dich an 'pattern matching'? Viele Kontrollstrukturen in Elixir
# arbeiten damit. # arbeiten damit.
# 'case' erlaubt es uns Werte mit vielerlei Mustern zu vergleichen. # 'case' erlaubt es uns Werte mit vielerlei Mustern zu vergleichen.
case {:one, :two} do case {:one, :two} do
{:four, :five} -> {:four, :five} ->
"Das wird nicht passen" "Das wird nicht passen"
{:one, x} -> {:one, x} ->
"Das schon und außerdem wird es ':two' dem Wert 'x' zuweisen." "Das schon und außerdem wird es ':two' dem Wert 'x' zuweisen."
_ -> _ ->
"Dieser Fall greift immer." "Dieser Fall greift immer."
end end
# Es ist eine übliche Praxis '_' einen Wert zuzuweisen, sofern dieser Wert # Es ist eine übliche Praxis '_' einen Wert zuzuweisen, sofern dieser Wert
# nicht weiter verwendet wird. # nicht weiter verwendet wird.
# Wenn wir uns zum Beispiel nur für den Kopf einer Liste interessieren: # Wenn wir uns zum Beispiel nur für den Kopf einer Liste interessieren:
[kopf | _] = [1,2,3] [kopf | _] = [1,2,3]
kopf #=> 1 kopf #=> 1
# Für bessere Lesbarkeit können wir auch das Folgende machen: # Für bessere Lesbarkeit können wir auch das Folgende machen:
[kopf | _rest] = [:a, :b, :c] [kopf | _rest] = [:a, :b, :c]
kopf #=> :a kopf #=> :a
# Mit 'cond' können diverse Bedingungen zur selben Zeit überprüft werden. Man # Mit 'cond' können diverse Bedingungen zur selben Zeit überprüft werden. Man
# benutzt 'cond' statt viele if-Verzweigungen zu verschachteln. # benutzt 'cond' statt viele if-Verzweigungen zu verschachteln.
cond do cond do
1 + 1 == 3 -> 1 + 1 == 3 ->
"Ich werde nie aufgerufen." "Ich werde nie aufgerufen."
2 * 5 == 12 -> 2 * 5 == 12 ->
"Ich auch nicht." "Ich auch nicht."
1 + 2 == 3 -> 1 + 2 == 3 ->
"Aber ich!" "Aber ich!"
end end
# Es ist üblich eine letzte Bedingung einzufügen, die immer zu wahr evaluiert. # Es ist üblich eine letzte Bedingung einzufügen, die immer zu wahr evaluiert.
cond do cond do
1 + 1 == 3 -> 1 + 1 == 3 ->
"Ich werde nie aufgerufen." "Ich werde nie aufgerufen."
2 * 5 == 12 -> 2 * 5 == 12 ->
"Ich auch nicht." "Ich auch nicht."
true -> true ->
"Aber ich! (dies ist im Grunde ein 'else')" "Aber ich! (dies ist im Grunde ein 'else')"
end end
# 'try/catch' wird verwendet um Werte zu fangen, die zuvor 'geworfen' wurden. # 'try/catch' wird verwendet um Werte zu fangen, die zuvor 'geworfen' wurden.
# Das Konstrukt unterstützt außerdem eine 'after'-Klausel die aufgerufen wird, # Das Konstrukt unterstützt außerdem eine 'after'-Klausel die aufgerufen wird,
# egal ob zuvor ein Wert gefangen wurde. # egal ob zuvor ein Wert gefangen wurde.
try do try do
throw(:hello) throw(:hello)
catch catch
nachricht -> "#{nachricht} gefangen." nachricht -> "#{nachricht} gefangen."
after after
IO.puts("Ich bin die 'after'-Klausel.") IO.puts("Ich bin die 'after'-Klausel.")
end end
#=> Ich bin die 'after'-Klausel. #=> Ich bin die 'after'-Klausel.
# ":hello gefangen" # ":hello gefangen"
## --------------------------- ## ---------------------------
## -- Module und Funktionen ## -- Module und Funktionen
## --------------------------- ## ---------------------------
# Anonyme Funktionen (man beachte den Punkt) # Anonyme Funktionen (man beachte den Punkt)
square = fn(x) -> x * x end square = fn(x) -> x * x end
square.(5) #=> 25 square.(5) #=> 25
# Anonyme Funktionen unterstützen auch 'pattern' und 'guards'. Guards erlauben # Anonyme Funktionen unterstützen auch 'pattern' und 'guards'. Guards erlauben
# es die Mustererkennung zu justieren und werden mit dem Schlüsselwort 'when' # es die Mustererkennung zu justieren und werden mit dem Schlüsselwort 'when'
# eingeführt: # eingeführt:
f = fn f = fn
x, y when x > 0 -> x + y x, y when x > 0 -> x + y
x, y -> x * y x, y -> x * y
end end
f.(1, 3) #=> 4 f.(1, 3) #=> 4
f.(-1, 3) #=> -3 f.(-1, 3) #=> -3
# Elixir bietet zahlreiche eingebaute Funktionen. Diese sind im gleichen # Elixir bietet zahlreiche eingebaute Funktionen. Diese sind im gleichen
# Geltungsbereich ('scope') verfügbar. # Geltungsbereich ('scope') verfügbar.
is_number(10) #=> true is_number(10) #=> true
is_list("hello") #=> false is_list("hello") #=> false
elem({1,2,3}, 0) #=> 1 elem({1,2,3}, 0) #=> 1
# Mehrere Funktionen können in einem Modul gruppiert werden. Innerhalb eines # Mehrere Funktionen können in einem Modul gruppiert werden. Innerhalb eines
# Moduls ist es möglich mit dem Schlüsselwort 'def' eine Funktion zu # Moduls ist es möglich mit dem Schlüsselwort 'def' eine Funktion zu
# definieren. # definieren.
defmodule Math do defmodule Math do
def sum(a, b) do def sum(a, b) do
a + b a + b
end end
def square(x) do def square(x) do
x * x x * x
end end
end end
Math.sum(1, 2) #=> 3 Math.sum(1, 2) #=> 3
Math.square(3) #=> 9 Math.square(3) #=> 9
# Um unser einfaches Mathe-Modul zu kompilieren muss es unter 'math.ex' # Um unser einfaches Mathe-Modul zu kompilieren muss es unter 'math.ex'
# gesichert werden. Anschließend kann es mit 'elixirc' im Terminal aufgerufen # gesichert werden. Anschließend kann es mit 'elixirc' im Terminal aufgerufen
# werden: elixirc math.ex # werden: elixirc math.ex
# Innerhalb eines Moduls definieren wir private Funktionen mit 'defp'. Eine # Innerhalb eines Moduls definieren wir private Funktionen mit 'defp'. Eine
# Funktion, die mit 'def' erstellt wurde, kann von anderen Modulen aufgerufen # Funktion, die mit 'def' erstellt wurde, kann von anderen Modulen aufgerufen
# werden; eine private Funktion kann nur lokal angesprochen werden. # werden; eine private Funktion kann nur lokal angesprochen werden.
defmodule PrivateMath do defmodule PrivateMath do
def sum(a, b) do def sum(a, b) do
do_sum(a, b) do_sum(a, b)
end end
defp do_sum(a, b) do defp do_sum(a, b) do
a + b a + b
end end
end end
PrivateMath.sum(1, 2) #=> 3 PrivateMath.sum(1, 2) #=> 3
# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError) # PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
# Auch Funktionsdeklarationen unterstützen 'guards' und Mustererkennung: # Auch Funktionsdeklarationen unterstützen 'guards' und Mustererkennung:
defmodule Geometry do defmodule Geometry do
def area({:rectangle, w, h}) do def area({:rectangle, w, h}) do
w * h w * h
end end
def area({:circle, r}) when is_number(r) do def area({:circle, r}) when is_number(r) do
3.14 * r * r 3.14 * r * r
end end
end end
Geometry.area({:rectangle, 2, 3}) #=> 6 Geometry.area({:rectangle, 2, 3}) #=> 6
Geometry.area({:circle, 3}) #=> 28.25999999999999801048 Geometry.area({:circle, 3}) #=> 28.25999999999999801048
# Geometry.area({:circle, "not_a_number"}) # Geometry.area({:circle, "not_a_number"})
#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 #=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
# Wegen der Unveränderlichkeit von Variablen ist Rekursion ein wichtiger # Wegen der Unveränderlichkeit von Variablen ist Rekursion ein wichtiger
# Bestandteil von Elixir. # Bestandteil von Elixir.
defmodule Recursion do defmodule Recursion do
def sum_list([head | tail], acc) do def sum_list([head | tail], acc) do
sum_list(tail, acc + head) sum_list(tail, acc + head)
end end
def sum_list([], acc) do def sum_list([], acc) do
acc acc
end end
end end
Recursion.sum_list([1,2,3], 0) #=> 6 Recursion.sum_list([1,2,3], 0) #=> 6
# Elixir-Module unterstützen Attribute. Es gibt eingebaute Attribute, ebenso # Elixir-Module unterstützen Attribute. Es gibt eingebaute Attribute, ebenso
# ist es möglich eigene Attribute hinzuzufügen. # ist es möglich eigene Attribute hinzuzufügen.
defmodule MyMod do defmodule MyMod do
@moduledoc """ @moduledoc """
Dies ist ein eingebautes Attribut in einem Beispiel-Modul Dies ist ein eingebautes Attribut in einem Beispiel-Modul
""" """
@my_data 100 # Dies ist ein selbst-definiertes Attribut. @my_data 100 # Dies ist ein selbst-definiertes Attribut.
IO.inspect(@my_data) #=> 100 IO.inspect(@my_data) #=> 100
end end
## --------------------------- ## ---------------------------
## -- 'Records' und Ausnahmebehandlung ## -- 'Records' und Ausnahmebehandlung
## --------------------------- ## ---------------------------
# 'Records' sind im Grunde Strukturen, die es erlauben einem Wert einen eigenen # 'Records' sind im Grunde Strukturen, die es erlauben einem Wert einen eigenen
# Namen zuzuweisen. # Namen zuzuweisen.
defrecord Person, name: nil, age: 0, height: 0 defrecord Person, name: nil, age: 0, height: 0
joe_info = Person.new(name: "Joe", age: 30, height: 180) joe_info = Person.new(name: "Joe", age: 30, height: 180)
#=> Person[name: "Joe", age: 30, height: 180] #=> Person[name: "Joe", age: 30, height: 180]
# Zugriff auf den Wert von 'name' # Zugriff auf den Wert von 'name'
joe_info.name #=> "Joe" joe_info.name #=> "Joe"
# Den Wert von 'age' überschreiben # Den Wert von 'age' überschreiben
joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180] joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180]
# Der 'try'-Block wird zusammen mit dem 'rescue'-Schlüsselwort dazu verwendet, # Der 'try'-Block wird zusammen mit dem 'rescue'-Schlüsselwort dazu verwendet,
# um Ausnahmen beziehungsweise Fehler zu behandeln. # um Ausnahmen beziehungsweise Fehler zu behandeln.
try do try do
raise "Irgendein Fehler." raise "Irgendein Fehler."
rescue rescue
RuntimeError -> "Laufzeit-Fehler gefangen." RuntimeError -> "Laufzeit-Fehler gefangen."
_error -> "Und dies fängt jeden Fehler." _error -> "Und dies fängt jeden Fehler."
end end
# Alle Ausnahmen haben das Attribut 'message' # Alle Ausnahmen haben das Attribut 'message'
try do try do
raise "ein Fehler" raise "ein Fehler"
rescue rescue
x in [RuntimeError] -> x in [RuntimeError] ->
x.message x.message
end end
## --------------------------- ## ---------------------------
## -- Nebenläufigkeit ## -- Nebenläufigkeit
## --------------------------- ## ---------------------------
# Elixir beruht auf dem Aktoren-Model zur Behandlung der Nebenläufigkeit. Alles # Elixir beruht auf dem Aktoren-Model zur Behandlung der Nebenläufigkeit. Alles
# was man braucht um in Elixir nebenläufige Programme zu schreiben sind drei # was man braucht um in Elixir nebenläufige Programme zu schreiben sind drei
# Primitive: Prozesse erzeugen, Nachrichten senden und Nachrichten empfangen. # Primitive: Prozesse erzeugen, Nachrichten senden und Nachrichten empfangen.
# Um einen neuen Prozess zu erzeugen nutzen wir die 'spawn'-Funktion, die # Um einen neuen Prozess zu erzeugen nutzen wir die 'spawn'-Funktion, die
# wiederum eine Funktion als Argument entgegen nimmt. # wiederum eine Funktion als Argument entgegen nimmt.
f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245> f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
spawn(f) #=> #PID<0.40.0> spawn(f) #=> #PID<0.40.0>
# 'spawn' gibt eine pid (einen Identifikator des Prozesses) zurück. Diese kann # 'spawn' gibt eine pid (einen Identifikator des Prozesses) zurück. Diese kann
# nun verwendet werden, um Nachrichten an den Prozess zu senden. Um # nun verwendet werden, um Nachrichten an den Prozess zu senden. Um
# zu senden nutzen wir den '<-' Operator. Damit das alles Sinn macht müssen wir # zu senden nutzen wir den '<-' Operator. Damit das alles Sinn macht müssen wir
# in der Lage sein Nachrichten zu empfangen. Dies wird mit dem # in der Lage sein Nachrichten zu empfangen. Dies wird mit dem
# 'receive'-Mechanismus sichergestellt: # 'receive'-Mechanismus sichergestellt:
defmodule Geometry do defmodule Geometry do
def area_loop do def area_loop do
receive do receive do
{:rectangle, w, h} -> {:rectangle, w, h} ->
IO.puts("Area = #{w * h}") IO.puts("Area = #{w * h}")
area_loop() area_loop()
{:circle, r} -> {:circle, r} ->
IO.puts("Area = #{3.14 * r * r}") IO.puts("Area = #{3.14 * r * r}")
area_loop() area_loop()
end end
end end
end end
# Kompiliere das Modul, starte einen Prozess und gib die 'area_loop' Funktion # Kompiliere das Modul, starte einen Prozess und gib die 'area_loop' Funktion
# in der Shell mit, etwa so: # in der Shell mit, etwa so:
pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0> pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
# Sende eine Nachricht an die 'pid', die ein Muster im 'receive'-Ausdruck # Sende eine Nachricht an die 'pid', die ein Muster im 'receive'-Ausdruck
# erfüllt: # erfüllt:
pid <- {:rectangle, 2, 3} pid <- {:rectangle, 2, 3}
#=> Area = 6 #=> Area = 6
# {:rectangle,2,3} # {:rectangle,2,3}
pid <- {:circle, 2} pid <- {:circle, 2}
#=> Area = 12.56000000000000049738 #=> Area = 12.56000000000000049738
# {:circle,2} # {:circle,2}
# Die Shell selbst ist ein Prozess und mit dem Schlüsselwort 'self' kann man # Die Shell selbst ist ein Prozess und mit dem Schlüsselwort 'self' kann man
# die aktuelle pid herausfinden. # die aktuelle pid herausfinden.
self() #=> #PID<0.27.0> self() #=> #PID<0.27.0>
``` ```
## Referenzen und weitere Lektüre ## Referenzen und weitere Lektüre
* [Getting started guide](http://elixir-lang.org/getting_started/1.html) auf der [elixir Website](http://elixir-lang.org) * [Getting started guide](http://elixir-lang.org/getting_started/1.html) auf der [elixir Website](http://elixir-lang.org)
* [Elixir Documentation](http://elixir-lang.org/docs/master/) * [Elixir Documentation](http://elixir-lang.org/docs/master/)
* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) von Fred Hebert * ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) von Fred Hebert
* "Programming Erlang: Software for a Concurrent World" von Joe Armstrong * "Programming Erlang: Software for a Concurrent World" von Joe Armstrong

File diff suppressed because it is too large Load Diff

View File

@@ -1,263 +1,263 @@
--- ---
category: tool category: tool
tool: make tool: make
contributors: contributors:
- ["Robert Steed", "https://github.com/robochat"] - ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"] - ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
translators: translators:
- ["Martin Schimandl", "https://github.com/Git-Jiro"] - ["Martin Schimandl", "https://github.com/Git-Jiro"]
filename: Makefile-de filename: Makefile-de
lang: de-de lang: de-de
--- ---
Eine Makefile definiert einen Graphen von Regeln um ein Ziel (oder Ziele) 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 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 ein Ziel in Einklang mit dem Quellcode zu bringen. Make wurde berühmterweise
von Stuart Feldman 1976 übers Wochenende geschrieben. Make ist noch immer von Stuart Feldman 1976 übers Wochenende geschrieben. Make ist noch immer
sehr verbreitet (vorallem im Unix Umfeld) obwohl es bereits sehr viel sehr verbreitet (vorallem im Unix Umfeld) obwohl es bereits sehr viel
Konkurrenz und Kritik zu Make gibt. Konkurrenz und Kritik zu Make gibt.
Es gibt eine Vielzahl an Varianten von Make, dieser Artikel beschäftigt sich Es gibt eine Vielzahl an Varianten von Make, dieser Artikel beschäftigt sich
mit der Version GNU Make. Diese Version ist Standard auf Linux. mit der Version GNU Make. Diese Version ist Standard auf Linux.
```make ```make
# Kommentare können so geschrieben werden. # Kommentare können so geschrieben werden.
# Dateien sollten Makefile heißen, denn dann können sie als `make <ziel>` # Dateien sollten Makefile heißen, denn dann können sie als `make <ziel>`
# aufgerufen werden. Ansonsten muss `make -f "dateiname" <ziel>` verwendet # aufgerufen werden. Ansonsten muss `make -f "dateiname" <ziel>` verwendet
# werden. # werden.
# Warnung - Es sollten nur TABULATOREN zur Einrückung im Makefile verwendet # Warnung - Es sollten nur TABULATOREN zur Einrückung im Makefile verwendet
# werden. Niemals Leerzeichen! # werden. Niemals Leerzeichen!
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Grundlagen # Grundlagen
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Eine Regel - Diese Regel wird nur abgearbeitet wenn die Datei file0.txt # Eine Regel - Diese Regel wird nur abgearbeitet wenn die Datei file0.txt
# nicht existiert. # nicht existiert.
file0.txt: file0.txt:
echo "foo" > file0.txt echo "foo" > file0.txt
# Selbst Kommentare in der 'Rezept' Sektion werden an die Shell # Selbst Kommentare in der 'Rezept' Sektion werden an die Shell
# weitergegeben. Versuche `make file0.txt` oder einfach `make` # weitergegeben. Versuche `make file0.txt` oder einfach `make`
# die erste Regel ist die Standard-Regel. # die erste Regel ist die Standard-Regel.
# Diese Regel wird nur abgearbeitet, wenn file0.txt aktueller als file1.txt ist. # Diese Regel wird nur abgearbeitet, wenn file0.txt aktueller als file1.txt ist.
file1.txt: file0.txt file1.txt: file0.txt
cat file0.txt > file1.txt cat file0.txt > file1.txt
# Verwende die selben Quoting-Regeln wie die Shell # Verwende die selben Quoting-Regeln wie die Shell
@cat file0.txt >> file1.txt @cat file0.txt >> file1.txt
# @ unterdrückt die Ausgabe des Befehls an stdout. # @ unterdrückt die Ausgabe des Befehls an stdout.
-@echo 'hello' -@echo 'hello'
# - bedeutet, dass Make die Abarbeitung fortsetzt auch wenn Fehler # - bedeutet, dass Make die Abarbeitung fortsetzt auch wenn Fehler
# passieren. # passieren.
# Versuche `make file1.txt` auf der Kommandozeile. # Versuche `make file1.txt` auf der Kommandozeile.
# Eine Regel kann mehrere Ziele und mehrere Voraussetzungen haben. # Eine Regel kann mehrere Ziele und mehrere Voraussetzungen haben.
file2.txt file3.txt: file0.txt file1.txt file2.txt file3.txt: file0.txt file1.txt
touch file2.txt touch file2.txt
touch file3.txt touch file3.txt
# Make wird sich beschweren, wenn es mehrere Rezepte für die gleiche Regel gibt. # 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 # Leere Rezepte zählen nicht und können dazu verwendet werden weitere
# Voraussetzungen hinzuzufügen. # Voraussetzungen hinzuzufügen.
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Phony-Ziele # Phony-Ziele
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Ein Phony-Ziel ist ein Ziel, das keine Datei ist. # Ein Phony-Ziel ist ein Ziel, das keine Datei ist.
# Es wird nie aktuell sein, daher wird Make immer versuchen, es abzuarbeiten # Es wird nie aktuell sein, daher wird Make immer versuchen, es abzuarbeiten
all: maker process all: maker process
# Es ist erlaubt Dinge ausserhalb der Reihenfolge zu deklarieren. # Es ist erlaubt Dinge ausserhalb der Reihenfolge zu deklarieren.
maker: maker:
touch ex0.txt ex1.txt touch ex0.txt ex1.txt
# Um das Fehlschlagen von Phony-Regeln zu vermeiden wenn eine echte Datei den # Um das Fehlschlagen von Phony-Regeln zu vermeiden wenn eine echte Datei den
# selben namen wie ein Phony-Ziel hat: # selben namen wie ein Phony-Ziel hat:
.PHONY: all maker process .PHONY: all maker process
# Das ist ein spezielles Ziel. Es gibt noch ein paar mehr davon. # Das ist ein spezielles Ziel. Es gibt noch ein paar mehr davon.
# Eine Regel mit einem Phony-Ziel als Voraussetzung wird immer abgearbeitet # Eine Regel mit einem Phony-Ziel als Voraussetzung wird immer abgearbeitet
ex0.txt ex1.txt: maker ex0.txt ex1.txt: maker
# Häufige Phony-Ziele sind: all make clean install ... # Häufige Phony-Ziele sind: all make clean install ...
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Automatische Variablen & Wildcards # Automatische Variablen & Wildcards
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
process: file*.txt # Eine Wildcard um Dateinamen zu vergleichen process: file*.txt # Eine Wildcard um Dateinamen zu vergleichen
@echo $^ # $^ ist eine Variable die eine Liste aller @echo $^ # $^ ist eine Variable die eine Liste aller
# Voraussetzungen enthält. # Voraussetzungen enthält.
@echo $@ # Namen des Ziels ausgeben. @echo $@ # Namen des Ziels ausgeben.
#(Bei mehreren Ziel-Regeln enthält $@ den Verursacher der Abarbeitung #(Bei mehreren Ziel-Regeln enthält $@ den Verursacher der Abarbeitung
#der Regel.) #der Regel.)
@echo $< # Die erste Voraussetzung aus der Liste @echo $< # Die erste Voraussetzung aus der Liste
@echo $? # Nur die Voraussetzungen, die nicht aktuell sind. @echo $? # Nur die Voraussetzungen, die nicht aktuell sind.
@echo $+ # Alle Voraussetzungen inklusive Duplikate (nicht wie Üblich) @echo $+ # Alle Voraussetzungen inklusive Duplikate (nicht wie Üblich)
#@echo $| # Alle 'order only' Voraussetzungen #@echo $| # Alle 'order only' Voraussetzungen
# Selbst wenn wir die Voraussetzungen der Regel aufteilen, $^ wird sie finden. # Selbst wenn wir die Voraussetzungen der Regel aufteilen, $^ wird sie finden.
process: ex1.txt file0.txt process: ex1.txt file0.txt
# ex1.txt wird gefunden werden, aber file0.txt wird dedupliziert. # ex1.txt wird gefunden werden, aber file0.txt wird dedupliziert.
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Muster # Muster
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Mit Mustern kann man make beibringen wie Dateien in andere Dateien # Mit Mustern kann man make beibringen wie Dateien in andere Dateien
# umgewandelt werden. # umgewandelt werden.
%.png: %.svg %.png: %.svg
inkscape --export-png $^ inkscape --export-png $^
# Muster-Vergleichs-Regeln werden nur abgearbeitet, wenn make entscheidet das # Muster-Vergleichs-Regeln werden nur abgearbeitet, wenn make entscheidet das
# Ziel zu erzeugen # Ziel zu erzeugen
# Verzeichnis-Pfade werden normalerweise bei Muster-Vergleichs-Regeln ignoriert. # Verzeichnis-Pfade werden normalerweise bei Muster-Vergleichs-Regeln ignoriert.
# Aber make wird versuchen die am besten passende Regel zu verwenden. # Aber make wird versuchen die am besten passende Regel zu verwenden.
small/%.png: %.svg small/%.png: %.svg
inkscape --export-png --export-dpi 30 $^ inkscape --export-png --export-dpi 30 $^
# Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden, die es # Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden, die es
# findet. # findet.
%.png: %.svg %.png: %.svg
@echo this rule is chosen @echo this rule is chosen
# Allerdings wird make die erste Muster-Vergleicher-Regel verwenden, die das # Allerdings wird make die erste Muster-Vergleicher-Regel verwenden, die das
# Ziel erzeugen kann. # Ziel erzeugen kann.
%.png: %.ps %.png: %.ps
@echo this rule is not chosen if *.svg and *.ps are both present @echo this rule is not chosen if *.svg and *.ps are both present
# Make hat bereits ein paar eingebaute Muster-Vergleichs-Regelen. Zum Beispiel # Make hat bereits ein paar eingebaute Muster-Vergleichs-Regelen. Zum Beispiel
# weiß Make wie man aus *.c Dateien *.o Dateien erzeugt. # weiß Make wie man aus *.c Dateien *.o Dateien erzeugt.
# Ältere Versionen von Make verwenden möglicherweise Suffix-Regeln anstatt # Ältere Versionen von Make verwenden möglicherweise Suffix-Regeln anstatt
# Muster-Vergleichs-Regeln. # Muster-Vergleichs-Regeln.
.png.ps: .png.ps:
@echo this rule is similar to a pattern rule. @echo this rule is similar to a pattern rule.
# Aktivieren der Suffix-Regel # Aktivieren der Suffix-Regel
.SUFFIXES: .png .SUFFIXES: .png
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Variablen # Variablen
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# auch Makros genannt. # auch Makros genannt.
# Variablen sind im Grunde genommen Zeichenketten-Typen. # Variablen sind im Grunde genommen Zeichenketten-Typen.
name = Ted name = Ted
name2="Sarah" name2="Sarah"
echo: echo:
@echo $(name) @echo $(name)
@echo ${name2} @echo ${name2}
@echo $name # Das funktioniert nicht, wird als $(n)ame behandelt. @echo $name # Das funktioniert nicht, wird als $(n)ame behandelt.
@echo $(name3) # Unbekannte Variablen werden als leere Zeichenketten behandelt. @echo $(name3) # Unbekannte Variablen werden als leere Zeichenketten behandelt.
# Es git 4 Stellen um Variablen zu setzen. # Es git 4 Stellen um Variablen zu setzen.
# In Reihenfolge der Priorität von höchster zu niedrigster: # In Reihenfolge der Priorität von höchster zu niedrigster:
# 1: Befehls-Zeilen Argumente # 1: Befehls-Zeilen Argumente
# 2: Makefile # 2: Makefile
# 3: Shell Umbebungs-Variablen - Make importiert diese automatisch. # 3: Shell Umbebungs-Variablen - Make importiert diese automatisch.
# 3: MAke hat einige vordefinierte Variablen. # 3: MAke hat einige vordefinierte Variablen.
name4 ?= Jean name4 ?= Jean
# Setze die Variable nur wenn es eine gleichnamige Umgebungs-Variable noch # Setze die Variable nur wenn es eine gleichnamige Umgebungs-Variable noch
# nicht gibt. # nicht gibt.
override name5 = David override name5 = David
# Verhindert, dass Kommando-Zeilen Argumente diese Variable ändern können. # Verhindert, dass Kommando-Zeilen Argumente diese Variable ändern können.
name4 +=grey name4 +=grey
# Werte an eine Variable anhängen (inkludiert Leerzeichen). # Werte an eine Variable anhängen (inkludiert Leerzeichen).
# Muster-Spezifische Variablen Werte (GNU Erweiterung). # Muster-Spezifische Variablen Werte (GNU Erweiterung).
echo: name2 = Sara # Wahr innerhalb der passenden Regel und auch innerhalb echo: name2 = Sara # Wahr innerhalb der passenden Regel und auch innerhalb
# rekursiver Voraussetzungen (ausser wenn es den Graphen zerstören # rekursiver Voraussetzungen (ausser wenn es den Graphen zerstören
# kann, wenn es zu kompilizert wird!) # kann, wenn es zu kompilizert wird!)
# Ein paar Variablen, die von Make automatisch definiert werden. # Ein paar Variablen, die von Make automatisch definiert werden.
echo_inbuilt: echo_inbuilt:
echo $(CC) echo $(CC)
echo ${CXX} echo ${CXX}
echo $(FC) echo $(FC)
echo ${CFLAGS} echo ${CFLAGS}
echo $(CPPFLAGS) echo $(CPPFLAGS)
echo ${CXXFLAGS} echo ${CXXFLAGS}
echo $(LDFLAGS) echo $(LDFLAGS)
echo ${LDLIBS} echo ${LDLIBS}
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Variablen 2 # Variablen 2
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Der erste Typ von Variablen wird bei jeder Verwendung ausgewertet. # Der erste Typ von Variablen wird bei jeder Verwendung ausgewertet.
# Das kann aufwendig sein, daher exisitert ein zweiter Typ von Variablen. # Das kann aufwendig sein, daher exisitert ein zweiter Typ von Variablen.
# Diese werden nur einmal ausgewertet. (Das ist eine GNU make Erweiterung) # Diese werden nur einmal ausgewertet. (Das ist eine GNU make Erweiterung)
var := hello var := hello
var2 ::= $(var) hello var2 ::= $(var) hello
#:= und ::= sind äquivalent. #:= und ::= sind äquivalent.
# Diese Variablen werden prozedural ausgwertet (in der Reihenfolge in der sie # Diese Variablen werden prozedural ausgwertet (in der Reihenfolge in der sie
# auftauchen), die stehen daher im wiederspruch zum Rest der Sprache! # auftauchen), die stehen daher im wiederspruch zum Rest der Sprache!
# Das funktioniert nicht # Das funktioniert nicht
var3 ::= $(var4) and good luck var3 ::= $(var4) and good luck
var4 ::= good night var4 ::= good night
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Funktionen # Funktionen
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Make verfügt über eine Vielzahl von Funktionen. # Make verfügt über eine Vielzahl von Funktionen.
sourcefiles = $(wildcard *.c */*.c) sourcefiles = $(wildcard *.c */*.c)
objectfiles = $(patsubst %.c,%.o,$(sourcefiles)) objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
# Das Format ist $(func arg0,arg1,arg2...) # Das Format ist $(func arg0,arg1,arg2...)
# Ein paar Beispiele # Ein paar Beispiele
ls: * src/* ls: * src/*
@echo $(filter %.txt, $^) @echo $(filter %.txt, $^)
@echo $(notdir $^) @echo $(notdir $^)
@echo $(join $(dir $^),$(notdir $^)) @echo $(join $(dir $^),$(notdir $^))
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Direktiven # Direktiven
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Inkludiere andere Makefile, sehr praktisch für platformspezifischen Code # Inkludiere andere Makefile, sehr praktisch für platformspezifischen Code
include foo.mk include foo.mk
sport = tennis sport = tennis
# Konditionale kompiliereung # Konditionale kompiliereung
report: report:
ifeq ($(sport),tennis) ifeq ($(sport),tennis)
@echo 'game, set, match' @echo 'game, set, match'
else else
@echo "They think it's all over; it is now" @echo "They think it's all over; it is now"
endif endif
# Es gibt auch ifneq, ifdef, ifndef # Es gibt auch ifneq, ifdef, ifndef
foo = true foo = true
ifdef $(foo) ifdef $(foo)
bar = 'hello' bar = 'hello'
endif endif
``` ```
### Mehr Resourcen ### Mehr Resourcen
+ [gnu make documentation](https://www.gnu.org/software/make/manual/) + [gnu make documentation](https://www.gnu.org/software/make/manual/)
+ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/) + [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) + learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)

View File

@@ -1,281 +1,281 @@
--- ---
category: tool category: tool
tool: docker tool: docker
filename: docker.bat filename: docker.bat
contributors: contributors:
- ["Ruslan López", "http://javapro.org/"] - ["Ruslan López", "http://javapro.org/"]
- ["Michael Chen", "https://github.com/ML-Chen"] - ["Michael Chen", "https://github.com/ML-Chen"]
- ["Akshita Dixit", "https://github.com/akshitadixit"] - ["Akshita Dixit", "https://github.com/akshitadixit"]
- ["Marcel Ribeiro-Dantas", "https://github.com/mribeirodantas"] - ["Marcel Ribeiro-Dantas", "https://github.com/mribeirodantas"]
--- ---
Docker is a tool that helps you build, test, ship and run applications Docker is a tool that helps you build, test, ship and run applications
seamlessly across various machines. It replicates the environment our software seamlessly across various machines. It replicates the environment our software
needs on any machine. You can get Docker for your machine from needs on any machine. You can get Docker for your machine from
https://docs.docker.com/get-docker/ https://docs.docker.com/get-docker/
It has grown in popularity over the last decade due to being lightweight and It has grown in popularity over the last decade due to being lightweight and
fast as compared to virtual-machines that are bulky and slow. Unlike VMs, docker fast as compared to virtual-machines that are bulky and slow. Unlike VMs, docker
does not need a full blown OS of its own to be loaded to start and does not does not need a full blown OS of its own to be loaded to start and does not
compete for resources other than what the application it is running will use. compete for resources other than what the application it is running will use.
VMs on the other hand are pretty resource intensive on our processors, disks and VMs on the other hand are pretty resource intensive on our processors, disks and
memory hence running multiple VMs for various applications becomes a challenge memory hence running multiple VMs for various applications becomes a challenge
in a limited capacity architecture. in a limited capacity architecture.
<pre> <pre>
┌────────────────────────┐ ┌───────────────────────┐ ┌────────────────────────┐ ┌───────────────────────┐
│ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │
│ │ App │ │ │ │ App │ │ │ │ App │ │ │ │ App │ │
│ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │
│ ┌────────┐ ┌────────┐ │ │ ┌────────┐ ┌───────┐ │ │ ┌────────┐ ┌────────┐ │ │ ┌────────┐ ┌───────┐ │
│ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │
│ └────────┘ └────────┘ │ │ └────────┘ └───────┘ │ │ └────────┘ └────────┘ │ │ └────────┘ └───────┘ │
│ ┌───────────────────┐ │ │ ┌──────────────────┐ │ │ ┌───────────────────┐ │ │ ┌──────────────────┐ │
│ │ Guest OS │ │ │ │ Guest OS │ │ │ │ Guest OS │ │ │ │ Guest OS │ │
│ └───────────────────┘ │ │ └──────────────────┘ │ │ └───────────────────┘ │ │ └──────────────────┘ │
│ VM1 │ │ VM2 │ │ VM1 │ │ VM2 │
└────────────────────────┘ └───────────────────────┘ └────────────────────────┘ └───────────────────────┘
┌──────────────────────────────────────────────────┐ ┌──────────────────────────────────────────────────┐
│ Hypervisor │ │ Hypervisor │
└──────────────────────────────────────────────────┘ └──────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────┐ ┌──────────────────────────────────────────────────┐
│ Host OS │ │ Host OS │
└──────────────────────────────────────────────────┘ └──────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────┐ ┌──────────────────────────────────────────────────┐
│ Hardware Infrastructure │ │ Hardware Infrastructure │
└──────────────────────────────────────────────────┘ └──────────────────────────────────────────────────┘
(VM based architecture) (VM based architecture)
┌────────────────────────┐ ┌───────────────────────┐ ┌────────────────────────┐ ┌───────────────────────┐
│ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │
│ │ App │ │ │ │ App │ │ │ │ App │ │ │ │ App │ │
│ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │
│ ┌────────┐ ┌────────┐ │ │ ┌────────┐ ┌───────┐ │ │ ┌────────┐ ┌────────┐ │ │ ┌────────┐ ┌───────┐ │
│ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │ │ │ Libs │ │ Deps │ │
│ └────────┘ └────────┘ │ │ └────────┘ └───────┘ │ │ └────────┘ └────────┘ │ │ └────────┘ └───────┘ │
│ Container1 │ │ Container2 │ │ Container1 │ │ Container2 │
└────────────────────────┘ └───────────────────────┘ └────────────────────────┘ └───────────────────────┘
┌──────────────────────────────────────────────────┐ ┌──────────────────────────────────────────────────┐
│ Docker │ │ Docker │
└──────────────────────────────────────────────────┘ └──────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────┐ ┌──────────────────────────────────────────────────┐
│ OS │ │ OS │
└──────────────────────────────────────────────────┘ └──────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────┐ ┌──────────────────────────────────────────────────┐
│ Hardware Infrastructure │ │ Hardware Infrastructure │
└──────────────────────────────────────────────────┘ └──────────────────────────────────────────────────┘
(Docker based architecture) (Docker based architecture)
</pre> </pre>
Couple of terms we will encounter frequently are Docker Images and Docker Couple of terms we will encounter frequently are Docker Images and Docker
Containers. Images are packages or templates of containers all stored in a Containers. Images are packages or templates of containers all stored in a
container registry such as [Docker Hub](https://hub.docker.com/). Containers container registry such as [Docker Hub](https://hub.docker.com/). Containers
are standalone, executable instances of these images which include code, are standalone, executable instances of these images which include code,
runtime, system tools, system libraries and settings - everything required to runtime, system tools, system libraries and settings - everything required to
get the software up and running. Coming to Docker, it follows a client-server get the software up and running. Coming to Docker, it follows a client-server
architecture wherein the CLI client communicates with the server component, architecture wherein the CLI client communicates with the server component,
which here is, the Docker Engine using RESTful API to issue commands. which here is, the Docker Engine using RESTful API to issue commands.
## The Docker CLI ## The Docker CLI
```bash ```bash
# after installing Docker from https://docs.docker.com/get-docker/ # after installing Docker from https://docs.docker.com/get-docker/
# To list available commands, either run `docker` with no parameters or execute # To list available commands, either run `docker` with no parameters or execute
# `docker help` # `docker help`
$ docker $ docker
>>> docker [OPTIONS] COMMAND [ARG...] >>> docker [OPTIONS] COMMAND [ARG...]
docker [ --help | -v | --version ] docker [ --help | -v | --version ]
A self-sufficient runtime for containers. A self-sufficient runtime for containers.
Options: Options:
--config string Location of client config files (default "/root/.docker") --config string Location of client config files (default "/root/.docker")
-c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use") -c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
-D, --debug Enable debug mode -D, --debug Enable debug mode
--help Print usage --help Print usage
-H, --host value Daemon socket(s) to connect to (default []) -H, --host value Daemon socket(s) to connect to (default [])
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
--tls Use TLS; implied by --tlsverify --tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem") --tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem") --tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/root/.docker/key.pem") --tlskey string Path to TLS key file (default "/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote --tlsverify Use TLS and verify the remote
-v, --version Print version information and quit -v, --version Print version information and quit
Commands: Commands:
attach Attach to a running container attach Attach to a running container
# […] # […]
$ docker run hello-world $ docker run hello-world
# `docker run <container-name>` is used to run a container, it will pull the # `docker run <container-name>` is used to run a container, it will pull the
# images from Docker Hub if they don't already exist in your system. Here the # images from Docker Hub if they don't already exist in your system. Here the
# docker client connects to the daemon which in turn pulls the "hello-world" # docker client connects to the daemon which in turn pulls the "hello-world"
# image from the Docker Hub. The daemon then builds a new container from the # image from the Docker Hub. The daemon then builds a new container from the
# image which runs the executable that produces the output streamed back to the # image which runs the executable that produces the output streamed back to the
# client that we see on our terminals. # client that we see on our terminals.
$ docker run -d ubuntu sleep 60s $ docker run -d ubuntu sleep 60s
# The -d (or --detach) flag is when we want to run a container in the background # The -d (or --detach) flag is when we want to run a container in the background
# and return back to the terminal. Here we detach an ubuntu container from the # and return back to the terminal. Here we detach an ubuntu container from the
# terminal, the output should be the id and the command exits. If we check # terminal, the output should be the id and the command exits. If we check
# running containers, we should still see ours there: # running containers, we should still see ours there:
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 133261b4894a ubuntu "sleep 60s" 3 seconds ago Up 2 seconds vigorous_gould # 133261b4894a ubuntu "sleep 60s" 3 seconds ago Up 2 seconds vigorous_gould
$ docker run <container-id> -p 3000:8000 $ docker run <container-id> -p 3000:8000
# The -p (or --publish) flag is used to expose port 8000 inside the container to # The -p (or --publish) flag is used to expose port 8000 inside the container to
# port 3000 outside the container. This is because the app inside the container # port 3000 outside the container. This is because the app inside the container
# runs in isolation, hence the port 8000 where the app runs is private to the # runs in isolation, hence the port 8000 where the app runs is private to the
# container. # container.
$ docker run -i $ docker run -i
# or # or
$ docker run -it $ docker run -it
# Docker runs our containers in a non-interactive mode i.e. they do not accept # Docker runs our containers in a non-interactive mode i.e. they do not accept
# inputs or work dynamically while running. The -i flag keeps input open to the # inputs or work dynamically while running. The -i flag keeps input open to the
# container, and the -t flag creates a pseudo-terminal that the shell can attach # container, and the -t flag creates a pseudo-terminal that the shell can attach
# to (can be combined as -it) # to (can be combined as -it)
$ docker ps -a $ docker ps -a
# The `docker ps` command only shows running containers by default. To see all # The `docker ps` command only shows running containers by default. To see all
# containers, use the -a (or --all) flag # containers, use the -a (or --all) flag
# Running the above command should output something similar in the terminal: # Running the above command should output something similar in the terminal:
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 82f84bf6912b hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago eloquent_sammet # 82f84bf6912b hello-world "/hello" 9 minutes ago Exited (0) 9 minutes ago eloquent_sammet
$ docker stop hello-world $ docker stop hello-world
# or # or
$ docker start hello-world $ docker start hello-world
# The stop command simply stops one or more containers, and the start command # The stop command simply stops one or more containers, and the start command
# starts the container(s) up again! `docker start -a ubuntu` will attach our # starts the container(s) up again! `docker start -a ubuntu` will attach our
# detached container back to the terminal i.e. runs in the foreground # detached container back to the terminal i.e. runs in the foreground
$ docker create alpine $ docker create alpine
# `docker create` creates a new container for us with the image specified (here, # `docker create` creates a new container for us with the image specified (here,
# alpine), the container does not auto-start unlike `docker run`. This command # alpine), the container does not auto-start unlike `docker run`. This command
# is used to set up a container configuration and then `docker start` to shoot # is used to set up a container configuration and then `docker start` to shoot
# it up when required. Note that the status is "Created": # it up when required. Note that the status is "Created":
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 4c71c727c73d alpine "/bin/sh" 29 seconds ago Created naughty_ritchie # 4c71c727c73d alpine "/bin/sh" 29 seconds ago Created naughty_ritchie
$ docker rm 82f84 $ docker rm 82f84
# Removes one or more containers using their container ID. # Removes one or more containers using their container ID.
# P.S.: we can use only the first few characters of the entire ID to identify # P.S.: we can use only the first few characters of the entire ID to identify
# containers # containers
$ docker images $ docker images
# Displays all images and their information, created here means the latest image # Displays all images and their information, created here means the latest image
# tag updated on Docker Hub: # tag updated on Docker Hub:
# REPOSITORY TAG IMAGE ID CREATED SIZE # REPOSITORY TAG IMAGE ID CREATED SIZE
# ubuntu latest a8780b506fa4 9 days ago 77.8MB # ubuntu latest a8780b506fa4 9 days ago 77.8MB
# alpine latest 9c6f07244728 3 months ago 5.54MB # alpine latest 9c6f07244728 3 months ago 5.54MB
# hello-world latest feb5d9fea6a5 13 months ago 13.3kB # hello-world latest feb5d9fea6a5 13 months ago 13.3kB
$ docker rmi $ docker rmi
# Removes one or more images from your system which do not have their instances # Removes one or more images from your system which do not have their instances
# (or containers as we know them) running. If the image has an attached # (or containers as we know them) running. If the image has an attached
# container, either delete the container first or use the -f (or --force) flag # container, either delete the container first or use the -f (or --force) flag
# to forcefully delete both the container and image. # to forcefully delete both the container and image.
$ docker pull busybox $ docker pull busybox
# The pull command downloads the specified image on our system from Docker Hub. # The pull command downloads the specified image on our system from Docker Hub.
$ docker exec -it 7b272 bash $ docker exec -it 7b272 bash
# This command is used to run a command in the running container's default # This command is used to run a command in the running container's default
# directory. Here 7b272 was our ubuntu container and the above command would # directory. Here 7b272 was our ubuntu container and the above command would
# help us interact with the container by opening a bash session. # help us interact with the container by opening a bash session.
$ docker logs <container-id> $ docker logs <container-id>
# Displays the information logged by the specified container # Displays the information logged by the specified container
# root@7b27222e4bb7:/# whoami # root@7b27222e4bb7:/# whoami
# root # root
# root@7b27222e4bb7:/# pwd # root@7b27222e4bb7:/# pwd
# / # /
# root@7b27222e4bb7:/# ls # root@7b27222e4bb7:/# ls
# bin boot dev etc home lib lib32 lib64 libx3 srv sys tmp usr var # bin boot dev etc home lib lib32 lib64 libx3 srv sys tmp usr var
# root@7b27222e4bb7:/# exit # root@7b27222e4bb7:/# exit
# exit # exit
# More commands can be found at https://docs.docker.com/engine/reference/commandline/docker/ # More commands can be found at https://docs.docker.com/engine/reference/commandline/docker/
``` ```
## The Dockerfile ## The Dockerfile
The Dockerfile is a blueprint of a Docker image. We can mention the artifacts The Dockerfile is a blueprint of a Docker image. We can mention the artifacts
from our application along with their configurations into this file in the from our application along with their configurations into this file in the
specific syntax to let anyone create a Docker image of our application. specific syntax to let anyone create a Docker image of our application.
### A few things to keep in mind: ### A few things to keep in mind:
* It is always strictly named `Dockerfile` without any extensions * It is always strictly named `Dockerfile` without any extensions
* We have to build our custom image on top of some already available Docker base * We have to build our custom image on top of some already available Docker base
image. (there is an empty image called `scratch` which literally lets you build image. (there is an empty image called `scratch` which literally lets you build
an image from scratch) an image from scratch)
* All capitalised commands are part of the syntax, they are not case-sensitive * All capitalised commands are part of the syntax, they are not case-sensitive
but used like a convention but used like a convention
* Below is a sample Dockerfile but you can read in depth from the [official docs](https://docs.docker.com/engine/reference/builder/). * Below is a sample Dockerfile but you can read in depth from the [official docs](https://docs.docker.com/engine/reference/builder/).
```Dockerfile ```Dockerfile
FROM <base-image> FROM <base-image>
# define base image # define base image
ENV USERNAME='admin'\ ENV USERNAME='admin'\
PWD='****' PWD='****'
# optionally define environmental variables # optionally define environmental variables
RUN apt-get update RUN apt-get update
# run linux commands inside container env, does not affect host env # run linux commands inside container env, does not affect host env
# This executes during the time of image creation # This executes during the time of image creation
COPY <src> <target> COPY <src> <target>
# executes on the host, copies files from src (usually on the host) to target # executes on the host, copies files from src (usually on the host) to target
# on the container # on the container
ENTRYPOINT ["some-script.sh"] ENTRYPOINT ["some-script.sh"]
# executes an entire script as an entrypoint # executes an entire script as an entrypoint
CMD [<args>,...] CMD [<args>,...]
# always part of dockerfile, introduces entry point linux command e.g. # always part of dockerfile, introduces entry point linux command e.g.
# `CMD node server.js` # `CMD node server.js`
# This executes after image creation only when the container from the image # This executes after image creation only when the container from the image
# is running. # is running.
``` ```
### Build your images ### Build your images
Use the `docker build` command after wrapping your application into a Docker Use the `docker build` command after wrapping your application into a Docker
image to run ( or build) it. image to run ( or build) it.
```bash ```bash
$ docker build <path-to-dockerfile> $ docker build <path-to-dockerfile>
# used to build an image from the specified Dockerfile # used to build an image from the specified Dockerfile
# instead of path we could also specify a URL # instead of path we could also specify a URL
# -t tag is optional and used to name and tag your images for e.g. # -t tag is optional and used to name and tag your images for e.g.
# `$ docker build -t my-image:0.1 ./home/app` # `$ docker build -t my-image:0.1 ./home/app`
# rebuild images everytime you make changes in the dockerfile # rebuild images everytime you make changes in the dockerfile
``` ```
## Push your image to DockerHub ## Push your image to DockerHub
If you want your application's Docker image to be made publicly available for If you want your application's Docker image to be made publicly available for
any Docker user, you might wanna push it to the [Docker Hub](https://hub.docker.com/) which is a any Docker user, you might wanna push it to the [Docker Hub](https://hub.docker.com/) which is a
registry of Docker images. Make sure you have an account with a username and registry of Docker images. Make sure you have an account with a username and
password on Docker Hub. password on Docker Hub.
When pushing an image to Docker Hub, we must specify our Docker Hub username When pushing an image to Docker Hub, we must specify our Docker Hub username
as part of the source image name. We need to create the target image with the as part of the source image name. We need to create the target image with the
tag name of username/image-name much like GitHub repositories. tag name of username/image-name much like GitHub repositories.
```bash ```bash
$ docker login $ docker login
# to login to Docker Hub using your username and password # to login to Docker Hub using your username and password
$ docker tag <src-image>[:<src-tag>] <target-image>[:<target-tag>] $ docker tag <src-image>[:<src-tag>] <target-image>[:<target-tag>]
# this tags a local src-image to a public target-image # this tags a local src-image to a public target-image
# e.g. `docker tag my-sample-app:1.0.0 akshitadixit/my-sample-app` # e.g. `docker tag my-sample-app:1.0.0 akshitadixit/my-sample-app`
# if tags are not specified, they're defaulted to `latest` # if tags are not specified, they're defaulted to `latest`
$ docker push <target-image>[:<target-tag>] $ docker push <target-image>[:<target-tag>]
# uploads our image to Docker Hub # uploads our image to Docker Hub
# e.g. `docker push akshitadixit/my-sample-app` # e.g. `docker push akshitadixit/my-sample-app`
# this image will be accessible under your profile's repositories as # this image will be accessible under your profile's repositories as
# `https://hub.docker.com/r/username/image-name` # `https://hub.docker.com/r/username/image-name`
``` ```

View File

@@ -1,167 +1,167 @@
--- ---
language: docker language: docker
filename: docker-es.bat filename: docker-es.bat
contributors: contributors:
- ["Ruslan López", "http://javapro.org/"] - ["Ruslan López", "http://javapro.org/"]
- ["Michael Chen", "https://github.com/ML-Chen"] - ["Michael Chen", "https://github.com/ML-Chen"]
lang: es-es lang: es-es
--- ---
```bat ```bat
:: descargar, instalar y ejecutar la imágen del hola mundo :: descargar, instalar y ejecutar la imágen del hola mundo
docker run hello-world docker run hello-world
:: Si esta es la primera vez, deberíais de poder ver el mensaje :: Si esta es la primera vez, deberíais de poder ver el mensaje
:: Unable to find image 'hello-world:latest' locally :: Unable to find image 'hello-world:latest' locally
:: latest: Pulling from library/hello-world :: latest: Pulling from library/hello-world
:: 1b930d010525: Pull complete :: 1b930d010525: Pull complete
:: Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064 :: Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064
:: Status: Downloaded newer image for hello-world:latest :: Status: Downloaded newer image for hello-world:latest
:: ::
:: Hello from Docker! :: Hello from Docker!
:: This message shows that your installation appears to be working correctly. :: This message shows that your installation appears to be working correctly.
:: ::
:: To generate this message, Docker took the following steps: :: To generate this message, Docker took the following steps:
:: 1. The Docker client contacted the Docker daemon. :: 1. The Docker client contacted the Docker daemon.
:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. :: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
:: (amd64) :: (amd64)
:: 3. The Docker daemon created a new container from that image which runs the :: 3. The Docker daemon created a new container from that image which runs the
:: executable that produces the output you are currently reading. :: executable that produces the output you are currently reading.
:: 4. The Docker daemon streamed that output to the Docker client, which sent it :: 4. The Docker daemon streamed that output to the Docker client, which sent it
:: to your terminal. :: to your terminal.
:: ::
:: To try something more ambitious, you can run an Ubuntu container with: :: To try something more ambitious, you can run an Ubuntu container with:
:: $ docker run -it ubuntu bash :: $ docker run -it ubuntu bash
:: ::
:: Share images, automate workflows, and more with a free Docker ID: :: Share images, automate workflows, and more with a free Docker ID:
:: https://hub.docker.com/ :: https://hub.docker.com/
:: ::
:: For more examples and ideas, visit: :: For more examples and ideas, visit:
:: https://docs.docker.com/get-started/ :: https://docs.docker.com/get-started/
:: El susodicho mensaje se podría traducir como: :: El susodicho mensaje se podría traducir como:
:: ::
:: Hola desde Docker! :: Hola desde Docker!
:: Este mensaje muestra que su instalación parece estar funcionando crrectamente. :: Este mensaje muestra que su instalación parece estar funcionando crrectamente.
:: ::
:: Para generar este mensaje, Docker realizó los siguientes pasos: :: Para generar este mensaje, Docker realizó los siguientes pasos:
:: 1. El cliente de Docker contactó a Docker daemon. :: 1. El cliente de Docker contactó a Docker daemon.
:: 2. El Docker daemon obtubo la imágen "hello-world" desde Docker Hub. :: 2. El Docker daemon obtubo la imágen "hello-world" desde Docker Hub.
:: (amd64) :: (amd64)
:: 3. El Docker daemon creó un nuevo contenedor a partir de esa imagen con la cual ejecuta el :: 3. El Docker daemon creó un nuevo contenedor a partir de esa imagen con la cual ejecuta el
:: ejecutable que produce la salida que estás leyendo. :: ejecutable que produce la salida que estás leyendo.
:: 4. El Docker daemon transmitió dicha salida el cliente Docker, el cual :: 4. El Docker daemon transmitió dicha salida el cliente Docker, el cual
:: la envió a tu terminal. :: la envió a tu terminal.
:: ::
:: Para intentar algo más ambicioso, puede correr un contenedor Ubuntu mediante: :: Para intentar algo más ambicioso, puede correr un contenedor Ubuntu mediante:
:: $ docker run -it ubuntu bash :: $ docker run -it ubuntu bash
:: ::
:: Comparte imágenes, automatice flujos y más con un Docker ID gratuito: :: Comparte imágenes, automatice flujos y más con un Docker ID gratuito:
:: https://hub.docker.com/ :: https://hub.docker.com/
:: ahora veamos las imágenes que se están ejecutando actualmente :: ahora veamos las imágenes que se están ejecutando actualmente
docker ps docker ps
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS :: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES :: NAMES
:: veamos las imágenes que hemos ejecutado previamente :: veamos las imágenes que hemos ejecutado previamente
docker ps -a docker ps -a
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS :: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES :: NAMES
:: 4a76281f9c53 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago :: 4a76281f9c53 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago
:: happy_poincare :: happy_poincare
:: la parte del nombre se genera automáticamente, así que probablemente sea diferente para vos :: la parte del nombre se genera automáticamente, así que probablemente sea diferente para vos
:: eliminemos nuestra imagen previamente generada :: eliminemos nuestra imagen previamente generada
docker rm happy_poincare docker rm happy_poincare
:: verifiquemos si realmente fue borrada :: verifiquemos si realmente fue borrada
docker ps -a docker ps -a
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS :: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES :: NAMES
:: especifiquemos un nombre personalizado para el contenedor :: especifiquemos un nombre personalizado para el contenedor
docker run --name test_container hello-world docker run --name test_container hello-world
:: Hello from Docker! :: Hello from Docker!
:: This message shows that your installation appears to be working correctly. :: This message shows that your installation appears to be working correctly.
:: ::
:: To generate this message, Docker took the following steps: :: To generate this message, Docker took the following steps:
:: 1. The Docker client contacted the Docker daemon. :: 1. The Docker client contacted the Docker daemon.
:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. :: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
:: (amd64) :: (amd64)
:: 3. The Docker daemon created a new container from that image which runs the :: 3. The Docker daemon created a new container from that image which runs the
:: executable that produces the output you are currently reading. :: executable that produces the output you are currently reading.
:: 4. The Docker daemon streamed that output to the Docker client, which sent it :: 4. The Docker daemon streamed that output to the Docker client, which sent it
:: to your terminal. :: to your terminal.
:: ::
:: To try something more ambitious, you can run an Ubuntu container with: :: To try something more ambitious, you can run an Ubuntu container with:
:: $ docker run -it ubuntu bash :: $ docker run -it ubuntu bash
:: ::
:: Share images, automate workflows, and more with a free Docker ID: :: Share images, automate workflows, and more with a free Docker ID:
:: https://hub.docker.com/ :: https://hub.docker.com/
:: ::
:: For more examples and ideas, visit: :: For more examples and ideas, visit:
:: https://docs.docker.com/get-started/ :: https://docs.docker.com/get-started/
docker ps -a docker ps -a
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS :: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES :: NAMES
:: d345fe1a4f41 hello-world "/hello" About a minute ago Exited (0) About a minute ago :: d345fe1a4f41 hello-world "/hello" About a minute ago Exited (0) About a minute ago
:: test_container :: test_container
:: tal como podeis ver el nombre es el que especificamos :: tal como podeis ver el nombre es el que especificamos
:: obtener los registros de un contenedor nombrado :: obtener los registros de un contenedor nombrado
docker logs test_container docker logs test_container
:: Hello from Docker! :: Hello from Docker!
:: This message shows that your installation appears to be working correctly. :: This message shows that your installation appears to be working correctly.
:: ::
:: To generate this message, Docker took the following steps: :: To generate this message, Docker took the following steps:
:: 1. The Docker client contacted the Docker daemon. :: 1. The Docker client contacted the Docker daemon.
:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. :: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
:: (amd64) :: (amd64)
:: 3. The Docker daemon created a new container from that image which runs the :: 3. The Docker daemon created a new container from that image which runs the
:: executable that produces the output you are currently reading. :: executable that produces the output you are currently reading.
:: 4. The Docker daemon streamed that output to the Docker client, which sent it :: 4. The Docker daemon streamed that output to the Docker client, which sent it
:: to your terminal. :: to your terminal.
:: ::
:: To try something more ambitious, you can run an Ubuntu container with: :: To try something more ambitious, you can run an Ubuntu container with:
:: $ docker run -it ubuntu bash :: $ docker run -it ubuntu bash
:: ::
:: Share images, automate workflows, and more with a free Docker ID: :: Share images, automate workflows, and more with a free Docker ID:
:: https://hub.docker.com/ :: https://hub.docker.com/
:: ::
:: For more examples and ideas, visit: :: For more examples and ideas, visit:
:: https://docs.docker.com/get-started/ :: https://docs.docker.com/get-started/
docker rm test_container docker rm test_container
docker run ubuntu docker run ubuntu
:: Unable to find image 'ubuntu:latest' locally :: Unable to find image 'ubuntu:latest' locally
:: latest: Pulling from library/ubuntu :: latest: Pulling from library/ubuntu
:: 2746a4a261c9: Pull complete :: 2746a4a261c9: Pull complete
:: 4c1d20cdee96: Pull complete 0d3160e1d0de: Pull complete c8e37668deea: Pull complete Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4 :: 4c1d20cdee96: Pull complete 0d3160e1d0de: Pull complete c8e37668deea: Pull complete Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4
:: Status: Downloaded newer image for ubuntu:latest :: Status: Downloaded newer image for ubuntu:latest
docker ps -a docker ps -a
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS :: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES :: NAMES
:: c19e9e5b000a ubuntu "/bin/bash" 5 seconds ago Exited (0) 4 seconds ago :: c19e9e5b000a ubuntu "/bin/bash" 5 seconds ago Exited (0) 4 seconds ago
:: relaxed_nobel :: relaxed_nobel
:: ejecutando un contenedor en modo interactivo :: ejecutando un contenedor en modo interactivo
docker run -it ubuntu docker run -it ubuntu
:: root@e2cac48323d2:/# uname :: root@e2cac48323d2:/# uname
:: Linux :: Linux
:: root@e2cac48323d2:/# exit :: root@e2cac48323d2:/# exit
:: exit :: exit
docker rm relaxed_nobel docker rm relaxed_nobel
docker ps -a docker ps -a
:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS :: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
:: NAMES :: NAMES
:: e2cac48323d2 ubuntu "/bin/bash" 2 minutes ago Exited (0) About a minute ago :: e2cac48323d2 ubuntu "/bin/bash" 2 minutes ago Exited (0) About a minute ago
:: nifty_goldwasser :: nifty_goldwasser
docker rm nifty_goldwasser docker rm nifty_goldwasser
``` ```

View File

@@ -1,276 +1,276 @@
--- ---
language: toml language: toml
filename: learntoml-it.toml filename: learntoml-it.toml
contributors: contributors:
- ["Alois de Gouvello", "https://github.com/aloisdg"] - ["Alois de Gouvello", "https://github.com/aloisdg"]
translators: translators:
- ["Christian Grasso", "https://grasso.io"] - ["Christian Grasso", "https://grasso.io"]
lang: it-it lang: it-it
--- ---
TOML è l'acronimo di _Tom's Obvious, Minimal Language_. È un linguaggio per la TOML è l'acronimo di _Tom's Obvious, Minimal Language_. È un linguaggio per la
serializzazione di dati, progettato per i file di configurazione. serializzazione di dati, progettato per i file di configurazione.
È un'alternativa a linguaggi come YAML e JSON, che punta ad essere più leggibile È un'alternativa a linguaggi come YAML e JSON, che punta ad essere più leggibile
per le persone. Allo stesso tempo, TOML può essere utilizzato in modo abbastanza per le persone. Allo stesso tempo, TOML può essere utilizzato in modo abbastanza
semplice nella maggior parte dei linguaggi di programmazione, in quanto è semplice nella maggior parte dei linguaggi di programmazione, in quanto è
progettato per essere tradotto senza ambiguità in una hash table. progettato per essere tradotto senza ambiguità in una hash table.
Tieni presente che TOML è ancora in fase di sviluppo, e la sua specifica non è Tieni presente che TOML è ancora in fase di sviluppo, e la sua specifica non è
ancora stabile. Questo documento utilizza TOML 0.4.0. ancora stabile. Questo documento utilizza TOML 0.4.0.
```toml ```toml
# I commenti in TOML sono fatti così. # I commenti in TOML sono fatti così.
################ ################
# TIPI SCALARI # # TIPI SCALARI #
################ ################
# Il nostro oggetto root (corrispondente all'intero documento) sarà una mappa, # Il nostro oggetto root (corrispondente all'intero documento) sarà una mappa,
# anche chiamata dizionario, hash o oggetto in altri linguaggi. # anche chiamata dizionario, hash o oggetto in altri linguaggi.
# La key, il simbolo di uguale e il valore devono trovarsi sulla stessa riga, # La key, il simbolo di uguale e il valore devono trovarsi sulla stessa riga,
# eccetto per alcuni tipi di valori. # eccetto per alcuni tipi di valori.
key = "value" key = "value"
stringa = "ciao" stringa = "ciao"
numero = 42 numero = 42
float = 3.14 float = 3.14
boolean = true boolean = true
data = 1979-05-27T07:32:00-08:00 data = 1979-05-27T07:32:00-08:00
notazScientifica = 1e+12 notazScientifica = 1e+12
"puoi utilizzare le virgolette per la key" = true # Puoi usare " oppure ' "puoi utilizzare le virgolette per la key" = true # Puoi usare " oppure '
"la key può contenere" = "lettere, numeri, underscore e trattini" "la key può contenere" = "lettere, numeri, underscore e trattini"
############ ############
# Stringhe # # Stringhe #
############ ############
# Le stringhe possono contenere solo caratteri UTF-8 validi. # Le stringhe possono contenere solo caratteri UTF-8 validi.
# Possiamo effettuare l'escape dei caratteri, e alcuni hanno delle sequenze # Possiamo effettuare l'escape dei caratteri, e alcuni hanno delle sequenze
# di escape compatte. Ad esempio, \t corrisponde al TAB. # di escape compatte. Ad esempio, \t corrisponde al TAB.
stringaSemplice = "Racchiusa tra virgolette. \"Usa il backslash per l'escape\"." stringaSemplice = "Racchiusa tra virgolette. \"Usa il backslash per l'escape\"."
stringaMultiriga = """ stringaMultiriga = """
Racchiusa da tre virgolette doppie all'inizio e Racchiusa da tre virgolette doppie all'inizio e
alla fine - consente di andare a capo.""" alla fine - consente di andare a capo."""
stringaLiteral = 'Virgolette singole. Non consente di effettuare escape.' stringaLiteral = 'Virgolette singole. Non consente di effettuare escape.'
stringaMultirigaLiteral = ''' stringaMultirigaLiteral = '''
Racchiusa da tre virgolette singole all'inizio e Racchiusa da tre virgolette singole all'inizio e
alla fine - consente di andare a capo. alla fine - consente di andare a capo.
Anche in questo caso non si può fare escape. Anche in questo caso non si può fare escape.
Il primo ritorno a capo viene eliminato. Il primo ritorno a capo viene eliminato.
Tutti gli altri spazi aggiuntivi Tutti gli altri spazi aggiuntivi
vengono mantenuti. vengono mantenuti.
''' '''
# Per i dati binari è consigliabile utilizzare Base64 e # Per i dati binari è consigliabile utilizzare Base64 e
# gestirli manualmente dall'applicazione. # gestirli manualmente dall'applicazione.
########## ##########
# Interi # # Interi #
########## ##########
## Gli interi possono avere o meno un segno (+, -). ## Gli interi possono avere o meno un segno (+, -).
## Non si possono inserire zero superflui all'inizio. ## Non si possono inserire zero superflui all'inizio.
## Non è possibile inoltre utilizzare valori numerici ## Non è possibile inoltre utilizzare valori numerici
## non rappresentabili con una sequenza di cifre. ## non rappresentabili con una sequenza di cifre.
int1 = +42 int1 = +42
int2 = 0 int2 = 0
int3 = -21 int3 = -21
## Puoi utilizzare gli underscore per migliorare la leggibilità. ## Puoi utilizzare gli underscore per migliorare la leggibilità.
## Fai attenzione a non inserirne due di seguito. ## Fai attenzione a non inserirne due di seguito.
int4 = 5_349_221 int4 = 5_349_221
int5 = 1_2_3_4_5 # VALIDO, ma da evitare int5 = 1_2_3_4_5 # VALIDO, ma da evitare
######### #########
# Float # # Float #
######### #########
# I float permettono di rappresentare numeri decimali. # I float permettono di rappresentare numeri decimali.
flt1 = 3.1415 flt1 = 3.1415
flt2 = -5e6 flt2 = -5e6
flt3 = 6.626E-34 flt3 = 6.626E-34
########### ###########
# Boolean # # Boolean #
########### ###########
# I valori boolean (true/false) devono essere scritti in minuscolo. # I valori boolean (true/false) devono essere scritti in minuscolo.
bool1 = true bool1 = true
bool2 = false bool2 = false
############ ############
# Data/ora # # Data/ora #
############ ############
data1 = 1979-05-27T07:32:00Z # Specifica RFC 3339/ISO 8601 (UTC) data1 = 1979-05-27T07:32:00Z # Specifica RFC 3339/ISO 8601 (UTC)
data2 = 1979-05-26T15:32:00+08:00 # RFC 3339/ISO 8601 con offset data2 = 1979-05-26T15:32:00+08:00 # RFC 3339/ISO 8601 con offset
###################### ######################
# TIPI DI COLLECTION # # TIPI DI COLLECTION #
###################### ######################
######### #########
# Array # # Array #
######### #########
array1 = [ 1, 2, 3 ] array1 = [ 1, 2, 3 ]
array2 = [ "Le", "virgole", "sono", "delimitatori" ] array2 = [ "Le", "virgole", "sono", "delimitatori" ]
array3 = [ "Non", "unire", "tipi", "diversi" ] array3 = [ "Non", "unire", "tipi", "diversi" ]
array4 = [ "tutte", 'le stringhe', """hanno lo stesso""", '''tipo''' ] array4 = [ "tutte", 'le stringhe', """hanno lo stesso""", '''tipo''' ]
array5 = [ array5 = [
"Gli spazi vuoti", "sono", "ignorati" "Gli spazi vuoti", "sono", "ignorati"
] ]
########### ###########
# Tabelle # # Tabelle #
########### ###########
# Le tabelle (o hash table o dizionari) sono collection di coppie key/value. # Le tabelle (o hash table o dizionari) sono collection di coppie key/value.
# Iniziano con un nome tra parentesi quadre su una linea separata. # Iniziano con un nome tra parentesi quadre su una linea separata.
# Le tabelle vuote (senza alcun valore) sono valide. # Le tabelle vuote (senza alcun valore) sono valide.
[tabella] [tabella]
# Tutti i valori che si trovano sotto il nome della tabella # Tutti i valori che si trovano sotto il nome della tabella
# appartengono alla tabella stessa (finchè non ne viene creata un'altra). # appartengono alla tabella stessa (finchè non ne viene creata un'altra).
# L'ordine di questi valori non è garantito. # L'ordine di questi valori non è garantito.
[tabella-1] [tabella-1]
key1 = "una stringa" key1 = "una stringa"
key2 = 123 key2 = 123
[tabella-2] [tabella-2]
key1 = "un'altra stringa" key1 = "un'altra stringa"
key2 = 456 key2 = 456
# Utilizzando i punti è possibile creare delle sottotabelle. # Utilizzando i punti è possibile creare delle sottotabelle.
# Ogni parte suddivisa dai punti segue le regole delle key per il nome. # Ogni parte suddivisa dai punti segue le regole delle key per il nome.
[tabella-3."sotto.tabella"] [tabella-3."sotto.tabella"]
key1 = "prova" key1 = "prova"
# Ecco l'equivalente JSON della tabella precedente: # Ecco l'equivalente JSON della tabella precedente:
# { "tabella-3": { "sotto.tabella": { "key1": "prova" } } } # { "tabella-3": { "sotto.tabella": { "key1": "prova" } } }
# Gli spazi non vengono considerati, ma è consigliabile # Gli spazi non vengono considerati, ma è consigliabile
# evitare di usare spazi superflui. # evitare di usare spazi superflui.
[a.b.c] # consigliato [a.b.c] # consigliato
[ d.e.f ] # identico a [d.e.f] [ d.e.f ] # identico a [d.e.f]
# Non c'è bisogno di creare le tabelle superiori per creare una sottotabella. # Non c'è bisogno di creare le tabelle superiori per creare una sottotabella.
# [x] queste # [x] queste
# [x.y] non # [x.y] non
# [x.y.z] servono # [x.y.z] servono
[x.y.z.w] # per creare questa tabella [x.y.z.w] # per creare questa tabella
# Se non è stata già creata prima, puoi anche creare # Se non è stata già creata prima, puoi anche creare
# una tabella superiore più avanti. # una tabella superiore più avanti.
[a.b] [a.b]
c = 1 c = 1
[a] [a]
d = 2 d = 2
# Non puoi definire una key o una tabella più di una volta. # Non puoi definire una key o una tabella più di una volta.
# ERRORE # ERRORE
[a] [a]
b = 1 b = 1
[a] [a]
c = 2 c = 2
# ERRORE # ERRORE
[a] [a]
b = 1 b = 1
[a.b] [a.b]
c = 2 c = 2
# I nomi delle tabelle non possono essere vuoti. # I nomi delle tabelle non possono essere vuoti.
[] # NON VALIDO [] # NON VALIDO
[a.] # NON VALIDO [a.] # NON VALIDO
[a..b] # NON VALIDO [a..b] # NON VALIDO
[.b] # NON VALIDO [.b] # NON VALIDO
[.] # NON VALIDO [.] # NON VALIDO
################## ##################
# Tabelle inline # # Tabelle inline #
################## ##################
tabelleInline = { racchiuseData = "{ e }", rigaSingola = true } tabelleInline = { racchiuseData = "{ e }", rigaSingola = true }
punto = { x = 1, y = 2 } punto = { x = 1, y = 2 }
#################### ####################
# Array di tabelle # # Array di tabelle #
#################### ####################
# Un array di tabelle può essere creato utilizzando due parentesi quadre. # Un array di tabelle può essere creato utilizzando due parentesi quadre.
# Tutte le tabelle con questo nome saranno elementi dell'array. # Tutte le tabelle con questo nome saranno elementi dell'array.
# Gli elementi vengono inseriti nell'ordine in cui si trovano. # Gli elementi vengono inseriti nell'ordine in cui si trovano.
[[prodotti]] [[prodotti]]
nome = "array di tabelle" nome = "array di tabelle"
sku = 738594937 sku = 738594937
tabelleVuoteValide = true tabelleVuoteValide = true
[[prodotti]] [[prodotti]]
[[prodotti]] [[prodotti]]
nome = "un altro item" nome = "un altro item"
sku = 284758393 sku = 284758393
colore = "grigio" colore = "grigio"
# Puoi anche creare array di tabelle nested. Le sottotabelle con doppie # Puoi anche creare array di tabelle nested. Le sottotabelle con doppie
# parentesi quadre apparterranno alla tabella più vicina sopra di esse. # parentesi quadre apparterranno alla tabella più vicina sopra di esse.
[[frutta]] [[frutta]]
nome = "mela" nome = "mela"
[frutto.geometria] [frutto.geometria]
forma = "sferica" forma = "sferica"
nota = "Sono una proprietà del frutto" nota = "Sono una proprietà del frutto"
[[frutto.colore]] [[frutto.colore]]
nome = "rosso" nome = "rosso"
nota = "Sono un oggetto di un array dentro mela" nota = "Sono un oggetto di un array dentro mela"
[[frutto.colore]] [[frutto.colore]]
nome = "verde" nome = "verde"
nota = "Sono nello stesso array di rosso" nota = "Sono nello stesso array di rosso"
[[frutta]] [[frutta]]
nome = "banana" nome = "banana"
[[frutto.colore]] [[frutto.colore]]
nome = "giallo" nome = "giallo"
nota = "Anche io sono un oggetto di un array, ma dentro banana" nota = "Anche io sono un oggetto di un array, ma dentro banana"
``` ```
Ecco l'equivalente JSON dell'ultima tabella: Ecco l'equivalente JSON dell'ultima tabella:
```json ```json
{ {
"frutta": [ "frutta": [
{ {
"nome": "mela", "nome": "mela",
"geometria": { "forma": "sferica", "nota": "..."}, "geometria": { "forma": "sferica", "nota": "..."},
"colore": [ "colore": [
{ "nome": "rosso", "nota": "..." }, { "nome": "rosso", "nota": "..." },
{ "nome": "verde", "nota": "..." } { "nome": "verde", "nota": "..." }
] ]
}, },
{ {
"nome": "banana", "nome": "banana",
"colore": [ "colore": [
{ "nome": "giallo", "nota": "..." } { "nome": "giallo", "nota": "..." }
] ]
} }
] ]
} }
``` ```
### Altre risorse ### Altre risorse
+ [Repository ufficiale di TOML](https://github.com/toml-lang/toml) + [Repository ufficiale di TOML](https://github.com/toml-lang/toml)

View File

@@ -1,246 +1,246 @@
--- ---
category: tool category: tool
tool: make tool: make
contributors: contributors:
- ["Robert Steed", "https://github.com/robochat"] - ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"] - ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
filename: Makefile filename: Makefile
--- ---
A Makefile defines a graph of rules for creating a target (or targets). A Makefile defines a graph of rules for creating a target (or targets).
Its purpose is to do the minimum amount of work needed to update a Its purpose is to do the minimum amount of work needed to update a
target to the most recent version of the source. Famously written over a target to the most recent version of the source. Famously written over a
weekend by Stuart Feldman in 1976, it is still widely used (particularly weekend by Stuart Feldman in 1976, it is still widely used (particularly
on Unix and Linux) despite many competitors and criticisms. on Unix and Linux) despite many competitors and criticisms.
There are many varieties of make in existence, however this article There are many varieties of make in existence, however this article
assumes that we are using GNU make which is the standard on Linux. assumes that we are using GNU make which is the standard on Linux.
```make ```make
# Comments can be written like this. # Comments can be written like this.
# File should be named Makefile and then can be run as `make <target>`. # File should be named Makefile and then can be run as `make <target>`.
# Otherwise we use `make -f "filename" <target>`. # Otherwise we use `make -f "filename" <target>`.
# Warning - only use TABS to indent in Makefiles, never spaces! # Warning - only use TABS to indent in Makefiles, never spaces!
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Basics # Basics
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Rules are of the format # Rules are of the format
# target: <prerequisite> # target: <prerequisite>
# where prerequisites are optional. # where prerequisites are optional.
# A rule - this rule will only run if file0.txt doesn't exist. # A rule - this rule will only run if file0.txt doesn't exist.
file0.txt: file0.txt:
echo "foo" > file0.txt echo "foo" > file0.txt
# Even comments in these 'recipe' sections get passed to the shell. # Even comments in these 'recipe' sections get passed to the shell.
# Try `make file0.txt` or simply `make` - first rule is the default. # Try `make file0.txt` or simply `make` - first rule is the default.
# This rule will only run if file0.txt is newer than file1.txt. # This rule will only run if file0.txt is newer than file1.txt.
file1.txt: file0.txt file1.txt: file0.txt
cat file0.txt > file1.txt cat file0.txt > file1.txt
# use the same quoting rules as in the shell. # use the same quoting rules as in the shell.
@cat file0.txt >> file1.txt @cat file0.txt >> file1.txt
# @ stops the command from being echoed to stdout. # @ stops the command from being echoed to stdout.
-@echo 'hello' -@echo 'hello'
# - means that make will keep going in the case of an error. # - means that make will keep going in the case of an error.
# Try `make file1.txt` on the commandline. # Try `make file1.txt` on the commandline.
# A rule can have multiple targets and multiple prerequisites # A rule can have multiple targets and multiple prerequisites
file2.txt file3.txt: file0.txt file1.txt file2.txt file3.txt: file0.txt file1.txt
touch file2.txt touch file2.txt
touch file3.txt touch file3.txt
# Make will complain about multiple recipes for the same rule. Empty # Make will complain about multiple recipes for the same rule. Empty
# recipes don't count though and can be used to add new dependencies. # recipes don't count though and can be used to add new dependencies.
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Phony Targets # Phony Targets
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# A phony target. Any target that isn't a file. # A phony target. Any target that isn't a file.
# It will never be up to date so make will always try to run it. # It will never be up to date so make will always try to run it.
all: maker process all: maker process
# We can declare things out of order. # We can declare things out of order.
maker: maker:
touch ex0.txt ex1.txt touch ex0.txt ex1.txt
# Can avoid phony rules breaking when a real file has the same name by # Can avoid phony rules breaking when a real file has the same name by
.PHONY: all maker process .PHONY: all maker process
# This is a special target. There are several others. # This is a special target. There are several others.
# A rule with a dependency on a phony target will always run # A rule with a dependency on a phony target will always run
ex0.txt ex1.txt: maker ex0.txt ex1.txt: maker
# Common phony targets are: all make clean install ... # Common phony targets are: all make clean install ...
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Automatic Variables & Wildcards # Automatic Variables & Wildcards
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
process: file*.txt #using a wildcard to match filenames process: file*.txt #using a wildcard to match filenames
@echo $^ # $^ is a variable containing the list of prerequisites @echo $^ # $^ is a variable containing the list of prerequisites
@echo $@ # prints the target name @echo $@ # prints the target name
#(for multiple target rules, $@ is whichever caused the rule to run) #(for multiple target rules, $@ is whichever caused the rule to run)
@echo $< # the first prerequisite listed @echo $< # the first prerequisite listed
@echo $? # only the dependencies that are out of date @echo $? # only the dependencies that are out of date
@echo $+ # all dependencies including duplicates (unlike normal) @echo $+ # all dependencies including duplicates (unlike normal)
#@echo $| # all of the 'order only' prerequisites #@echo $| # all of the 'order only' prerequisites
# Even if we split up the rule dependency definitions, $^ will find them # Even if we split up the rule dependency definitions, $^ will find them
process: ex1.txt file0.txt process: ex1.txt file0.txt
# ex1.txt will be found but file0.txt will be deduplicated. # ex1.txt will be found but file0.txt will be deduplicated.
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Patterns # Patterns
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Can teach make how to convert certain files into other files. # Can teach make how to convert certain files into other files.
%.png: %.svg %.png: %.svg
inkscape --export-png $^ inkscape --export-png $^
# Pattern rules will only do anything if make decides to create the # Pattern rules will only do anything if make decides to create the
# target. # target.
# Directory paths are normally ignored when matching pattern rules. But # Directory paths are normally ignored when matching pattern rules. But
# make will try to use the most appropriate rule available. # make will try to use the most appropriate rule available.
small/%.png: %.svg small/%.png: %.svg
inkscape --export-png --export-dpi 30 $^ inkscape --export-png --export-dpi 30 $^
# make will use the last version for a pattern rule that it finds. # make will use the last version for a pattern rule that it finds.
%.png: %.svg %.png: %.svg
@echo this rule is chosen @echo this rule is chosen
# However make will use the first pattern rule that can make the target # However make will use the first pattern rule that can make the target
%.png: %.ps %.png: %.ps
@echo this rule is not chosen if *.svg and *.ps are both present @echo this rule is not chosen if *.svg and *.ps are both present
# make already has some pattern rules built-in. For instance, it knows # make already has some pattern rules built-in. For instance, it knows
# how to turn *.c files into *.o files. # how to turn *.c files into *.o files.
# Older makefiles might use suffix rules instead of pattern rules # Older makefiles might use suffix rules instead of pattern rules
.png.ps: .png.ps:
@echo this rule is similar to a pattern rule. @echo this rule is similar to a pattern rule.
# Tell make about the suffix rule # Tell make about the suffix rule
.SUFFIXES: .png .SUFFIXES: .png
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Variables # Variables
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# aka. macros # aka. macros
# Variables are basically all string types # Variables are basically all string types
name = Ted name = Ted
name2="Sarah" name2="Sarah"
echo: echo:
@echo $(name) @echo $(name)
@echo ${name2} @echo ${name2}
@echo $name # This won't work, treated as $(n)ame. @echo $name # This won't work, treated as $(n)ame.
@echo $(name3) # Unknown variables are treated as empty strings. @echo $(name3) # Unknown variables are treated as empty strings.
# There are 4 places to set variables. # There are 4 places to set variables.
# In order of priority from highest to lowest: # In order of priority from highest to lowest:
# 1: commandline arguments # 1: commandline arguments
# 2: Makefile # 2: Makefile
# 3: shell environment variables - make imports these automatically. # 3: shell environment variables - make imports these automatically.
# 4: make has some predefined variables # 4: make has some predefined variables
name4 ?= Jean name4 ?= Jean
# Only set the variable if environment variable is not already defined. # Only set the variable if environment variable is not already defined.
override name5 = David override name5 = David
# Stops commandline arguments from changing this variable. # Stops commandline arguments from changing this variable.
name4 +=grey name4 +=grey
# Append values to variable (includes a space). # Append values to variable (includes a space).
# Pattern-specific variable values (GNU extension). # Pattern-specific variable values (GNU extension).
echo: name2 = Sara # True within the matching rule echo: name2 = Sara # True within the matching rule
# and also within its remade recursive dependencies # and also within its remade recursive dependencies
# (except it can break when your graph gets too complicated!) # (except it can break when your graph gets too complicated!)
# Some variables defined automatically by make. # Some variables defined automatically by make.
echo_inbuilt: echo_inbuilt:
echo $(CC) echo $(CC)
echo ${CXX} echo ${CXX}
echo $(FC) echo $(FC)
echo ${CFLAGS} echo ${CFLAGS}
echo $(CPPFLAGS) echo $(CPPFLAGS)
echo ${CXXFLAGS} echo ${CXXFLAGS}
echo $(LDFLAGS) echo $(LDFLAGS)
echo ${LDLIBS} echo ${LDLIBS}
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Variables 2 # Variables 2
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# The first type of variables are evaluated each time they are used. # The first type of variables are evaluated each time they are used.
# This can be expensive, so a second type of variable exists which is # This can be expensive, so a second type of variable exists which is
# only evaluated once. (This is a GNU make extension) # only evaluated once. (This is a GNU make extension)
var := hello var := hello
var2 ::= $(var) hello var2 ::= $(var) hello
#:= and ::= are equivalent. #:= and ::= are equivalent.
# These variables are evaluated procedurally (in the order that they # These variables are evaluated procedurally (in the order that they
# appear), thus breaking with the rest of the language ! # appear), thus breaking with the rest of the language !
# This doesn't work # This doesn't work
var3 ::= $(var4) and good luck var3 ::= $(var4) and good luck
var4 ::= good night var4 ::= good night
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Functions # Functions
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# make has lots of functions available. # make has lots of functions available.
sourcefiles = $(wildcard *.c */*.c) sourcefiles = $(wildcard *.c */*.c)
objectfiles = $(patsubst %.c,%.o,$(sourcefiles)) objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
# Format is $(func arg0,arg1,arg2...) # Format is $(func arg0,arg1,arg2...)
# Some examples # Some examples
ls: * src/* ls: * src/*
@echo $(filter %.txt, $^) @echo $(filter %.txt, $^)
@echo $(notdir $^) @echo $(notdir $^)
@echo $(join $(dir $^),$(notdir $^)) @echo $(join $(dir $^),$(notdir $^))
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Directives # Directives
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Include other makefiles, useful for platform specific code # Include other makefiles, useful for platform specific code
include foo.mk include foo.mk
sport = tennis sport = tennis
# Conditional compilation # Conditional compilation
report: report:
ifeq ($(sport),tennis) ifeq ($(sport),tennis)
@echo 'game, set, match' @echo 'game, set, match'
else else
@echo "They think it's all over; it is now" @echo "They think it's all over; it is now"
endif endif
# There are also ifneq, ifdef, ifndef # There are also ifneq, ifdef, ifndef
foo = true foo = true
ifdef $(foo) ifdef $(foo)
bar = 'hello' bar = 'hello'
endif endif
``` ```
### More Resources ### More Resources
+ [gnu make documentation](https://www.gnu.org/software/make/manual/) + [gnu make documentation](https://www.gnu.org/software/make/manual/)
+ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/) + [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) + learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)

File diff suppressed because it is too large Load Diff

View File

@@ -1,245 +1,245 @@
--- ---
category: tool category: tool
tool: make tool: make
contributors: contributors:
- ["Robert Steed", "https://github.com/robochat"] - ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"] - ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
translators: translators:
- ["Rogério Gomes Rio", "https://github.com/rogerlista"] - ["Rogério Gomes Rio", "https://github.com/rogerlista"]
filename: Makefile-pt filename: Makefile-pt
lang: pt-br lang: pt-br
--- ---
Um Makefile define um gráfico de regras para criar um alvo (ou alvos). Sua finalidade é fazer o mínimo de trabalho necessário para atualizar um alvo para a versão mais recente da fonte. Famosamente escrito ao longo de um fim de semana por Stuart Feldman em 1976, ainda é amplamente usada (particularmente no Unix e no Linux) apesar de muitos concorrentes e críticas. Um Makefile define um gráfico de regras para criar um alvo (ou alvos). Sua finalidade é fazer o mínimo de trabalho necessário para atualizar um alvo para a versão mais recente da fonte. Famosamente escrito ao longo de um fim de semana por Stuart Feldman em 1976, ainda é amplamente usada (particularmente no Unix e no Linux) apesar de muitos concorrentes e críticas.
Existem muitas variedades de make na existência, no entanto, este artigo pressupõe que estamos usando o GNU make, que é o padrão no Linux. Existem muitas variedades de make na existência, no entanto, este artigo pressupõe que estamos usando o GNU make, que é o padrão no Linux.
```make ```make
# Comentários podem ser escritos assim. # Comentários podem ser escritos assim.
# O arquivo deve ser nomeado Makefile e então pode ser executado como `make <alvo>`. # O arquivo deve ser nomeado Makefile e então pode ser executado como `make <alvo>`.
# Caso contrário, nós usamos `make -f "nome-do-arquivo" <alvo>`. # Caso contrário, nós usamos `make -f "nome-do-arquivo" <alvo>`.
# Aviso - use somente TABS para identar em Makefiles, nunca espaços! # Aviso - use somente TABS para identar em Makefiles, nunca espaços!
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Noções básicas # Noções básicas
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Regras são do formato # Regras são do formato
# alvo: <pré-requisito> # alvo: <pré-requisito>
# onde os pré-requisitos são opcionais. # onde os pré-requisitos são opcionais.
# Uma regra - esta regra só será executada se o arquivo0.txt não existir. # Uma regra - esta regra só será executada se o arquivo0.txt não existir.
arquivo0.txt: arquivo0.txt:
echo "foo" > arquivo0.txt echo "foo" > arquivo0.txt
# Mesmo os comentários nestas seções da 'receita' são passados para o shell. # Mesmo os comentários nestas seções da 'receita' são passados para o shell.
# Experimentar `make arquivo0.txt` or simplyou simplesmente `make` - primeira regra é o padrão. # Experimentar `make arquivo0.txt` or simplyou simplesmente `make` - primeira regra é o padrão.
# Esta regra só será executada se arquivo0.txt for mais recente que arquivo1.txt. # Esta regra só será executada se arquivo0.txt for mais recente que arquivo1.txt.
arquivo1.txt: arquivo0.txt arquivo1.txt: arquivo0.txt
cat arquivo0.txt > arquivo1.txt cat arquivo0.txt > arquivo1.txt
# se as mesmas regras de citação do shell. # se as mesmas regras de citação do shell.
@cat arquivo0.txt >> arquivo1.txt @cat arquivo0.txt >> arquivo1.txt
# @ pára o comando de ser ecoado para stdout. # @ pára o comando de ser ecoado para stdout.
-@echo 'hello' -@echo 'hello'
# - significa que make continuará em caso de erro. # - significa que make continuará em caso de erro.
# Experimentar `make arquivo1.txt` na linha de comando. # Experimentar `make arquivo1.txt` na linha de comando.
# Uma regra pode ter vários alvos e vários pré-requisitos # Uma regra pode ter vários alvos e vários pré-requisitos
arquivo2.txt arquivo3.txt: arquivo0.txt arquivo1.txt arquivo2.txt arquivo3.txt: arquivo0.txt arquivo1.txt
touch arquivo2.txt touch arquivo2.txt
touch arquivo3.txt touch arquivo3.txt
# Make vai reclamar sobre várias receitas para a mesma regra. Esvaziar # Make vai reclamar sobre várias receitas para a mesma regra. Esvaziar
# receitas não contam e podem ser usadas para adicionar novas dependências. # receitas não contam e podem ser usadas para adicionar novas dependências.
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Alvos falsos # Alvos falsos
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Um alvo falso. Qualquer alvo que não seja um arquivo. # Um alvo falso. Qualquer alvo que não seja um arquivo.
# Ele nunca será atualizado, portanto, o make sempre tentará executá-lo. # Ele nunca será atualizado, portanto, o make sempre tentará executá-lo.
all: maker process all: maker process
# Podemos declarar as coisas fora de ordem. # Podemos declarar as coisas fora de ordem.
maker: maker:
touch ex0.txt ex1.txt touch ex0.txt ex1.txt
# Pode evitar quebrar regras falsas quando um arquivo real tem o mesmo nome # Pode evitar quebrar regras falsas quando um arquivo real tem o mesmo nome
.PHONY: all maker process .PHONY: all maker process
# Este é um alvo especial. Existem vários outros. # Este é um alvo especial. Existem vários outros.
# Uma regra com dependência de um alvo falso sempre será executada # Uma regra com dependência de um alvo falso sempre será executada
ex0.txt ex1.txt: maker ex0.txt ex1.txt: maker
# Alvos falsos comuns são: todos fazem instalação limpa ... # Alvos falsos comuns são: todos fazem instalação limpa ...
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Variáveis Automáticas e Curingas # Variáveis Automáticas e Curingas
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
process: Arquivo*.txt # Usando um curinga para corresponder nomes de arquivos process: Arquivo*.txt # Usando um curinga para corresponder nomes de arquivos
@echo $^ # $^ é uma variável que contém a lista de pré-requisitos @echo $^ # $^ é uma variável que contém a lista de pré-requisitos
@echo $@ # imprime o nome do alvo @echo $@ # imprime o nome do alvo
#(fpara várias regras alvo, $@ é o que causou a execução da regra) #(fpara várias regras alvo, $@ é o que causou a execução da regra)
@echo $< # o primeiro pré-requisito listado @echo $< # o primeiro pré-requisito listado
@echo $? # somente as dependências que estão desatualizadas @echo $? # somente as dependências que estão desatualizadas
@echo $+ # todas as dependências, incluindo duplicadas (ao contrário do normal) @echo $+ # todas as dependências, incluindo duplicadas (ao contrário do normal)
#@echo $| # todos os pré-requisitos 'somente pedidos' #@echo $| # todos os pré-requisitos 'somente pedidos'
# Mesmo se dividirmos as definições de dependência de regra, $^ vai encontrá-los # Mesmo se dividirmos as definições de dependência de regra, $^ vai encontrá-los
process: ex1.txt arquivo0.txt process: ex1.txt arquivo0.txt
# ex1.txt será encontrado, mas arquivo0.txt será desduplicado. # ex1.txt será encontrado, mas arquivo0.txt será desduplicado.
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Padrões # Padrões
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Pode ensinar make a converter certos arquivos em outros arquivos. # Pode ensinar make a converter certos arquivos em outros arquivos.
%.png: %.svg %.png: %.svg
inkscape --export-png $^ inkscape --export-png $^
# As regras padrões só farão qualquer coisa se decidirem criar o alvo. # As regras padrões só farão qualquer coisa se decidirem criar o alvo.
# Os caminhos de diretório são normalmente ignorados quando as regras de # Os caminhos de diretório são normalmente ignorados quando as regras de
# padrões são correspondentes. Mas make tentará usar a regra mais # padrões são correspondentes. Mas make tentará usar a regra mais
# apropriada disponível. # apropriada disponível.
small/%.png: %.svg small/%.png: %.svg
inkscape --export-png --export-dpi 30 $^ inkscape --export-png --export-dpi 30 $^
# make utilizará a última versão para uma regra de padrão que encontrar. # make utilizará a última versão para uma regra de padrão que encontrar.
%.png: %.svg %.png: %.svg
@echo esta regra é escolhida @echo esta regra é escolhida
# No entanto, o make usará a primeira regra padrão que pode se tornar o alvo # No entanto, o make usará a primeira regra padrão que pode se tornar o alvo
%.png: %.ps %.png: %.ps
@echo esta regra não é escolhida se *.svg and *.ps estão ambos presentes @echo esta regra não é escolhida se *.svg and *.ps estão ambos presentes
# make já tem algumas regras padrões embutidas. Por exemplo, ele sabe # make já tem algumas regras padrões embutidas. Por exemplo, ele sabe
# como transformar arquivos *.c em arquivos *.o. # como transformar arquivos *.c em arquivos *.o.
# Makefiles antigos podem usar regras de sufixo em vez de regras padrões # Makefiles antigos podem usar regras de sufixo em vez de regras padrões
.png.ps: .png.ps:
@echo essa regra é semelhante a uma regra de padrão. @echo essa regra é semelhante a uma regra de padrão.
# make sobre a regra de sufixo # make sobre a regra de sufixo
.SUFFIXES: .png .SUFFIXES: .png
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Variáveis # Variáveis
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# aka. macros # aka. macros
# As variáveis são basicamente todos os tipos de string # As variáveis são basicamente todos os tipos de string
name = Ted name = Ted
name2="Sarah" name2="Sarah"
echo: echo:
@echo $(name) @echo $(name)
@echo ${name2} @echo ${name2}
@echo $name # Isso não funcionará, tratado como $ (n)ame. @echo $name # Isso não funcionará, tratado como $ (n)ame.
@echo $(name3) # Variáveis desconhecidas são tratadas como strings vazias. @echo $(name3) # Variáveis desconhecidas são tratadas como strings vazias.
# Existem 4 lugares para definir variáveis. # Existem 4 lugares para definir variáveis.
# Em ordem de prioridade, do maior para o menor: # Em ordem de prioridade, do maior para o menor:
# 1: argumentos de linha de comando # 1: argumentos de linha de comando
# 2: Makefile # 2: Makefile
# 3: variáveis de ambiente do shell - faça importações automaticamente. # 3: variáveis de ambiente do shell - faça importações automaticamente.
# 4: make tem algumas variáveis predefinidas # 4: make tem algumas variáveis predefinidas
name4 ?= Jean name4 ?= Jean
# Somente defina a variável se a variável de ambiente ainda não estiver definida. # Somente defina a variável se a variável de ambiente ainda não estiver definida.
override name5 = David override name5 = David
# Pára os argumentos da linha de comando de alterar essa variável. # Pára os argumentos da linha de comando de alterar essa variável.
name4 +=grey name4 +=grey
# Anexar valores à variável (inclui um espaço). # Anexar valores à variável (inclui um espaço).
# Valores variáveis específicos de padrões (extensão GNU). # Valores variáveis específicos de padrões (extensão GNU).
echo: name2 = Sara # Verdadeiro dentro da regra de correspondência echo: name2 = Sara # Verdadeiro dentro da regra de correspondência
# e também dentro de suas recursivas dependências # e também dentro de suas recursivas dependências
# (exceto que ele pode quebrar quando seu gráfico ficar muito complicado!) # (exceto que ele pode quebrar quando seu gráfico ficar muito complicado!)
# Algumas variáveis definidas automaticamente pelo make # Algumas variáveis definidas automaticamente pelo make
echo_inbuilt: echo_inbuilt:
echo $(CC) echo $(CC)
echo ${CXX} echo ${CXX}
echo $(FC) echo $(FC)
echo ${CFLAGS} echo ${CFLAGS}
echo $(CPPFLAGS) echo $(CPPFLAGS)
echo ${CXXFLAGS} echo ${CXXFLAGS}
echo $(LDFLAGS) echo $(LDFLAGS)
echo ${LDLIBS} echo ${LDLIBS}
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Variáveis 2 # Variáveis 2
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# O primeiro tipo de variáveis ​​é avaliado a cada vez que elas são usadas. # O primeiro tipo de variáveis ​​é avaliado a cada vez que elas são usadas.
# TIsso pode ser caro, então existe um segundo tipo de variável que é # TIsso pode ser caro, então existe um segundo tipo de variável que é
# avaliado apenas uma vez. (Esta é uma extensão do GNU make) # avaliado apenas uma vez. (Esta é uma extensão do GNU make)
var := hello var := hello
var2 ::= $(var) hello var2 ::= $(var) hello
#:= e ::= são equivalentes. #:= e ::= são equivalentes.
# Essas variáveis são avaliadas procedimentalmente (na ordem em que # Essas variáveis são avaliadas procedimentalmente (na ordem em que
# aparecem), quebrando assim o resto da línguagem! # aparecem), quebrando assim o resto da línguagem!
# Isso não funciona # Isso não funciona
var3 ::= $(var4) and good luck var3 ::= $(var4) and good luck
var4 ::= good night var4 ::= good night
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Funções # Funções
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# make tem muitas funções disponíveis. # make tem muitas funções disponíveis.
sourcefiles = $(wildcard *.c */*.c) sourcefiles = $(wildcard *.c */*.c)
objectfiles = $(patsubst %.c,%.o,$(sourcefiles)) objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
# O formato é $(func arg0,arg1,arg2...) # O formato é $(func arg0,arg1,arg2...)
# Alguns exemplos # Alguns exemplos
ls: * src/* ls: * src/*
@echo $(filter %.txt, $^) @echo $(filter %.txt, $^)
@echo $(notdir $^) @echo $(notdir $^)
@echo $(join $(dir $^),$(notdir $^)) @echo $(join $(dir $^),$(notdir $^))
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Diretivas # Diretivas
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
# Inclua outros makefiles, úteis para código específico da plataforma # Inclua outros makefiles, úteis para código específico da plataforma
include foo.mk include foo.mk
sport = tennis sport = tennis
# Compilação condicional # Compilação condicional
report: report:
ifeq ($(sport),tennis) ifeq ($(sport),tennis)
@echo 'game, set, match' @echo 'game, set, match'
else else
@echo "They think it's all over; it is now" @echo "They think it's all over; it is now"
endif endif
# Há também ifneq, ifdef, ifndef # Há também ifneq, ifdef, ifndef
foo = true foo = true
ifdef $(foo) ifdef $(foo)
bar = 'hello' bar = 'hello'
endif endif
``` ```
### More Resources ### More Resources
+ [documentação gnu make](https://www.gnu.org/software/make/manual/) + [documentação gnu make](https://www.gnu.org/software/make/manual/)
+ [tutorial de carpintaria de software](http://swcarpentry.github.io/make-novice/) + [tutorial de carpintaria de software](http://swcarpentry.github.io/make-novice/)
+ aprenda C da maneira mais difícil [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html) + aprenda C da maneira mais difícil [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)

View File

@@ -1,225 +1,225 @@
--- ---
category: Algorithms & Data Structures category: Algorithms & Data Structures
name: Asymptotic Notation name: Asymptotic Notation
contributors: contributors:
- ["Jake Prather", "http://github.com/JakeHP"] - ["Jake Prather", "http://github.com/JakeHP"]
- ["Divay Prakash", "http://github.com/divayprakash"] - ["Divay Prakash", "http://github.com/divayprakash"]
translators: translators:
- ["pru-mike", "http://github.com/pru-mike"] - ["pru-mike", "http://github.com/pru-mike"]
lang: ru-ru lang: ru-ru
--- ---
# О-символика # О-символика
## Что это такое? ## Что это такое?
О-символика, или асимптотическая запись, — это система символов, позволяющая О-символика, или асимптотическая запись, — это система символов, позволяющая
оценить время выполнения алгоритма, устанавливая зависимость времени выполнения оценить время выполнения алгоритма, устанавливая зависимость времени выполнения
от увеличения объёма входных данных. Она также известна как оценка от увеличения объёма входных данных. Она также известна как оценка
сложности алгоритмов. Станет ли алгоритм невероятно медленным, когда сложности алгоритмов. Станет ли алгоритм невероятно медленным, когда
объём входных данных увеличится? Будет ли алгоритм выполняться достаточно быстро, объём входных данных увеличится? Будет ли алгоритм выполняться достаточно быстро,
если объём входных данных возрастёт? О-символика позволяет ответить на эти если объём входных данных возрастёт? О-символика позволяет ответить на эти
вопросы. вопросы.
## Можно ли по-другому найти ответы на эти вопросы? ## Можно ли по-другому найти ответы на эти вопросы?
Один способ — это подсчитать число элементарных операций в зависимости от Один способ — это подсчитать число элементарных операций в зависимости от
различных объёмов входных данных. Хотя это и приемлемое решение, тот объём различных объёмов входных данных. Хотя это и приемлемое решение, тот объём
работы, которого оно потребует, даже для простых алгоритмов делает его работы, которого оно потребует, даже для простых алгоритмов делает его
использование неоправданным. использование неоправданным.
Другой способ — это измерить, какое время алгоритм потребует для завершения на Другой способ — это измерить, какое время алгоритм потребует для завершения на
различных объёмах входных данных. В то же время, точность и относительность различных объёмах входных данных. В то же время, точность и относительность
этого метода (полученное время будет относиться только к той машине, на которой этого метода (полученное время будет относиться только к той машине, на которой
оно вычислено) зависит от среды выполнения: компьютерного аппаратного оно вычислено) зависит от среды выполнения: компьютерного аппаратного
обеспечения, мощности процессора и т.д. обеспечения, мощности процессора и т.д.
## Виды О-символики ## Виды О-символики
В первом разделе этого документа мы определили, что О-символика В первом разделе этого документа мы определили, что О-символика
позволяет оценивать алгоритмы в зависимости от изменения размера входных позволяет оценивать алгоритмы в зависимости от изменения размера входных
данных. Представим, что алгоритм — это функция f, n — размер входных данных и данных. Представим, что алгоритм — это функция f, n — размер входных данных и
f(n) — время выполнения. Тогда для данного алгоритма f с размером входных f(n) — время выполнения. Тогда для данного алгоритма f с размером входных
данных n получим какое-то результирующее время выполнения f(n). данных n получим какое-то результирующее время выполнения f(n).
Из этого можно построить график, где ось y — время выполнения, ось x — размер входных Из этого можно построить график, где ось y — время выполнения, ось x — размер входных
данных, а точки на графике — это время выполнения для заданного размера входных данных, а точки на графике — это время выполнения для заданного размера входных
данных. данных.
С помощью О-символики можно оценить функцию или алгоритм С помощью О-символики можно оценить функцию или алгоритм
несколькими различными способами. Например, можно оценить алгоритм исходя несколькими различными способами. Например, можно оценить алгоритм исходя
из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается
анализ на основе верхней оценки. Как правило, не используется нижняя оценка, анализ на основе верхней оценки. Как правило, не используется нижняя оценка,
потому что она не подходит под планируемые условия. Отличный пример — алгоритмы потому что она не подходит под планируемые условия. Отличный пример — алгоритмы
сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка
большинства таких алгоритмов может быть дана как одна операция. В то время как в большинства таких алгоритмов может быть дана как одна операция. В то время как в
большинстве случаев добавляемые элементы должны быть отсортированы большинстве случаев добавляемые элементы должны быть отсортированы
соответствующим образом при помощи дерева, что может потребовать обхода целой соответствующим образом при помощи дерева, что может потребовать обхода целой
ветви. Это и есть худший случай, для которого планируется верхняя оценка. ветви. Это и есть худший случай, для которого планируется верхняя оценка.
### Виды функций, пределы и упрощения ### Виды функций, пределы и упрощения
``` ```
Логарифмическая функция — log n Логарифмическая функция — log n
Линейная функция — an + b Линейная функция — an + b
Квадратичная функция — an^2 + bn +c Квадратичная функция — an^2 + bn +c
Степенная функция — an^z + . . . + an^2 + a*n^1 + a*n^0, где z — константа Степенная функция — an^z + . . . + an^2 + a*n^1 + a*n^0, где z — константа
Показательная функция — a^n, где a — константа Показательная функция — a^n, где a — константа
``` ```
Приведены несколько базовых функций, используемых при определении сложности в Приведены несколько базовых функций, используемых при определении сложности в
различных оценках. Список начинается с самой медленно возрастающей функции различных оценках. Список начинается с самой медленно возрастающей функции
(логарифм, наиболее быстрое время выполнения) и следует до самой быстро (логарифм, наиболее быстрое время выполнения) и следует до самой быстро
возрастающей функции (экспонента, самое медленное время выполнения). Отметим, возрастающей функции (экспонента, самое медленное время выполнения). Отметим,
что в то время, как «n», или размер входных данных, возрастает в каждой из этих функций, что в то время, как «n», или размер входных данных, возрастает в каждой из этих функций,
результат намного быстрее возрастает в квадратичной, степенной результат намного быстрее возрастает в квадратичной, степенной
и показательной по сравнению с логарифмической и линейной. и показательной по сравнению с логарифмической и линейной.
Крайне важно понимать, что при использовании описанной далее нотации необходимо Крайне важно понимать, что при использовании описанной далее нотации необходимо
использовать упрощённые выражения. использовать упрощённые выражения.
Это означает, что необходимо отбрасывать константы и слагаемые младших порядков, Это означает, что необходимо отбрасывать константы и слагаемые младших порядков,
потому что если размер входных данных (n в функции f(n) нашего примера) потому что если размер входных данных (n в функции f(n) нашего примера)
увеличивается до бесконечности (в пределе), тогда слагаемые младших порядков увеличивается до бесконечности (в пределе), тогда слагаемые младших порядков
и константы становятся пренебрежительно малыми. Таким образом, если есть и константы становятся пренебрежительно малыми. Таким образом, если есть
константа, например, размера 2^9001 или любого другого невообразимого размера, константа, например, размера 2^9001 или любого другого невообразимого размера,
надо понимать, что её упрощение внесёт значительные искажения в точность надо понимать, что её упрощение внесёт значительные искажения в точность
оценки. оценки.
Т.к. нам нужны упрощённые выражения, немного скорректируем нашу таблицу... Т.к. нам нужны упрощённые выражения, немного скорректируем нашу таблицу...
``` ```
Логарифм — log n Логарифм — log n
Линейная функция — n Линейная функция — n
Квадратичная функция — n^2 Квадратичная функция — n^2
Степенная функция — n^z, где z — константа Степенная функция — n^z, где z — константа
Показательная функция — a^n, где a — константа Показательная функция — a^n, где a — константа
``` ```
### О Большое ### О Большое
О Большое, записывается как **О**, — это асимптотическая запись для оценки худшего О Большое, записывается как **О**, — это асимптотическая запись для оценки худшего
случая, или для ограничения заданной функции сверху. Это позволяет сделать случая, или для ограничения заданной функции сверху. Это позволяет сделать
_**асимптотическую оценку верхней границы**_ скорости роста времени выполнения _**асимптотическую оценку верхней границы**_ скорости роста времени выполнения
алгоритма. Пусть `f(n)` — время выполнения алгоритма, а `g(n)` — заданная временная алгоритма. Пусть `f(n)` — время выполнения алгоритма, а `g(n)` — заданная временная
сложность, которая проверяется для алгоритма. Тогда `f(n)` — это O(g(n)), если сложность, которая проверяется для алгоритма. Тогда `f(n)` — это O(g(n)), если
существуют действительные константы c (c > 0) и n<sub>0</sub>, такие, существуют действительные константы c (c > 0) и n<sub>0</sub>, такие,
что `f(n)` <= `c g(n)` выполняется для всех n, начиная с некоторого n<sub>0</sub> (n > n<sub>0</sub>). что `f(n)` <= `c g(n)` выполняется для всех n, начиная с некоторого n<sub>0</sub> (n > n<sub>0</sub>).
*Пример 1* *Пример 1*
``` ```
f(n) = 3log n + 100 f(n) = 3log n + 100
g(n) = log n g(n) = log n
``` ```
Является ли `f(n)` O(g(n))? Является ли `f(n)` O(g(n))?
Является ли `3 log n + 100` O(log n)? Является ли `3 log n + 100` O(log n)?
Посмотрим на определение О Большого: Посмотрим на определение О Большого:
``` ```
3log n + 100 <= c * log n 3log n + 100 <= c * log n
``` ```
Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>? Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>?
``` ```
3log n + 100 <= 150 * log n, n > 2 (не определенно для n = 1) 3log n + 100 <= 150 * log n, n > 2 (не определенно для n = 1)
``` ```
Да! По определению О Большого `f(n)` является O(g(n)). Да! По определению О Большого `f(n)` является O(g(n)).
*Пример 2* *Пример 2*
``` ```
f(n) = 3 * n^2 f(n) = 3 * n^2
g(n) = n g(n) = n
``` ```
Является ли `f(n)` O(g(n))? Является ли `f(n)` O(g(n))?
Является ли `3 * n^2` O(n)? Является ли `3 * n^2` O(n)?
Посмотрим на определение О Большого: Посмотрим на определение О Большого:
``` ```
3 * n^2 <= c * n 3 * n^2 <= c * n
``` ```
Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>? Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>?
Нет, не существуют. `f(n)` НЕ ЯВЛЯЕТСЯ O(g(n)). Нет, не существуют. `f(n)` НЕ ЯВЛЯЕТСЯ O(g(n)).
### Омега Большое ### Омега Большое
Омега Большое, записывается как **Ω**, — это асимптотическая запись для оценки Омега Большое, записывается как **Ω**, — это асимптотическая запись для оценки
лучшего случая, или для ограничения заданной функции снизу. Это позволяет сделать лучшего случая, или для ограничения заданной функции снизу. Это позволяет сделать
_**асимптотическую оценку нижней границы**_ скорости роста времени выполнения _**асимптотическую оценку нижней границы**_ скорости роста времени выполнения
алгоритма. алгоритма.
`f(n)` является Ω(g(n)), если существуют действительные константы `f(n)` является Ω(g(n)), если существуют действительные константы
c (c > 0) и n<sub>0</sub> (n<sub>0</sub> > 0), такие, что `f(n)` >= `c g(n)` для всех n > n<sub>0</sub>. c (c > 0) и n<sub>0</sub> (n<sub>0</sub> > 0), такие, что `f(n)` >= `c g(n)` для всех n > n<sub>0</sub>.
### Примечание ### Примечание
Асимптотические оценки, сделанные при помощи О Большого и Омега Большого, могут Асимптотические оценки, сделанные при помощи О Большого и Омега Большого, могут
как являться, так и не являться точными. Для того чтобы обозначить, что границы не как являться, так и не являться точными. Для того чтобы обозначить, что границы не
являются асимптотически точными, используются записи О Малое и Омега Малое. являются асимптотически точными, используются записи О Малое и Омега Малое.
### О Малое ### О Малое
O Малое, записывается как **о**, — это асимптотическая запись для оценки верхней O Малое, записывается как **о**, — это асимптотическая запись для оценки верхней
границы времени выполнения алгоритма при условии, что граница не является границы времени выполнения алгоритма при условии, что граница не является
асимптотически точной. асимптотически точной.
`f(n)` является o(g(n)), если можно подобрать такие действительные константы, `f(n)` является o(g(n)), если можно подобрать такие действительные константы,
что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так
что `f(n)` < `c g(n)` выполняется для всех n (n > n<sub>0</sub>). что `f(n)` < `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
Определения О-символики для О Большого и О Малого похожи. Главное отличие в том, Определения О-символики для О Большого и О Малого похожи. Главное отличие в том,
что если f(n) = O(g(n)), тогда условие f(n) <= c g(n) выполняется, если _**существует**_ что если f(n) = O(g(n)), тогда условие f(n) <= c g(n) выполняется, если _**существует**_
константа c > 0, но если f(n) = o(g(n)), тогда условие f(n) < c g(n) выполняется константа c > 0, но если f(n) = o(g(n)), тогда условие f(n) < c g(n) выполняется
для _**всех**_ констант c > 0. для _**всех**_ констант c > 0.
### Омега Малое ### Омега Малое
Омега Малое, записывается как **ω**, — это асимптотическая запись для оценки Омега Малое, записывается как **ω**, — это асимптотическая запись для оценки
верхней границы времени выполнения алгоритма при условии, что граница не является верхней границы времени выполнения алгоритма при условии, что граница не является
асимптотически точной. асимптотически точной.
`f(n)` является ω(g(n)), если можно подобрать такие действительные константы, `f(n)` является ω(g(n)), если можно подобрать такие действительные константы,
что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так
что `f(n)` > `c g(n)` выполняется для всех n (n > n<sub>0</sub>). что `f(n)` > `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
Определения Ω-символики и ω-символики похожи. Главное отличие в том, что Определения Ω-символики и ω-символики похожи. Главное отличие в том, что
если f(n) = Ω(g(n)), тогда условие f(n) >= c g(n) выполняется, если _**существует**_ если f(n) = Ω(g(n)), тогда условие f(n) >= c g(n) выполняется, если _**существует**_
константа c > 0, но если f(n) = ω(g(n)), тогда условие f(n) > c g(n) константа c > 0, но если f(n) = ω(g(n)), тогда условие f(n) > c g(n)
выполняется для _**всех**_ констант c > 0. выполняется для _**всех**_ констант c > 0.
### Тета ### Тета
Тета, записывается как **Θ**, — это асимптотическая запись для оценки Тета, записывается как **Θ**, — это асимптотическая запись для оценки
_***асимптотически точной границы***_ времени выполнения алгоритма. _***асимптотически точной границы***_ времени выполнения алгоритма.
`f(n)` является Θ(g(n)), если для некоторых действительных `f(n)` является Θ(g(n)), если для некоторых действительных
констант c1, c2 и n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0) констант c1, c2 и n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0)
`c1 g(n)` < `f(n)` < `c2 g(n)` для всех n (n > n<sub>0</sub>). `c1 g(n)` < `f(n)` < `c2 g(n)` для всех n (n > n<sub>0</sub>).
`f(n)` является Θ(g(n)) означает, что `f(n)` является O(g(n)) `f(n)` является Θ(g(n)) означает, что `f(n)` является O(g(n))
и `f(n)` является Ω(g(n)). и `f(n)` является Ω(g(n)).
О Большое — основной инструмент для анализа сложности алгоритмов. О Большое — основной инструмент для анализа сложности алгоритмов.
Также см. примеры по ссылкам. Также см. примеры по ссылкам.
### Заключение ### Заключение
Такую тему сложно изложить кратко, поэтому обязательно стоит пройти по ссылкам и Такую тему сложно изложить кратко, поэтому обязательно стоит пройти по ссылкам и
посмотреть дополнительную литературу. В ней даётся более глубокое описание с посмотреть дополнительную литературу. В ней даётся более глубокое описание с
определениями и примерами. определениями и примерами.
## Дополнительная литература ## Дополнительная литература
* [Алгоритмы на Java](https://www.ozon.ru/context/detail/id/18319699/) * [Алгоритмы на Java](https://www.ozon.ru/context/detail/id/18319699/)
* [Алгоритмы. Построение и анализ](https://www.ozon.ru/context/detail/id/33769775/) * [Алгоритмы. Построение и анализ](https://www.ozon.ru/context/detail/id/33769775/)
## Ссылки ## Ссылки
* [Оценки времени исполнения. Символ O()](http://algolist.manual.ru/misc/o_n.php) * [Оценки времени исполнения. Символ O()](http://algolist.manual.ru/misc/o_n.php)
* [Асимптотический анализ и теория вероятностей](https://www.lektorium.tv/course/22903) * [Асимптотический анализ и теория вероятностей](https://www.lektorium.tv/course/22903)
## Ссылки (англ.) ## Ссылки (англ.)
* [Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1) * [Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1)
* [Cheatsheet 1](http://web.mit.edu/broder/Public/asymptotics-cheatsheet.pdf) * [Cheatsheet 1](http://web.mit.edu/broder/Public/asymptotics-cheatsheet.pdf)
* [Cheatsheet 2](http://bigocheatsheet.com/) * [Cheatsheet 2](http://bigocheatsheet.com/)

View File

@@ -1,125 +1,125 @@
--- ---
language: SQL language: SQL
contributors: contributors:
- ["Metin Yalçınkaya", "https://github.com/mtnylnky"] - ["Metin Yalçınkaya", "https://github.com/mtnylnky"]
lang: tr-tr lang: tr-tr
filename: learnsql-tr.sql filename: learnsql-tr.sql
--- ---
```sql ```sql
-- Yorumlar iki tire ile başlar -- Yorumlar iki tire ile başlar
-- KISITLAR -- KISITLAR
Not null -- Bir kolon asla boş olamaz Not null -- Bir kolon asla boş olamaz
default -- Boş olan yerlere varsayılan bir değer atar default -- Boş olan yerlere varsayılan bir değer atar
unique -- Bir kolondaki tüm değerlerin farklı olması kısıtlaması unique -- Bir kolondaki tüm değerlerin farklı olması kısıtlaması
primary key -- Bir tablodaki her veri için kimlik bilgisi niteliğindedir primary key -- Bir tablodaki her veri için kimlik bilgisi niteliğindedir
check -- Bir kolondaki değerlerin belli bir kısıtlamayı sağlamasını sağlar check -- Bir kolondaki değerlerin belli bir kısıtlamayı sağlamasını sağlar
-- Tablo oluşturulur -- Tablo oluşturulur
CREATE TABLE tablo1 (); CREATE TABLE tablo1 ();
-- Tabloyu içerisinde kolonlar ile oluşturma -- Tabloyu içerisinde kolonlar ile oluşturma
CREATE TABLE tablo1(id INTEGER PRIMARY KEY NOT NULL UNIQUE, ad TEXT, soyad TEXT, yas INTEGER); CREATE TABLE tablo1(id INTEGER PRIMARY KEY NOT NULL UNIQUE, ad TEXT, soyad TEXT, yas INTEGER);
-- TABLO varlığını kontrol eder -- TABLO varlığını kontrol eder
.table .table
-- Veri tabanında olan bütün tabloları görüntüler. -- Veri tabanında olan bütün tabloları görüntüler.
.schema .schema
-- Satır ekle -- Satır ekle
INSERT INTO tablo1 ( ad, soyad) VALUES ("Deger1","Deger2"); INSERT INTO tablo1 ( ad, soyad) VALUES ("Deger1","Deger2");
-- Veritabanında tablo üzerindeki verileri görüntüle -- Veritabanında tablo üzerindeki verileri görüntüle
-- Sadece 'ad' gibi sınırlı bir veri için -- Sadece 'ad' gibi sınırlı bir veri için
SELECT ad FROM tablo1; SELECT ad FROM tablo1;
-- Bütün veriler için -- Bütün veriler için
SELECT * FROM tablo1; SELECT * FROM tablo1;
-- Veri güncelleme -- Veri güncelleme
UPDATE tablo1 SET ad = "deger1-2"; WHERE name = "Deger1"; UPDATE tablo1 SET ad = "deger1-2"; WHERE name = "Deger1";
-- Satır sil -- Satır sil
DELETE FROM tablo1 WHERE id = 1; DELETE FROM tablo1 WHERE id = 1;
DELETE FROM tablo1 WHERE ad = "Deger1" OR ad = "Deger2"; DELETE FROM tablo1 WHERE ad = "Deger1" OR ad = "Deger2";
-- Tabloya sonradan kolon ekleme -- Tabloya sonradan kolon ekleme
ALTER TABLE tablo1 ADD COLUMN email TEXT; ALTER TABLE tablo1 ADD COLUMN email TEXT;
-- Tablodaki kolon adı değiştirme -- Tablodaki kolon adı değiştirme
EXEC sp_rename ' tablo1.[ad]', Ad, 'COLUMN'; EXEC sp_rename ' tablo1.[ad]', Ad, 'COLUMN';
-- Tablo adı değiştirme -- Tablo adı değiştirme
ALTER TABLE table1 RENAME TO Table1; ALTER TABLE table1 RENAME TO Table1;
-- Tabloyu silme -- Tabloyu silme
DROP TABLE Table1; DROP TABLE Table1;
-- BİR TABLOYU BAŞKA TABLO KULLANARAK DOLDURMAK -- BİR TABLOYU BAŞKA TABLO KULLANARAK DOLDURMAK
INSERT INTO Tablo2 SELECT id,ad, soyad, email from Tablo1; INSERT INTO Tablo2 SELECT id,ad, soyad, email from Tablo1;
-- LIKE KOMUTU -- LIKE KOMUTU
-- Belirli bir kritere göre arama yaparken kullanılır -- Belirli bir kritere göre arama yaparken kullanılır
-- Adı 'A' ile başlayan veriler -- Adı 'A' ile başlayan veriler
SELECT * FROM tablo1 WHERE adi LIKE "A%"; SELECT * FROM tablo1 WHERE adi LIKE "A%";
-- İçinde 'A' olan veriler -- İçinde 'A' olan veriler
SELECT * FROM tablo1 WHERE adi LIKE "%A%"; SELECT * FROM tablo1 WHERE adi LIKE "%A%";
-- LIMIT KOMUTU -- LIMIT KOMUTU
-- Gösterilen satır sayısını sınırlamak için -- Gösterilen satır sayısını sınırlamak için
SELECT * FROM Tablo1 LIMIT 6; SELECT * FROM Tablo1 LIMIT 6;
-- Gösterilen satırları belirli bir noktadan başlamak üzere sınırlamak için -- Gösterilen satırları belirli bir noktadan başlamak üzere sınırlamak için
SELECT * FROM Tablo1 LIMIT 6 OFFSET 3; SELECT * FROM Tablo1 LIMIT 6 OFFSET 3;
-- ORDER BY KOMUTU -- ORDER BY KOMUTU
-- Herhangi bir kolona göre gösterilen değerleri azalan veya artan şekilde sıralamak için -- Herhangi bir kolona göre gösterilen değerleri azalan veya artan şekilde sıralamak için
SELECT kolon FROM tablo1 WHERE yas ORDER BY column1, column2, .. columnN] [ASC | DESC]; SELECT kolon FROM tablo1 WHERE yas ORDER BY column1, column2, .. columnN] [ASC | DESC];
SELECT * FROM Tablo1 ORDER BY yas ASC SELECT * FROM Tablo1 ORDER BY yas ASC
SELECT * FROM Tablo1 ORDER BY yas DESC SELECT * FROM Tablo1 ORDER BY yas DESC
-- DISTINCT ANAHTAR SÖZCÜĞÜ -- DISTINCT ANAHTAR SÖZCÜĞÜ
-- Bu anahtar sözcükle sadece farklı değerler gösterilir. -- Bu anahtar sözcükle sadece farklı değerler gösterilir.
SELECT DISTINCT yas FROM tablo1; SELECT DISTINCT yas FROM tablo1;
-- JOIN KOMUTU -- JOIN KOMUTU
-- CROSS JOIN -- CROSS JOIN
-- Cross join bir tablodaki her satırı ikinci tablodaki bir satır ile eşleştirmek için kulanılır. -- Cross join bir tablodaki her satırı ikinci tablodaki bir satır ile eşleştirmek için kulanılır.
-- Eğer birinci tabloda x satır ikinci tabloda y satır varsa sonuçta x*y satır olur. -- Eğer birinci tabloda x satır ikinci tabloda y satır varsa sonuçta x*y satır olur.
SELECT ... FROM table1 CROSS JOIN table2 SELECT ... FROM table1 CROSS JOIN table2
SELECT ad, yas FROM Tablo1 CROSS JOIN Tablo2; SELECT ad, yas FROM Tablo1 CROSS JOIN Tablo2;
-- INNER JOIN -- INNER JOIN
-- Inner join iki tablodaki ortak kolon değerlerini kullanarak bir sonuç üretir. -- Inner join iki tablodaki ortak kolon değerlerini kullanarak bir sonuç üretir.
SELECT ... FROM table1 [INNER] JOIN table2 ON conditional_expression SELECT ... FROM table1 [INNER] JOIN table2 ON conditional_expression
SELECT ad, yas FROM Tablo1 INNER JOIN Tablo2 ON Tablo1.ad = Tablo2.soyad; SELECT ad, yas FROM Tablo1 INNER JOIN Tablo2 ON Tablo1.ad = Tablo2.soyad;
-- OUTER JOIN -- OUTER JOIN
-- Outer join iki tablodaki ortak kolon değerlerinin dışında kalanları kullanarak bir sonuç üretir. -- Outer join iki tablodaki ortak kolon değerlerinin dışında kalanları kullanarak bir sonuç üretir.
SELECT isci_num, isim, dept FROM Tablo1 LEFT OUTER JOIN Tablo2 ON Tablo1.id = Tablo2.isci_num; SELECT isci_num, isim, dept FROM Tablo1 LEFT OUTER JOIN Tablo2 ON Tablo1.id = Tablo2.isci_num;
-- ÇEKİRDEK FONKSİYONLAR -- ÇEKİRDEK FONKSİYONLAR
COUNT -- Sayma COUNT -- Sayma
AVG -- Ortalama AVG -- Ortalama
ABS -- Mutlak değer ABS -- Mutlak değer
SUM -- Toplam SUM -- Toplam
RANDOM -- Rastgele RANDOM -- Rastgele
ROUND -- Yuvarlama ROUND -- Yuvarlama
MAX -- Maksimim MAX -- Maksimim
MIN -- Minimum MIN -- Minimum
UPPER -- Büyük Harf UPPER -- Büyük Harf
LOWER -- Küçük Harf LOWER -- Küçük Harf
LENGTH -- Uzunluk LENGTH -- Uzunluk
CURRENT_TIMESTAMP -- Zaman CURRENT_TIMESTAMP -- Zaman
SELECT max(yas) FROM Table1; SELECT max(yas) FROM Table1;
SELECT min(yas) FROM Table1; SELECT min(yas) FROM Table1;
SELECT avg(yas) FROM Table1; SELECT avg(yas) FROM Table1;
SELECT * From Table1 WHERE yas ==18; SELECT * From Table1 WHERE yas ==18;
SELECT sum(yas) FROM Table1; SELECT sum(yas) FROM Table1;
SELECT random() AS Random; SELECT random() AS Random;
SELECT upper(ad) FROM Table1; SELECT upper(ad) FROM Table1;
SELECT lower(ad) FROM Table1; SELECT lower(ad) FROM Table1;
SELECT ad, length(ad) FROM Table1; SELECT ad, length(ad) FROM Table1;
``` ```

View File

@@ -1,328 +1,328 @@
--- ---
category: tool category: tool
tool: git tool: git
contributors: contributors:
- ["Jake Prather", "http://github.com/JakeHP"] - ["Jake Prather", "http://github.com/JakeHP"]
- ["Vinh Nguyen", "https://twitter.com/vinhnx"] - ["Vinh Nguyen", "https://twitter.com/vinhnx"]
filename: LearnGit-vi.txt filename: LearnGit-vi.txt
lang: vi-vn lang: vi-vn
--- ---
Git là một hệ quản lý mã nguồn và phiên bản phân tán (distributed version control and source code management system). Git là một hệ quản lý mã nguồn và phiên bản phân tán (distributed version control and source code management system).
Nó làm được điều này là do một loạt các snapshot từ đề án của bạn, và nó hoạt động Nó làm được điều này là do một loạt các snapshot từ đề án của bạn, và nó hoạt động
với các snapshot đó để cung cấp cho bạn với chức năng đến phiên bản và với các snapshot đó để cung cấp cho bạn với chức năng đến phiên bản và
quản lý mã nguồn của bạn. quản lý mã nguồn của bạn.
## Khái Niệm Versioning ## Khái Niệm Versioning
### Version Control là gì? ### Version Control là gì?
Version Control là một hệ thống ghi lại những thay đổi ở một tập tin, hay một nhóm các tập tin, theo thời gian. Version Control là một hệ thống ghi lại những thay đổi ở một tập tin, hay một nhóm các tập tin, theo thời gian.
### So sánh giữa Centralized Versioning và Distributed Versioning ### So sánh giữa Centralized Versioning và Distributed Versioning
* Quản lý phiên bản tập trung (Centralized Versioning) tập trung vào việc đồng bộ hóa, theo dõi, và lưu trữ tập tin. * Quản lý phiên bản tập trung (Centralized Versioning) tập trung vào việc đồng bộ hóa, theo dõi, và lưu trữ tập tin.
* Quản lý phiên bản phân tán (Distributed Versioning) tập trung vào việc chia sẻ các thay đổi. Mỗi sự thay đổi có một mã định dạng (id) duy nhất. * Quản lý phiên bản phân tán (Distributed Versioning) tập trung vào việc chia sẻ các thay đổi. Mỗi sự thay đổi có một mã định dạng (id) duy nhất.
* Các hệ phân tán không có cấu trúc định sẵn. Bạn có thể thay đổi một kiểu SVN, hệ phân tán, với git. * Các hệ phân tán không có cấu trúc định sẵn. Bạn có thể thay đổi một kiểu SVN, hệ phân tán, với git.
[Thông tin thêm](http://git-scm.com/book/en/Getting-Started-About-Version-Control) [Thông tin thêm](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
### Tại Sao Dùng Git? ### Tại Sao Dùng Git?
* Có thể hoạt động offline. * Có thể hoạt động offline.
* Cộng tác với nhau rất dễ dàng! * Cộng tác với nhau rất dễ dàng!
* Phân nhánh dễ dàng! * Phân nhánh dễ dàng!
* Trộn (Merging) * Trộn (Merging)
* Git nhanh. * Git nhanh.
* Git linh hoạt. * Git linh hoạt.
## Kiến Trúc Git ## Kiến Trúc Git
### Repository ### Repository
Một nhóm các tập tin, thư mục, các ghi chép trong quá khứ, commit, và heads. Tưởng tượng nó như là một cấu trúc dữ liệu mã nguồn, Một nhóm các tập tin, thư mục, các ghi chép trong quá khứ, commit, và heads. Tưởng tượng nó như là một cấu trúc dữ liệu mã nguồn,
với thuộc tính mà một "nhân tố" mã nguồn cho bạn quyền truy cập đến lịch sử sửa đổi, và một số thứ khác. với thuộc tính mà một "nhân tố" mã nguồn cho bạn quyền truy cập đến lịch sử sửa đổi, và một số thứ khác.
Một git repository bao gồm thư mục .git & tree đang làm việc. Một git repository bao gồm thư mục .git & tree đang làm việc.
### Thư mục .git (thành phần của một repository) ### Thư mục .git (thành phần của một repository)
Thư mục .git chứa tất cả các cấu hình, log, nhánh, HEAD, và hơn nữa. Thư mục .git chứa tất cả các cấu hình, log, nhánh, HEAD, và hơn nữa.
[Danh Sách Chi Tiết.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html) [Danh Sách Chi Tiết.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
### Tree Đang Làm (thành phần của một repository) ### Tree Đang Làm (thành phần của một repository)
Đây cơ bản là các thư mục và tập tin trong repository của bạn. Nó thường được tham chiếu Đây cơ bản là các thư mục và tập tin trong repository của bạn. Nó thường được tham chiếu
thư mục đang làm việc của bạn thư mục đang làm việc của bạn
### Chỉ mục (thành phần của một thư mục .git) ### Chỉ mục (thành phần của một thư mục .git)
Chỉ mục của là một staging area trong git. Nó đơn giản là một lớp riêng biệt với tree đang làm việc của bạn Chỉ mục của là một staging area trong git. Nó đơn giản là một lớp riêng biệt với tree đang làm việc của bạn
từ Git repository. Điều này cho nhà phát triền nhiều lựa chọn hơn trong việc xem xét những gì được gửi đến Git từ Git repository. Điều này cho nhà phát triền nhiều lựa chọn hơn trong việc xem xét những gì được gửi đến Git
repository. repository.
### Commit ### Commit
Một git commit là một snapshot của một nhóm các thay đổi, hoặc các thao tác Working Tree của bạn. Một git commit là một snapshot của một nhóm các thay đổi, hoặc các thao tác Working Tree của bạn.
Ví dụ, nếu bạn thêm 5 tập tin, và xóa 2 tập tin khác, những thay đổi này sẽ được chứa trong Ví dụ, nếu bạn thêm 5 tập tin, và xóa 2 tập tin khác, những thay đổi này sẽ được chứa trong
một commit (hoặc snapshot). Commit này có thể được đẩy đến các repo khác, hoặc không! một commit (hoặc snapshot). Commit này có thể được đẩy đến các repo khác, hoặc không!
### Nhánh ### Nhánh
Nhánh thực chất là một con trỏ đến commit mới nhất mà bạn vừa thực hiện. Khi bạn commit, Nhánh thực chất là một con trỏ đến commit mới nhất mà bạn vừa thực hiện. Khi bạn commit,
con trỏ này sẽ cập nhật tự động và trỏ đến commit mới nhất. con trỏ này sẽ cập nhật tự động và trỏ đến commit mới nhất.
### HEAD và head (thành phần của thư mục .git) ### HEAD và head (thành phần của thư mục .git)
HEAD là một con trỏ đến branch hiện tại. Một repo chỉ có một HEAD *đang hoạt động*. HEAD là một con trỏ đến branch hiện tại. Một repo chỉ có một HEAD *đang hoạt động*.
head là một con trỏ đến bất kỳ commit nào. Một repo có thể có nhiều head. head là một con trỏ đến bất kỳ commit nào. Một repo có thể có nhiều head.
### Các Tài Nguyên Mang Tính Khái Niệm ### Các Tài Nguyên Mang Tính Khái Niệm
* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/) * [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/)
* [Git For Designers](http://hoth.entp.com/output/git_for_designers.html) * [Git For Designers](http://hoth.entp.com/output/git_for_designers.html)
## Các Lệnh ## Các Lệnh
### init ### init
Tạo một repo Git rỗng. Các cài đặt, thông tin lưu trữ... của Git Tạo một repo Git rỗng. Các cài đặt, thông tin lưu trữ... của Git
được lưu ở một thư mục tên là ".git". được lưu ở một thư mục tên là ".git".
```bash ```bash
$ git init $ git init
``` ```
### config ### config
Để chỉnh tùy chọn. Bất kể là cho repo, hay cho hệ thống, hay điều chỉnh Để chỉnh tùy chọn. Bất kể là cho repo, hay cho hệ thống, hay điều chỉnh
toàn cục (global) toàn cục (global)
```bash ```bash
# In Ra & Và Gán Một Số Biến Tùy Chỉnh Cơ Bản (Toàn cục - Global) # In Ra & Và Gán Một Số Biến Tùy Chỉnh Cơ Bản (Toàn cục - Global)
$ git config --global user.email $ git config --global user.email
$ git config --global user.name $ git config --global user.name
$ git config --global user.email "MyEmail@Zoho.com" $ git config --global user.email "MyEmail@Zoho.com"
$ git config --global user.name "My Name" $ git config --global user.name "My Name"
``` ```
[Tìm hiểu thêm về git config.](http://git-scm.com/docs/git-config) [Tìm hiểu thêm về git config.](http://git-scm.com/docs/git-config)
### help ### help
Để cho bạn lối truy cập nhanh đến một chỉ dẫn cực kỳ chi tiết của từng lệnh. Hoặc chỉ để Để cho bạn lối truy cập nhanh đến một chỉ dẫn cực kỳ chi tiết của từng lệnh. Hoặc chỉ để
nhắc bạn một số cú pháp. nhắc bạn một số cú pháp.
```bash ```bash
# Xem nhanh các lệnh có sẵn # Xem nhanh các lệnh có sẵn
$ git help $ git help
# Xem tất các các lệnh # Xem tất các các lệnh
$ git help -a $ git help -a
# Lệnh help riêng biệt - tài liệu người dùng # Lệnh help riêng biệt - tài liệu người dùng
# git help <command_here> # git help <command_here>
$ git help add $ git help add
$ git help commit $ git help commit
$ git help init $ git help init
``` ```
### status ### status
Để hiển thị sự khác nhau giữa tập tin index (cơ bản là repo đang làm việc) và HEAD commit Để hiển thị sự khác nhau giữa tập tin index (cơ bản là repo đang làm việc) và HEAD commit
hiện tại. hiện tại.
```bash ```bash
# Sẽ hiển thị nhánh, các tập tin chưa track (chưa commit), các thay đổi và những khác biệt khác # Sẽ hiển thị nhánh, các tập tin chưa track (chưa commit), các thay đổi và những khác biệt khác
$ git status $ git status
# Để xem các "tid bits" về git status # Để xem các "tid bits" về git status
$ git help status $ git help status
``` ```
### add ### add
Để thêm các tập vào tree/thư mục/repo hiện tại. Nếu bạn không `git add` các tập tin mới đến Để thêm các tập vào tree/thư mục/repo hiện tại. Nếu bạn không `git add` các tập tin mới đến
tree/thư mục hiện tại, chúng sẽ không được kèm theo trong các commit! tree/thư mục hiện tại, chúng sẽ không được kèm theo trong các commit!
```bash ```bash
# thêm một file vào thư mục hiện tại # thêm một file vào thư mục hiện tại
$ git add HelloWorld.java $ git add HelloWorld.java
# thêm một file vào một thư mục khác # thêm một file vào một thư mục khác
$ git add /path/to/file/HelloWorld.c $ git add /path/to/file/HelloWorld.c
# Hỗ trợ Regular Expression! # Hỗ trợ Regular Expression!
$ git add ./*.java $ git add ./*.java
``` ```
### branch ### branch
Quản lý nhánh (branch). Bạn có thể xem, sửa, tạo, xóa các nhánh bằng cách dùng lệnh này. Quản lý nhánh (branch). Bạn có thể xem, sửa, tạo, xóa các nhánh bằng cách dùng lệnh này.
```bash ```bash
# liệt kê các branch đang có và ở remote # liệt kê các branch đang có và ở remote
$ git branch -a $ git branch -a
# tạo branch mới # tạo branch mới
$ git branch myNewBranch $ git branch myNewBranch
# xóa một branch # xóa một branch
$ git branch -d myBranch $ git branch -d myBranch
# đặt tên lại một branch # đặt tên lại một branch
# git branch -m <oldname> <newname> # git branch -m <oldname> <newname>
$ git branch -m myBranchName myNewBranchName $ git branch -m myBranchName myNewBranchName
# chỉnh sửa diễn giải của một branch # chỉnh sửa diễn giải của một branch
$ git branch myBranchName --edit-description $ git branch myBranchName --edit-description
``` ```
### checkout ### checkout
Cập nhật tất cả các file trong tree hiện tại để cho trùng khớp với phiên bản của index, hoặc tree cụ thể. Cập nhật tất cả các file trong tree hiện tại để cho trùng khớp với phiên bản của index, hoặc tree cụ thể.
```bash ```bash
# Checkout (chuyển) một repo - mặc định là nhánh master # Checkout (chuyển) một repo - mặc định là nhánh master
$ git checkout $ git checkout
# Checkout một nhánh cụ thể # Checkout một nhánh cụ thể
$ git checkout branchName $ git checkout branchName
# Tạo một nhánh mới và chuyển đến nó, tương tự: "git branch <name>; git checkout <name>" # Tạo một nhánh mới và chuyển đến nó, tương tự: "git branch <name>; git checkout <name>"
$ git checkout -b newBranch $ git checkout -b newBranch
``` ```
### clone ### clone
Nhân bản, hoặc sao chép, một repo hiện có thành một thư mục mới. Nó cũng thêm Nhân bản, hoặc sao chép, một repo hiện có thành một thư mục mới. Nó cũng thêm
các branch có remote-tracking cho mỗi branch trong một repo được nhân bản, mà các branch có remote-tracking cho mỗi branch trong một repo được nhân bản, mà
cho phép bạn push đến một remote branch. cho phép bạn push đến một remote branch.
```bash ```bash
# Nhân bản learnxinyminutes-docs # Nhân bản learnxinyminutes-docs
$ git clone https://github.com/adambard/learnxinyminutes-docs.git $ git clone https://github.com/adambard/learnxinyminutes-docs.git
``` ```
### commit ### commit
Lưu trữ nội dung hiện tại của index trong một "commit" mới. Điều này cho phép tạo ra thay đổi và một ghi chú tạo ra bởi người dùng. Lưu trữ nội dung hiện tại của index trong một "commit" mới. Điều này cho phép tạo ra thay đổi và một ghi chú tạo ra bởi người dùng.
```bash ```bash
# commit với một ghi chú # commit với một ghi chú
$ git commit -m "Added multiplyNumbers() function to HelloWorld.c" $ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
``` ```
### diff ### diff
Hiển thị sự khác biệt giữa một file trong thư mục hiện tại, index và commits. Hiển thị sự khác biệt giữa một file trong thư mục hiện tại, index và commits.
```bash ```bash
# Hiển thị sự khác biệt giữa thư mục hiện tại và index # Hiển thị sự khác biệt giữa thư mục hiện tại và index
$ git diff $ git diff
# Hiển thị khác biệt giữa index và commit mới nhất. # Hiển thị khác biệt giữa index và commit mới nhất.
$ git diff --cached $ git diff --cached
# Hiển thị khác biệt giữa thư mục đang làm việc và commit mới nhất # Hiển thị khác biệt giữa thư mục đang làm việc và commit mới nhất
$ git diff HEAD $ git diff HEAD
``` ```
### grep ### grep
Cho phép bạn tìm kiếm nhanh một repo. Cho phép bạn tìm kiếm nhanh một repo.
Các tinh chỉnh tùy chọn: Các tinh chỉnh tùy chọn:
```bash ```bash
# Cảm ơn Travis Jeffery vì những lệnh này # Cảm ơn Travis Jeffery vì những lệnh này
# Đặt số của dòng được hiển thị trong kết quả tìm kiếm grep # Đặt số của dòng được hiển thị trong kết quả tìm kiếm grep
$ git config --global grep.lineNumber true $ git config --global grep.lineNumber true
# Làm cho kết quả tìm kiếm dễ đọc hơn, bao gồm cả gom nhóm # Làm cho kết quả tìm kiếm dễ đọc hơn, bao gồm cả gom nhóm
$ git config --global alias.g "grep --break --heading --line-number" $ git config --global alias.g "grep --break --heading --line-number"
``` ```
```bash ```bash
# Tìm "variableName" trong tất cả các file Java # Tìm "variableName" trong tất cả các file Java
$ git grep 'variableName' -- '*.java' $ git grep 'variableName' -- '*.java'
# Tìm một dòng mà có chứa "arrayListName" và, "add" hoặc "remove" # Tìm một dòng mà có chứa "arrayListName" và, "add" hoặc "remove"
$ git grep -e 'arrayListName' --and \( -e add -e remove \) $ git grep -e 'arrayListName' --and \( -e add -e remove \)
``` ```
Google để xem thêm các ví dụ Google để xem thêm các ví dụ
[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja) [Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
### log ### log
Hiển thị các commit đến repo. Hiển thị các commit đến repo.
```bash ```bash
# Hiện tất cả các commit # Hiện tất cả các commit
$ git log $ git log
# Hiện X commit # Hiện X commit
$ git log -n 10 $ git log -n 10
# Chỉ hiện các commit đã merge merge commits # Chỉ hiện các commit đã merge merge commits
$ git log --merges $ git log --merges
``` ```
### merge ### merge
"Trộn" các thay đổi từ commit bên ngoài vào trong nhánh hiện tại. "Trộn" các thay đổi từ commit bên ngoài vào trong nhánh hiện tại.
```bash ```bash
# Merge branch cụ thể vào branch hiện tại. # Merge branch cụ thể vào branch hiện tại.
$ git merge branchName $ git merge branchName
# Luôn khởi tạo một merge commit khi trộn (merge) # Luôn khởi tạo một merge commit khi trộn (merge)
$ git merge --no-ff branchName $ git merge --no-ff branchName
``` ```
### mv ### mv
Đặt lại tên hoặc di chuyển một file Đặt lại tên hoặc di chuyển một file
```bash ```bash
# Đặt lại tên một file # Đặt lại tên một file
$ git mv HelloWorld.c HelloNewWorld.c $ git mv HelloWorld.c HelloNewWorld.c
# Di chuyển một file # Di chuyển một file
$ git mv HelloWorld.c ./new/path/HelloWorld.c $ git mv HelloWorld.c ./new/path/HelloWorld.c
# Buộc đặt lại tên hoặc di chuyển # Buộc đặt lại tên hoặc di chuyển
# "existingFile" đã tồn tại trong thự mục, sẽ bị ghi đè # "existingFile" đã tồn tại trong thự mục, sẽ bị ghi đè
$ git mv -f myFile existingFile $ git mv -f myFile existingFile
``` ```
### pull ### pull
Pull về từ một repo và merge nó vào branch khác. Pull về từ một repo và merge nó vào branch khác.
```bash ```bash
# Cập nhật repo local của bạn, bằng cách merge các thay đổi mới # Cập nhật repo local của bạn, bằng cách merge các thay đổi mới
# từ remote "origin" và nhánh "master". # từ remote "origin" và nhánh "master".
# git pull <remote> <branch> # git pull <remote> <branch>
# git pull => hoàn toàn mặc định như => git pull origin master # git pull => hoàn toàn mặc định như => git pull origin master
$ git pull origin master $ git pull origin master
# Merge các thay đổi từ remote branch và rebase # Merge các thay đổi từ remote branch và rebase
# các commit trong branch lên trên local repo, như sau: "git pull <remote> <branch>, git rebase <branch>" # các commit trong branch lên trên local repo, như sau: "git pull <remote> <branch>, git rebase <branch>"
$ git pull origin master --rebase $ git pull origin master --rebase
``` ```
### push ### push
push và merge các thay đổi từ một branch đến một remote & branch. push và merge các thay đổi từ một branch đến một remote & branch.
```bash ```bash
# Push và merge các thay đổi từ một repo local đến một # Push và merge các thay đổi từ một repo local đến một
# remote có tên là "origin" và nhánh "master". # remote có tên là "origin" và nhánh "master".
@@ -334,68 +334,68 @@ $ git push origin master
$ git push -u origin master $ git push -u origin master
# Từ lúc này, bất cứ khi nào bạn muốn push từ cùng một nhánh local đó, sử dụng lối tắt: # Từ lúc này, bất cứ khi nào bạn muốn push từ cùng một nhánh local đó, sử dụng lối tắt:
$ git push $ git push
``` ```
### rebase (thận trọng) ### rebase (thận trọng)
Lấy tất cả các thay đổi mà đã được commit trên một nhánh, và replay (?) chúng trên một nhánh khác. Lấy tất cả các thay đổi mà đã được commit trên một nhánh, và replay (?) chúng trên một nhánh khác.
*Không rebase các commit mà bạn đã push đến một repo công khai*. *Không rebase các commit mà bạn đã push đến một repo công khai*.
```bash ```bash
# Rebase experimentBranch lên master # Rebase experimentBranch lên master
# git rebase <basebranch> <topicbranch> # git rebase <basebranch> <topicbranch>
$ git rebase master experimentBranch $ git rebase master experimentBranch
``` ```
[Đọc Thêm.](http://git-scm.com/book/en/Git-Branching-Rebasing) [Đọc Thêm.](http://git-scm.com/book/en/Git-Branching-Rebasing)
### reset (thận trọng) ### reset (thận trọng)
Thiết lập lạo HEAD hiện tại đến một trạng thái cụ thể. Điều này cho phép bạn làm lại các merges, Thiết lập lạo HEAD hiện tại đến một trạng thái cụ thể. Điều này cho phép bạn làm lại các merges,
pulls, commits, thêm, and hơn nữa. Nó là một lệnh hay nhưng cũng nguy hiểm nếu bạn không pulls, commits, thêm, and hơn nữa. Nó là một lệnh hay nhưng cũng nguy hiểm nếu bạn không
biết mình đang làm gì. biết mình đang làm gì.
```bash ```bash
# Thiết lập lại staging area, để trùng với commit mới nhất (để thư mục không thay đổi) # Thiết lập lại staging area, để trùng với commit mới nhất (để thư mục không thay đổi)
$ git reset $ git reset
# Thiết lập lại staging area, để trùng với commit mới nhất, và ghi đè lên thư mục hiện tại # Thiết lập lại staging area, để trùng với commit mới nhất, và ghi đè lên thư mục hiện tại
$ git reset --hard $ git reset --hard
# Di chuyển nhánh hiện tại đến một commit cụ thể (để thư mục không thay đổi) # Di chuyển nhánh hiện tại đến một commit cụ thể (để thư mục không thay đổi)
# tất cả thay đổi vẫn duy trì trong thư mục. # tất cả thay đổi vẫn duy trì trong thư mục.
$ git reset 31f2bb1 $ git reset 31f2bb1
# Di chuyển nhánh hiện tại lùi về một commit cụ thể # Di chuyển nhánh hiện tại lùi về một commit cụ thể
# và làm cho thư mục hiện tại trùng (xóa các thay đổi chưa được commit và tất cả các commit # và làm cho thư mục hiện tại trùng (xóa các thay đổi chưa được commit và tất cả các commit
# sau một commit cụ thể). # sau một commit cụ thể).
$ git reset --hard 31f2bb1 $ git reset --hard 31f2bb1
``` ```
### rm ### rm
Ngược lại với git add, git rm xóa file từ tree đang làm việc. Ngược lại với git add, git rm xóa file từ tree đang làm việc.
```bash ```bash
# xóa HelloWorld.c # xóa HelloWorld.c
$ git rm HelloWorld.c $ git rm HelloWorld.c
# Xóa file từ thư mục khác # Xóa file từ thư mục khác
$ git rm /pather/to/the/file/HelloWorld.c $ git rm /pather/to/the/file/HelloWorld.c
``` ```
## Thông tin thêm ## Thông tin thêm
* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1) * [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
* [git-scm - Video Tutorials](http://git-scm.com/videos) * [git-scm - Video Tutorials](http://git-scm.com/videos)
* [git-scm - Documentation](http://git-scm.com/docs) * [git-scm - Documentation](http://git-scm.com/docs)
* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/) * [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/)
* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf) * [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
* [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html) * [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html)

View File

@@ -1,316 +1,316 @@
--- ---
language: Objective-C language: Objective-C
contributors: contributors:
- ["Eugene Yagrushkin", "www.about.me/yagrushkin"] - ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
- ["Yannick Loriot", "https://github.com/YannickL"] - ["Yannick Loriot", "https://github.com/YannickL"]
lang: vi-vn lang: vi-vn
filename: LearnObjectiveC-vi.m filename: LearnObjectiveC-vi.m
--- ---
Objective-C ngôn ngữ lập trình chính đưc sử dụng bởi Apple cho các hệ điều hành macOS, iOS các framework tương ng của họ, Cocoa Cocoa Touch. Objective-C ngôn ngữ lập trình chính đưc sử dụng bởi Apple cho các hệ điều hành macOS, iOS các framework tương ng của họ, Cocoa Cocoa Touch.
một ngôn ngữ lập trình mục đích tổng quát, hướng đi tượng bổ sung thêm kiểu truyền thông điệp giống Smalltalk vào ngôn ngữ lập trình C. một ngôn ngữ lập trình mục đích tổng quát, hướng đi tượng bổ sung thêm kiểu truyền thông điệp giống Smalltalk vào ngôn ngữ lập trình C.
```objective-c ```objective-c
// Chú thích dòng đơn bắt đầu với // // Chú thích dòng đơn bắt đầu với //
/* /*
Chú thích đa dòng trông như thế này. Chú thích đa dòng trông như thế này.
*/ */
// Nhập các headers của framework Foundation với cú pháp #import // Nhập các headers của framework Foundation với cú pháp #import
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "MyClass.h" #import "MyClass.h"
// Đầu vào chương trình của bạn là một hàm gọi là // Đầu vào chương trình của bạn là một hàm gọi là
// main với một kiểu trả về kiểu integer. // main với một kiểu trả về kiểu integer.
int main (int argc, const char * argv[]) int main (int argc, const char * argv[])
{ {
// Tạo một autorelease pool để quản lý bộ nhớ vào chương trình // Tạo một autorelease pool để quản lý bộ nhớ vào chương trình
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// Sử dụng hàm NSLog() để in ra các dòng lệnh vào console // Sử dụng hàm NSLog() để in ra các dòng lệnh vào console
NSLog(@"Hello World!"); // Print the string "Hello World!" NSLog(@"Hello World!"); // Print the string "Hello World!"
/////////////////////////////////////// ///////////////////////////////////////
// Kiểu & Biến (Types & Variables) // Kiểu & Biến (Types & Variables)
/////////////////////////////////////// ///////////////////////////////////////
// Khai báo số nguyên // Khai báo số nguyên
int myPrimitive1 = 1; int myPrimitive1 = 1;
long myPrimitive2 = 234554664565; long myPrimitive2 = 234554664565;
// Khai báo đối tượng // Khai báo đối tượng
// Đặt dấu nháy * vào trước tên biến cho khai báo đối tượng strong // Đặt dấu nháy * vào trước tên biến cho khai báo đối tượng strong
MyClass *myObject1 = nil; // Strong MyClass *myObject1 = nil; // Strong
id myObject2 = nil; // Weak id myObject2 = nil; // Weak
// %@ là một đối tượng // %@ là một đối tượng
// 'miêu tả' ('desciption') là thông lệ để trình bày giá trị của các Đối tượng // 'miêu tả' ('desciption') là thông lệ để trình bày giá trị của các Đối tượng
NSLog(@"%@ và %@", myObject1, [myObject2 description]); // In ra "(null) và (null)" NSLog(@"%@ và %@", myObject1, [myObject2 description]); // In ra "(null) và (null)"
// Chuỗi // Chuỗi
NSString *worldString = @"World"; NSString *worldString = @"World";
NSLog(@"Hello %@!", worldString); // In ra "Hello World!" NSLog(@"Hello %@!", worldString); // In ra "Hello World!"
// Ký tự literals // Ký tự literals
NSNumber *theLetterZNumber = @'Z'; NSNumber *theLetterZNumber = @'Z';
char theLetterZ = [theLetterZNumber charValue]; char theLetterZ = [theLetterZNumber charValue];
NSLog(@"%c", theLetterZ); NSLog(@"%c", theLetterZ);
// Số nguyên literals // Số nguyên literals
NSNumber *fortyTwoNumber = @42; NSNumber *fortyTwoNumber = @42;
int fortyTwo = [fortyTwoNumber intValue]; int fortyTwo = [fortyTwoNumber intValue];
NSLog(@"%i", fortyTwo); NSLog(@"%i", fortyTwo);
NSNumber *fortyTwoUnsignedNumber = @42U; NSNumber *fortyTwoUnsignedNumber = @42U;
unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue]; unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
NSLog(@"%u", fortyTwoUnsigned); NSLog(@"%u", fortyTwoUnsigned);
NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42]; NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
short fortyTwoShort = [fortyTwoShortNumber shortValue]; short fortyTwoShort = [fortyTwoShortNumber shortValue];
NSLog(@"%hi", fortyTwoShort); NSLog(@"%hi", fortyTwoShort);
NSNumber *fortyTwoLongNumber = @42L; NSNumber *fortyTwoLongNumber = @42L;
long fortyTwoLong = [fortyTwoLongNumber longValue]; long fortyTwoLong = [fortyTwoLongNumber longValue];
NSLog(@"%li", fortyTwoLong); NSLog(@"%li", fortyTwoLong);
// Dấu phẩy động (floating point) literals // Dấu phẩy động (floating point) literals
NSNumber *piFloatNumber = @3.141592654F; NSNumber *piFloatNumber = @3.141592654F;
float piFloat = [piFloatNumber floatValue]; float piFloat = [piFloatNumber floatValue];
NSLog(@"%f", piFloat); NSLog(@"%f", piFloat);
NSNumber *piDoubleNumber = @3.1415926535; NSNumber *piDoubleNumber = @3.1415926535;
double piDouble = [piDoubleNumber doubleValue]; double piDouble = [piDoubleNumber doubleValue];
NSLog(@"%f", piDouble); NSLog(@"%f", piDouble);
// BOOL literals // BOOL literals
NSNumber *yesNumber = @YES; NSNumber *yesNumber = @YES;
NSNumber *noNumber = @NO; NSNumber *noNumber = @NO;
// Đối tượng Mảng // Đối tượng Mảng
NSArray *anArray = @[@1, @2, @3, @4]; NSArray *anArray = @[@1, @2, @3, @4];
NSNumber *thirdNumber = anArray[2]; NSNumber *thirdNumber = anArray[2];
NSLog(@"Third number = %@", thirdNumber); // In ra "Third number = 3" NSLog(@"Third number = %@", thirdNumber); // In ra "Third number = 3"
// Đối tượng Từ điển // Đối tượng Từ điển
NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" }; NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
NSObject *valueObject = aDictionary[@"A Key"]; NSObject *valueObject = aDictionary[@"A Key"];
NSLog(@"Đối tượng = %@", valueObject); // In ra "Object = (null)" NSLog(@"Đối tượng = %@", valueObject); // In ra "Object = (null)"
/////////////////////////////////////// ///////////////////////////////////////
// Toán Tử (Operators) // Toán Tử (Operators)
/////////////////////////////////////// ///////////////////////////////////////
// Các toán tử cũng hoạt động giống như ngôn ngữ C // Các toán tử cũng hoạt động giống như ngôn ngữ C
// Ví dụ: // Ví dụ:
2 + 5; // => 7 2 + 5; // => 7
4.2f + 5.1f; // => 9.3f 4.2f + 5.1f; // => 9.3f
3 == 2; // => 0 (NO) 3 == 2; // => 0 (NO)
3 != 2; // => 1 (YES) 3 != 2; // => 1 (YES)
1 && 1; // => 1 (Logical and) 1 && 1; // => 1 (Logical and)
0 || 1; // => 1 (Logical or) 0 || 1; // => 1 (Logical or)
~0x0F; // => 0xF0 (bitwise negation) ~0x0F; // => 0xF0 (bitwise negation)
0x0F & 0xF0; // => 0x00 (bitwise AND) 0x0F & 0xF0; // => 0x00 (bitwise AND)
0x01 << 1; // => 0x02 (bitwise dịch trái (bởi 1)) 0x01 << 1; // => 0x02 (bitwise dịch trái (bởi 1))
///////////////////////////////////////////// /////////////////////////////////////////////
// Cấu Trúc Điều Khiển (Controls Structures) // Cấu Trúc Điều Khiển (Controls Structures)
///////////////////////////////////////////// /////////////////////////////////////////////
// Câu lệnh If-Else // Câu lệnh If-Else
if (NO) if (NO)
{ {
NSLog(@"I am never run"); NSLog(@"I am never run");
} else if (0) } else if (0)
{ {
NSLog(@"I am also never run"); NSLog(@"I am also never run");
} else } else
{ {
NSLog(@"I print"); NSLog(@"I print");
} }
// Câu lệnh Switch // Câu lệnh Switch
switch (2) switch (2)
{ {
case 0: case 0:
{ {
NSLog(@"I am never run"); NSLog(@"I am never run");
} break; } break;
case 1: case 1:
{ {
NSLog(@"I am also never run"); NSLog(@"I am also never run");
} break; } break;
default: default:
{ {
NSLog(@"I print"); NSLog(@"I print");
} break; } break;
} }
// Câu lệnh vòng lặp While // Câu lệnh vòng lặp While
int ii = 0; int ii = 0;
while (ii < 4) while (ii < 4)
{ {
NSLog(@"%d,", ii++); // ii++ tăng dần, sau khi sử dụng giá trị của nó. NSLog(@"%d,", ii++); // ii++ tăng dần, sau khi sử dụng giá trị của nó.
} // => in ra "0," } // => in ra "0,"
// "1," // "1,"
// "2," // "2,"
// "3," // "3,"
// Câu lệnh vòng lặp For // Câu lệnh vòng lặp For
int jj; int jj;
for (jj=0; jj < 4; jj++) for (jj=0; jj < 4; jj++)
{ {
NSLog(@"%d,", jj); NSLog(@"%d,", jj);
} // => in ra "0," } // => in ra "0,"
// "1," // "1,"
// "2," // "2,"
// "3," // "3,"
// Câu lệnh Foreach // Câu lệnh Foreach
NSArray *values = @[@0, @1, @2, @3]; NSArray *values = @[@0, @1, @2, @3];
for (NSNumber *value in values) for (NSNumber *value in values)
{ {
NSLog(@"%@,", value); NSLog(@"%@,", value);
} // => in ra "0," } // => in ra "0,"
// "1," // "1,"
// "2," // "2,"
// "3," // "3,"
// Câu lệnh Try-Catch-Finally // Câu lệnh Try-Catch-Finally
@try @try
{ {
// Your statements here // Your statements here
@throw [NSException exceptionWithName:@"FileNotFoundException" @throw [NSException exceptionWithName:@"FileNotFoundException"
reason:@"Không Tìm Thấy Tập Tin trên Hệ Thống" userInfo:nil]; reason:@"Không Tìm Thấy Tập Tin trên Hệ Thống" userInfo:nil];
} @catch (NSException * e) } @catch (NSException * e)
{ {
NSLog(@"Exception: %@", e); NSLog(@"Exception: %@", e);
} @finally } @finally
{ {
NSLog(@"Finally"); NSLog(@"Finally");
} // => in ra "Exception: Không Tìm Thấy Tập Tin trên Hệ Thống" } // => in ra "Exception: Không Tìm Thấy Tập Tin trên Hệ Thống"
// "Finally" // "Finally"
/////////////////////////////////////// ///////////////////////////////////////
// Đối Tượng (Objects) // Đối Tượng (Objects)
/////////////////////////////////////// ///////////////////////////////////////
// Tạo một thực thể đối tượng bằng cách phân vùng nhớ và khởi tạo đối tượng đó. // Tạo một thực thể đối tượng bằng cách phân vùng nhớ và khởi tạo đối tượng đó.
// Một đối tượng sẽ không thật sự hoạt động cho đến khi cả 2 bước alloc] init] được hoàn thành // Một đối tượng sẽ không thật sự hoạt động cho đến khi cả 2 bước alloc] init] được hoàn thành
MyClass *myObject = [[MyClass alloc] init]; MyClass *myObject = [[MyClass alloc] init];
// Mô hình lập trình hướng đối tượng của Objective-C dựa trên việc truyền thông điệp (message) // Mô hình lập trình hướng đối tượng của Objective-C dựa trên việc truyền thông điệp (message)
// và các thực thể đối tượng với nhau. // và các thực thể đối tượng với nhau.
// Trong Objective-C một đối tượng không đơn thuần gọi phương thức; nó truyền thông điệp. // Trong Objective-C một đối tượng không đơn thuần gọi phương thức; nó truyền thông điệp.
[myObject instanceMethodWithParameter:@"Steve Jobs"]; [myObject instanceMethodWithParameter:@"Steve Jobs"];
// Dọn dẹp vùng nhớ mà bạn đã dùng ở chương trình // Dọn dẹp vùng nhớ mà bạn đã dùng ở chương trình
[pool drain]; [pool drain];
// Kết thúc chương trình // Kết thúc chương trình
return 0; return 0;
} }
/////////////////////////////////////// ///////////////////////////////////////
// Lớp và Hàm (Classes & Functions) // Lớp và Hàm (Classes & Functions)
/////////////////////////////////////// ///////////////////////////////////////
// Khai báo lớp của bạn ở một tập tin header (MyClass.h): // Khai báo lớp của bạn ở một tập tin header (MyClass.h):
// Cú pháp Khai Báo Lớp: // Cú pháp Khai Báo Lớp:
// @interface ClassName : ParentClassName <ImplementedProtocols> // @interface ClassName : ParentClassName <ImplementedProtocols>
// { // {
// Khai báo biến thành viên; // Khai báo biến thành viên;
// } // }
// -/+ (type) Khai báo method; // -/+ (type) Khai báo method;
// @end // @end
@interface MyClass : NSObject <MyProtocol> @interface MyClass : NSObject <MyProtocol>
{ {
int count; int count;
id data; id data;
NSString *name; NSString *name;
} }
// Ký hiệu (notation) tiện ích để tự động khởi tạo public getter và setter // Ký hiệu (notation) tiện ích để tự động khởi tạo public getter và setter
@property int count; @property int count;
@property (copy) NSString *name; // Sao chép đối tượng trong quá trình gán. @property (copy) NSString *name; // Sao chép đối tượng trong quá trình gán.
@property (readonly) id data; // Chỉ khai báo phương thức getter. @property (readonly) id data; // Chỉ khai báo phương thức getter.
// Phương thức // Phương thức
+/- (return type)methodSignature:(Parameter Type *)parameterName; +/- (return type)methodSignature:(Parameter Type *)parameterName;
// dấu '+' cho phương thức lớp // dấu '+' cho phương thức lớp
+ (NSString *)classMethod; + (NSString *)classMethod;
// dấu '-' cho phương thức thực thể // dấu '-' cho phương thức thực thể
- (NSString *)instanceMethodWithParameter:(NSString *)string; - (NSString *)instanceMethodWithParameter:(NSString *)string;
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number; - (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
@end @end
// Thực thi các phương thức trong một tập tin thực thi (MyClass.m): // Thực thi các phương thức trong một tập tin thực thi (MyClass.m):
@implementation MyClass @implementation MyClass
// Gọi khi đối tượng được release // Gọi khi đối tượng được release
- (void)dealloc - (void)dealloc
{ {
} }
// Phương thức khởi tạo (Constructors) là một cách để tạo các lớp // Phương thức khởi tạo (Constructors) là một cách để tạo các lớp
// Đây là phương thức khởi tạo mặc định được gọi khi đối tượng được khởi tạo // Đây là phương thức khởi tạo mặc định được gọi khi đối tượng được khởi tạo
- (id)init - (id)init
{ {
if ((self = [super init])) if ((self = [super init]))
{ {
self.count = 1; self.count = 1;
} }
return self; return self;
} }
+ (NSString *)classMethod + (NSString *)classMethod
{ {
return [[self alloc] init]; return [[self alloc] init];
} }
- (NSString *)instanceMethodWithParameter:(NSString *)string - (NSString *)instanceMethodWithParameter:(NSString *)string
{ {
return @"New string"; return @"New string";
} }
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number - (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
{ {
return @42; return @42;
} }
// Các phương thức được khai báo vào MyProtocol // Các phương thức được khai báo vào MyProtocol
- (void)myProtocolMethod - (void)myProtocolMethod
{ {
// câu lệnh // câu lệnh
} }
@end @end
/* /*
* Một protocol khai báo các phương thức mà có thể thực thi bởi bất kỳ lớp nào. * Một protocol khai báo các phương thức mà có thể thực thi bởi bất kỳ lớp nào.
* Các protocol chính chúng không phải là các lớp. Chúng chỉ đơn giản là định ra giao diện (interface) * Các protocol chính chúng không phải là các lớp. Chúng chỉ đơn giản là định ra giao diện (interface)
* mà các đối tượng khác có trách nhiệm sẽ thực thi. * mà các đối tượng khác có trách nhiệm sẽ thực thi.
*/ */
@protocol MyProtocol @protocol MyProtocol
- (void)myProtocolMethod; - (void)myProtocolMethod;
@end @end
``` ```
## Xem Thêm ## Xem Thêm
+ [Wikipedia Objective-C](http://en.wikipedia.org/wiki/Objective-C) + [Wikipedia Objective-C](http://en.wikipedia.org/wiki/Objective-C)
+ Apple Docs': + Apple Docs':
+ [Learning Objective-C](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/) + [Learning Objective-C](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/)
+ [Programming With Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html) + [Programming With Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html)
+ [Object-Oriented Programming with Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005149) + [Object-Oriented Programming with Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005149)
+ [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html) + [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)
+ [iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started) + [iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started)

File diff suppressed because it is too large Load Diff

View File

@@ -1,345 +1,345 @@
--- ---
language: elisp language: elisp
contributors: contributors:
- ["Bastien Guerry", "http://bzg.fr"] - ["Bastien Guerry", "http://bzg.fr"]
translators: translators:
- ["Chenbo Li", "http://binarythink.net"] - ["Chenbo Li", "http://binarythink.net"]
filename: learn-emacs-lisp-zh.el filename: learn-emacs-lisp-zh.el
lang: zh-cn lang: zh-cn
--- ---
```scheme ```scheme
;; 15分钟学会Emacs Lisp (v0.2a) ;; 15分钟学会Emacs Lisp (v0.2a)
;;作者bzghttps://github.com/bzg ;;作者bzghttps://github.com/bzg
;; 译者lichenbohttp://douban.com/people/lichenbo ;; 译者lichenbohttp://douban.com/people/lichenbo
;; ;;
;; 请先阅读Peter Norvig的一篇好文: ;; 请先阅读Peter Norvig的一篇好文:
;; http://norvig.com/21-days.html ;; http://norvig.com/21-days.html
;; 译者注中文版请见http://blog.youxu.info/21-days/ ;; 译者注中文版请见http://blog.youxu.info/21-days/
;; ;;
;; 之后安装GNU Emacs 24.3: ;; 之后安装GNU Emacs 24.3:
;; ;;
;; Debian: apt-get install emacs (视具体发行版而定) ;; Debian: apt-get install emacs (视具体发行版而定)
;; MacOSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg ;; MacOSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg
;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip ;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip
;; ;;
;; 更多信息可以在这里找到: ;; 更多信息可以在这里找到:
;; http://www.gnu.org/software/emacs/#Obtaining ;; http://www.gnu.org/software/emacs/#Obtaining
;; 很重要的警告: ;; 很重要的警告:
;; ;;
;; 按照这个教程来学习并不会对你的电脑有任何损坏 ;; 按照这个教程来学习并不会对你的电脑有任何损坏
;; 除非你自己在学习的过程中愤怒地把它砸了 ;; 除非你自己在学习的过程中愤怒地把它砸了
;; 如果出现了这种情况,我不会承担任何责任 ;; 如果出现了这种情况,我不会承担任何责任
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 打开emacs ;; 打开emacs
;; ;;
;; 按'q'消除欢迎界面 ;; 按'q'消除欢迎界面
;; ;;
;; 现在请注意窗口底部的那一个灰色长条 ;; 现在请注意窗口底部的那一个灰色长条
;; ;;
;; "*scratch*" 是你现在编辑界面的名字。 ;; "*scratch*" 是你现在编辑界面的名字。
;; 这个编辑界面叫做一个"buffer"。 ;; 这个编辑界面叫做一个"buffer"。
;; ;;
;; 每当你打开Emacs时都会默认打开这个scratch buffer ;; 每当你打开Emacs时都会默认打开这个scratch buffer
;; 此时你并没有在编辑任何文件而是在编辑一个buffer ;; 此时你并没有在编辑任何文件而是在编辑一个buffer
;; 之后你可以将这个buffer保存到一个文件中。 ;; 之后你可以将这个buffer保存到一个文件中。
;; ;;
;; 之后的"Lisp interaction" 则是表明我们可以用的某组命令 ;; 之后的"Lisp interaction" 则是表明我们可以用的某组命令
;; ;;
;; Emacs在每个buffer中都有一组内置的命令 ;; Emacs在每个buffer中都有一组内置的命令
;; 而当你激活某种特定的模式时,就可以使用相应的命令 ;; 而当你激活某种特定的模式时,就可以使用相应的命令
;; 这里我们使用`lisp-interaction-mode' ;; 这里我们使用`lisp-interaction-mode'
;; 这样我们就可以使用内置的Emacs Lisp以下简称Elisp命令了。 ;; 这样我们就可以使用内置的Emacs Lisp以下简称Elisp命令了。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 分号是注释开始的标志 ;; 分号是注释开始的标志
;; ;;
;; Elisp 是由符号表达式构成的 (即"s-表达式"或"s式"): ;; Elisp 是由符号表达式构成的 (即"s-表达式"或"s式"):
(+ 2 2) (+ 2 2)
;; 这个s式的意思是 "对2进行加2操作". ;; 这个s式的意思是 "对2进行加2操作".
;; s式周围有括号而且也可以嵌套: ;; s式周围有括号而且也可以嵌套:
(+ 2 (+ 1 1)) (+ 2 (+ 1 1))
;; 一个s式可以包含原子符号或者其他s式 ;; 一个s式可以包含原子符号或者其他s式
;; 在上面的例子中1和2是原子符号 ;; 在上面的例子中1和2是原子符号
;; (+ 2 (+ 1 1)) 和 (+ 1 1) 是s式. ;; (+ 2 (+ 1 1)) 和 (+ 1 1) 是s式.
;; 在 `lisp-interaction-mode' 中你可以计算s式. ;; 在 `lisp-interaction-mode' 中你可以计算s式.
;; 把光标移到闭括号后之后按下ctrl+j以后简写为'C-j' ;; 把光标移到闭括号后之后按下ctrl+j以后简写为'C-j'
(+ 3 (+ 1 2)) (+ 3 (+ 1 2))
;; ^ 光标放到这里 ;; ^ 光标放到这里
;; 按下`C-j' 就会输出 6 ;; 按下`C-j' 就会输出 6
;; `C-j' 会在buffer中插入当前运算的结果 ;; `C-j' 会在buffer中插入当前运算的结果
;; 而`C-xC-e' 则会在emacs最底部显示结果也就是被称作"minibuffer"的区域 ;; 而`C-xC-e' 则会在emacs最底部显示结果也就是被称作"minibuffer"的区域
;; 为了避免把我们的buffer填满无用的结果我们以后会一直用`C-xC-e' ;; 为了避免把我们的buffer填满无用的结果我们以后会一直用`C-xC-e'
;; `setq' 可以将一个值赋给一个变量 ;; `setq' 可以将一个值赋给一个变量
(setq my-name "Bastien") (setq my-name "Bastien")
;; `C-xC-e' 输出 "Bastien" (在 mini-buffer 中显示) ;; `C-xC-e' 输出 "Bastien" (在 mini-buffer 中显示)
;; `insert' 会在光标处插入字符串: ;; `insert' 会在光标处插入字符串:
(insert "Hello!") (insert "Hello!")
;; `C-xC-e' 输出 "Hello!" ;; `C-xC-e' 输出 "Hello!"
;; 在这里我们只传给了insert一个参数"Hello!", 但是 ;; 在这里我们只传给了insert一个参数"Hello!", 但是
;; 我们也可以传给它更多的参数比如2个 ;; 我们也可以传给它更多的参数比如2个
(insert "Hello" " world!") (insert "Hello" " world!")
;; `C-xC-e' 输出 "Hello world!" ;; `C-xC-e' 输出 "Hello world!"
;; 你也可以用变量名来代替字符串 ;; 你也可以用变量名来代替字符串
(insert "Hello, I am " my-name) (insert "Hello, I am " my-name)
;; `C-xC-e' 输出 "Hello, I am Bastien" ;; `C-xC-e' 输出 "Hello, I am Bastien"
;; 你可以把s式嵌入函数中 ;; 你可以把s式嵌入函数中
(defun hello () (insert "Hello, I am " my-name)) (defun hello () (insert "Hello, I am " my-name))
;; `C-xC-e' 输出 hello ;; `C-xC-e' 输出 hello
;; 现在执行这个函数 ;; 现在执行这个函数
(hello) (hello)
;; `C-xC-e' 输出 Hello, I am Bastien ;; `C-xC-e' 输出 Hello, I am Bastien
;; 函数中空括号的意思是我们不需要接受任何参数 ;; 函数中空括号的意思是我们不需要接受任何参数
;; 但是我们不能一直总是用my-name这个变量 ;; 但是我们不能一直总是用my-name这个变量
;; 所以我们现在使我们的函数接受一个叫做"name"的参数 ;; 所以我们现在使我们的函数接受一个叫做"name"的参数
(defun hello (name) (insert "Hello " name)) (defun hello (name) (insert "Hello " name))
;; `C-xC-e' 输出 hello ;; `C-xC-e' 输出 hello
;; 现在我们调用这个函数,并且将"you"作为参数传递 ;; 现在我们调用这个函数,并且将"you"作为参数传递
(hello "you") (hello "you")
;; `C-xC-e' 输出 "Hello you" ;; `C-xC-e' 输出 "Hello you"
;; 成功! ;; 成功!
;; 现在我们可以休息一下 ;; 现在我们可以休息一下
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 下面我们在新的窗口中新建一个名为 "*test*" 的buffer: ;; 下面我们在新的窗口中新建一个名为 "*test*" 的buffer:
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
;; `C-xC-e' 这时屏幕上会显示两个窗口,而光标此时位于*test* buffer内 ;; `C-xC-e' 这时屏幕上会显示两个窗口,而光标此时位于*test* buffer内
;; 用鼠标单击上面的buffer就会使光标移回。 ;; 用鼠标单击上面的buffer就会使光标移回。
;; 或者你可以使用 `C-xo' 使得光标跳到另一个窗口中 ;; 或者你可以使用 `C-xo' 使得光标跳到另一个窗口中
;; 你可以用 `progn'命令将s式结合起来: ;; 你可以用 `progn'命令将s式结合起来:
(progn (progn
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
(hello "you")) (hello "you"))
;; `C-xC-e' 此时屏幕分为两个窗口,并且在*test* buffer中显示"Hello you" ;; `C-xC-e' 此时屏幕分为两个窗口,并且在*test* buffer中显示"Hello you"
;; 现在为了简洁我们需要在每个s式后面都使用`C-xC-e'来执行,后面就不再说明了 ;; 现在为了简洁我们需要在每个s式后面都使用`C-xC-e'来执行,后面就不再说明了
;; 记得可以用过鼠标或者`C-xo'回到*scratch*这个buffer。 ;; 记得可以用过鼠标或者`C-xo'回到*scratch*这个buffer。
;; 清除当前buffer也是常用操作之一 ;; 清除当前buffer也是常用操作之一
(progn (progn
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
(erase-buffer) (erase-buffer)
(hello "there")) (hello "there"))
;; 也可以回到其他的窗口中 ;; 也可以回到其他的窗口中
(progn (progn
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
(erase-buffer) (erase-buffer)
(hello "you") (hello "you")
(other-window 1)) (other-window 1))
;; 你可以用 `let' 将一个值和一个局部变量绑定: ;; 你可以用 `let' 将一个值和一个局部变量绑定:
(let ((local-name "you")) (let ((local-name "you"))
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
(erase-buffer) (erase-buffer)
(hello local-name) (hello local-name)
(other-window 1)) (other-window 1))
;; 这里我们就不需要使用 `progn' 了, 因为 `let' 也可以将很多s式组合起来。 ;; 这里我们就不需要使用 `progn' 了, 因为 `let' 也可以将很多s式组合起来。
;; 格式化字符串的方法: ;; 格式化字符串的方法:
(format "Hello %s!\n" "visitor") (format "Hello %s!\n" "visitor")
;; %s 是字符串占位符,这里被"visitor"替代. ;; %s 是字符串占位符,这里被"visitor"替代.
;; \n 是换行符。 ;; \n 是换行符。
;; 现在我们用格式化的方法再重写一下我们的函数: ;; 现在我们用格式化的方法再重写一下我们的函数:
(defun hello (name) (defun hello (name)
(insert (format "Hello %s!\n" name))) (insert (format "Hello %s!\n" name)))
(hello "you") (hello "you")
;; 我们再用`let'新建另一个函数: ;; 我们再用`let'新建另一个函数:
(defun greeting (name) (defun greeting (name)
(let ((your-name "Bastien")) (let ((your-name "Bastien"))
(insert (format "Hello %s!\n\nI am %s." (insert (format "Hello %s!\n\nI am %s."
name ; the argument of the function name ; the argument of the function
your-name ; the let-bound variable "Bastien" your-name ; the let-bound variable "Bastien"
)))) ))))
;; 之后执行: ;; 之后执行:
(greeting "you") (greeting "you")
;; 有些函数可以和用户交互: ;; 有些函数可以和用户交互:
(read-from-minibuffer "Enter your name: ") (read-from-minibuffer "Enter your name: ")
;; 这个函数会返回在执行时用户输入的信息 ;; 这个函数会返回在执行时用户输入的信息
;; 现在我们让`greeting'函数显示你的名字: ;; 现在我们让`greeting'函数显示你的名字:
(defun greeting (from-name) (defun greeting (from-name)
(let ((your-name (read-from-minibuffer "Enter your name: "))) (let ((your-name (read-from-minibuffer "Enter your name: ")))
(insert (format "Hello!\n\nI am %s and you are %s." (insert (format "Hello!\n\nI am %s and you are %s."
from-name ; the argument of the function from-name ; the argument of the function
your-name ; the let-bound var, entered at prompt your-name ; the let-bound var, entered at prompt
)))) ))))
(greeting "Bastien") (greeting "Bastien")
;; 我们让结果在另一个窗口中显示: ;; 我们让结果在另一个窗口中显示:
(defun greeting (from-name) (defun greeting (from-name)
(let ((your-name (read-from-minibuffer "Enter your name: "))) (let ((your-name (read-from-minibuffer "Enter your name: ")))
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
(erase-buffer) (erase-buffer)
(insert (format "Hello %s!\n\nI am %s." your-name from-name)) (insert (format "Hello %s!\n\nI am %s." your-name from-name))
(other-window 1))) (other-window 1)))
;; 测试一下: ;; 测试一下:
(greeting "Bastien") (greeting "Bastien")
;; 第二节结束,休息一下吧。 ;; 第二节结束,休息一下吧。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 我们将一些名字存到列表中: ;; 我们将一些名字存到列表中:
(setq list-of-names '("Sarah" "Chloe" "Mathilde")) (setq list-of-names '("Sarah" "Chloe" "Mathilde"))
;; 用 `car'来取得第一个名字: ;; 用 `car'来取得第一个名字:
(car list-of-names) (car list-of-names)
;; 用 `cdr'取得剩下的名字: ;; 用 `cdr'取得剩下的名字:
(cdr list-of-names) (cdr list-of-names)
;; 用 `push'把名字添加到列表的开头: ;; 用 `push'把名字添加到列表的开头:
(push "Stephanie" list-of-names) (push "Stephanie" list-of-names)
;; 注意: `car' 和 `cdr' 并不修改列表本身, 但是 `push' 却会对列表本身进行操作. ;; 注意: `car' 和 `cdr' 并不修改列表本身, 但是 `push' 却会对列表本身进行操作.
;; 这个区别是很重要的: 有些函数没有任何副作用(比如`car' ;; 这个区别是很重要的: 有些函数没有任何副作用(比如`car'
;; 但还有一些却是有的 (比如 `push'). ;; 但还有一些却是有的 (比如 `push').
;; 我们来对`list-of-names'列表中的每一个元素都使用hello函数: ;; 我们来对`list-of-names'列表中的每一个元素都使用hello函数:
(mapcar 'hello list-of-names) (mapcar 'hello list-of-names)
;; 将 `greeting' 改进,使的我们能够对`list-of-names'中的所有名字执行: ;; 将 `greeting' 改进,使的我们能够对`list-of-names'中的所有名字执行:
(defun greeting () (defun greeting ()
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
(erase-buffer) (erase-buffer)
(mapcar 'hello list-of-names) (mapcar 'hello list-of-names)
(other-window 1)) (other-window 1))
(greeting) (greeting)
;; 记得我们之前定义的 `hello' 函数吗? 这个函数接受一个参数,名字。 ;; 记得我们之前定义的 `hello' 函数吗? 这个函数接受一个参数,名字。
;; `mapcar' 调用 `hello', 并将`list-of-names'作为参数先后传给`hello' ;; `mapcar' 调用 `hello', 并将`list-of-names'作为参数先后传给`hello'
;; 现在我们对显示的buffer中的内容进行一些更改 ;; 现在我们对显示的buffer中的内容进行一些更改
(defun replace-hello-by-bonjour () (defun replace-hello-by-bonjour ()
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
(goto-char (point-min)) (goto-char (point-min))
(while (search-forward "Hello") (while (search-forward "Hello")
(replace-match "Bonjour")) (replace-match "Bonjour"))
(other-window 1)) (other-window 1))
;; (goto-char (point-min)) 将光标移到buffer的开始 ;; (goto-char (point-min)) 将光标移到buffer的开始
;; (search-forward "Hello") 查找字符串"Hello" ;; (search-forward "Hello") 查找字符串"Hello"
;; (while x y) 当x返回某个值时执行y这个s式 ;; (while x y) 当x返回某个值时执行y这个s式
;; 当x返回`nil' (空), 退出循环 ;; 当x返回`nil' (空), 退出循环
(replace-hello-by-bonjour) (replace-hello-by-bonjour)
;; 你会看到所有在*test* buffer中出现的"Hello"字样都被换成了"Bonjour" ;; 你会看到所有在*test* buffer中出现的"Hello"字样都被换成了"Bonjour"
;; 你也会得到以下错误提示: "Search failed: Hello". ;; 你也会得到以下错误提示: "Search failed: Hello".
;; ;;
;; 如果要避免这个错误, 你需要告诉 `search-forward' 这个命令是否在 ;; 如果要避免这个错误, 你需要告诉 `search-forward' 这个命令是否在
;; buffer的某个地方停止查找, 并且在什么都没找到时是否应该不给出错误提示 ;; buffer的某个地方停止查找, 并且在什么都没找到时是否应该不给出错误提示
;; (search-forward "Hello" nil t) 可以达到这个要求: ;; (search-forward "Hello" nil t) 可以达到这个要求:
;; `nil' 参数的意思是 : 查找并不限于某个范围内 ;; `nil' 参数的意思是 : 查找并不限于某个范围内
;; `t' 参数的意思是: 当什么都没找到时,不给出错误提示 ;; `t' 参数的意思是: 当什么都没找到时,不给出错误提示
;; 在下面的函数中我们用到了s式并且不给出任何错误提示: ;; 在下面的函数中我们用到了s式并且不给出任何错误提示:
(defun hello-to-bonjour () (defun hello-to-bonjour ()
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
(erase-buffer) (erase-buffer)
;; 为`list-of-names'中的每个名字调用hello ;; 为`list-of-names'中的每个名字调用hello
(mapcar 'hello list-of-names) (mapcar 'hello list-of-names)
(goto-char (point-min)) (goto-char (point-min))
;; 将"Hello" 替换为"Bonjour" ;; 将"Hello" 替换为"Bonjour"
(while (search-forward "Hello" nil t) (while (search-forward "Hello" nil t)
(replace-match "Bonjour")) (replace-match "Bonjour"))
(other-window 1)) (other-window 1))
(hello-to-bonjour) (hello-to-bonjour)
;; 给这些名字加粗: ;; 给这些名字加粗:
(defun boldify-names () (defun boldify-names ()
(switch-to-buffer-other-window "*test*") (switch-to-buffer-other-window "*test*")
(goto-char (point-min)) (goto-char (point-min))
(while (re-search-forward "Bonjour \\(.+\\)!" nil t) (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
(add-text-properties (match-beginning 1) (add-text-properties (match-beginning 1)
(match-end 1) (match-end 1)
(list 'face 'bold))) (list 'face 'bold)))
(other-window 1)) (other-window 1))
;; 这个函数使用了 `re-search-forward': ;; 这个函数使用了 `re-search-forward':
;; 和查找一个字符串不同,你用这个命令可以查找一个模式,即正则表达式 ;; 和查找一个字符串不同,你用这个命令可以查找一个模式,即正则表达式
;; 正则表达式 "Bonjour \\(.+\\)!" 的意思是: ;; 正则表达式 "Bonjour \\(.+\\)!" 的意思是:
;; 字符串 "Bonjour ", 之后跟着 ;; 字符串 "Bonjour ", 之后跟着
;; 一组 | \\( ... \\) 结构 ;; 一组 | \\( ... \\) 结构
;; 任意字符 | . 的含义 ;; 任意字符 | . 的含义
;; 有可能重复的 | + 的含义 ;; 有可能重复的 | + 的含义
;; 之后跟着 "!" 这个字符串 ;; 之后跟着 "!" 这个字符串
;; 准备好了?试试看。 ;; 准备好了?试试看。
(boldify-names) (boldify-names)
;; `add-text-properties' 可以添加文字属性, 比如文字样式 ;; `add-text-properties' 可以添加文字属性, 比如文字样式
;; 好的,我们成功了! ;; 好的,我们成功了!
;; 如果你想对一个变量或者函数有更多的了解: ;; 如果你想对一个变量或者函数有更多的了解:
;; ;;
;; C-h v 变量 回车 ;; C-h v 变量 回车
;; C-h f 函数 回车 ;; C-h f 函数 回车
;; ;;
;; 阅读Emacs Lisp官方文档: ;; 阅读Emacs Lisp官方文档:
;; ;;
;; C-h i m elisp 回车 ;; C-h i m elisp 回车
;; ;;
;; 在线阅读Emacs Lisp文档: ;; 在线阅读Emacs Lisp文档:
;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html ;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
;; 感谢以下同学的建议和反馈: ;; 感谢以下同学的建议和反馈:
;; - Wes Hardaker ;; - Wes Hardaker
;; - notbob ;; - notbob
;; - Kevin Montuori ;; - Kevin Montuori
;; - Arne Babenhauserheide ;; - Arne Babenhauserheide
;; - Alan Schmitt ;; - Alan Schmitt
;; - spacegoing ;; - spacegoing
``` ```

File diff suppressed because it is too large Load Diff