mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-27 19:28:51 +00:00
Merge remote-tracking branch 'adambard/master'
This commit is contained in:
commit
46d3c28a5f
@ -18,7 +18,7 @@ All contributions are welcome, from the tiniest typo to a brand new article. Tra
|
|||||||
in all languages are welcome (or, for that matter, original articles in any language).
|
in all languages are welcome (or, for that matter, original articles in any language).
|
||||||
Send a pull request or open an issue any time of day or night.
|
Send a pull request or open an issue any time of day or night.
|
||||||
|
|
||||||
**Please tag your issues pull requests with [language/lang-code] at the beginning**
|
**Please tag your issues and pull requests with [language/lang-code] at the beginning**
|
||||||
**(e.g. [python/en] for English Python).** This will help everyone pick out things they
|
**(e.g. [python/en] for English Python).** This will help everyone pick out things they
|
||||||
care about.
|
care about.
|
||||||
|
|
||||||
|
@ -8,10 +8,10 @@ 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
|
||||||
|
@ -72,45 +72,45 @@ for a given function. Say `f(n)` is your algorithm runtime, and `g(n)` is an arb
|
|||||||
you are trying to relate to your algorithm. `f(n)` is O(g(n)), if for any real constant c (c > 0),
|
you are trying to relate to your algorithm. `f(n)` is O(g(n)), if for any real constant c (c > 0),
|
||||||
`f(n)` <= `c g(n)` for every input size n (n > 0).
|
`f(n)` <= `c g(n)` for every input size n (n > 0).
|
||||||
|
|
||||||
*Example 1*
|
*Example 1*
|
||||||
|
|
||||||
```
|
```
|
||||||
f(n) = 3log n + 100
|
f(n) = 3log n + 100
|
||||||
g(n) = log n
|
g(n) = log n
|
||||||
```
|
```
|
||||||
|
|
||||||
Is `f(n)` O(g(n))?
|
Is `f(n)` O(g(n))?
|
||||||
Is `3 log n + 100` O(log n)?
|
Is `3 log n + 100` O(log n)?
|
||||||
Let's look to the definition of Big-O.
|
Let's look to the definition of Big-O.
|
||||||
|
|
||||||
```
|
```
|
||||||
3log n + 100 <= c * log n
|
3log n + 100 <= c * log n
|
||||||
```
|
```
|
||||||
|
|
||||||
Is there some constant c that satisfies this for all n?
|
Is there some constant c that satisfies this for all n?
|
||||||
|
|
||||||
```
|
```
|
||||||
3log n + 100 <= 150 * log n, n > 2 (undefined at n = 1)
|
3log n + 100 <= 150 * log n, n > 2 (undefined at n = 1)
|
||||||
```
|
```
|
||||||
|
|
||||||
Yes! The definition of Big-O has been met therefore `f(n)` is O(g(n)).
|
Yes! The definition of Big-O has been met therefore `f(n)` is O(g(n)).
|
||||||
|
|
||||||
*Example 2*
|
*Example 2*
|
||||||
|
|
||||||
```
|
```
|
||||||
f(n) = 3*n^2
|
f(n) = 3*n^2
|
||||||
g(n) = n
|
g(n) = n
|
||||||
```
|
```
|
||||||
|
|
||||||
Is `f(n)` O(g(n))?
|
Is `f(n)` O(g(n))?
|
||||||
Is `3 * n^2` O(n)?
|
Is `3 * n^2` O(n)?
|
||||||
Let's look at the definition of Big-O.
|
Let's look at the definition of Big-O.
|
||||||
|
|
||||||
```
|
```
|
||||||
3 * n^2 <= c * n
|
3 * n^2 <= c * n
|
||||||
```
|
```
|
||||||
|
|
||||||
Is there some constant c that satisfies this for all n?
|
Is there some constant c that satisfies this for all n?
|
||||||
No, there isn't. `f(n)` is NOT O(g(n)).
|
No, there isn't. `f(n)` is NOT O(g(n)).
|
||||||
|
|
||||||
### Big-Omega
|
### Big-Omega
|
||||||
|
@ -51,7 +51,7 @@ echo $Variable
|
|||||||
echo "$Variable"
|
echo "$Variable"
|
||||||
echo '$Variable'
|
echo '$Variable'
|
||||||
# When you use the variable itself — assign it, export it, or else — you write
|
# When you use the variable itself — assign it, export it, or else — you write
|
||||||
# its name without $. If you want to use variable's value, you should use $.
|
# its name without $. If you want to use the variable's value, you should use $.
|
||||||
# Note that ' (single quote) won't expand the variables!
|
# Note that ' (single quote) won't expand the variables!
|
||||||
|
|
||||||
# String substitution in variables
|
# String substitution in variables
|
||||||
@ -70,11 +70,11 @@ echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
|
|||||||
|
|
||||||
# Builtin variables:
|
# Builtin variables:
|
||||||
# There are some useful builtin variables, like
|
# There are some useful builtin variables, like
|
||||||
echo "Last program return value: $?"
|
echo "Last program's return value: $?"
|
||||||
echo "Script's PID: $$"
|
echo "Script's PID: $$"
|
||||||
echo "Number of arguments: $#"
|
echo "Number of arguments passed to script: $#"
|
||||||
echo "Scripts arguments: $@"
|
echo "All arguments passed to script: $@"
|
||||||
echo "Scripts arguments separated in different variables: $1 $2..."
|
echo "Script's arguments separated into different variables: $1 $2..."
|
||||||
|
|
||||||
# Reading a value from input:
|
# Reading a value from input:
|
||||||
echo "What's your name?"
|
echo "What's your name?"
|
||||||
@ -90,17 +90,26 @@ else
|
|||||||
echo "Your name is your username"
|
echo "Your name is your username"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# NOTE: if $Name is empty, bash sees the above condition as:
|
||||||
|
if [ -ne $USER ]
|
||||||
|
# which is invalid syntax
|
||||||
|
# so the "safe" way to use potentially empty variables in bash is:
|
||||||
|
if [ "$Name" -ne $USER ] ...
|
||||||
|
# which, when $Name is empty, is seen by bash as:
|
||||||
|
if [ "" -ne $USER ] ...
|
||||||
|
# which works as expected
|
||||||
|
|
||||||
# There is also conditional execution
|
# There is also conditional execution
|
||||||
echo "Always executed" || echo "Only executed if first command fails"
|
echo "Always executed" || echo "Only executed if first command fails"
|
||||||
echo "Always executed" && echo "Only executed if first command does NOT fail"
|
echo "Always executed" && echo "Only executed if first command does NOT fail"
|
||||||
|
|
||||||
# To use && and || with if statements, you need multiple pairs of square brackets:
|
# To use && and || with if statements, you need multiple pairs of square brackets:
|
||||||
if [ $Name == "Steve" ] && [ $Age -eq 15 ]
|
if [ "$Name" == "Steve" ] && [ "$Age" -eq 15 ]
|
||||||
then
|
then
|
||||||
echo "This will run if $Name is Steve AND $Age is 15."
|
echo "This will run if $Name is Steve AND $Age is 15."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $Name == "Daniya" ] || [ $Name == "Zach" ]
|
if [ "$Name" == "Daniya" ] || [ "$Name" == "Zach" ]
|
||||||
then
|
then
|
||||||
echo "This will run if $Name is Daniya OR Zach."
|
echo "This will run if $Name is Daniya OR Zach."
|
||||||
fi
|
fi
|
||||||
@ -108,8 +117,8 @@ fi
|
|||||||
# Expressions are denoted with the following format:
|
# Expressions are denoted with the following format:
|
||||||
echo $(( 10 + 5 ))
|
echo $(( 10 + 5 ))
|
||||||
|
|
||||||
# Unlike other programming languages, bash is a shell — so it works in a context
|
# Unlike other programming languages, bash is a shell so it works in the context
|
||||||
# of current directory. You can list files and directories in the current
|
# of a current directory. You can list files and directories in the current
|
||||||
# directory with the ls command:
|
# directory with the ls command:
|
||||||
ls
|
ls
|
||||||
|
|
||||||
@ -252,7 +261,7 @@ grep "^foo.*bar$" file.txt
|
|||||||
grep -c "^foo.*bar$" file.txt
|
grep -c "^foo.*bar$" file.txt
|
||||||
# if you literally want to search for the string,
|
# if you literally want to search for the string,
|
||||||
# and not the regex, use fgrep (or grep -F)
|
# and not the regex, use fgrep (or grep -F)
|
||||||
fgrep "^foo.*bar$" file.txt
|
fgrep "^foo.*bar$" file.txt
|
||||||
|
|
||||||
|
|
||||||
# Read Bash shell builtins documentation with the bash 'help' builtin:
|
# Read Bash shell builtins documentation with the bash 'help' builtin:
|
||||||
|
@ -245,7 +245,13 @@ cout << fooRef; // Prints "I am foo. Hi!"
|
|||||||
// Doesn't reassign "fooRef". This is the same as "foo = bar", and
|
// Doesn't reassign "fooRef". This is the same as "foo = bar", and
|
||||||
// foo == "I am bar"
|
// foo == "I am bar"
|
||||||
// after this line.
|
// after this line.
|
||||||
|
cout << &fooRef << endl; //Prints the address of foo
|
||||||
fooRef = bar;
|
fooRef = bar;
|
||||||
|
cout << &fooRef << endl; //Still prints the address of foo
|
||||||
|
cout << fooRef; // Prints "I am bar"
|
||||||
|
|
||||||
|
//The address of fooRef remains the same, i.e. it is still referring to foo.
|
||||||
|
|
||||||
|
|
||||||
const string& barRef = bar; // Create a const reference to bar.
|
const string& barRef = bar; // Create a const reference to bar.
|
||||||
// Like C, const values (and pointers and references) cannot be modified.
|
// Like C, const values (and pointers and references) cannot be modified.
|
||||||
@ -258,7 +264,7 @@ string retVal = tempObjectFun();
|
|||||||
|
|
||||||
// What happens in the second line is actually:
|
// What happens in the second line is actually:
|
||||||
// - a string object is returned from tempObjectFun
|
// - a string object is returned from tempObjectFun
|
||||||
// - a new string is constructed with the returned object as arugment to the
|
// - a new string is constructed with the returned object as argument to the
|
||||||
// constructor
|
// constructor
|
||||||
// - the returned object is destroyed
|
// - the returned object is destroyed
|
||||||
// The returned object is called a temporary object. Temporary objects are
|
// The returned object is called a temporary object. Temporary objects are
|
||||||
@ -304,6 +310,70 @@ basic_string(basic_string&& other);
|
|||||||
// constructor that "salvages" parts of that temporary string. You will see this
|
// constructor that "salvages" parts of that temporary string. You will see this
|
||||||
// concept referred to as "move semantics".
|
// concept referred to as "move semantics".
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// Enums
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
// Enums are a way to assign a value to a constant most commonly used for
|
||||||
|
// easier visualization and reading of code
|
||||||
|
enum ECarTypes
|
||||||
|
{
|
||||||
|
Sedan,
|
||||||
|
Hatchback,
|
||||||
|
SUV,
|
||||||
|
Wagon
|
||||||
|
};
|
||||||
|
|
||||||
|
ECarTypes GetPreferredCarType()
|
||||||
|
{
|
||||||
|
return ECarTypes::Hatchback;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As of C++11 there is an easy way to assign a type to the enum which can be
|
||||||
|
// useful in serialization of data and converting enums back-and-forth between
|
||||||
|
// the desired type and their respective constants
|
||||||
|
enum ECarTypes : uint8_t
|
||||||
|
{
|
||||||
|
Sedan, // 0
|
||||||
|
Hatchback, // 1
|
||||||
|
SUV = 254, // 254
|
||||||
|
Hybrid // 255
|
||||||
|
};
|
||||||
|
|
||||||
|
void WriteByteToFile(uint8_t InputValue)
|
||||||
|
{
|
||||||
|
// Serialize the InputValue to a file
|
||||||
|
}
|
||||||
|
|
||||||
|
void WritePreferredCarTypeToFile(ECarTypes InputCarType)
|
||||||
|
{
|
||||||
|
// The enum is implicitly converted to a uint8_t due to its declared enum type
|
||||||
|
WriteByteToFile(InputCarType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// On the other hand you may not want enums to be accidentally cast to an integer
|
||||||
|
// type or to other enums so it is instead possible to create an enum class which
|
||||||
|
// won't be implicitly converted
|
||||||
|
enum class ECarTypes : uint8_t
|
||||||
|
{
|
||||||
|
Sedan, // 0
|
||||||
|
Hatchback, // 1
|
||||||
|
SUV = 254, // 254
|
||||||
|
Hybrid // 255
|
||||||
|
};
|
||||||
|
|
||||||
|
void WriteByteToFile(uint8_t InputValue)
|
||||||
|
{
|
||||||
|
// Serialize the InputValue to a file
|
||||||
|
}
|
||||||
|
|
||||||
|
void WritePreferredCarTypeToFile(ECarTypes InputCarType)
|
||||||
|
{
|
||||||
|
// Won't compile even though ECarTypes is a uint8_t due to the enum
|
||||||
|
// being declared as an "enum class"!
|
||||||
|
WriteByteToFile(InputCarType);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
// Classes and object-oriented programming
|
// Classes and object-oriented programming
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
@ -398,6 +468,8 @@ int main() {
|
|||||||
// Inheritance:
|
// Inheritance:
|
||||||
|
|
||||||
// This class inherits everything public and protected from the Dog class
|
// This class inherits everything public and protected from the Dog class
|
||||||
|
// as well as private but may not directly access private members/methods
|
||||||
|
// without a public or protected method for doing so
|
||||||
class OwnedDog : public Dog {
|
class OwnedDog : public Dog {
|
||||||
|
|
||||||
void setOwner(const std::string& dogsOwner);
|
void setOwner(const std::string& dogsOwner);
|
||||||
@ -729,6 +801,24 @@ void doSomethingWithAFile(const std::string& filename)
|
|||||||
// all automatically destroy their contents when they fall out of scope.
|
// all automatically destroy their contents when they fall out of scope.
|
||||||
// - Mutexes using lock_guard and unique_lock
|
// - Mutexes using lock_guard and unique_lock
|
||||||
|
|
||||||
|
// containers with object keys of non-primitive values (custom classes) require
|
||||||
|
// compare function in the object itself or as a function pointer. Primitives
|
||||||
|
// have default comparators, but you can override it.
|
||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
int j;
|
||||||
|
Foo(int a) : j(a) {}
|
||||||
|
};
|
||||||
|
struct compareFunction {
|
||||||
|
bool operator()(const Foo& a, const Foo& b) const {
|
||||||
|
return a.j < b.j;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//this isn't allowed (although it can vary depending on compiler)
|
||||||
|
//std::map<Foo, int> fooMap;
|
||||||
|
std::map<Foo, int, compareFunction> fooMap;
|
||||||
|
fooMap[Foo(1)] = 1;
|
||||||
|
fooMap.find(Foo(1)); //true
|
||||||
|
|
||||||
/////////////////////
|
/////////////////////
|
||||||
// Fun stuff
|
// Fun stuff
|
||||||
|
158
c.html.markdown
158
c.html.markdown
@ -6,7 +6,8 @@ contributors:
|
|||||||
- ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"]
|
- ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"]
|
||||||
- ["Jakub Trzebiatowski", "http://cbs.stgn.pl"]
|
- ["Jakub Trzebiatowski", "http://cbs.stgn.pl"]
|
||||||
- ["Marco Scannadinari", "https://marcoms.github.io"]
|
- ["Marco Scannadinari", "https://marcoms.github.io"]
|
||||||
|
- ["Zachary Ferguson", "https://github.io/zfergus2"]
|
||||||
|
- ["himanshu", "https://github.com/himanshu81494"]
|
||||||
---
|
---
|
||||||
|
|
||||||
Ah, C. Still **the** language of modern high-performance computing.
|
Ah, C. Still **the** language of modern high-performance computing.
|
||||||
@ -27,6 +28,7 @@ Multi-line comments don't nest /* Be careful */ // comment ends on this line...
|
|||||||
*/ // ...not this one!
|
*/ // ...not this one!
|
||||||
|
|
||||||
// Constants: #define <keyword>
|
// Constants: #define <keyword>
|
||||||
|
// Constants are written in all-caps out of convention, not requirement
|
||||||
#define DAYS_IN_YEAR 365
|
#define DAYS_IN_YEAR 365
|
||||||
|
|
||||||
// Enumeration constants are also ways to declare constants.
|
// Enumeration constants are also ways to declare constants.
|
||||||
@ -52,10 +54,21 @@ int function_2(void);
|
|||||||
// Must declare a 'function prototype' before main() when functions occur after
|
// Must declare a 'function prototype' before main() when functions occur after
|
||||||
// your main() function.
|
// your main() function.
|
||||||
int add_two_ints(int x1, int x2); // function prototype
|
int add_two_ints(int x1, int x2); // function prototype
|
||||||
|
// although `int add_two_ints(int, int);` is also valid (no need to name the args),
|
||||||
|
// it is recommended to name arguments in the prototype as well for easier inspection
|
||||||
|
|
||||||
// Your program's entry point is a function called
|
// Your program's entry point is a function called
|
||||||
// main with an integer return type.
|
// main with an integer return type.
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
// your program
|
||||||
|
}
|
||||||
|
|
||||||
|
// The command line arguments used to run your program are also passed to main
|
||||||
|
// argc being the number of arguments - your program's name counts as 1
|
||||||
|
// argv is an array of character arrays - containing the arguments themselves
|
||||||
|
// argv[0] = name of your program, argv[1] = first argument, etc.
|
||||||
|
int main (int argc, char** argv)
|
||||||
|
{
|
||||||
// print output using printf, for "print formatted"
|
// print output using printf, for "print formatted"
|
||||||
// %d is an integer, \n is a newline
|
// %d is an integer, \n is a newline
|
||||||
printf("%d\n", 0); // => Prints 0
|
printf("%d\n", 0); // => Prints 0
|
||||||
@ -63,6 +76,9 @@ int main(void) {
|
|||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Types
|
// Types
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
// All variables MUST be declared at the top of the current block scope
|
||||||
|
// we declare them dynamically along the code for the sake of the tutorial
|
||||||
|
|
||||||
// ints are usually 4 bytes
|
// ints are usually 4 bytes
|
||||||
int x_int = 0;
|
int x_int = 0;
|
||||||
@ -130,15 +146,12 @@ int main(void) {
|
|||||||
// can be declared as well. The size of such an array need not be a compile
|
// can be declared as well. The size of such an array need not be a compile
|
||||||
// time constant:
|
// time constant:
|
||||||
printf("Enter the array size: "); // ask the user for an array size
|
printf("Enter the array size: "); // ask the user for an array size
|
||||||
char buf[0x100];
|
int size;
|
||||||
fgets(buf, sizeof buf, stdin);
|
fscanf(stdin, "%d", &size);
|
||||||
|
int var_length_array[size]; // declare the VLA
|
||||||
// strtoul parses a string to an unsigned integer
|
|
||||||
size_t size2 = strtoul(buf, NULL, 10);
|
|
||||||
int var_length_array[size2]; // declare the VLA
|
|
||||||
printf("sizeof array = %zu\n", sizeof var_length_array);
|
printf("sizeof array = %zu\n", sizeof var_length_array);
|
||||||
|
|
||||||
// A possible outcome of this program may be:
|
// Example:
|
||||||
// > Enter the array size: 10
|
// > Enter the array size: 10
|
||||||
// > sizeof array = 40
|
// > sizeof array = 40
|
||||||
|
|
||||||
@ -219,7 +232,7 @@ int main(void) {
|
|||||||
0 || 1; // => 1 (Logical or)
|
0 || 1; // => 1 (Logical or)
|
||||||
0 || 0; // => 0
|
0 || 0; // => 0
|
||||||
|
|
||||||
// Conditional expression ( ? : )
|
// Conditional ternary expression ( ? : )
|
||||||
int e = 5;
|
int e = 5;
|
||||||
int f = 10;
|
int f = 10;
|
||||||
int z;
|
int z;
|
||||||
@ -289,6 +302,8 @@ int main(void) {
|
|||||||
for (i = 0; i <= 5; i++) {
|
for (i = 0; i <= 5; i++) {
|
||||||
; // use semicolon to act as the body (null statement)
|
; // use semicolon to act as the body (null statement)
|
||||||
}
|
}
|
||||||
|
// Or
|
||||||
|
for (i = 0; i <= 5; i++);
|
||||||
|
|
||||||
// branching with multiple choices: switch()
|
// branching with multiple choices: switch()
|
||||||
switch (a) {
|
switch (a) {
|
||||||
@ -304,7 +319,29 @@ int main(void) {
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
using "goto" in C
|
||||||
|
*/
|
||||||
|
typedef enum { false, true } bool;
|
||||||
|
// for C don't have bool as data type :(
|
||||||
|
bool disaster = false;
|
||||||
|
int i, j;
|
||||||
|
for(i=0;i<100;++i)
|
||||||
|
for(j=0;j<100;++j)
|
||||||
|
{
|
||||||
|
if((i + j) >= 150)
|
||||||
|
disaster = true;
|
||||||
|
if(disaster)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
error :
|
||||||
|
printf("Error occured at i = %d & j = %d.\n", i, j);
|
||||||
|
/*
|
||||||
|
https://ideone.com/GuPhd6
|
||||||
|
this will print out "Error occured at i = 52 & j = 99."
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Typecasting
|
// Typecasting
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
@ -403,6 +440,17 @@ int main(void) {
|
|||||||
for (xx = 0; xx < 20; xx++) {
|
for (xx = 0; xx < 20; xx++) {
|
||||||
*(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx
|
*(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx
|
||||||
} // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints)
|
} // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints)
|
||||||
|
|
||||||
|
// Note that there is no standard way to get the length of a
|
||||||
|
// dynamically allocated array in C. Because of this, if your arrays are
|
||||||
|
// going to be passed around your program a lot, you need another variable
|
||||||
|
// to keep track of the number of elements (size) of an array. See the
|
||||||
|
// functions section for more info.
|
||||||
|
int size = 10;
|
||||||
|
int *my_arr = malloc(sizeof(int) * size);
|
||||||
|
// Add an element to the array
|
||||||
|
my_arr = realloc(my_arr, ++size);
|
||||||
|
my_arr[10] = 5;
|
||||||
|
|
||||||
// Dereferencing memory that you haven't allocated gives
|
// Dereferencing memory that you haven't allocated gives
|
||||||
// "unpredictable results" - the program is said to invoke "undefined behavior"
|
// "unpredictable results" - the program is said to invoke "undefined behavior"
|
||||||
@ -470,6 +518,46 @@ char c[] = "This is a test.";
|
|||||||
str_reverse(c);
|
str_reverse(c);
|
||||||
printf("%s\n", c); // => ".tset a si sihT"
|
printf("%s\n", c); // => ".tset a si sihT"
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
as we can return only one variable
|
||||||
|
to change values of more than one variables we use call by reference
|
||||||
|
*/
|
||||||
|
void swapTwoNumbers(int *a, int *b)
|
||||||
|
{
|
||||||
|
int temp = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b = temp;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
int first = 10;
|
||||||
|
int second = 20;
|
||||||
|
printf("first: %d\nsecond: %d\n", first, second);
|
||||||
|
swapTwoNumbers(&first, &second);
|
||||||
|
printf("first: %d\nsecond: %d\n", first, second);
|
||||||
|
// values will be swapped
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
With regards to arrays, they will always be passed to functions
|
||||||
|
as pointers. Even if you statically allocate an array like `arr[10]`,
|
||||||
|
it still gets passed as a pointer to the first element in any function calls.
|
||||||
|
Again, there is no standard way to get the size of a dynamically allocated
|
||||||
|
array in C.
|
||||||
|
*/
|
||||||
|
// Size must be passed!
|
||||||
|
// Otherwise, this function has no way of knowing how big the array is.
|
||||||
|
void printIntArray(int *arr, int size) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
printf("arr[%d] is: %d\n", i, arr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
int my_arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||||
|
int size = 10;
|
||||||
|
printIntArray(my_arr, size);
|
||||||
|
// will print "arr[0] is: 1" etc
|
||||||
|
*/
|
||||||
|
|
||||||
// if referring to external variables outside function, must use extern keyword.
|
// if referring to external variables outside function, must use extern keyword.
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -626,8 +714,56 @@ typedef void (*my_fnp_type)(char *);
|
|||||||
// , | left to right //
|
// , | left to right //
|
||||||
//---------------------------------------------------//
|
//---------------------------------------------------//
|
||||||
|
|
||||||
```
|
/******************************* Header Files **********************************
|
||||||
|
|
||||||
|
Header files are an important part of c as they allow for the connection of c
|
||||||
|
source files and can simplify code and definitions by seperating them into
|
||||||
|
seperate files.
|
||||||
|
|
||||||
|
Header files are syntaxtically similar to c source files but reside in ".h"
|
||||||
|
files. They can be included in your c source file by using the precompiler
|
||||||
|
command #include "example.h", given that example.h exists in the same directory
|
||||||
|
as the c file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* A safe guard to prevent the header from being defined too many times. This */
|
||||||
|
/* happens in the case of circle dependency, the contents of the header is */
|
||||||
|
/* already defined. */
|
||||||
|
#ifndef EXAMPLE_H /* if EXAMPLE_H is not yet defined. */
|
||||||
|
#define EXAMPLE_H /* Define the macro EXAMPLE_H. */
|
||||||
|
|
||||||
|
/* Other headers can be included in headers and therefore transitively */
|
||||||
|
/* included into files that include this header. */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Like c source files macros can be defined in headers and used in files */
|
||||||
|
/* that include this header file. */
|
||||||
|
#define EXAMPLE_NAME "Dennis Ritchie"
|
||||||
|
/* Function macros can also be defined. */
|
||||||
|
#define ADD(a, b) (a + b)
|
||||||
|
|
||||||
|
/* Structs and typedefs can be used for consistency between files. */
|
||||||
|
typedef struct node
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
struct node *next;
|
||||||
|
} Node;
|
||||||
|
|
||||||
|
/* So can enumerations. */
|
||||||
|
enum traffic_light_state {GREEN, YELLOW, RED};
|
||||||
|
|
||||||
|
/* Function prototypes can also be defined here for use in multiple files, */
|
||||||
|
/* but it is bad practice to define the function in the header. Definitions */
|
||||||
|
/* should instead be put in a c file. */
|
||||||
|
Node createLinkedList(int *vals, int len);
|
||||||
|
|
||||||
|
/* Beyond the above elements, other definitions should be left to a c source */
|
||||||
|
/* file. Excessive includeds or definitions should, also not be contained in */
|
||||||
|
/* a header file but instead put into separate headers or a c file. */
|
||||||
|
|
||||||
|
#endif /* End of the if precompiler directive. */
|
||||||
|
|
||||||
|
```
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
|
||||||
Best to find yourself a copy of [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language)
|
Best to find yourself a copy of [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language)
|
||||||
|
@ -27,7 +27,7 @@ writeln( "There are ", 3, " commas (\",\") in this line of code" );
|
|||||||
stdout.writeln( "This goes to standard output, just like plain writeln() does");
|
stdout.writeln( "This goes to standard output, just like plain writeln() does");
|
||||||
stderr.writeln( "This goes to standard error" );
|
stderr.writeln( "This goes to standard error" );
|
||||||
|
|
||||||
// Variables don't have to be explicitly typed as long as
|
// Variables don't have to be explicitly typed as long as
|
||||||
// the compiler can figure out the type that it will hold.
|
// the compiler can figure out the type that it will hold.
|
||||||
var myVar = 10; // 10 is an int, so myVar is implicitly an int
|
var myVar = 10; // 10 is an int, so myVar is implicitly an int
|
||||||
myVar = -10;
|
myVar = -10;
|
||||||
@ -65,9 +65,9 @@ const almostPi: real = 22.0/7.0;
|
|||||||
param compileTimeConst: int = 16;
|
param compileTimeConst: int = 16;
|
||||||
|
|
||||||
// The config modifier allows values to be set at the command line
|
// The config modifier allows values to be set at the command line
|
||||||
// and is much easier than the usual getOpts debacle
|
// and is much easier than the usual getOpts debacle
|
||||||
// config vars and consts can be changed through the command line at run time
|
// config vars and consts can be changed through the command line at run time
|
||||||
config var varCmdLineArg: int = -123;
|
config var varCmdLineArg: int = -123;
|
||||||
config const constCmdLineArg: int = 777;
|
config const constCmdLineArg: int = 777;
|
||||||
// Set with --VarName=Value or --VarName Value at run time
|
// Set with --VarName=Value or --VarName Value at run time
|
||||||
|
|
||||||
@ -119,9 +119,9 @@ a *= thatInt; // Times-equals ( a = a * thatInt; )
|
|||||||
b &&= thatBool; // Logical-and-equals ( b = b && thatBool; )
|
b &&= thatBool; // Logical-and-equals ( b = b && thatBool; )
|
||||||
a <<= 3; // Left-bit-shift-equals ( a = a << 10; )
|
a <<= 3; // Left-bit-shift-equals ( a = a << 10; )
|
||||||
// and many, many more.
|
// and many, many more.
|
||||||
// Unlike other C family languages there are no
|
// Unlike other C family languages there are no
|
||||||
// pre/post-increment/decrement operators like
|
// pre/post-increment/decrement operators like
|
||||||
// ++j, --j, j++, j--
|
// ++j, --j, j++, j--
|
||||||
|
|
||||||
// Swap operator
|
// Swap operator
|
||||||
var old_this = thisInt;
|
var old_this = thisInt;
|
||||||
@ -155,7 +155,7 @@ writeln( (a,b,thisInt,thatInt,thisBool,thatBool) );
|
|||||||
|
|
||||||
// Type aliasing
|
// Type aliasing
|
||||||
type chroma = int; // Type of a single hue
|
type chroma = int; // Type of a single hue
|
||||||
type RGBColor = 3*chroma; // Type representing a full color
|
type RGBColor = 3*chroma; // Type representing a full color
|
||||||
var black: RGBColor = ( 0,0,0 );
|
var black: RGBColor = ( 0,0,0 );
|
||||||
var white: RGBColor = ( 255, 255, 255 );
|
var white: RGBColor = ( 255, 255, 255 );
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ select( inputOption ){
|
|||||||
writeln( "Chose 'otherOption'" );
|
writeln( "Chose 'otherOption'" );
|
||||||
writeln( "Which has a body" );
|
writeln( "Which has a body" );
|
||||||
}
|
}
|
||||||
otherwise {
|
otherwise {
|
||||||
writeln( "Any other Input" );
|
writeln( "Any other Input" );
|
||||||
writeln( "the otherwise case doesn't need a do if the body is one line" );
|
writeln( "the otherwise case doesn't need a do if the body is one line" );
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ do{
|
|||||||
writeln( jSum );
|
writeln( jSum );
|
||||||
|
|
||||||
// For loops are much like those in python in that they iterate over a range.
|
// For loops are much like those in python in that they iterate over a range.
|
||||||
// Ranges themselves are types, and can be stuffed into variables
|
// Ranges themselves are types, and can be stuffed into variables
|
||||||
// (more about that later)
|
// (more about that later)
|
||||||
for i in 1..10 do write( i , ", ") ;
|
for i in 1..10 do write( i , ", ") ;
|
||||||
writeln( );
|
writeln( );
|
||||||
@ -240,28 +240,28 @@ for x in 1..10 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ranges and Domains
|
// Ranges and Domains
|
||||||
// For-loops and arrays both use ranges and domains to
|
// For-loops and arrays both use ranges and domains to
|
||||||
// define an index set that can be iterated over.
|
// define an index set that can be iterated over.
|
||||||
// Ranges are single dimensional
|
// Ranges are single dimensional
|
||||||
// Domains can be multi-dimensional and can
|
// Domains can be multi-dimensional and can
|
||||||
// represent indices of different types as well.
|
// represent indices of different types as well.
|
||||||
// They are first-class citizen types, and can be assigned into variables
|
// They are first-class citizen types, and can be assigned into variables
|
||||||
var range1to10: range = 1..10; // 1, 2, 3, ..., 10
|
var range1to10: range = 1..10; // 1, 2, 3, ..., 10
|
||||||
var range2to11 = 2..11; // 2, 3, 4, ..., 11
|
var range2to11 = 2..11; // 2, 3, 4, ..., 11
|
||||||
var rangeThistoThat: range = thisInt..thatInt; // using variables
|
var rangeThistoThat: range = thisInt..thatInt; // using variables
|
||||||
var rangeEmpty: range = 100..-100 ; // this is valid but contains no indices
|
var rangeEmpty: range = 100..-100 ; // this is valid but contains no indices
|
||||||
|
|
||||||
// Ranges can be unbounded
|
// Ranges can be unbounded
|
||||||
var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ;
|
var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ;
|
||||||
// 1, 2, 3, 4, 5, ...
|
// 1, 2, 3, 4, 5, ...
|
||||||
// Note: the range(boundedType= ... ) is only
|
// Note: the range(boundedType= ... ) is only
|
||||||
// necessary if we explicitly type the variable
|
// necessary if we explicitly type the variable
|
||||||
|
|
||||||
var rangeNegInfto1 = ..1; // ..., -4, -3, -2, -1, 0, 1
|
var rangeNegInfto1 = ..1; // ..., -4, -3, -2, -1, 0, 1
|
||||||
|
|
||||||
// Ranges can be strided using the 'by' operator.
|
// Ranges can be strided using the 'by' operator.
|
||||||
var range2to10by2: range(stridable=true) = 2..10 by 2; // 2, 4, 6, 8, 10
|
var range2to10by2: range(stridable=true) = 2..10 by 2; // 2, 4, 6, 8, 10
|
||||||
// Note: the range(stridable=true) is only
|
// Note: the range(stridable=true) is only
|
||||||
// necessary if we explicitly type the variable
|
// necessary if we explicitly type the variable
|
||||||
|
|
||||||
// Use by to create a reverse range
|
// Use by to create a reverse range
|
||||||
@ -275,9 +275,9 @@ var rangeCountBy: range(stridable=true) = -5..#12 by 2; // -5, -3, -1, 1, 3, 5
|
|||||||
writeln( rangeCountBy );
|
writeln( rangeCountBy );
|
||||||
|
|
||||||
// Can query properties of the range
|
// Can query properties of the range
|
||||||
// Print the first index, last index, number of indices,
|
// Print the first index, last index, number of indices,
|
||||||
// stride, and ask if 2 is include in the range
|
// stride, and ask if 2 is include in the range
|
||||||
writeln( ( rangeCountBy.first, rangeCountBy.last, rangeCountBy.length,
|
writeln( ( rangeCountBy.first, rangeCountBy.last, rangeCountBy.length,
|
||||||
rangeCountBy.stride, rangeCountBy.member( 2 ) ) );
|
rangeCountBy.stride, rangeCountBy.member( 2 ) ) );
|
||||||
|
|
||||||
for i in rangeCountBy{
|
for i in rangeCountBy{
|
||||||
@ -307,9 +307,9 @@ var stringSet: domain(string); // empty set of strings
|
|||||||
stringSet += "a";
|
stringSet += "a";
|
||||||
stringSet += "b";
|
stringSet += "b";
|
||||||
stringSet += "c";
|
stringSet += "c";
|
||||||
stringSet += "a"; // Redundant add "a"
|
stringSet += "a"; // Redundant add "a"
|
||||||
stringSet -= "c"; // Remove "c"
|
stringSet -= "c"; // Remove "c"
|
||||||
writeln( stringSet );
|
writeln( stringSet );
|
||||||
|
|
||||||
// Both ranges and domains can be sliced to produce a range or domain with the
|
// Both ranges and domains can be sliced to produce a range or domain with the
|
||||||
// intersection of indices
|
// intersection of indices
|
||||||
@ -332,13 +332,13 @@ var intArray2: [{1..10}] int; //equivalent
|
|||||||
for i in 1..10 do
|
for i in 1..10 do
|
||||||
intArray[i] = -i;
|
intArray[i] = -i;
|
||||||
writeln( intArray );
|
writeln( intArray );
|
||||||
// We cannot access intArray[0] because it exists outside
|
// We cannot access intArray[0] because it exists outside
|
||||||
// of the index set, {1..10}, we defined it to have.
|
// of the index set, {1..10}, we defined it to have.
|
||||||
// intArray[11] is illegal for the same reason.
|
// intArray[11] is illegal for the same reason.
|
||||||
|
|
||||||
var realDomain: domain(2) = {1..5,1..7};
|
var realDomain: domain(2) = {1..5,1..7};
|
||||||
var realArray: [realDomain] real;
|
var realArray: [realDomain] real;
|
||||||
var realArray2: [1..5,1..7] real; // Equivalent
|
var realArray2: [1..5,1..7] real; // Equivalent
|
||||||
var realArray3: [{1..5,1..7}] real; // Equivalent
|
var realArray3: [{1..5,1..7}] real; // Equivalent
|
||||||
|
|
||||||
for i in 1..5 {
|
for i in 1..5 {
|
||||||
@ -350,8 +350,8 @@ for i in 1..5 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Arrays have domains as members that we can iterate over
|
// Arrays have domains as members that we can iterate over
|
||||||
for idx in realArray.domain { // Again, idx is a 2*int tuple
|
for idx in realArray.domain { // Again, idx is a 2*int tuple
|
||||||
realArray[idx] = 1 / realArray[idx[1],idx[2]]; // Access by tuple and list
|
realArray[idx] = 1 / realArray[idx[1],idx[2]]; // Access by tuple and list
|
||||||
}
|
}
|
||||||
|
|
||||||
writeln( realArray );
|
writeln( realArray );
|
||||||
@ -377,7 +377,7 @@ var thatArray : [{0..5}] int;
|
|||||||
// Simply assign one to the other.
|
// Simply assign one to the other.
|
||||||
// This copies thisArray into thatArray, instead of just creating a reference.
|
// This copies thisArray into thatArray, instead of just creating a reference.
|
||||||
// Modifying thisArray does not also modify thatArray.
|
// Modifying thisArray does not also modify thatArray.
|
||||||
thatArray = thisArray;
|
thatArray = thisArray;
|
||||||
thatArray[1] = -1;
|
thatArray[1] = -1;
|
||||||
writeln( (thisArray, thatArray) );
|
writeln( (thisArray, thatArray) );
|
||||||
|
|
||||||
@ -389,12 +389,12 @@ writeln( (thisArray, thatArray) );
|
|||||||
var thisPlusThat = thisArray + thatArray;
|
var thisPlusThat = thisArray + thatArray;
|
||||||
writeln( thisPlusThat );
|
writeln( thisPlusThat );
|
||||||
|
|
||||||
// Arrays and loops can also be expressions, where loop
|
// Arrays and loops can also be expressions, where loop
|
||||||
// body's expression is the result of each iteration.
|
// body's expression is the result of each iteration.
|
||||||
var arrayFromLoop = for i in 1..10 do i;
|
var arrayFromLoop = for i in 1..10 do i;
|
||||||
writeln( arrayFromLoop );
|
writeln( arrayFromLoop );
|
||||||
|
|
||||||
// An expression can result in nothing,
|
// An expression can result in nothing,
|
||||||
// such as when filtering with an if-expression
|
// such as when filtering with an if-expression
|
||||||
var evensOrFives = for i in 1..10 do if (i % 2 == 0 || i % 5 == 0) then i;
|
var evensOrFives = for i in 1..10 do if (i % 2 == 0 || i % 5 == 0) then i;
|
||||||
|
|
||||||
@ -407,7 +407,7 @@ var evensOrFivesAgain = [ i in 1..10 ] if (i % 2 == 0 || i % 5 == 0) then i;
|
|||||||
// Or over the values of the array
|
// Or over the values of the array
|
||||||
arrayFromLoop = [ value in arrayFromLoop ] value + 1;
|
arrayFromLoop = [ value in arrayFromLoop ] value + 1;
|
||||||
|
|
||||||
// Note: this notation can get somewhat tricky. For example:
|
// Note: this notation can get somewhat tricky. For example:
|
||||||
// evensOrFives = [ i in 1..10 ] if (i % 2 == 0 || i % 5 == 0) then i;
|
// evensOrFives = [ i in 1..10 ] if (i % 2 == 0 || i % 5 == 0) then i;
|
||||||
// would break.
|
// would break.
|
||||||
// The reasons for this are explained in depth when discussing zipped iterators.
|
// The reasons for this are explained in depth when discussing zipped iterators.
|
||||||
@ -431,7 +431,7 @@ proc addThree( n ) {
|
|||||||
doublePrint( addThree( fibonacci( 20 ) ) );
|
doublePrint( addThree( fibonacci( 20 ) ) );
|
||||||
|
|
||||||
// Can also take 'unlimited' number of parameters
|
// Can also take 'unlimited' number of parameters
|
||||||
proc maxOf( x ...?k ) {
|
proc maxOf( x ...?k ) {
|
||||||
// x refers to a tuple of one type, with k elements
|
// x refers to a tuple of one type, with k elements
|
||||||
var maximum = x[1];
|
var maximum = x[1];
|
||||||
for i in 2..k do maximum = if (maximum < x[i]) then x[i] else maximum;
|
for i in 2..k do maximum = if (maximum < x[i]) then x[i] else maximum;
|
||||||
@ -439,7 +439,7 @@ proc maxOf( x ...?k ) {
|
|||||||
}
|
}
|
||||||
writeln( maxOf( 1, -10, 189, -9071982, 5, 17, 20001, 42 ) );
|
writeln( maxOf( 1, -10, 189, -9071982, 5, 17, 20001, 42 ) );
|
||||||
|
|
||||||
// The ? operator is called the query operator, and is used to take
|
// The ? operator is called the query operator, and is used to take
|
||||||
// undetermined values (like tuple or array sizes, and generic types).
|
// undetermined values (like tuple or array sizes, and generic types).
|
||||||
|
|
||||||
// Taking arrays as parameters.
|
// Taking arrays as parameters.
|
||||||
@ -463,7 +463,7 @@ writeln( defaultsProc( x=11 ) );
|
|||||||
writeln( defaultsProc( x=12, y=5.432 ) );
|
writeln( defaultsProc( x=12, y=5.432 ) );
|
||||||
writeln( defaultsProc( y=9.876, x=13 ) );
|
writeln( defaultsProc( y=9.876, x=13 ) );
|
||||||
|
|
||||||
// Intent modifiers on the arguments convey how
|
// Intent modifiers on the arguments convey how
|
||||||
// those arguments are passed to the procedure
|
// those arguments are passed to the procedure
|
||||||
// in: copy arg in, but not out
|
// in: copy arg in, but not out
|
||||||
// out: copy arg out, but not in
|
// out: copy arg out, but not in
|
||||||
@ -489,18 +489,18 @@ writeln( "Outside After: ", (inVar, outVar, inoutVar, refVar) );
|
|||||||
// Similarly we can define intents on the return type
|
// Similarly we can define intents on the return type
|
||||||
// refElement returns a reference to an element of array
|
// refElement returns a reference to an element of array
|
||||||
proc refElement( array : [?D] ?T, idx ) ref : T {
|
proc refElement( array : [?D] ?T, idx ) ref : T {
|
||||||
return array[ idx ]; // returns a reference to
|
return array[ idx ]; // returns a reference to
|
||||||
}
|
}
|
||||||
|
|
||||||
var myChangingArray : [1..5] int = [1,2,3,4,5];
|
var myChangingArray : [1..5] int = [1,2,3,4,5];
|
||||||
writeln( myChangingArray );
|
writeln( myChangingArray );
|
||||||
// Store reference to element in ref variable
|
// Store reference to element in ref variable
|
||||||
ref refToElem = refElement( myChangingArray, 5 );
|
ref refToElem = refElement( myChangingArray, 5 );
|
||||||
writeln( refToElem );
|
writeln( refToElem );
|
||||||
refToElem = -2; // modify reference which modifies actual value in array
|
refToElem = -2; // modify reference which modifies actual value in array
|
||||||
writeln( refToElem );
|
writeln( refToElem );
|
||||||
writeln( myChangingArray );
|
writeln( myChangingArray );
|
||||||
// This makes more practical sense for class methods where references to
|
// This makes more practical sense for class methods where references to
|
||||||
// elements in a data-structure are returned via a method or iterator
|
// elements in a data-structure are returned via a method or iterator
|
||||||
|
|
||||||
// We can query the type of arguments to generic procedures
|
// We can query the type of arguments to generic procedures
|
||||||
@ -520,21 +520,21 @@ genericProc( 1.0+2.0i, 3.0+4.0i );
|
|||||||
|
|
||||||
// We can also enforce a form of polymorphism with the 'where' clause
|
// We can also enforce a form of polymorphism with the 'where' clause
|
||||||
// This allows the compiler to decide which function to use.
|
// This allows the compiler to decide which function to use.
|
||||||
// Note: that means that all information needs to be known at compile-time.
|
// Note: that means that all information needs to be known at compile-time.
|
||||||
// The param modifier on the arg is used to enforce this constraint.
|
// The param modifier on the arg is used to enforce this constraint.
|
||||||
proc whereProc( param N : int ): void
|
proc whereProc( param N : int ): void
|
||||||
where ( N > 0 ) {
|
where ( N > 0 ) {
|
||||||
writeln( "N is greater than 0" );
|
writeln( "N is greater than 0" );
|
||||||
}
|
}
|
||||||
|
|
||||||
proc whereProc( param N : int ): void
|
proc whereProc( param N : int ): void
|
||||||
where ( N < 0 ) {
|
where ( N < 0 ) {
|
||||||
writeln( "N is less than 0" );
|
writeln( "N is less than 0" );
|
||||||
}
|
}
|
||||||
|
|
||||||
whereProc( 10 );
|
whereProc( 10 );
|
||||||
whereProc( -1 );
|
whereProc( -1 );
|
||||||
// whereProc( 0 ) would result in a compiler error because there
|
// whereProc( 0 ) would result in a compiler error because there
|
||||||
// are no functions that satisfy the where clause's condition.
|
// are no functions that satisfy the where clause's condition.
|
||||||
// We could have defined a whereProc without a where clause that would then have
|
// We could have defined a whereProc without a where clause that would then have
|
||||||
// served as a catch all for all the other cases (of which there is only one).
|
// served as a catch all for all the other cases (of which there is only one).
|
||||||
@ -543,7 +543,7 @@ whereProc( -1 );
|
|||||||
// We can define the unary operators:
|
// We can define the unary operators:
|
||||||
// + - ! ~
|
// + - ! ~
|
||||||
// and the binary operators:
|
// and the binary operators:
|
||||||
// + - * / % ** == <= >= < > << >> & | ˆ by
|
// + - * / % ** == <= >= < > << >> & | ˆ by
|
||||||
// += -= *= /= %= **= &= |= ˆ= <<= >>= <=>
|
// += -= *= /= %= **= &= |= ˆ= <<= >>= <=>
|
||||||
|
|
||||||
// Boolean exclusive or operator
|
// Boolean exclusive or operator
|
||||||
@ -569,14 +569,14 @@ Note: You could break everything if you get careless with your overloads.
|
|||||||
This here will break everything. Don't do it.
|
This here will break everything. Don't do it.
|
||||||
proc +( left: int, right: int ): int{
|
proc +( left: int, right: int ): int{
|
||||||
return left - right;
|
return left - right;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Iterators are a sisters to the procedure, and almost
|
// Iterators are a sisters to the procedure, and almost
|
||||||
// everything about procedures also applies to iterators
|
// everything about procedures also applies to iterators
|
||||||
// However, instead of returning a single value,
|
// However, instead of returning a single value,
|
||||||
// iterators yield many values to a loop.
|
// iterators yield many values to a loop.
|
||||||
// This is useful when a complicated set or order of iterations is needed but
|
// This is useful when a complicated set or order of iterations is needed but
|
||||||
// allows the code defining the iterations to be separate from the loop body.
|
// allows the code defining the iterations to be separate from the loop body.
|
||||||
iter oddsThenEvens( N: int ): int {
|
iter oddsThenEvens( N: int ): int {
|
||||||
for i in 1..N by 2 do
|
for i in 1..N by 2 do
|
||||||
@ -601,15 +601,15 @@ for i in absolutelyNothing( 10 ){
|
|||||||
writeln( "Woa there! absolutelyNothing yielded ", i );
|
writeln( "Woa there! absolutelyNothing yielded ", i );
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can zipper together two or more iterators (who have the same number
|
// We can zipper together two or more iterators (who have the same number
|
||||||
// of iterations) using zip() to create a single zipped iterator, where each
|
// of iterations) using zip() to create a single zipped iterator, where each
|
||||||
// iteration of the zipped iterator yields a tuple of one value yielded
|
// iteration of the zipped iterator yields a tuple of one value yielded
|
||||||
// from each iterator.
|
// from each iterator.
|
||||||
// Ranges have implicit iterators
|
// Ranges have implicit iterators
|
||||||
for (positive, negative) in zip( 1..5, -5..-1) do
|
for (positive, negative) in zip( 1..5, -5..-1) do
|
||||||
writeln( (positive, negative) );
|
writeln( (positive, negative) );
|
||||||
|
|
||||||
// Zipper iteration is quite important in the assignment of arrays,
|
// Zipper iteration is quite important in the assignment of arrays,
|
||||||
// slices of arrays, and array/loop expressions.
|
// slices of arrays, and array/loop expressions.
|
||||||
var fromThatArray : [1..#5] int = [1,2,3,4,5];
|
var fromThatArray : [1..#5] int = [1,2,3,4,5];
|
||||||
var toThisArray : [100..#5] int;
|
var toThisArray : [100..#5] int;
|
||||||
@ -629,11 +629,11 @@ for (i, j) in zip( toThisArray.domain, -100..#5 ){
|
|||||||
}
|
}
|
||||||
writeln( toThisArray );
|
writeln( toThisArray );
|
||||||
|
|
||||||
// This is all very important in undestanding why the statement
|
// This is all very important in understanding why the statement
|
||||||
// var iterArray : [1..10] int = [ i in 1..10 ] if ( i % 2 == 1 ) then j;
|
// var iterArray : [1..10] int = [ i in 1..10 ] if ( i % 2 == 1 ) then j;
|
||||||
// exhibits a runtime error.
|
// exhibits a runtime error.
|
||||||
// Even though the domain of the array and the loop-expression are
|
// Even though the domain of the array and the loop-expression are
|
||||||
// the same size, the body of the expression can be though of as an iterator.
|
// the same size, the body of the expression can be thought of as an iterator.
|
||||||
// Because iterators can yield nothing, that iterator yields a different number
|
// Because iterators can yield nothing, that iterator yields a different number
|
||||||
// of things than the domain of the array or loop, which is not allowed.
|
// of things than the domain of the array or loop, which is not allowed.
|
||||||
|
|
||||||
@ -641,8 +641,8 @@ writeln( toThisArray );
|
|||||||
// They currently lack privatization
|
// They currently lack privatization
|
||||||
class MyClass {
|
class MyClass {
|
||||||
// Member variables
|
// Member variables
|
||||||
var memberInt : int;
|
var memberInt : int;
|
||||||
var memberBool : bool = true;
|
var memberBool : bool = true;
|
||||||
|
|
||||||
// Classes have default constructors that don't need to be coded (see below)
|
// Classes have default constructors that don't need to be coded (see below)
|
||||||
// Our explicitly defined constructor
|
// Our explicitly defined constructor
|
||||||
@ -659,28 +659,28 @@ class MyClass {
|
|||||||
proc setMemberInt( val: int ){
|
proc setMemberInt( val: int ){
|
||||||
this.memberInt = val;
|
this.memberInt = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc setMemberBool( val: bool ){
|
proc setMemberBool( val: bool ){
|
||||||
this.memberBool = val;
|
this.memberBool = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc getMemberInt( ): int{
|
proc getMemberInt( ): int{
|
||||||
return this.memberInt;
|
return this.memberInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc getMemberBool( ): bool {
|
proc getMemberBool( ): bool {
|
||||||
return this.memberBool;
|
return this.memberBool;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct using default constructor, using default values
|
// Construct using default constructor, using default values
|
||||||
var myObject = new MyClass( 10 );
|
var myObject = new MyClass( 10 );
|
||||||
myObject = new MyClass( memberInt = 10 ); // Equivalent
|
myObject = new MyClass( memberInt = 10 ); // Equivalent
|
||||||
writeln( myObject.getMemberInt( ) );
|
writeln( myObject.getMemberInt( ) );
|
||||||
// ... using our values
|
// ... using our values
|
||||||
var myDiffObject = new MyClass( -1, true );
|
var myDiffObject = new MyClass( -1, true );
|
||||||
myDiffObject = new MyClass( memberInt = -1,
|
myDiffObject = new MyClass( memberInt = -1,
|
||||||
memberBool = true ); // Equivalent
|
memberBool = true ); // Equivalent
|
||||||
writeln( myDiffObject );
|
writeln( myDiffObject );
|
||||||
|
|
||||||
@ -689,7 +689,7 @@ var myOtherObject = new MyClass( 1.95 );
|
|||||||
myOtherObject = new MyClass( val = 1.95 ); // Equivalent
|
myOtherObject = new MyClass( val = 1.95 ); // Equivalent
|
||||||
writeln( myOtherObject.getMemberInt( ) );
|
writeln( myOtherObject.getMemberInt( ) );
|
||||||
|
|
||||||
// We can define an operator on our class as well but
|
// We can define an operator on our class as well but
|
||||||
// the definition has to be outside the class definition
|
// the definition has to be outside the class definition
|
||||||
proc +( A : MyClass, B : MyClass) : MyClass {
|
proc +( A : MyClass, B : MyClass) : MyClass {
|
||||||
return new MyClass( memberInt = A.getMemberInt( ) + B.getMemberInt( ),
|
return new MyClass( memberInt = A.getMemberInt( ) + B.getMemberInt( ),
|
||||||
@ -715,46 +715,46 @@ class GenericClass {
|
|||||||
type classType;
|
type classType;
|
||||||
var classDomain: domain(1);
|
var classDomain: domain(1);
|
||||||
var classArray: [classDomain] classType;
|
var classArray: [classDomain] classType;
|
||||||
|
|
||||||
// Explicit constructor
|
// Explicit constructor
|
||||||
proc GenericClass( type classType, elements : int ){
|
proc GenericClass( type classType, elements : int ){
|
||||||
this.classDomain = {1..#elements};
|
this.classDomain = {1..#elements};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy constructor
|
// Copy constructor
|
||||||
// Note: We still have to put the type as an argument, but we can
|
// Note: We still have to put the type as an argument, but we can
|
||||||
// default to the type of the other object using the query (?) operator
|
// default to the type of the other object using the query (?) operator
|
||||||
// Further, we can take advantage of this to allow our copy constructor
|
// Further, we can take advantage of this to allow our copy constructor
|
||||||
// to copy classes of different types and cast on the fly
|
// to copy classes of different types and cast on the fly
|
||||||
proc GenericClass( other : GenericClass(?otherType),
|
proc GenericClass( other : GenericClass(?otherType),
|
||||||
type classType = otherType ) {
|
type classType = otherType ) {
|
||||||
this.classDomain = other.classDomain;
|
this.classDomain = other.classDomain;
|
||||||
// Copy and cast
|
// Copy and cast
|
||||||
for idx in this.classDomain do this[ idx ] = other[ idx ] : classType;
|
for idx in this.classDomain do this[ idx ] = other[ idx ] : classType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define bracket notation on a GenericClass
|
// Define bracket notation on a GenericClass
|
||||||
// object so it can behave like a normal array
|
// object so it can behave like a normal array
|
||||||
// i.e. objVar[ i ] or objVar( i )
|
// i.e. objVar[ i ] or objVar( i )
|
||||||
proc this( i : int ) ref : classType {
|
proc this( i : int ) ref : classType {
|
||||||
return this.classArray[ i ];
|
return this.classArray[ i ];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define an implicit iterator for the class
|
// Define an implicit iterator for the class
|
||||||
// to yield values from the array to a loop
|
// to yield values from the array to a loop
|
||||||
// i.e. for i in objVar do ....
|
// i.e. for i in objVar do ....
|
||||||
iter these( ) ref : classType {
|
iter these( ) ref : classType {
|
||||||
for i in this.classDomain do
|
for i in this.classDomain do
|
||||||
yield this[i];
|
yield this[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var realList = new GenericClass( real, 10 );
|
var realList = new GenericClass( real, 10 );
|
||||||
// We can assign to the member array of the object using the bracket
|
// We can assign to the member array of the object using the bracket
|
||||||
// notation that we defined ( proc this( i: int ){ ... } )
|
// notation that we defined ( proc this( i: int ){ ... } )
|
||||||
for i in realList.classDomain do realList[i] = i + 1.0;
|
for i in realList.classDomain do realList[i] = i + 1.0;
|
||||||
// We can iterate over the values in our list with the iterator
|
// We can iterate over the values in our list with the iterator
|
||||||
// we defined ( iter these( ){ ... } )
|
// we defined ( iter these( ){ ... } )
|
||||||
for value in realList do write( value, ", " );
|
for value in realList do write( value, ", " );
|
||||||
writeln( );
|
writeln( );
|
||||||
@ -777,23 +777,23 @@ writeln( );
|
|||||||
module OurModule {
|
module OurModule {
|
||||||
// We can use modules inside of other modules.
|
// We can use modules inside of other modules.
|
||||||
use Time; // Time is one of the standard modules.
|
use Time; // Time is one of the standard modules.
|
||||||
|
|
||||||
// We'll use this procedure in the parallelism section.
|
// We'll use this procedure in the parallelism section.
|
||||||
proc countdown( seconds: int ){
|
proc countdown( seconds: int ){
|
||||||
for i in 1..seconds by -1 {
|
for i in 1..seconds by -1 {
|
||||||
writeln( i );
|
writeln( i );
|
||||||
sleep( 1 );
|
sleep( 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submodules of OurModule
|
// Submodules of OurModule
|
||||||
// It is possible to create arbitrarily deep module nests.
|
// It is possible to create arbitrarily deep module nests.
|
||||||
module ChildModule {
|
module ChildModule {
|
||||||
proc foo(){
|
proc foo(){
|
||||||
writeln( "ChildModule.foo()");
|
writeln( "ChildModule.foo()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module SiblingModule {
|
module SiblingModule {
|
||||||
proc foo(){
|
proc foo(){
|
||||||
writeln( "SiblingModule.foo()" );
|
writeln( "SiblingModule.foo()" );
|
||||||
@ -806,7 +806,7 @@ module OurModule {
|
|||||||
use OurModule;
|
use OurModule;
|
||||||
|
|
||||||
// At this point we have not used ChildModule or SiblingModule so their symbols
|
// At this point we have not used ChildModule or SiblingModule so their symbols
|
||||||
// (i.e. foo ) are not available to us.
|
// (i.e. foo ) are not available to us.
|
||||||
// However, the module names are, and we can explicitly call foo() through them.
|
// However, the module names are, and we can explicitly call foo() through them.
|
||||||
SiblingModule.foo(); // Calls SiblingModule.foo()
|
SiblingModule.foo(); // Calls SiblingModule.foo()
|
||||||
|
|
||||||
@ -821,13 +821,13 @@ foo(); // Less explicit call on ChildModule.foo()
|
|||||||
proc main(){
|
proc main(){
|
||||||
|
|
||||||
// Parallelism
|
// Parallelism
|
||||||
// In other languages, parallelism is typically done with
|
// In other languages, parallelism is typically done with
|
||||||
// complicated libraries and strange class structure hierarchies.
|
// complicated libraries and strange class structure hierarchies.
|
||||||
// Chapel has it baked right into the language.
|
// Chapel has it baked right into the language.
|
||||||
|
|
||||||
// A begin statement will spin the body of that statement off
|
// A begin statement will spin the body of that statement off
|
||||||
// into one new task.
|
// into one new task.
|
||||||
// A sync statement will ensure that the progress of the main
|
// A sync statement will ensure that the progress of the main
|
||||||
// task will not progress until the children have synced back up.
|
// task will not progress until the children have synced back up.
|
||||||
sync {
|
sync {
|
||||||
begin { // Start of new task's body
|
begin { // Start of new task's body
|
||||||
@ -848,7 +848,7 @@ proc main(){
|
|||||||
printFibb( 20 ); // new task
|
printFibb( 20 ); // new task
|
||||||
printFibb( 10 ); // new task
|
printFibb( 10 ); // new task
|
||||||
printFibb( 5 ); // new task
|
printFibb( 5 ); // new task
|
||||||
{
|
{
|
||||||
// This is a nested statement body and thus is a single statement
|
// This is a nested statement body and thus is a single statement
|
||||||
// to the parent statement and is executed by a single task
|
// to the parent statement and is executed by a single task
|
||||||
writeln( "this gets" );
|
writeln( "this gets" );
|
||||||
@ -867,26 +867,26 @@ proc main(){
|
|||||||
// NOTE! coforall should be used only for creating tasks!
|
// NOTE! coforall should be used only for creating tasks!
|
||||||
// Using it to iterating over a structure is very a bad idea!
|
// Using it to iterating over a structure is very a bad idea!
|
||||||
|
|
||||||
// forall loops are another parallel loop, but only create a smaller number
|
// forall loops are another parallel loop, but only create a smaller number
|
||||||
// of tasks, specifically --dataParTasksPerLocale=number of task
|
// of tasks, specifically --dataParTasksPerLocale=number of task
|
||||||
forall i in 1..100 {
|
forall i in 1..100 {
|
||||||
write( i, ", ");
|
write( i, ", ");
|
||||||
}
|
}
|
||||||
writeln( );
|
writeln( );
|
||||||
// Here we see that there are sections that are in order, followed by
|
// Here we see that there are sections that are in order, followed by
|
||||||
// a section that would not follow ( e.g. 1, 2, 3, 7, 8, 9, 4, 5, 6, ).
|
// a section that would not follow ( e.g. 1, 2, 3, 7, 8, 9, 4, 5, 6, ).
|
||||||
// This is because each task is taking on a chunk of the range 1..10
|
// This is because each task is taking on a chunk of the range 1..10
|
||||||
// (1..3, 4..6, or 7..9) doing that chunk serially, but each task happens
|
// (1..3, 4..6, or 7..9) doing that chunk serially, but each task happens
|
||||||
// in parallel.
|
// in parallel.
|
||||||
// Your results may depend on your machine and configuration
|
// Your results may depend on your machine and configuration
|
||||||
|
|
||||||
// For both the forall and coforall loops, the execution of the
|
// For both the forall and coforall loops, the execution of the
|
||||||
// parent task will not continue until all the children sync up.
|
// parent task will not continue until all the children sync up.
|
||||||
|
|
||||||
// forall loops are particularly useful for parallel iteration over arrays.
|
// forall loops are particularly useful for parallel iteration over arrays.
|
||||||
// Lets run an experiment to see how much faster a parallel loop is
|
// Lets run an experiment to see how much faster a parallel loop is
|
||||||
use Time; // Import the Time module to use Timer objects
|
use Time; // Import the Time module to use Timer objects
|
||||||
var timer: Timer;
|
var timer: Timer;
|
||||||
var myBigArray: [{1..4000,1..4000}] real; // Large array we will write into
|
var myBigArray: [{1..4000,1..4000}] real; // Large array we will write into
|
||||||
|
|
||||||
// Serial Experiment
|
// Serial Experiment
|
||||||
@ -906,7 +906,7 @@ proc main(){
|
|||||||
timer.stop( ); // Stop timer
|
timer.stop( ); // Stop timer
|
||||||
writeln( "Parallel: ", timer.elapsed( ) ); // Print elapsed time
|
writeln( "Parallel: ", timer.elapsed( ) ); // Print elapsed time
|
||||||
timer.clear( );
|
timer.clear( );
|
||||||
// You may have noticed that (depending on how many cores you have)
|
// You may have noticed that (depending on how many cores you have)
|
||||||
// that the parallel loop went faster than the serial loop
|
// that the parallel loop went faster than the serial loop
|
||||||
|
|
||||||
// The bracket style loop-expression described
|
// The bracket style loop-expression described
|
||||||
@ -914,7 +914,7 @@ proc main(){
|
|||||||
[ val in myBigArray ] val = 1 / val; // Parallel operation
|
[ val in myBigArray ] val = 1 / val; // Parallel operation
|
||||||
|
|
||||||
// Atomic variables, common to many languages, are ones whose operations
|
// Atomic variables, common to many languages, are ones whose operations
|
||||||
// occur uninterupted. Multiple threads can both modify atomic variables
|
// occur uninterrupted. Multiple threads can both modify atomic variables
|
||||||
// and can know that their values are safe.
|
// and can know that their values are safe.
|
||||||
// Chapel atomic variables can be of type bool, int, uint, and real.
|
// Chapel atomic variables can be of type bool, int, uint, and real.
|
||||||
var uranium: atomic int;
|
var uranium: atomic int;
|
||||||
@ -926,15 +926,15 @@ proc main(){
|
|||||||
writeln( uranium.read() );
|
writeln( uranium.read() );
|
||||||
|
|
||||||
var replaceWith = 239;
|
var replaceWith = 239;
|
||||||
var was = uranium.exchange( replaceWith );
|
var was = uranium.exchange( replaceWith );
|
||||||
writeln( "uranium was ", was, " but is now ", replaceWith );
|
writeln( "uranium was ", was, " but is now ", replaceWith );
|
||||||
|
|
||||||
var isEqualTo = 235;
|
var isEqualTo = 235;
|
||||||
if ( uranium.compareExchange( isEqualTo, replaceWith ) ) {
|
if ( uranium.compareExchange( isEqualTo, replaceWith ) ) {
|
||||||
writeln( "uranium was equal to ", isEqualTo,
|
writeln( "uranium was equal to ", isEqualTo,
|
||||||
" so replaced value with ", replaceWith );
|
" so replaced value with ", replaceWith );
|
||||||
} else {
|
} else {
|
||||||
writeln( "uranium was not equal to ", isEqualTo,
|
writeln( "uranium was not equal to ", isEqualTo,
|
||||||
" so value stays the same... whatever it was" );
|
" so value stays the same... whatever it was" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -960,13 +960,13 @@ proc main(){
|
|||||||
begin { // Reader task
|
begin { // Reader task
|
||||||
writeln( "Reader: waiting to read." );
|
writeln( "Reader: waiting to read." );
|
||||||
var read_sync = someSyncVar$;
|
var read_sync = someSyncVar$;
|
||||||
writeln( "value is ", read_sync );
|
writeln( "Reader: value is ", read_sync );
|
||||||
}
|
}
|
||||||
|
|
||||||
begin { // Writer task
|
begin { // Writer task
|
||||||
writeln( "Writer: will write in..." );
|
writeln( "Writer: will write in..." );
|
||||||
countdown( 3 );
|
countdown( 3 );
|
||||||
someSyncVar$ = 123;
|
someSyncVar$ = 123;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,14 +989,14 @@ proc main(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heres an example of using atomics and a synch variable to create a
|
// Heres an example of using atomics and a synch variable to create a
|
||||||
// count-down mutex (also known as a multiplexer)
|
// count-down mutex (also known as a multiplexer)
|
||||||
var count: atomic int; // our counter
|
var count: atomic int; // our counter
|
||||||
var lock$: sync bool; // the mutex lock
|
var lock$: sync bool; // the mutex lock
|
||||||
|
|
||||||
count.write( 2 ); // Only let two tasks in at a time.
|
count.write( 2 ); // Only let two tasks in at a time.
|
||||||
lock$.writeXF( true ); // Set lock$ to full (unlocked)
|
lock$.writeXF( true ); // Set lock$ to full (unlocked)
|
||||||
// Note: The value doesnt actually matter, just the state
|
// Note: The value doesnt actually matter, just the state
|
||||||
// (full:unlocked / empty:locked)
|
// (full:unlocked / empty:locked)
|
||||||
// Also, writeXF() fills (F) the sync var regardless of its state (X)
|
// Also, writeXF() fills (F) the sync var regardless of its state (X)
|
||||||
|
|
||||||
@ -1005,10 +1005,10 @@ proc main(){
|
|||||||
do{
|
do{
|
||||||
lock$; // Read lock$ (wait)
|
lock$; // Read lock$ (wait)
|
||||||
}while ( count.read() < 1 ); // Keep waiting until a spot opens up
|
}while ( count.read() < 1 ); // Keep waiting until a spot opens up
|
||||||
|
|
||||||
count.sub(1); // decrement the counter
|
count.sub(1); // decrement the counter
|
||||||
lock$.writeXF( true ); // Set lock$ to full (signal)
|
lock$.writeXF( true ); // Set lock$ to full (signal)
|
||||||
|
|
||||||
// Actual 'work'
|
// Actual 'work'
|
||||||
writeln( "Task #", task, " doing work." );
|
writeln( "Task #", task, " doing work." );
|
||||||
sleep( 2 );
|
sleep( 2 );
|
||||||
@ -1027,13 +1027,13 @@ proc main(){
|
|||||||
|
|
||||||
// 'maxloc' gives max value and index of the max value
|
// 'maxloc' gives max value and index of the max value
|
||||||
// Note: We have to zip the array and domain together with the zip iterator
|
// Note: We have to zip the array and domain together with the zip iterator
|
||||||
var (theMaxValue, idxOfMax) = maxloc reduce zip(listOfValues,
|
var (theMaxValue, idxOfMax) = maxloc reduce zip(listOfValues,
|
||||||
listOfValues.domain);
|
listOfValues.domain);
|
||||||
|
|
||||||
writeln( (sumOfValues, maxValue, idxOfMax, listOfValues[ idxOfMax ] ) );
|
writeln( (sumOfValues, maxValue, idxOfMax, listOfValues[ idxOfMax ] ) );
|
||||||
|
|
||||||
// Scans apply the operation incrementally and return an array of the
|
// Scans apply the operation incrementally and return an array of the
|
||||||
// value of the operation at that index as it progressed through the
|
// value of the operation at that index as it progressed through the
|
||||||
// array from array.domain.low to array.domain.high
|
// array from array.domain.low to array.domain.high
|
||||||
var runningSumOfValues = + scan listOfValues;
|
var runningSumOfValues = + scan listOfValues;
|
||||||
var maxScan = max scan listOfValues;
|
var maxScan = max scan listOfValues;
|
||||||
@ -1046,14 +1046,14 @@ Who is this tutorial for?
|
|||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
This tutorial is for people who want to learn the ropes of chapel without having to hear about what fiber mixture the ropes are, or how they were braided, or how the braid configurations differ between one another.
|
This tutorial is for people who want to learn the ropes of chapel without having to hear about what fiber mixture the ropes are, or how they were braided, or how the braid configurations differ between one another.
|
||||||
It won't teach you how to develop amazingly performant code, and it's not exhaustive.
|
It won't teach you how to develop amazingly performant code, and it's not exhaustive.
|
||||||
Refer to the [language specification](http://chapel.cray.com/language.html) and the [module documentation](http://chapel.cray.com/docs/latest/) for more details.
|
Refer to the [language specification](http://chapel.cray.com/language.html) and the [module documentation](http://chapel.cray.com/docs/latest/) for more details.
|
||||||
|
|
||||||
Occasionally check back here and on the [Chapel site](http://chapel.cray.com) to see if more topics have been added or more tutorials created.
|
Occasionally check back here and on the [Chapel site](http://chapel.cray.com) to see if more topics have been added or more tutorials created.
|
||||||
|
|
||||||
### What this tutorial is lacking:
|
### What this tutorial is lacking:
|
||||||
|
|
||||||
* Exposition of the standard modules
|
* Exposition of the [standard modules](http://chapel.cray.com/docs/latest/modules/modules.html)
|
||||||
* Multiple Locales (distributed memory system)
|
* Multiple Locales (distributed memory system)
|
||||||
* Records
|
* Records
|
||||||
* Parallel iterators
|
* Parallel iterators
|
||||||
@ -1061,11 +1061,11 @@ Occasionally check back here and on the [Chapel site](http://chapel.cray.com) to
|
|||||||
Your input, questions, and discoveries are important to the developers!
|
Your input, questions, and discoveries are important to the developers!
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
The Chapel language is still in-development (version 1.11.0), so there are occasional hiccups with performance and language features.
|
The Chapel language is still in-development (version 1.12.0), so there are occasional hiccups with performance and language features.
|
||||||
The more information you give the Chapel development team about issues you encounter or features you would like to see, the better the language becomes.
|
The more information you give the Chapel development team about issues you encounter or features you would like to see, the better the language becomes.
|
||||||
Feel free to email the team and other developers through the [sourceforge email lists](https://sourceforge.net/p/chapel/mailman).
|
Feel free to email the team and other developers through the [sourceforge email lists](https://sourceforge.net/p/chapel/mailman).
|
||||||
|
|
||||||
If you're really interested in the development of the compiler or contributing to the project,
|
If you're really interested in the development of the compiler or contributing to the project,
|
||||||
[check out the master Github repository](https://github.com/chapel-lang/chapel).
|
[check out the master Github repository](https://github.com/chapel-lang/chapel).
|
||||||
It is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).
|
It is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).
|
||||||
|
|
||||||
@ -1074,14 +1074,14 @@ Installing the Compiler
|
|||||||
|
|
||||||
Chapel can be built and installed on your average 'nix machine (and cygwin).
|
Chapel can be built and installed on your average 'nix machine (and cygwin).
|
||||||
[Download the latest release version](https://github.com/chapel-lang/chapel/releases/)
|
[Download the latest release version](https://github.com/chapel-lang/chapel/releases/)
|
||||||
and its as easy as
|
and it's as easy as
|
||||||
|
|
||||||
1. `tar -xvf chapel-1.11.0.tar.gz`
|
1. `tar -xvf chapel-1.12.0.tar.gz`
|
||||||
2. `cd chapel-1.11.0`
|
2. `cd chapel-1.12.0`
|
||||||
3. `make`
|
3. `make`
|
||||||
4. `source util/setchplenv.bash # or .sh or .csh or .fish`
|
4. `source util/setchplenv.bash # or .sh or .csh or .fish`
|
||||||
|
|
||||||
You will need to `source util/setchplenv.EXT` from within the Chapel directory (`$CHPL_HOME`) every time your terminal starts so its suggested that you drop that command in a script that will get executed on startup (like .bashrc).
|
You will need to `source util/setchplenv.EXT` from within the Chapel directory (`$CHPL_HOME`) every time your terminal starts so it's suggested that you drop that command in a script that will get executed on startup (like .bashrc).
|
||||||
|
|
||||||
Chapel is easily installed with Brew for OS X
|
Chapel is easily installed with Brew for OS X
|
||||||
|
|
||||||
@ -1100,4 +1100,4 @@ Notable arguments:
|
|||||||
* `--fast`: enables a number of optimizations and disables array bounds checks. Should only enable when application is stable.
|
* `--fast`: enables a number of optimizations and disables array bounds checks. Should only enable when application is stable.
|
||||||
* `--set <Symbol Name>=<Value>`: set config param `<Symbol Name>` to `<Value>` at compile-time.
|
* `--set <Symbol Name>=<Value>`: set config param `<Symbol Name>` to `<Value>` at compile-time.
|
||||||
* `--main-module <Module Name>`: use the main() procedure found in the module `<Module Name>` as the executable's main.
|
* `--main-module <Module Name>`: use the main() procedure found in the module `<Module Name>` as the executable's main.
|
||||||
* `--module-dir <Directory>`: includes `<Directory>` in the module search path.
|
* `--module-dir <Directory>`: includes `<Directory>` in the module search path.
|
||||||
|
@ -142,11 +142,11 @@ You'll want to be familiar with Clojure. Make sure you understand everything in
|
|||||||
|
|
||||||
### Further Reading
|
### Further Reading
|
||||||
|
|
||||||
Writing Macros from [Clojure for the Brave and True](http://www.braveclojure.com/)
|
Writing Macros from [Clojure for the Brave and True](http://www.braveclojure.com/)
|
||||||
[http://www.braveclojure.com/writing-macros/](http://www.braveclojure.com/writing-macros/)
|
[http://www.braveclojure.com/writing-macros/](http://www.braveclojure.com/writing-macros/)
|
||||||
|
|
||||||
Official docs
|
Official docs
|
||||||
[http://clojure.org/macros](http://clojure.org/macros)
|
[http://clojure.org/macros](http://clojure.org/macros)
|
||||||
|
|
||||||
When to use macros?
|
When to use macros?
|
||||||
[http://dunsmor.com/lisp/onlisp/onlisp_12.html](http://dunsmor.com/lisp/onlisp/onlisp_12.html)
|
[http://dunsmor.com/lisp/onlisp/onlisp_12.html](http://dunsmor.com/lisp/onlisp/onlisp_12.html)
|
||||||
|
@ -264,6 +264,31 @@ keymap ; => {:a 1, :b 2, :c 3}
|
|||||||
(print "Saying hello to " name)
|
(print "Saying hello to " name)
|
||||||
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
|
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
|
||||||
|
|
||||||
|
|
||||||
|
; Use the threading macros (-> and ->>) to express transformations of
|
||||||
|
; data more clearly.
|
||||||
|
|
||||||
|
; The "Thread-first" macro (->) inserts into each form the result of
|
||||||
|
; the previous, as the first argument (second item)
|
||||||
|
(->
|
||||||
|
{:a 1 :b 2}
|
||||||
|
(assoc :c 3) ;=> (assoc {:a 1 :b 2} :c 3)
|
||||||
|
(dissoc :b)) ;=> (dissoc (assoc {:a 1 :b 2} :c 3) :b)
|
||||||
|
|
||||||
|
; This expression could be written as:
|
||||||
|
; (dissoc (assoc {:a 1 :b 2} :c 3) :b)
|
||||||
|
; and evaluates to {:a 1 :c 3}
|
||||||
|
|
||||||
|
; The double arrow does the same thing, but inserts the result of
|
||||||
|
; each line at the *end* of the form. This is useful for collection
|
||||||
|
; operations in particular:
|
||||||
|
(->>
|
||||||
|
(range 10)
|
||||||
|
(map inc) ;=> (map inc (range 10)
|
||||||
|
(filter odd?) ;=> (filter odd? (map inc (range 10))
|
||||||
|
(into [])) ;=> (into [] (filter odd? (map inc (range 10)))
|
||||||
|
; Result: [1 3 5 7 9]
|
||||||
|
|
||||||
; Modules
|
; Modules
|
||||||
;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ contributors:
|
|||||||
filename: coffeescript.coffee
|
filename: coffeescript.coffee
|
||||||
---
|
---
|
||||||
|
|
||||||
CoffeeScript is a little language that compiles one-to-one into the equivalent JavaScript, and there is no interpretation at runtime.
|
CoffeeScript is a little language that compiles one-to-one into the equivalent JavaScript, and there is no interpretation at runtime.
|
||||||
As one of the succeeders of JavaScript, CoffeeScript tries its best to output readable, pretty-printed and smooth-running JavaScript codes working well in every JavaScript runtime.
|
As one of the successors to JavaScript, CoffeeScript tries its best to output readable, pretty-printed and smooth-running JavaScript code, which works well in every JavaScript runtime.
|
||||||
|
|
||||||
See also [the CoffeeScript website](http://coffeescript.org/), which has a complete tutorial on CoffeeScript.
|
See also [the CoffeeScript website](http://coffeescript.org/), which has a complete tutorial on CoffeeScript.
|
||||||
|
|
||||||
@ -54,35 +54,35 @@ math =
|
|||||||
square: square
|
square: square
|
||||||
cube: (x) -> x * square x
|
cube: (x) -> x * square x
|
||||||
#=> var math = {
|
#=> var math = {
|
||||||
# "root": Math.sqrt,
|
# "root": Math.sqrt,
|
||||||
# "square": square,
|
# "square": square,
|
||||||
# "cube": function(x) { return x * square(x); }
|
# "cube": function(x) { return x * square(x); }
|
||||||
#}
|
# };
|
||||||
|
|
||||||
# Splats:
|
# Splats:
|
||||||
race = (winner, runners...) ->
|
race = (winner, runners...) ->
|
||||||
print winner, runners
|
print winner, runners
|
||||||
#=>race = function() {
|
#=>race = function() {
|
||||||
# var runners, winner;
|
# var runners, winner;
|
||||||
# winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
# winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
||||||
# return print(winner, runners);
|
# return print(winner, runners);
|
||||||
#};
|
# };
|
||||||
|
|
||||||
# Existence:
|
# Existence:
|
||||||
alert "I knew it!" if elvis?
|
alert "I knew it!" if elvis?
|
||||||
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
|
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
|
||||||
|
|
||||||
# Array comprehensions:
|
# Array comprehensions:
|
||||||
cubes = (math.cube num for num in list)
|
cubes = (math.cube num for num in list)
|
||||||
#=>cubes = (function() {
|
#=>cubes = (function() {
|
||||||
# var _i, _len, _results;
|
# var _i, _len, _results;
|
||||||
# _results = [];
|
# _results = [];
|
||||||
# for (_i = 0, _len = list.length; _i < _len; _i++) {
|
# for (_i = 0, _len = list.length; _i < _len; _i++) {
|
||||||
# num = list[_i];
|
# num = list[_i];
|
||||||
# _results.push(math.cube(num));
|
# _results.push(math.cube(num));
|
||||||
# }
|
# }
|
||||||
# return _results;
|
# return _results;
|
||||||
# })();
|
# })();
|
||||||
|
|
||||||
foods = ['broccoli', 'spinach', 'chocolate']
|
foods = ['broccoli', 'spinach', 'chocolate']
|
||||||
eat food for food in foods when food isnt 'chocolate'
|
eat food for food in foods when food isnt 'chocolate'
|
||||||
|
330
coldfusion.html.markdown
Normal file
330
coldfusion.html.markdown
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
---
|
||||||
|
language: coldfusion
|
||||||
|
filename: learncoldfusion.cfm
|
||||||
|
contributors:
|
||||||
|
- ["Wayne Boka", "http://wboka.github.io"]
|
||||||
|
- ["Kevin Morris", "https://twitter.com/kevinmorris"]
|
||||||
|
---
|
||||||
|
|
||||||
|
ColdFusion is a scripting language for web development.
|
||||||
|
[Read more here.](http://www.adobe.com/products/coldfusion-family.html)
|
||||||
|
|
||||||
|
### CFML
|
||||||
|
_**C**old**F**usion **M**arkup **L**anguage_
|
||||||
|
ColdFusion started as a tag-based language. Almost all functionality is available using tags.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<em>HTML tags have been provided for output readability</em>
|
||||||
|
|
||||||
|
<!--- Comments start with "<!---" and end with "--->" --->
|
||||||
|
<!---
|
||||||
|
Comments can
|
||||||
|
also
|
||||||
|
span
|
||||||
|
multiple lines
|
||||||
|
--->
|
||||||
|
|
||||||
|
<!--- CFML tags have a similar format to HTML tags. --->
|
||||||
|
<h1>Simple Variables</h1>
|
||||||
|
<!--- Variable Declaration: Variables are loosely typed, similar to javascript --->
|
||||||
|
<p>Set <b>myVariable</b> to "myValue"</p>
|
||||||
|
<cfset myVariable = "myValue" />
|
||||||
|
<p>Set <b>myNumber</b> to 3.14</p>
|
||||||
|
<cfset myNumber = 3.14 />
|
||||||
|
|
||||||
|
<!--- Displaying simple data --->
|
||||||
|
<!--- Use <cfoutput> for simple values such as strings, numbers, and expressions --->
|
||||||
|
<p>Display <b>myVariable</b>: <cfoutput>#myVariable#</cfoutput></p><!--- myValue --->
|
||||||
|
<p>Display <b>myNumber</b>: <cfoutput>#myNumber#</cfoutput></p><!--- 3.14 --->
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h1>Complex Variables</h1>
|
||||||
|
<!--- Declaring complex variables --->
|
||||||
|
<!--- Declaring an array of 1 dimension: literal or bracket notation --->
|
||||||
|
<p>Set <b>myArray1</b> to an array of 1 dimension using literal or bracket notation</p>
|
||||||
|
<cfset myArray1 = [] />
|
||||||
|
<!--- Declaring an array of 1 dimension: function notation --->
|
||||||
|
<p>Set <b>myArray2</b> to an array of 1 dimension using function notation</p>
|
||||||
|
<cfset myArray2 = ArrayNew(1) />
|
||||||
|
|
||||||
|
<!--- Outputting complex variables --->
|
||||||
|
<p>Contents of <b>myArray1</b></p>
|
||||||
|
<cfdump var="#myArray1#" /> <!--- An empty array object --->
|
||||||
|
<p>Contents of <b>myArray2</b></p>
|
||||||
|
<cfdump var="#myArray2#" /> <!--- An empty array object --->
|
||||||
|
|
||||||
|
<!--- Operators --->
|
||||||
|
<!--- Arithmetic --->
|
||||||
|
<h1>Operators</h1>
|
||||||
|
<h2>Arithmetic</h2>
|
||||||
|
<p>1 + 1 = <cfoutput>#1 + 1#</cfoutput></p>
|
||||||
|
<p>10 - 7 = <cfoutput>#10 - 7#<br /></cfoutput></p>
|
||||||
|
<p>15 * 10 = <cfoutput>#15 * 10#<br /></cfoutput></p>
|
||||||
|
<p>100 / 5 = <cfoutput>#100 / 5#<br /></cfoutput></p>
|
||||||
|
<p>120 % 5 = <cfoutput>#120 % 5#<br /></cfoutput></p>
|
||||||
|
<p>120 mod 5 = <cfoutput>#120 mod 5#<br /></cfoutput></p>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<!--- Comparison --->
|
||||||
|
<h2>Comparison</h2>
|
||||||
|
<h3>Standard Notation</h3>
|
||||||
|
<p>Is 1 eq 1? <cfoutput>#1 eq 1#</cfoutput></p>
|
||||||
|
<p>Is 15 neq 1? <cfoutput>#15 neq 1#</cfoutput></p>
|
||||||
|
<p>Is 10 gt 8? <cfoutput>#10 gt 8#</cfoutput></p>
|
||||||
|
<p>Is 1 lt 2? <cfoutput>#1 lt 2#</cfoutput></p>
|
||||||
|
<p>Is 10 gte 5? <cfoutput>#10 gte 5#</cfoutput></p>
|
||||||
|
<p>Is 1 lte 5? <cfoutput>#1 lte 5#</cfoutput></p>
|
||||||
|
|
||||||
|
<h3>Alternative Notation</h3>
|
||||||
|
<p>Is 1 == 1? <cfoutput>#1 eq 1#</cfoutput></p>
|
||||||
|
<p>Is 15 != 1? <cfoutput>#15 neq 1#</cfoutput></p>
|
||||||
|
<p>Is 10 > 8? <cfoutput>#10 gt 8#</cfoutput></p>
|
||||||
|
<p>Is 1 < 2? <cfoutput>#1 lt 2#</cfoutput></p>
|
||||||
|
<p>Is 10 >= 5? <cfoutput>#10 gte 5#</cfoutput></p>
|
||||||
|
<p>Is 1 <= 5? <cfoutput>#1 lte 5#</cfoutput></p>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<!--- Control Structures --->
|
||||||
|
<h1>Control Structures</h1>
|
||||||
|
|
||||||
|
<cfset myCondition = "Test" />
|
||||||
|
|
||||||
|
<p>Condition to test for: "<cfoutput>#myCondition#</cfoutput>"</p>
|
||||||
|
|
||||||
|
<cfif myCondition eq "Test">
|
||||||
|
<cfoutput>#myCondition#. We're testing.</cfoutput>
|
||||||
|
<cfelseif myCondition eq "Production">
|
||||||
|
<cfoutput>#myCondition#. Proceed Carefully!!!</cfoutput>
|
||||||
|
<cfelse>
|
||||||
|
myCondition is unknown
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<!--- Loops --->
|
||||||
|
<h1>Loops</h1>
|
||||||
|
<h2>For Loop</h2>
|
||||||
|
<cfloop from="0" to="10" index="i">
|
||||||
|
<p>Index equals <cfoutput>#i#</cfoutput></p>
|
||||||
|
</cfloop>
|
||||||
|
|
||||||
|
<h2>For Each Loop (Complex Variables)</h2>
|
||||||
|
|
||||||
|
<p>Set <b>myArray3</b> to [5, 15, 99, 45, 100]</p>
|
||||||
|
|
||||||
|
<cfset myArray3 = [5, 15, 99, 45, 100] />
|
||||||
|
|
||||||
|
<cfloop array="#myArray3#" index="i">
|
||||||
|
<p>Index equals <cfoutput>#i#</cfoutput></p>
|
||||||
|
</cfloop>
|
||||||
|
|
||||||
|
<p>Set <b>myArray4</b> to ["Alpha", "Bravo", "Charlie", "Delta", "Echo"]</p>
|
||||||
|
|
||||||
|
<cfset myArray4 = ["Alpha", "Bravo", "Charlie", "Delta", "Echo"] />
|
||||||
|
|
||||||
|
<cfloop array="#myArray4#" index="s">
|
||||||
|
<p>Index equals <cfoutput>#s#</cfoutput></p>
|
||||||
|
</cfloop>
|
||||||
|
|
||||||
|
<h2>Switch Statement</h2>
|
||||||
|
|
||||||
|
<p>Set <b>myArray5</b> to [5, 15, 99, 45, 100]</p>
|
||||||
|
|
||||||
|
<cfset myArray5 = [5, 15, 99, 45, 100] />
|
||||||
|
|
||||||
|
<cfloop array="#myArray5#" index="i">
|
||||||
|
<cfswitch expression="#i#">
|
||||||
|
<cfcase value="5,15,45" delimiters=",">
|
||||||
|
<p><cfoutput>#i#</cfoutput> is a multiple of 5.</p>
|
||||||
|
</cfcase>
|
||||||
|
<cfcase value="99">
|
||||||
|
<p><cfoutput>#i#</cfoutput> is ninety-nine.</p>
|
||||||
|
</cfcase>
|
||||||
|
<cfdefaultcase>
|
||||||
|
<p><cfoutput>#i#</cfoutput> is not 5, 15, 45, or 99.</p>
|
||||||
|
</cfdefaultcase>
|
||||||
|
</cfswitch>
|
||||||
|
</cfloop>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h1>Converting types</h1>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
table.table th, table.table td {
|
||||||
|
border: 1px solid #000000;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.table th {
|
||||||
|
background-color: #CCCCCC;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<table class="table" cellspacing="0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Value</th>
|
||||||
|
<th>As Boolean</th>
|
||||||
|
<th>As number</th>
|
||||||
|
<th>As date-time</th>
|
||||||
|
<th>As string</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>"Yes"</th>
|
||||||
|
<td>TRUE</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>Error</td>
|
||||||
|
<td>"Yes"</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>"No"</th>
|
||||||
|
<td>FALSE</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>Error</td>
|
||||||
|
<td>"No"</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>TRUE</th>
|
||||||
|
<td>TRUE</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>Error</td>
|
||||||
|
<td>"Yes"</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>FALSE</th>
|
||||||
|
<td>FALSE</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>Error</td>
|
||||||
|
<td>"No"</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Number</th>
|
||||||
|
<td>True if Number is not 0; False otherwise.</td>
|
||||||
|
<td>Number</td>
|
||||||
|
<td>See "Date-time values" earlier in this chapter.</td>
|
||||||
|
<td>String representation of the number (for example, "8").</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>String</th>
|
||||||
|
<td>If "Yes", True <br>If "No", False <br>If it can be converted to 0, False <br>If it can be converted to any other number, True</td>
|
||||||
|
<td>If it represents a number (for example, "1,000" or "12.36E-12"), it is converted to the corresponding number.</td>
|
||||||
|
<td>If it represents a date-time (see next column), it is converted to the numeric value of the corresponding date-time object. <br>If it is an ODBC date, time, or timestamp (for example "{ts '2001-06-14 11:30:13'}", or if it is expressed in a standard U.S. date or time format, including the use of full or abbreviated month names, it is converted to the corresponding date-time value. <br>Days of the week or unusual punctuation result in an error. <br>Dashes, forward-slashes, and spaces are generally allowed.</td>
|
||||||
|
<td>String</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<td>Error</td>
|
||||||
|
<td>The numeric value of the date-time object.</td>
|
||||||
|
<td>Date</td>
|
||||||
|
<td>An ODBC timestamp.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h1>Components</h1>
|
||||||
|
|
||||||
|
<em>Code for reference (Functions must return something to support IE)</em>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
<cfcomponent>
|
||||||
|
<cfset this.hello = "Hello" />
|
||||||
|
<cfset this.world = "world" />
|
||||||
|
|
||||||
|
<cffunction name="sayHello">
|
||||||
|
<cfreturn this.hello & ", " & this.world & "!" />
|
||||||
|
</cffunction>
|
||||||
|
|
||||||
|
<cffunction name="setHello">
|
||||||
|
<cfargument name="newHello" type="string" required="true" />
|
||||||
|
|
||||||
|
<cfset this.hello = arguments.newHello />
|
||||||
|
|
||||||
|
<cfreturn true />
|
||||||
|
</cffunction>
|
||||||
|
|
||||||
|
<cffunction name="setWorld">
|
||||||
|
<cfargument name="newWorld" type="string" required="true" />
|
||||||
|
|
||||||
|
<cfset this.world = arguments.newWorld />
|
||||||
|
|
||||||
|
<cfreturn true />
|
||||||
|
</cffunction>
|
||||||
|
|
||||||
|
<cffunction name="getHello">
|
||||||
|
<cfreturn this.hello />
|
||||||
|
</cffunction>
|
||||||
|
|
||||||
|
<cffunction name="getWorld">
|
||||||
|
<cfreturn this.world />
|
||||||
|
</cffunction>
|
||||||
|
</cfcomponent>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<cfset this.hello = "Hello" />
|
||||||
|
<cfset this.world = "world" />
|
||||||
|
|
||||||
|
<cffunction name="sayHello">
|
||||||
|
<cfreturn this.hello & ", " & this.world & "!" />
|
||||||
|
</cffunction>
|
||||||
|
|
||||||
|
<cffunction name="setHello">
|
||||||
|
<cfargument name="newHello" type="string" required="true" />
|
||||||
|
|
||||||
|
<cfset this.hello = arguments.newHello />
|
||||||
|
|
||||||
|
<cfreturn true />
|
||||||
|
</cffunction>
|
||||||
|
|
||||||
|
<cffunction name="setWorld">
|
||||||
|
<cfargument name="newWorld" type="string" required="true" />
|
||||||
|
|
||||||
|
<cfset this.world = arguments.newWorld />
|
||||||
|
|
||||||
|
<cfreturn true />
|
||||||
|
</cffunction>
|
||||||
|
|
||||||
|
<cffunction name="getHello">
|
||||||
|
<cfreturn this.hello />
|
||||||
|
</cffunction>
|
||||||
|
|
||||||
|
<cffunction name="getWorld">
|
||||||
|
<cfreturn this.world />
|
||||||
|
</cffunction>
|
||||||
|
|
||||||
|
|
||||||
|
<b>sayHello()</b>
|
||||||
|
<cfoutput><p>#sayHello()#</p></cfoutput>
|
||||||
|
<b>getHello()</b>
|
||||||
|
<cfoutput><p>#getHello()#</p></cfoutput>
|
||||||
|
<b>getWorld()</b>
|
||||||
|
<cfoutput><p>#getWorld()#</p></cfoutput>
|
||||||
|
<b>setHello("Hola")</b>
|
||||||
|
<cfoutput><p>#setHello("Hola")#</p></cfoutput>
|
||||||
|
<b>setWorld("mundo")</b>
|
||||||
|
<cfoutput><p>#setWorld("mundo")#</p></cfoutput>
|
||||||
|
<b>sayHello()</b>
|
||||||
|
<cfoutput><p>#sayHello()#</p></cfoutput>
|
||||||
|
<b>getHello()</b>
|
||||||
|
<cfoutput><p>#getHello()#</p></cfoutput>
|
||||||
|
<b>getWorld()</b>
|
||||||
|
<cfoutput><p>#getWorld()#</p></cfoutput>
|
||||||
|
```
|
||||||
|
|
||||||
|
### CFScript
|
||||||
|
_**C**old**F**usion **S**cript_
|
||||||
|
In recent years, the ColdFusion language has added script syntax to mirror tag functionality. When using an up-to-date CF server, almost all functionality is available using scrypt syntax.
|
||||||
|
|
||||||
|
## Further Reading
|
||||||
|
|
||||||
|
The links provided here below are just to get an understanding of the topic, feel free to Google and find specific examples.
|
||||||
|
|
||||||
|
1. [Coldfusion Reference From Adobe](https://helpx.adobe.com/coldfusion/cfml-reference/topics.html)
|
||||||
|
2. [Open Source Documentation](http://cfdocs.org/)
|
@ -175,7 +175,8 @@ nil ; for false - and the empty list
|
|||||||
:age 5))
|
:age 5))
|
||||||
*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
|
*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
|
||||||
|
|
||||||
(dog-p *rover*) ; => t ;; ewww)
|
(dog-p *rover*) ; => true #| -p signifies "predicate". It's used to
|
||||||
|
check if *rover* is an instance of dog. |#
|
||||||
(dog-name *rover*) ; => "rover"
|
(dog-name *rover*) ; => "rover"
|
||||||
|
|
||||||
;; Dog-p, make-dog, and dog-name are all created by defstruct!
|
;; Dog-p, make-dog, and dog-name are all created by defstruct!
|
||||||
@ -260,7 +261,7 @@ nil ; for false - and the empty list
|
|||||||
|
|
||||||
(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
|
(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
|
||||||
:adjustable t :fill-pointer t))
|
:adjustable t :fill-pointer t))
|
||||||
|
|
||||||
*adjvec* ; => #(1 2 3)
|
*adjvec* ; => #(1 2 3)
|
||||||
|
|
||||||
;; Adding new element:
|
;; Adding new element:
|
||||||
@ -613,9 +614,16 @@ nil ; for false - and the empty list
|
|||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
|
||||||
[Keep moving on to the Practical Common Lisp book.](http://www.gigamonkeys.com/book/)
|
* [Keep moving on to the Practical Common Lisp book.](http://www.gigamonkeys.com/book/)
|
||||||
|
* [A Gentle Introduction to...](https://www.cs.cmu.edu/~dst/LispBook/book.pdf)
|
||||||
|
|
||||||
|
|
||||||
|
## Extra Info
|
||||||
|
|
||||||
|
* [CLiki](http://www.cliki.net/)
|
||||||
|
* [common-lisp.net](https://common-lisp.net/)
|
||||||
|
* [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl)
|
||||||
|
|
||||||
## Credits.
|
## Credits.
|
||||||
|
|
||||||
Lots of thanks to the Scheme people for rolling up a great starting
|
Lots of thanks to the Scheme people for rolling up a great starting
|
||||||
|
258
cs-cz/markdown.html.markdown
Normal file
258
cs-cz/markdown.html.markdown
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
---
|
||||||
|
language: markdown
|
||||||
|
contributors:
|
||||||
|
- ["Dan Turkel", "http://danturkel.com/"]
|
||||||
|
translators:
|
||||||
|
- ["Michal Martinek", "https://github.com/MichalMartinek"]
|
||||||
|
filename: markdown.md
|
||||||
|
---
|
||||||
|
|
||||||
|
Markdown byl vytvořen Johnem Gruberem v roce 2004. Je zamýšlen jako lehce čitelná
|
||||||
|
a psatelná syntaxe, která je jednoduše převeditelná do HTML (a dnes i do mnoha
|
||||||
|
dalších formátů)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- Markdown je nadstavba nad HTML, takže jakýkoliv kód HTML je validní
|
||||||
|
Markdown, to znamená, že můžeme používat HTML elementy, třeba jako komentář, a
|
||||||
|
nebudou ovlivněny parserem Markdownu. Avšak, pokud vytvoříte HTML element v
|
||||||
|
Markdownu, tak nemůžete používat syntaxi Markdownu uvnitř tohoto elementu. -->
|
||||||
|
|
||||||
|
<!-- Markdown se také mírně liší v jednotlivých interpretacích parseru. Tento
|
||||||
|
návod vás bude upozorňovat, které vlastnosti jsou obecné a které specifické pro
|
||||||
|
konkrétní parser. -->
|
||||||
|
|
||||||
|
<!-- Nadpisy -->
|
||||||
|
<!-- Můžete vytvořit HTML elementy <h1> až <h6> jednoduše tak, že text předsadíte
|
||||||
|
počtem křížků (#), podle toho jaké úrovně to má být nadpis -->
|
||||||
|
# Toto je <h1>
|
||||||
|
## Toto je <h2>
|
||||||
|
### Toto je <h3>
|
||||||
|
#### Toto je <h4>
|
||||||
|
##### Toto je <h5>
|
||||||
|
###### Toto je <h6>
|
||||||
|
|
||||||
|
<!-- Markdown obsahuje taky dvě další cesty, jak udělat h1 a h2 -->
|
||||||
|
Toto je h1
|
||||||
|
==========
|
||||||
|
|
||||||
|
Toto je h2
|
||||||
|
----------
|
||||||
|
|
||||||
|
<!-- Jednoduché stylování textu -->
|
||||||
|
<!-- Pomocí markdownu můžete text jednoduše označit jako kurzívu či tučný -->
|
||||||
|
|
||||||
|
*Tento text je kurzívou;*
|
||||||
|
_Stejně jako tento._
|
||||||
|
|
||||||
|
**Tento text je tučně**
|
||||||
|
__Stejně jako tento.__
|
||||||
|
|
||||||
|
***Tento text je obojí***
|
||||||
|
**_Jako tento!_**
|
||||||
|
*__A tento!__*
|
||||||
|
|
||||||
|
<!-- Ve verzi Markdownu od Githubu, máme k dispozici taky prošktrnutí: -->
|
||||||
|
|
||||||
|
~~Tento text je prošktrnutý.~~
|
||||||
|
|
||||||
|
<!-- Odstavce jsou jedna nebo více řádek textu, oddělených jednou nebo více prázdnými řádky. -->
|
||||||
|
|
||||||
|
Toto je odstavec. Píši odstavec, není to zábava?
|
||||||
|
|
||||||
|
Teď jsem v odstavci 2.
|
||||||
|
Jsem pořád v odstavci 2!
|
||||||
|
|
||||||
|
|
||||||
|
Toto je odstavec 3.
|
||||||
|
|
||||||
|
<!-- Chtěli jste někdy vložit znak <br /> tag? Můžete napsat na konec odstavce
|
||||||
|
dvě nebo více mezer a potom začít nový odstavec. -->
|
||||||
|
|
||||||
|
Tento odstavec končí dvěma mezerami.
|
||||||
|
|
||||||
|
Nad tímto odstavcem je <br />!
|
||||||
|
|
||||||
|
<!-- Blokové citace se dělají jednoduše pomocí znaku >. -->
|
||||||
|
|
||||||
|
> Toto je bloková citace. Můžete dokonce
|
||||||
|
> manuálně rozdělit řádky, a před každý vložit >, nebo nechat vaše řádky jakkoliv dlouhé, ať se zarovnají sami.
|
||||||
|
> Nedělá to rozdíl, dokud začínáte vždy znakem >.
|
||||||
|
|
||||||
|
> Můžu použít více než jednu
|
||||||
|
>> odsazení?
|
||||||
|
> Jak je to úhledné, že?
|
||||||
|
|
||||||
|
<!-- Seznamy -->
|
||||||
|
<!-- Nečíslovaný seznam můžete jednoduše udělat pomocí hvězdiček, plusů, nebo
|
||||||
|
pomlček -->
|
||||||
|
|
||||||
|
* Položka
|
||||||
|
* Položka
|
||||||
|
* Jinná položka
|
||||||
|
|
||||||
|
nebo
|
||||||
|
|
||||||
|
+ Položka
|
||||||
|
+ Položka
|
||||||
|
+ Další položka
|
||||||
|
|
||||||
|
nebo
|
||||||
|
|
||||||
|
- Položka
|
||||||
|
- Položka
|
||||||
|
- Další položka
|
||||||
|
|
||||||
|
<!-- Číslovaný seznam se dělají pomocí čísla a . -->
|
||||||
|
|
||||||
|
1. Položka jedna
|
||||||
|
2. Položka dvě
|
||||||
|
3. Položka tři
|
||||||
|
|
||||||
|
<!-- Nemusíte dokonce psát čísla správně a markdown je zobrazi správně,
|
||||||
|
ale nemusí to být vždy dobrý nápad -->
|
||||||
|
|
||||||
|
1. Položka jedna
|
||||||
|
1. Položka dvě
|
||||||
|
1. Položka tři
|
||||||
|
<!-- (Toto zobrazí to samě, jako příklad nadtím.) -->
|
||||||
|
|
||||||
|
<!-- Můžete také tvořit podseznamy -->
|
||||||
|
|
||||||
|
1. Položka jedna
|
||||||
|
2. Položka dvě
|
||||||
|
3. Položka tři
|
||||||
|
* Podpoložka
|
||||||
|
* Podpoložka
|
||||||
|
4. Položka čtyři
|
||||||
|
|
||||||
|
<!-- Existují i zašktávací seznamy. Toto vytvoří HTML checkboxy. -->
|
||||||
|
|
||||||
|
Boxy níže bez 'x' jsou nezašktrnuté checkboxy.
|
||||||
|
- [ ] První úkol
|
||||||
|
- [ ] Druhý úkol
|
||||||
|
Tento box bude zašktrnutý
|
||||||
|
- [x] Tento úkol byl dokončen
|
||||||
|
|
||||||
|
<!-- Bloky ködu -->
|
||||||
|
<!-- Můžete označit kód bloku (který používá <code> element) odsazením pomocí 4
|
||||||
|
mezer, nebo tabu -->
|
||||||
|
|
||||||
|
Toto je kód
|
||||||
|
Stejně jako toto
|
||||||
|
|
||||||
|
<!-- Můžete dokonce přidat další 4 mezery nebo tab pro další odsazení -->
|
||||||
|
|
||||||
|
moje_pole.each do |i|
|
||||||
|
puts i
|
||||||
|
end
|
||||||
|
|
||||||
|
<!-- Kód na řádku může být označen pomocí zpětných apostrofů ` -->
|
||||||
|
|
||||||
|
Jan nevědel, jak se dělá `go_to()` funkce!
|
||||||
|
|
||||||
|
<!-- V Markdownu od Githubu , můžete použít speciální syntaxi pro kód -->
|
||||||
|
|
||||||
|
\`\`\`ruby <!-- vyjma zpětných lomítek, jenom ```ruby ! -->
|
||||||
|
def neco
|
||||||
|
puts "Ahoj světe!"
|
||||||
|
end
|
||||||
|
\`\`\` <!-- zde taky, žádné zpětná lomítka, pouze ``` -->
|
||||||
|
|
||||||
|
<!-- Text výše nepotřebuje odsazení a navíc Github použije zvýraznění označeného
|
||||||
|
jazyka. -->
|
||||||
|
|
||||||
|
<!-- Horizontální čára (<hr />) -->
|
||||||
|
<!-- Horizontální čára se jednoduše přidá pomocí 3 nebo více hvězdiček nebo pomlček
|
||||||
|
s nebo bez mezer. -->
|
||||||
|
|
||||||
|
***
|
||||||
|
---
|
||||||
|
- - -
|
||||||
|
****************
|
||||||
|
|
||||||
|
<!-- Odkazy -->
|
||||||
|
<!-- Jedna z nejlepších věcí na Markdownu je, jak jednoduše se dělají odkazy.
|
||||||
|
Dejte text, který chcete zobrazit, do [] následovaný url v závorkách () a je to. -->
|
||||||
|
|
||||||
|
[Klikni na mě!](http://test.com/)
|
||||||
|
|
||||||
|
<!-- Můžete také přidat jméno linku pomocí uvozovek -->
|
||||||
|
|
||||||
|
[Klikni na mě!](http://test.com/ "Odkaz na Test.com")
|
||||||
|
|
||||||
|
<!-- Relativní cesty fungují taky -->
|
||||||
|
|
||||||
|
[Jdi na hudbu](/hudba/).
|
||||||
|
|
||||||
|
<!-- Markdown taktéž podporuje reference odkazů. -->
|
||||||
|
|
||||||
|
[Klikni na tento odkaz][link1] pro více informací!
|
||||||
|
[Taky zkontrolujte tento odkaz][neco], když chcete.
|
||||||
|
|
||||||
|
[link1]: http://test.com/ "Cool!"
|
||||||
|
[neco]: http://neco.czz/ "Dobře!"
|
||||||
|
|
||||||
|
<!-- Titulek může být v apostrofech nebo závorkách, nebo vyjmutý úplně. Reference
|
||||||
|
může být kdekoliv ve vašem dokumentu a identifikátor může být jakýkoliv, dokud
|
||||||
|
je unikátní.-->
|
||||||
|
|
||||||
|
<!-- Také existuje "implicitní pojmenování", které použije text jako id -->
|
||||||
|
|
||||||
|
[Toto][] je odkaz..
|
||||||
|
|
||||||
|
[toto]: http://totojelink.cz/
|
||||||
|
|
||||||
|
<!-- Ale toto není zrovna běžné užívané. -->
|
||||||
|
|
||||||
|
<!-- Obrázky -->
|
||||||
|
<!-- Obrázky se dělají stejně jako odkazy, ale s vykřičníkem na začátku -->
|
||||||
|
|
||||||
|
![Toto je atribut alt pro obrázek](http://imgur.com/myimage.jpg "Nepovinný titulek")
|
||||||
|
|
||||||
|
<!-- Reference fungují, jak bychom čekali-->
|
||||||
|
|
||||||
|
![Toto je atribut alt][mujobrazek]
|
||||||
|
|
||||||
|
[mujobrazek]: relativni/cesta/obrazek.jpg "a toto by byl titulek"
|
||||||
|
|
||||||
|
<!-- Ostatní -->
|
||||||
|
<!-- Automatické odkazy -->
|
||||||
|
|
||||||
|
<http://stranka.cz/> je stejná jako
|
||||||
|
[http://stranka.cz/](http://stranka.cz/)
|
||||||
|
|
||||||
|
<!-- Automatické odkazy pro emaily-->
|
||||||
|
|
||||||
|
<jmeno@prijmeni.cz>
|
||||||
|
|
||||||
|
<!-- Escapování znaků -->
|
||||||
|
|
||||||
|
Chci napsat *tento text obklopený hvězdičkami*, ale nechci aby to bylo kurzívou, tak udělám: \*tento text obklopený hvězdičkami\*.
|
||||||
|
|
||||||
|
<!-- Klávesové zkratky -->
|
||||||
|
<!-- V Markdownu od Githubu, můžete použít tag <kbd> k reprezentování klaves na počítači -->
|
||||||
|
|
||||||
|
Váš počítač přestal pracovat? Zkuste
|
||||||
|
<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
|
||||||
|
|
||||||
|
<!-- Tabulky -->
|
||||||
|
<!-- Tabulky jsou povolené pouze v Markdownu od Githubu a jsou trochu podivně,
|
||||||
|
ale když je opravdu chcete: -->
|
||||||
|
|
||||||
|
| Sloupec1 | Sloupec2 | Sloupec3 |
|
||||||
|
| :----------- | :------: | ------------: |
|
||||||
|
| Vlevo zarovn.| Na střed | Vpravo zarovn.|
|
||||||
|
| blah | blah | blah |
|
||||||
|
|
||||||
|
<!-- nebo, to jde i taky: -->
|
||||||
|
|
||||||
|
Sloupec 1 | Sloupec2 | Sloupec3
|
||||||
|
:-- | :-: | --:
|
||||||
|
Ohh toto je tak ošklivé | radši to | nedělejte
|
||||||
|
|
||||||
|
<!-- Konec -->
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Pro více informací, prozkoumejte oficiální článek o syntaxi od Johna Grubera
|
||||||
|
[zde](http://daringfireball.net/projects/markdown/syntax) a skvělý tahák od Adama Pritcharda [zde](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
|
@ -48,7 +48,7 @@ Poznámka: Tento článek je zaměřen na Python 3. Zde se můžete [naučit sta
|
|||||||
-5 // 3 # => -2
|
-5 // 3 # => -2
|
||||||
-5.0 // 3.0 # => -2.0
|
-5.0 // 3.0 # => -2.0
|
||||||
|
|
||||||
# Pokud použiteje desetinné číslo, výsledek je jím také
|
# Pokud použijete desetinné číslo, výsledek je jím také
|
||||||
3 * 2.0 # => 6.0
|
3 * 2.0 # => 6.0
|
||||||
|
|
||||||
# Modulo
|
# Modulo
|
||||||
@ -420,7 +420,7 @@ next(iterator) # Vyhodí StopIteration
|
|||||||
## 4. Funkce
|
## 4. Funkce
|
||||||
####################################################
|
####################################################
|
||||||
|
|
||||||
# Pro vytvoření nové funkce použijte def
|
# Pro vytvoření nové funkce použijte klíčové slovo def
|
||||||
def secist(x, y):
|
def secist(x, y):
|
||||||
print("x je {} a y je {}".format(x, y))
|
print("x je {} a y je {}".format(x, y))
|
||||||
return x + y # Hodnoty se vrací pomocí return
|
return x + y # Hodnoty se vrací pomocí return
|
||||||
@ -520,7 +520,7 @@ class Clovek(object):
|
|||||||
# podtržítka na začátku a na konci značí, že se jedná o atribut nebo
|
# podtržítka na začátku a na konci značí, že se jedná o atribut nebo
|
||||||
# objekt využívaný Pythonem ke speciálním účelům, ale můžete sami
|
# objekt využívaný Pythonem ke speciálním účelům, ale můžete sami
|
||||||
# definovat jeho chování. Metody jako __init__, __str__, __repr__
|
# definovat jeho chování. Metody jako __init__, __str__, __repr__
|
||||||
# a další se nazývají "magické metody". Nikdy nepoužívejte toto
|
# a další se nazývají "magické metody". Nikdy nepoužívejte toto
|
||||||
# speciální pojmenování pro běžné metody.
|
# speciální pojmenování pro běžné metody.
|
||||||
def __init__(self, jmeno):
|
def __init__(self, jmeno):
|
||||||
# Přiřazení parametru do atributu instance jmeno
|
# Přiřazení parametru do atributu instance jmeno
|
||||||
@ -566,7 +566,7 @@ Clovek.odkaslej_si() # => "*ehm*"
|
|||||||
|
|
||||||
# Lze importovat moduly
|
# Lze importovat moduly
|
||||||
import math
|
import math
|
||||||
print(math.sqrt(16)) # => 4
|
print(math.sqrt(16.0)) # => 4
|
||||||
|
|
||||||
# Lze také importovat pouze vybrané funkce z modulu
|
# Lze také importovat pouze vybrané funkce z modulu
|
||||||
from math import ceil, floor
|
from math import ceil, floor
|
||||||
|
@ -6,6 +6,8 @@ contributors:
|
|||||||
- ["Melvyn Laïly", "http://x2a.yt"]
|
- ["Melvyn Laïly", "http://x2a.yt"]
|
||||||
- ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
|
- ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
|
||||||
- ["Wouter Van Schandevijl", "http://github.com/laoujin"]
|
- ["Wouter Van Schandevijl", "http://github.com/laoujin"]
|
||||||
|
- ["Jo Pearce", "http://github.com/jdpearce"]
|
||||||
|
- ["Chris Zimmerman", "https://github.com/chriszimmerman"]
|
||||||
filename: LearnCSharp.cs
|
filename: LearnCSharp.cs
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -25,7 +27,7 @@ Multi-line comments look like this
|
|||||||
//public void MethodOrClassOrOtherWithParsableHelp() {}
|
//public void MethodOrClassOrOtherWithParsableHelp() {}
|
||||||
|
|
||||||
// Specify the namespaces this source code will be using
|
// Specify the namespaces this source code will be using
|
||||||
// The namespaces below are all part of the standard .NET Framework Class Libary
|
// The namespaces below are all part of the standard .NET Framework Class Libary
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
@ -43,12 +45,12 @@ using System.Data.Entity;
|
|||||||
// Using this code from another source file: using Learning.CSharp;
|
// Using this code from another source file: using Learning.CSharp;
|
||||||
namespace Learning.CSharp
|
namespace Learning.CSharp
|
||||||
{
|
{
|
||||||
// Each .cs file should at least contain a class with the same name as the file
|
// Each .cs file should at least contain a class with the same name as the file.
|
||||||
// you're allowed to do otherwise, but shouldn't for sanity.
|
// You're allowed to do otherwise, but shouldn't for sanity.
|
||||||
public class LearnCSharp
|
public class LearnCSharp
|
||||||
{
|
{
|
||||||
// BASIC SYNTAX - skip to INTERESTING FEATURES if you have used Java or C++ before
|
// BASIC SYNTAX - skip to INTERESTING FEATURES if you have used Java or C++ before
|
||||||
public static void Syntax()
|
public static void Syntax()
|
||||||
{
|
{
|
||||||
// Use Console.WriteLine to print lines
|
// Use Console.WriteLine to print lines
|
||||||
Console.WriteLine("Hello World");
|
Console.WriteLine("Hello World");
|
||||||
@ -159,7 +161,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
// List<datatype> <var name> = new List<datatype>();
|
// List<datatype> <var name> = new List<datatype>();
|
||||||
List<int> intList = new List<int>();
|
List<int> intList = new List<int>();
|
||||||
List<string> stringList = new List<string>();
|
List<string> stringList = new List<string>();
|
||||||
List<int> z = new List<int> { 9000, 1000, 1337 }; // intialize
|
List<int> z = new List<int> { 9000, 1000, 1337 }; // initialize
|
||||||
// The <> are for generics - Check out the cool stuff section
|
// The <> are for generics - Check out the cool stuff section
|
||||||
|
|
||||||
// Lists don't default to a value;
|
// Lists don't default to a value;
|
||||||
@ -236,7 +238,8 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
// Ternary operators
|
// Ternary operators
|
||||||
// A simple if/else can be written as follows
|
// A simple if/else can be written as follows
|
||||||
// <condition> ? <true> : <false>
|
// <condition> ? <true> : <false>
|
||||||
string isTrue = (true) ? "True" : "False";
|
int toCompare = 17;
|
||||||
|
string isTrue = toCompare == 17 ? "True" : "False";
|
||||||
|
|
||||||
// While loop
|
// While loop
|
||||||
int fooWhile = 0;
|
int fooWhile = 0;
|
||||||
@ -370,11 +373,11 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
//
|
//
|
||||||
// INTERESTING FEATURES
|
// INTERESTING FEATURES
|
||||||
//
|
//
|
||||||
|
|
||||||
// DEFAULT METHOD SIGNATURES
|
// DEFAULT METHOD SIGNATURES
|
||||||
|
|
||||||
public // Visibility
|
public // Visibility
|
||||||
static // Allows for direct call on class without object
|
static // Allows for direct call on class without object
|
||||||
int // Return Type,
|
int // Return Type,
|
||||||
MethodSignatures(
|
MethodSignatures(
|
||||||
int maxCount, // First variable, expects an int
|
int maxCount, // First variable, expects an int
|
||||||
@ -382,7 +385,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
int another = 3,
|
int another = 3,
|
||||||
params string[] otherParams // captures all other parameters passed to method
|
params string[] otherParams // captures all other parameters passed to method
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,6 +395,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
ref int maxCount, // Pass by reference
|
ref int maxCount, // Pass by reference
|
||||||
out int count)
|
out int count)
|
||||||
{
|
{
|
||||||
|
//the argument passed in as 'count' will hold the value of 15 outside of this function
|
||||||
count = 15; // out param must be assigned before control leaves the method
|
count = 15; // out param must be assigned before control leaves the method
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,8 +403,8 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
// The classes for TKey and TValue is specified by the user calling this function.
|
// The classes for TKey and TValue is specified by the user calling this function.
|
||||||
// This method emulates the SetDefault of Python
|
// This method emulates the SetDefault of Python
|
||||||
public static TValue SetDefault<TKey, TValue>(
|
public static TValue SetDefault<TKey, TValue>(
|
||||||
IDictionary<TKey, TValue> dictionary,
|
IDictionary<TKey, TValue> dictionary,
|
||||||
TKey key,
|
TKey key,
|
||||||
TValue defaultItem)
|
TValue defaultItem)
|
||||||
{
|
{
|
||||||
TValue result;
|
TValue result;
|
||||||
@ -409,7 +413,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// You can narrow down the objects that are passed in
|
// You can narrow down the objects that are passed in
|
||||||
public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
|
public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
|
||||||
{
|
{
|
||||||
// We can iterate, since T is a IEnumerable
|
// We can iterate, since T is a IEnumerable
|
||||||
@ -417,12 +421,48 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
// Item is an int
|
// Item is an int
|
||||||
Console.WriteLine(item.ToString());
|
Console.WriteLine(item.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// YIELD
|
||||||
|
// Usage of the "yield" keyword indicates that the method it appears in is an Iterator
|
||||||
|
// (this means you can use it in a foreach loop)
|
||||||
|
public static IEnumerable<int> YieldCounter(int limit = 10)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < limit; i++)
|
||||||
|
yield return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// which you would call like this :
|
||||||
|
public static void PrintYieldCounterToConsole()
|
||||||
|
{
|
||||||
|
foreach (var counter in YieldCounter())
|
||||||
|
Console.WriteLine(counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// you can use more than one "yield return" in a method
|
||||||
|
public static IEnumerable<int> ManyYieldCounter()
|
||||||
|
{
|
||||||
|
yield return 0;
|
||||||
|
yield return 1;
|
||||||
|
yield return 2;
|
||||||
|
yield return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// you can also use "yield break" to stop the Iterator
|
||||||
|
// this method would only return half of the values from 0 to limit.
|
||||||
|
public static IEnumerable<int> YieldCounterWithBreak(int limit = 10)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < limit; i++)
|
||||||
|
{
|
||||||
|
if (i > limit/2) yield break;
|
||||||
|
yield return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void OtherInterestingFeatures()
|
public static void OtherInterestingFeatures()
|
||||||
{
|
{
|
||||||
// OPTIONAL PARAMETERS
|
// OPTIONAL PARAMETERS
|
||||||
MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
|
MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
|
||||||
MethodSignatures(3, another: 3); // explicity set a parameter, skipping optional ones
|
MethodSignatures(3, another: 3); // explicitly set a parameter, skipping optional ones
|
||||||
|
|
||||||
// BY REF AND OUT PARAMETERS
|
// BY REF AND OUT PARAMETERS
|
||||||
int maxCount = 0, count; // ref params must have value
|
int maxCount = 0, count; // ref params must have value
|
||||||
@ -442,6 +482,9 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
// ?? is syntactic sugar for specifying default value (coalesce)
|
// ?? is syntactic sugar for specifying default value (coalesce)
|
||||||
// in case variable is null
|
// in case variable is null
|
||||||
int notNullable = nullable ?? 0; // 0
|
int notNullable = nullable ?? 0; // 0
|
||||||
|
|
||||||
|
// ?. is an operator for null-propagation - a shorthand way of checking for null
|
||||||
|
nullable?.Print(); // Use the Print() extension method if nullable isn't null
|
||||||
|
|
||||||
// IMPLICITLY TYPED VARIABLES - you can let the compiler work out what the type is:
|
// IMPLICITLY TYPED VARIABLES - you can let the compiler work out what the type is:
|
||||||
var magic = "magic is a string, at compile time, so you still get type safety";
|
var magic = "magic is a string, at compile time, so you still get type safety";
|
||||||
@ -449,13 +492,13 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
|
|
||||||
// GENERICS
|
// GENERICS
|
||||||
//
|
//
|
||||||
var phonebook = new Dictionary<string, string>() {
|
var phonebook = new Dictionary<string, string>() {
|
||||||
{"Sarah", "212 555 5555"} // Add some entries to the phone book
|
{"Sarah", "212 555 5555"} // Add some entries to the phone book
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calling SETDEFAULT defined as a generic above
|
// Calling SETDEFAULT defined as a generic above
|
||||||
Console.WriteLine(SetDefault<string,string>(phonebook, "Shaun", "No Phone")); // No Phone
|
Console.WriteLine(SetDefault<string,string>(phonebook, "Shaun", "No Phone")); // No Phone
|
||||||
// nb, you don't need to specify the TKey and TValue since they can be
|
// nb, you don't need to specify the TKey and TValue since they can be
|
||||||
// derived implicitly
|
// derived implicitly
|
||||||
Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555
|
Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555
|
||||||
|
|
||||||
@ -490,26 +533,26 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
|
|
||||||
// DISPOSABLE RESOURCES MANAGEMENT - let you handle unmanaged resources easily.
|
// DISPOSABLE RESOURCES MANAGEMENT - let you handle unmanaged resources easily.
|
||||||
// Most of objects that access unmanaged resources (file handle, device contexts, etc.)
|
// Most of objects that access unmanaged resources (file handle, device contexts, etc.)
|
||||||
// implement the IDisposable interface. The using statement takes care of
|
// implement the IDisposable interface. The using statement takes care of
|
||||||
// cleaning those IDisposable objects for you.
|
// cleaning those IDisposable objects for you.
|
||||||
using (StreamWriter writer = new StreamWriter("log.txt"))
|
using (StreamWriter writer = new StreamWriter("log.txt"))
|
||||||
{
|
{
|
||||||
writer.WriteLine("Nothing suspicious here");
|
writer.WriteLine("Nothing suspicious here");
|
||||||
// At the end of scope, resources will be released.
|
// At the end of scope, resources will be released.
|
||||||
// Even if an exception is thrown.
|
// Even if an exception is thrown.
|
||||||
}
|
}
|
||||||
|
|
||||||
// PARALLEL FRAMEWORK
|
// PARALLEL FRAMEWORK
|
||||||
// http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
|
// http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
|
||||||
var websites = new string[] {
|
var websites = new string[] {
|
||||||
"http://www.google.com", "http://www.reddit.com",
|
"http://www.google.com", "http://www.reddit.com",
|
||||||
"http://www.shaunmccarthy.com"
|
"http://www.shaunmccarthy.com"
|
||||||
};
|
};
|
||||||
var responses = new Dictionary<string, string>();
|
var responses = new Dictionary<string, string>();
|
||||||
|
|
||||||
// Will spin up separate threads for each request, and join on them
|
// Will spin up separate threads for each request, and join on them
|
||||||
// before going to the next step!
|
// before going to the next step!
|
||||||
Parallel.ForEach(websites,
|
Parallel.ForEach(websites,
|
||||||
new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads
|
new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads
|
||||||
website =>
|
website =>
|
||||||
{
|
{
|
||||||
@ -533,7 +576,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
(introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
|
(introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
|
||||||
Console.WriteLine(student.Introduce("Beth"));
|
Console.WriteLine(student.Introduce("Beth"));
|
||||||
|
|
||||||
// IQUERYABLE<T> - almost all collections implement this, which gives you a lot of
|
// IQUERYABLE<T> - almost all collections implement this, which gives you a lot of
|
||||||
// very useful Map / Filter / Reduce style methods
|
// very useful Map / Filter / Reduce style methods
|
||||||
var bikes = new List<Bicycle>();
|
var bikes = new List<Bicycle>();
|
||||||
bikes.Sort(); // Sorts the array
|
bikes.Sort(); // Sorts the array
|
||||||
@ -555,8 +598,8 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
// ASPARALLEL
|
// ASPARALLEL
|
||||||
// And this is where things get wicked - combines linq and parallel operations
|
// And this is where things get wicked - combines linq and parallel operations
|
||||||
var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
|
var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
|
||||||
// this will happen in parallel! Threads will automagically be spun up and the
|
// this will happen in parallel! Threads will automagically be spun up and the
|
||||||
// results divvied amongst them! Amazing for large datasets when you have lots of
|
// results divvied amongst them! Amazing for large datasets when you have lots of
|
||||||
// cores
|
// cores
|
||||||
|
|
||||||
// LINQ - maps a store to IQueryable<T> objects, with delayed execution
|
// LINQ - maps a store to IQueryable<T> objects, with delayed execution
|
||||||
@ -574,9 +617,9 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
.Select(b => b.Name); // still no query run
|
.Select(b => b.Name); // still no query run
|
||||||
|
|
||||||
// Now the query runs, but opens a reader, so only populates are you iterate through
|
// Now the query runs, but opens a reader, so only populates are you iterate through
|
||||||
foreach (string bike in query)
|
foreach (string bike in query)
|
||||||
Console.WriteLine(result);
|
Console.WriteLine(result);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -609,7 +652,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
{
|
{
|
||||||
return _cadence;
|
return _cadence;
|
||||||
}
|
}
|
||||||
set // set - define a method to set a proprety
|
set // set - define a method to set a property
|
||||||
{
|
{
|
||||||
_cadence = value; // Value is the value passed in to the setter
|
_cadence = value; // Value is the value passed in to the setter
|
||||||
}
|
}
|
||||||
@ -628,7 +671,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
private set; // You can set modifiers on the get/set methods
|
private set; // You can set modifiers on the get/set methods
|
||||||
}
|
}
|
||||||
|
|
||||||
int _speed; // Everything is private by default: Only accessible from within this class.
|
int _speed; // Everything is private by default: Only accessible from within this class.
|
||||||
// can also use keyword private
|
// can also use keyword private
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
@ -675,7 +718,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
|
|
||||||
// Constructors are a way of creating classes
|
// Constructors are a way of creating classes
|
||||||
// This is a default constructor
|
// This is a default constructor
|
||||||
public Bicycle()
|
public Bicycle()
|
||||||
{
|
{
|
||||||
this.Gear = 1; // you can access members of the object with the keyword this
|
this.Gear = 1; // you can access members of the object with the keyword this
|
||||||
Cadence = 50; // but you don't always need it
|
Cadence = 50; // but you don't always need it
|
||||||
@ -687,13 +730,13 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
|
|
||||||
// This is a specified constructor (it contains arguments)
|
// This is a specified constructor (it contains arguments)
|
||||||
public Bicycle(int startCadence, int startSpeed, int startGear,
|
public Bicycle(int startCadence, int startSpeed, int startGear,
|
||||||
string name, bool hasCardsInSpokes, BikeBrand brand)
|
string name, bool hasCardsInSpokes, BikeBrand brand)
|
||||||
: base() // calls base first
|
: base() // calls base first
|
||||||
{
|
{
|
||||||
Gear = startGear;
|
Gear = startGear;
|
||||||
Cadence = startCadence;
|
Cadence = startCadence;
|
||||||
_speed = startSpeed;
|
_speed = startSpeed;
|
||||||
Name = name;
|
Name = name;
|
||||||
_hasCardsInSpokes = hasCardsInSpokes;
|
_hasCardsInSpokes = hasCardsInSpokes;
|
||||||
Brand = brand;
|
Brand = brand;
|
||||||
}
|
}
|
||||||
@ -749,7 +792,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
|
|
||||||
// It's also possible to define custom Indexers on objects.
|
// It's also possible to define custom Indexers on objects.
|
||||||
// All though this is not entirely useful in this example, you
|
// All though this is not entirely useful in this example, you
|
||||||
// could do bicycle[0] which yields "chris" to get the first passenger or
|
// could do bicycle[0] which returns "chris" to get the first passenger or
|
||||||
// bicycle[1] = "lisa" to set the passenger. (of this apparent quattrocycle)
|
// bicycle[1] = "lisa" to set the passenger. (of this apparent quattrocycle)
|
||||||
private string[] passengers = { "chris", "phil", "darren", "regina" };
|
private string[] passengers = { "chris", "phil", "darren", "regina" };
|
||||||
|
|
||||||
@ -760,7 +803,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
return passengers[i] = value;
|
passengers[i] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,7 +879,8 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
bool Broken { get; } // interfaces can contain properties as well as methods & events
|
bool Broken { get; } // interfaces can contain properties as well as methods & events
|
||||||
}
|
}
|
||||||
|
|
||||||
// Class can inherit only one other class, but can implement any amount of interfaces
|
// Class can inherit only one other class, but can implement any amount of interfaces, however
|
||||||
|
// the base class name must be the first in the list and all interfaces follow
|
||||||
class MountainBike : Bicycle, IJumpable, IBreakable
|
class MountainBike : Bicycle, IJumpable, IBreakable
|
||||||
{
|
{
|
||||||
int damage = 0;
|
int damage = 0;
|
||||||
@ -856,7 +900,7 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to connect to DB for LinqToSql example.
|
/// Used to connect to DB for LinqToSql example.
|
||||||
/// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional)
|
/// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional)
|
||||||
/// http://msdn.microsoft.com/en-us/data/jj193542.aspx
|
/// http://msdn.microsoft.com/en-us/data/jj193542.aspx
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -869,19 +913,48 @@ on a new line! ""Wow!"", the masses cried";
|
|||||||
|
|
||||||
public DbSet<Bicycle> Bikes { get; set; }
|
public DbSet<Bicycle> Bikes { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Classes can be split across multiple .cs files
|
||||||
|
// A1.cs
|
||||||
|
public partial class A
|
||||||
|
{
|
||||||
|
public static void A1()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Method A1 in class A");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A2.cs
|
||||||
|
public partial class A
|
||||||
|
{
|
||||||
|
public static void A2()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Method A2 in class A");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Program using the partial class "A"
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
A.A1();
|
||||||
|
A.A2();
|
||||||
|
}
|
||||||
|
}
|
||||||
} // End Namespace
|
} // End Namespace
|
||||||
```
|
```
|
||||||
|
|
||||||
## Topics Not Covered
|
## Topics Not Covered
|
||||||
|
|
||||||
* Attributes
|
* Attributes
|
||||||
* async/await, yield, pragma directives
|
* async/await, pragma directives
|
||||||
* Web Development
|
* Web Development
|
||||||
* ASP.NET MVC & WebApi (new)
|
* ASP.NET MVC & WebApi (new)
|
||||||
* ASP.NET Web Forms (old)
|
* ASP.NET Web Forms (old)
|
||||||
* WebMatrix (tool)
|
* WebMatrix (tool)
|
||||||
* Desktop Development
|
* Desktop Development
|
||||||
* Windows Presentation Foundation (WPF) (new)
|
* Windows Presentation Foundation (WPF) (new)
|
||||||
* Winforms (old)
|
* Winforms (old)
|
||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
@ -4,25 +4,22 @@ contributors:
|
|||||||
- ["Mohammad Valipour", "https://github.com/mvalipour"]
|
- ["Mohammad Valipour", "https://github.com/mvalipour"]
|
||||||
- ["Marco Scannadinari", "https://github.com/marcoms"]
|
- ["Marco Scannadinari", "https://github.com/marcoms"]
|
||||||
- ["Geoffrey Liu", "https://github.com/g-liu"]
|
- ["Geoffrey Liu", "https://github.com/g-liu"]
|
||||||
|
- ["Connor Shea", "https://github.com/connorshea"]
|
||||||
|
- ["Deepanshu Utkarsh", "https://github.com/duci9y"]
|
||||||
|
- ["Tyler Mumford", "https://tylermumford.com"]
|
||||||
filename: learncss.css
|
filename: learncss.css
|
||||||
---
|
---
|
||||||
|
|
||||||
In the early days of the web there were no visual elements, just pure text. But with the
|
Web pages are built with HTML, which specifies the content of a page. CSS (Cascading Style Sheets) is a separate language which specifies a page's **appearance**.
|
||||||
further development of browsers, fully visual web pages also became common.
|
|
||||||
CSS is the standard language that exists to keep the separation between
|
|
||||||
the content (HTML) and the look-and-feel of web pages.
|
|
||||||
|
|
||||||
In short, what CSS does is to provide a syntax that enables you to target
|
CSS code is made of static *rules*. Each rule takes one or more *selectors* and gives specific *values* to a number of visual *properties*. Those properties are then applied to the page elements indicated by the selectors.
|
||||||
different elements on an HTML page and assign different visual properties to them.
|
|
||||||
|
|
||||||
Like any other languages, CSS has many versions. Here we focus on CSS2.0,
|
This guide has been written with CSS 2 in mind, which is extended by the new features of CSS 3.
|
||||||
which is not the most recent version, but is the most widely supported and compatible version.
|
|
||||||
|
|
||||||
**NOTE:** Because the outcome of CSS consists of visual effects, in order to
|
**NOTE:** Because CSS produces visual results, in order to learn it, you need to try everything in a CSS playground like [dabblet](http://dabblet.com/).
|
||||||
learn it, you need try everything in a
|
|
||||||
CSS playground like [dabblet](http://dabblet.com/).
|
|
||||||
The main focus of this article is on the syntax and some general tips.
|
The main focus of this article is on the syntax and some general tips.
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
```css
|
```css
|
||||||
/* comments appear inside slash-asterisk, just like this line!
|
/* comments appear inside slash-asterisk, just like this line!
|
||||||
@ -32,92 +29,103 @@ The main focus of this article is on the syntax and some general tips.
|
|||||||
## SELECTORS
|
## SELECTORS
|
||||||
#################### */
|
#################### */
|
||||||
|
|
||||||
/* Generally, the primary statement in CSS is very simple */
|
/* the selector is used to target an element on a page. */
|
||||||
selector { property: value; /* more properties...*/ }
|
selector { property: value; /* more properties...*/ }
|
||||||
|
|
||||||
/* the selector is used to target an element on page.
|
|
||||||
|
|
||||||
You can target all elements on the page using asterisk! */
|
|
||||||
* { color:red; }
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Given an element like this on the page:
|
Here is an example element:
|
||||||
|
|
||||||
<div class='some-class class2' id='someId' attr='value' otherAttr='en-us foo bar' />
|
<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' />
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* you can target it by its name */
|
/* You can target it using one of its CSS classes */
|
||||||
.some-class { }
|
.class1 { }
|
||||||
|
|
||||||
/* or by both classes! */
|
/* or both classes! */
|
||||||
.some-class.class2 { }
|
.class1.class2 { }
|
||||||
|
|
||||||
/* or by its element name */
|
/* or its name */
|
||||||
div { }
|
div { }
|
||||||
|
|
||||||
/* or its id */
|
/* or its id */
|
||||||
#someId { }
|
#anID { }
|
||||||
|
|
||||||
/* or by the fact that it has an attribute! */
|
/* or using the fact that it has an attribute! */
|
||||||
[attr] { font-size:smaller; }
|
[attr] { font-size:smaller; }
|
||||||
|
|
||||||
/* or that the attribute has a specific value */
|
/* or that the attribute has a specific value */
|
||||||
[attr='value'] { font-size:smaller; }
|
[attr='value'] { font-size:smaller; }
|
||||||
|
|
||||||
/* start with a value (CSS3) */
|
/* starts with a value (CSS 3) */
|
||||||
[attr^='val'] { font-size:smaller; }
|
[attr^='val'] { font-size:smaller; }
|
||||||
|
|
||||||
/* or ends with (CSS3) */
|
/* or ends with a value (CSS 3) */
|
||||||
[attr$='ue'] { font-size:smaller; }
|
[attr$='ue'] { font-size:smaller; }
|
||||||
|
|
||||||
/* or select by one of the values from the whitespace separated list (CSS3) */
|
/* or contains a value in a space-separated list */
|
||||||
[otherAttr~='foo'] { font-size:smaller; }
|
[otherAttr~='foo'] { }
|
||||||
|
[otherAttr~='bar'] { }
|
||||||
|
|
||||||
/* or value can be exactly “value” or can begin with “value” immediately followed by “-” (U+002D) */
|
/* or contains a value in a dash-separated list, ie, "-" (U+002D) */
|
||||||
[otherAttr|='en'] { font-size:smaller; }
|
[otherAttr|='en'] { font-size:smaller; }
|
||||||
|
|
||||||
|
|
||||||
/* and more importantly you can combine these together -- there shouldn't be
|
/* You can combine different selectors to create a more focused selector. Don't
|
||||||
any space between different parts because that makes it to have another
|
put spaces between them. */
|
||||||
meaning. */
|
|
||||||
div.some-class[attr$='ue'] { }
|
div.some-class[attr$='ue'] { }
|
||||||
|
|
||||||
/* you can also select an element based on its parent. */
|
/* You can select an element which is a child of another element */
|
||||||
|
div.some-parent > .class-name { }
|
||||||
|
|
||||||
/* an element which is direct child of an element (selected the same way) */
|
/* or a descendant of another element. Children are the direct descendants of
|
||||||
div.some-parent > .class-name {}
|
their parent element, only one level down the tree. Descendants can be any
|
||||||
|
level down the tree. */
|
||||||
|
div.some-parent .class-name { }
|
||||||
|
|
||||||
/* or any of its parents in the tree
|
/* Warning: the same selector without a space has another meaning.
|
||||||
the following basically means any element that has class "class-name"
|
Can you guess what? */
|
||||||
and is child of a div with class name "some-parent" IN ANY DEPTH */
|
div.some-parent.class-name { }
|
||||||
div.some-parent .class-name {}
|
|
||||||
|
|
||||||
/* warning: the same selector without space has another meaning.
|
/* You may also select an element based on its adjacent sibling */
|
||||||
can you say what? */
|
.i-am-just-before + .this-element { }
|
||||||
div.some-parent.class-name {}
|
|
||||||
|
|
||||||
/* you also might choose to select an element based on its direct
|
/* or any sibling preceding it */
|
||||||
previous sibling */
|
.i-am-any-element-before ~ .this-element { }
|
||||||
.i-am-before + .this-element { }
|
|
||||||
|
|
||||||
/* or any sibling before this */
|
/* There are some selectors called pseudo classes that can be used to select an
|
||||||
.i-am-any-before ~ .this-element {}
|
element only when it is in a particular state */
|
||||||
|
|
||||||
/* There are some pseudo classes that allows you to select an element
|
/* for example, when the cursor hovers over an element */
|
||||||
based on its page behaviour (rather than page structure) */
|
selector:hover { }
|
||||||
|
|
||||||
/* for example for when an element is hovered */
|
/* or a link has been visited */
|
||||||
selector:hover {}
|
selector:visited { }
|
||||||
|
|
||||||
/* or a visited link */
|
/* or hasn't been visited */
|
||||||
selected:visited {}
|
selected:link { }
|
||||||
|
|
||||||
/* or not visited link */
|
/* or an element is in focus */
|
||||||
selected:link {}
|
selected:focus { }
|
||||||
|
|
||||||
/* or an input element which is focused */
|
/* any element that is the first child of its parent */
|
||||||
selected:focus {}
|
selector:first-child {}
|
||||||
|
|
||||||
|
/* any element that is the last child of its parent */
|
||||||
|
selector:last-child {}
|
||||||
|
|
||||||
|
/* Just like pseudo classes, pseudo elements allow you to style certain parts of a document */
|
||||||
|
|
||||||
|
/* matches a virtual first child of the selected element */
|
||||||
|
selector::before {}
|
||||||
|
|
||||||
|
/* matches a virtual last child of the selected element */
|
||||||
|
selector::after {}
|
||||||
|
|
||||||
|
/* At appropriate places, an asterisk may be used as a wildcard to select every
|
||||||
|
element */
|
||||||
|
* { } /* all elements */
|
||||||
|
.parent * { } /* all descendants */
|
||||||
|
.parent > * { } /* all children */
|
||||||
|
|
||||||
/* ####################
|
/* ####################
|
||||||
## PROPERTIES
|
## PROPERTIES
|
||||||
@ -125,123 +133,122 @@ selected:focus {}
|
|||||||
|
|
||||||
selector {
|
selector {
|
||||||
|
|
||||||
/* Units */
|
/* Units of length can be absolute or relative. */
|
||||||
width: 50%; /* in percent */
|
|
||||||
font-size: 2em; /* times current font-size */
|
/* Relative units */
|
||||||
width: 200px; /* in pixels */
|
width: 50%; /* percentage of parent element width */
|
||||||
font-size: 20pt; /* in points */
|
font-size: 2em; /* multiples of element's original font-size */
|
||||||
width: 5cm; /* in centimeters */
|
font-size: 2rem; /* or the root element's font-size */
|
||||||
min-width: 50mm; /* in millimeters */
|
font-size: 2vw; /* multiples of 1% of the viewport's width (CSS 3) */
|
||||||
max-width: 5in; /* in inches. max-(width|height) */
|
font-size: 2vh; /* or its height */
|
||||||
height: 0.2vh; /* times vertical height of browser viewport (CSS3) */
|
font-size: 2vmin; /* whichever of a vh or a vw is smaller */
|
||||||
width: 0.4vw; /* times horizontal width of browser viewport (CSS3) */
|
font-size: 2vmax; /* or greater */
|
||||||
min-height: 0.1vmin; /* the lesser of vertical, horizontal dimensions of browser viewport (CSS3) */
|
|
||||||
max-width: 0.3vmax; /* same as above, except the greater of the dimensions (CSS3) */
|
/* Absolute units */
|
||||||
|
width: 200px; /* pixels */
|
||||||
|
font-size: 20pt; /* points */
|
||||||
|
width: 5cm; /* centimeters */
|
||||||
|
min-width: 50mm; /* millimeters */
|
||||||
|
max-width: 5in; /* inches */
|
||||||
|
|
||||||
/* Colors */
|
/* Colors */
|
||||||
background-color: #F6E; /* in short hex */
|
color: #F6E; /* short hex format */
|
||||||
background-color: #F262E2; /* in long hex format */
|
color: #FF66EE; /* long hex format */
|
||||||
background-color: tomato; /* can be a named color */
|
color: tomato; /* a named color */
|
||||||
background-color: rgb(255, 255, 255); /* in rgb */
|
color: rgb(255, 255, 255); /* as rgb values */
|
||||||
background-color: rgb(10%, 20%, 50%); /* in rgb percent */
|
color: rgb(10%, 20%, 50%); /* as rgb percentages */
|
||||||
background-color: rgba(255, 0, 0, 0.3); /* in semi-transparent rgb (CSS3) */
|
color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */
|
||||||
background-color: transparent; /* see thru */
|
color: transparent; /* equivalent to setting the alpha to 0 */
|
||||||
background-color: hsl(0, 100%, 50%); /* hsl format (CSS3). */
|
color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */
|
||||||
background-color: hsla(0, 100%, 50%, 0.3); /* Similar to RGBA, specify opacity at end (CSS3) */
|
color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */
|
||||||
|
|
||||||
|
|
||||||
/* Images */
|
/* Images as backgrounds of elements */
|
||||||
background-image: url(/path-to-image/image.jpg); /* quotes inside url() optional */
|
background-image: url(/img-path/img.jpg); /* quotes inside url() optional */
|
||||||
|
|
||||||
/* Fonts */
|
/* Fonts */
|
||||||
font-family: Arial;
|
font-family: Arial;
|
||||||
font-family: "Courier New"; /* if name has space it appears in single or double quotes */
|
/* if the font family name has a space, it must be quoted */
|
||||||
font-family: "Courier New", Trebuchet, Arial, sans-serif; /* if first one was not found
|
font-family: "Courier New";
|
||||||
browser uses the second font, and so forth */
|
/* if the first one is not found, the browser uses the next, and so on */
|
||||||
|
font-family: "Courier New", Trebuchet, Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Save any CSS you want in a file with extension `.css`.
|
Save a CSS stylesheet with the extension `.css`.
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<!-- you need to include the css file in your page's <head>: -->
|
<!-- You need to include the css file in your page's <head>. This is the
|
||||||
|
recommended method. Refer to http://stackoverflow.com/questions/8284365 -->
|
||||||
<link rel='stylesheet' type='text/css' href='path/to/style.css' />
|
<link rel='stylesheet' type='text/css' href='path/to/style.css' />
|
||||||
|
|
||||||
<!-- you can also include some CSS inline in your markup. However it is highly
|
<!-- You can also include some CSS inline in your markup. -->
|
||||||
recommended to avoid this. -->
|
|
||||||
<style>
|
<style>
|
||||||
a { color: purple; }
|
a { color: purple; }
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- or directly set CSS properties on the element.
|
<!-- Or directly set CSS properties on the element. -->
|
||||||
This has to be avoided as much as you can. -->
|
|
||||||
<div style="border: 1px solid red;">
|
<div style="border: 1px solid red;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Precedence
|
## Precedence or Cascade
|
||||||
|
|
||||||
As you noticed an element may be targetted by more than one selector.
|
An element may be targeted by multiple selectors and may have a property set on it in more than once. In these cases, one of the rules takes precedence over others. Rules with a more specific selector take precedence over a less specific one, and a rule occuring later in the stylesheet overwrites a previous one.
|
||||||
and may have a property set on it in more than one.
|
|
||||||
In these cases, one of the rules takes precedence over others.
|
This process is called cascading, hence the name Cascading Style Sheets.
|
||||||
|
|
||||||
Given the following CSS:
|
Given the following CSS:
|
||||||
|
|
||||||
```css
|
```css
|
||||||
/*A*/
|
/* A */
|
||||||
p.class1[attr='value']
|
p.class1[attr='value']
|
||||||
|
|
||||||
/*B*/
|
/* B */
|
||||||
p.class1 {}
|
p.class1 { }
|
||||||
|
|
||||||
/*C*/
|
/* C */
|
||||||
p.class2 {}
|
p.class2 { }
|
||||||
|
|
||||||
/*D*/
|
/* D */
|
||||||
p {}
|
p { }
|
||||||
|
|
||||||
/*E*/
|
/* E */
|
||||||
p { property: value !important; }
|
p { property: value !important; }
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
and the following markup:
|
and the following markup:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<p style='/*F*/ property:value;' class='class1 class2' attr='value'>
|
<p style='/*F*/ property:value;' class='class1 class2' attr='value' />
|
||||||
</p>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The precedence of style is as followed:
|
The precedence of style is as follows. Remember, the precedence is for each **property**, not for the entire block.
|
||||||
Remember, the precedence is for each **property**, not for the entire block.
|
|
||||||
|
|
||||||
* `E` has the highest precedence because of the keyword `!important`.
|
* `E` has the highest precedence because of the keyword `!important`. It is recommended that you avoid its usage.
|
||||||
It is recommended to avoid this unless it is strictly necessary to use.
|
* `F` is next, because it is an inline style.
|
||||||
* `F` is next, because it is inline style.
|
* `A` is next, because it is more "specific" than anything else. It has 3 specifiers: The name of the element `p`, its class `class1`, an attribute `attr='value'`.
|
||||||
* `A` is next, because it is more "specific" than anything else.
|
* `C` is next, even though it has the same specificity as `B`. This is because it appears after `B`.
|
||||||
more specific = more specifiers. here 3 specifiers: 1 tagname `p` +
|
* `B` is next.
|
||||||
class name `class1` + 1 attribute `attr='value'`
|
* `D` is the last one.
|
||||||
* `C` is next. although it has the same specificness as `B`
|
|
||||||
but it appears last.
|
|
||||||
* Then is `B`
|
|
||||||
* and lastly is `D`.
|
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
Most of the features in CSS2 (and gradually in CSS3) are compatible across
|
Most of the features in CSS 2 (and many in CSS 3) are available across all browsers and devices. But it's always good practice to check before using a new feature.
|
||||||
all browsers and devices. But it's always vital to have in mind the compatibility
|
|
||||||
of what you use in CSS with your target browsers.
|
|
||||||
|
|
||||||
[QuirksMode CSS](http://www.quirksmode.org/css/) is one of the best sources for this.
|
## Resources
|
||||||
|
|
||||||
To run a quick compatibility check, [CanIUse](http://caniuse.com) is a great resource.
|
* [CanIUse](http://caniuse.com) (Detailed compatibility info)
|
||||||
|
* [Dabblet](http://dabblet.com/) (CSS playground)
|
||||||
|
* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS) (Tutorials and reference)
|
||||||
|
* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/) (Reference)
|
||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
|
||||||
* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/)
|
* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/)
|
||||||
|
* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/)
|
||||||
* [QuirksMode CSS](http://www.quirksmode.org/css/)
|
* [QuirksMode CSS](http://www.quirksmode.org/css/)
|
||||||
* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context)
|
* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context)
|
||||||
|
* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing
|
||||||
|
* [CSS-Tricks](https://css-tricks.com)
|
||||||
|
133
d.html.markdown
133
d.html.markdown
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
language: D
|
language: D
|
||||||
filename: learnd.d
|
filename: learnd.d
|
||||||
contributors:
|
contributors:
|
||||||
- ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"]
|
- ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"]
|
||||||
lang: en
|
lang: en
|
||||||
@ -18,13 +18,15 @@ void main(string[] args) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If you're like me and spend way too much time on the internet, odds are you've heard
|
If you're like me and spend way too much time on the internet, odds are you've heard
|
||||||
about [D](http://dlang.org/). The D programming language is a modern, general-purpose,
|
about [D](http://dlang.org/). The D programming language is a modern, general-purpose,
|
||||||
multi-paradigm language with support for everything from low-level features to
|
multi-paradigm language with support for everything from low-level features to
|
||||||
expressive high-level abstractions.
|
expressive high-level abstractions.
|
||||||
|
|
||||||
D is actively developed by Walter Bright and Andrei Alexandrescu, two super smart, really cool
|
D is actively developed by a large group of super-smart people and is spearheaded by
|
||||||
dudes. With all that out of the way, let's look at some examples!
|
[Walter Bright](https://en.wikipedia.org/wiki/Walter_Bright) and
|
||||||
|
[Andrei Alexandrescu](https://en.wikipedia.org/wiki/Andrei_Alexandrescu).
|
||||||
|
With all that out of the way, let's look at some examples!
|
||||||
|
|
||||||
```c
|
```c
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
@ -36,9 +38,10 @@ void main() {
|
|||||||
writeln(i);
|
writeln(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto n = 1; // use auto for type inferred variables
|
// 'auto' can be used for inferring types.
|
||||||
|
auto n = 1;
|
||||||
// Numeric literals can use _ as a digit seperator for clarity
|
|
||||||
|
// Numeric literals can use '_' as a digit separator for clarity.
|
||||||
while(n < 10_000) {
|
while(n < 10_000) {
|
||||||
n += n;
|
n += n;
|
||||||
}
|
}
|
||||||
@ -47,16 +50,18 @@ void main() {
|
|||||||
n -= (n / 2);
|
n -= (n / 2);
|
||||||
} while(n > 0);
|
} while(n > 0);
|
||||||
|
|
||||||
// For and while are nice, but in D-land we prefer foreach
|
// For and while are nice, but in D-land we prefer 'foreach' loops.
|
||||||
// The .. creates a continuous range, excluding the end
|
// The '..' creates a continuous range, including the first value
|
||||||
foreach(i; 1..1_000_000) {
|
// but excluding the last.
|
||||||
|
foreach(n; 1..1_000_000) {
|
||||||
if(n % 2 == 0)
|
if(n % 2 == 0)
|
||||||
writeln(i);
|
writeln(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach_reverse(i; 1..int.max) {
|
// There's also 'foreach_reverse' when you want to loop backwards.
|
||||||
|
foreach_reverse(n; 1..int.max) {
|
||||||
if(n % 2 == 1) {
|
if(n % 2 == 1) {
|
||||||
writeln(i);
|
writeln(n);
|
||||||
} else {
|
} else {
|
||||||
writeln("No!");
|
writeln("No!");
|
||||||
}
|
}
|
||||||
@ -65,20 +70,22 @@ void main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
We can define new types with `struct`, `class`, `union`, and `enum`. Structs and unions
|
We can define new types with `struct`, `class`, `union`, and `enum`. Structs and unions
|
||||||
are passed to functions by value (i.e. copied) and classes are passed by reference. Futhermore,
|
are passed to functions by value (i.e. copied) and classes are passed by reference. Furthermore,
|
||||||
we can use templates to parameterize all of these on both types and values!
|
we can use templates to parameterize all of these on both types and values!
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// Here, T is a type parameter. Think <T> from C++/C#/Java
|
// Here, 'T' is a type parameter. Think '<T>' from C++/C#/Java.
|
||||||
struct LinkedList(T) {
|
struct LinkedList(T) {
|
||||||
T data = null;
|
T data = null;
|
||||||
LinkedList!(T)* next; // The ! is used to instaniate a parameterized type. Again, think <T>
|
|
||||||
|
// Use '!' to instantiate a parameterized type. Again, think '<T>'.
|
||||||
|
LinkedList!(T)* next;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BinTree(T) {
|
class BinTree(T) {
|
||||||
T data = null;
|
T data = null;
|
||||||
|
|
||||||
// If there is only one template parameter, we can omit parens
|
// If there is only one template parameter, we can omit the parentheses.
|
||||||
BinTree!T left;
|
BinTree!T left;
|
||||||
BinTree!T right;
|
BinTree!T right;
|
||||||
}
|
}
|
||||||
@ -93,37 +100,34 @@ enum Day {
|
|||||||
Saturday,
|
Saturday,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use alias to create abbreviations for types
|
// Use alias to create abbreviations for types.
|
||||||
|
|
||||||
alias IntList = LinkedList!int;
|
alias IntList = LinkedList!int;
|
||||||
alias NumTree = BinTree!double;
|
alias NumTree = BinTree!double;
|
||||||
|
|
||||||
// We can create function templates as well!
|
// We can create function templates as well!
|
||||||
|
|
||||||
T max(T)(T a, T b) {
|
T max(T)(T a, T b) {
|
||||||
if(a < b)
|
if(a < b)
|
||||||
return b;
|
return b;
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the ref keyword to ensure pass by referece.
|
// Use the ref keyword to ensure pass by reference. That is, even if 'a' and 'b'
|
||||||
// That is, even if a and b are value types, they
|
// are value types, they will always be passed by reference to 'swap()'.
|
||||||
// will always be passed by reference to swap
|
|
||||||
void swap(T)(ref T a, ref T b) {
|
void swap(T)(ref T a, ref T b) {
|
||||||
auto temp = a;
|
auto temp = a;
|
||||||
|
|
||||||
a = b;
|
a = b;
|
||||||
b = temp;
|
b = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// With templates, we can also parameterize on values, not just types
|
// With templates, we can also parameterize on values, not just types.
|
||||||
class Matrix(uint m, uint n, T = int) {
|
class Matrix(uint m, uint n, T = int) {
|
||||||
T[m] rows;
|
T[m] rows;
|
||||||
T[n] columns;
|
T[n] columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mat = new Matrix!(3, 3); // We've defaulted type T to int
|
auto mat = new Matrix!(3, 3); // We've defaulted type 'T' to 'int'.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -133,25 +137,24 @@ have the syntax of POD structures (`structure.x = 7`) with the semantics of
|
|||||||
getter and setter methods (`object.setX(7)`)!
|
getter and setter methods (`object.setX(7)`)!
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// Consider a class parameterized on a types T, U
|
// Consider a class parameterized on types 'T' & 'U'.
|
||||||
|
|
||||||
class MyClass(T, U) {
|
class MyClass(T, U) {
|
||||||
T _data;
|
T _data;
|
||||||
U _other;
|
U _other;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// And "getter" and "setter" methods like so
|
// And "getter" and "setter" methods like so:
|
||||||
class MyClass(T, U) {
|
class MyClass(T, U) {
|
||||||
T _data;
|
T _data;
|
||||||
U _other;
|
U _other;
|
||||||
|
|
||||||
// Constructors are always named `this`
|
// Constructors are always named 'this'.
|
||||||
this(T t, U u) {
|
this(T t, U u) {
|
||||||
|
// This will call the setter methods below.
|
||||||
data = t;
|
data = t;
|
||||||
other = u;
|
other = u;
|
||||||
}
|
}
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
@property T data() {
|
@property T data() {
|
||||||
return _data;
|
return _data;
|
||||||
@ -161,7 +164,7 @@ class MyClass(T, U) {
|
|||||||
return _other;
|
return _other;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
@property void data(T t) {
|
@property void data(T t) {
|
||||||
_data = t;
|
_data = t;
|
||||||
}
|
}
|
||||||
@ -170,16 +173,24 @@ class MyClass(T, U) {
|
|||||||
_other = u;
|
_other = u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// And we use them in this manner
|
|
||||||
|
|
||||||
|
// And we use them in this manner:
|
||||||
void main() {
|
void main() {
|
||||||
auto mc = MyClass!(int, string);
|
auto mc = new MyClass!(int, string)(7, "seven");
|
||||||
|
|
||||||
mc.data = 7;
|
// Import the 'stdio' module from the standard library for writing to
|
||||||
mc.other = "seven";
|
// console (imports can be local to a scope).
|
||||||
|
import std.stdio;
|
||||||
writeln(mc.data);
|
|
||||||
writeln(mc.other);
|
// Call the getters to fetch the values.
|
||||||
|
writefln("Earlier: data = %d, str = %s", mc.data, mc.other);
|
||||||
|
|
||||||
|
// Call the setters to assign new values.
|
||||||
|
mc.data = 8;
|
||||||
|
mc.other = "eight";
|
||||||
|
|
||||||
|
// Call the getters again to fetch the new values.
|
||||||
|
writefln("Later: data = %d, str = %s", mc.data, mc.other);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -188,12 +199,12 @@ our getter and setter methods, and keep the clean syntax of
|
|||||||
accessing members directly!
|
accessing members directly!
|
||||||
|
|
||||||
Other object-oriented goodies at our disposal
|
Other object-oriented goodies at our disposal
|
||||||
include `interface`s, `abstract class`es,
|
include interfaces, abstract classes,
|
||||||
and `override`ing methods. D does inheritance just like Java:
|
and overriding methods. D does inheritance just like Java:
|
||||||
Extend one class, implement as many interfaces as you please.
|
Extend one class, implement as many interfaces as you please.
|
||||||
|
|
||||||
We've seen D's OOP facilities, but let's switch gears. D offers
|
We've seen D's OOP facilities, but let's switch gears. D offers
|
||||||
functional programming with first-class functions, `pure`
|
functional programming with first-class functions, `pure`
|
||||||
functions, and immutable data. In addition, all of your favorite
|
functions, and immutable data. In addition, all of your favorite
|
||||||
functional algorithms (map, filter, reduce and friends) can be
|
functional algorithms (map, filter, reduce and friends) can be
|
||||||
found in the wonderful `std.algorithm` module!
|
found in the wonderful `std.algorithm` module!
|
||||||
@ -205,9 +216,9 @@ import std.range : iota; // builds an end-exclusive range
|
|||||||
void main() {
|
void main() {
|
||||||
// We want to print the sum of a list of squares of even ints
|
// We want to print the sum of a list of squares of even ints
|
||||||
// from 1 to 100. Easy!
|
// from 1 to 100. Easy!
|
||||||
|
|
||||||
// Just pass lambda expressions as template parameters!
|
// Just pass lambda expressions as template parameters!
|
||||||
// You can pass any old function you like, but lambdas are convenient here.
|
// You can pass any function you like, but lambdas are convenient here.
|
||||||
auto num = iota(1, 101).filter!(x => x % 2 == 0)
|
auto num = iota(1, 101).filter!(x => x % 2 == 0)
|
||||||
.map!(y => y ^^ 2)
|
.map!(y => y ^^ 2)
|
||||||
.reduce!((a, b) => a + b);
|
.reduce!((a, b) => a + b);
|
||||||
@ -216,32 +227,34 @@ void main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Notice how we got to build a nice Haskellian pipeline to compute num?
|
Notice how we got to build a nice Haskellian pipeline to compute num?
|
||||||
That's thanks to a D innovation know as Uniform Function Call Syntax.
|
That's thanks to a D innovation know as Uniform Function Call Syntax (UFCS).
|
||||||
With UFCS, we can choose whether to write a function call as a method
|
With UFCS, we can choose whether to write a function call as a method
|
||||||
or free function call! Walter wrote a nice article on this
|
or free function call! Walter wrote a nice article on this
|
||||||
[here.](http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394)
|
[here.](http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394)
|
||||||
In short, you can call functions whose first parameter
|
In short, you can call functions whose first parameter
|
||||||
is of some type A on any expression of type A as a method.
|
is of some type A on any expression of type A as a method.
|
||||||
|
|
||||||
I like parallelism. Anyone else like parallelism? Sure you do. Let's do some!
|
I like parallelism. Anyone else like parallelism? Sure you do. Let's do some!
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
// Let's say we want to populate a large array with the square root of all
|
||||||
|
// consecutive integers starting from 1 (up until the size of the array), and we
|
||||||
|
// want to do this concurrently taking advantage of as many cores as we have
|
||||||
|
// available.
|
||||||
|
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
import std.parallelism : parallel;
|
import std.parallelism : parallel;
|
||||||
import std.math : sqrt;
|
import std.math : sqrt;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// We want take the square root every number in our array,
|
// Create your large array
|
||||||
// and take advantage of as many cores as we have available.
|
|
||||||
auto arr = new double[1_000_000];
|
auto arr = new double[1_000_000];
|
||||||
|
|
||||||
// Use an index, and an array element by referece,
|
// Use an index, access every array element by reference (because we're
|
||||||
// and just call parallel on the array!
|
// going to change each element) and just call parallel on the array!
|
||||||
foreach(i, ref elem; parallel(arr)) {
|
foreach(i, ref elem; parallel(arr)) {
|
||||||
ref = sqrt(i + 1.0);
|
ref = sqrt(i + 1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -81,7 +81,7 @@ example5() {
|
|||||||
// Where classBody can include instance methods and variables, but also
|
// Where classBody can include instance methods and variables, but also
|
||||||
// class methods and variables.
|
// class methods and variables.
|
||||||
class Example6Class {
|
class Example6Class {
|
||||||
var example6InstanceVariable = "Example6 instance variable";
|
var example6InstanceVariable = "Example6 instance variable";
|
||||||
sayIt() {
|
sayIt() {
|
||||||
print(example6InstanceVariable);
|
print(example6InstanceVariable);
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ example6() {
|
|||||||
|
|
||||||
// Class methods and variables are declared with "static" terms.
|
// Class methods and variables are declared with "static" terms.
|
||||||
class Example7Class {
|
class Example7Class {
|
||||||
static var example7ClassVariable = "Example7 class variable";
|
static var example7ClassVariable = "Example7 class variable";
|
||||||
static sayItFromClass() {
|
static sayItFromClass() {
|
||||||
print(example7ClassVariable);
|
print(example7ClassVariable);
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ example7() {
|
|||||||
// by default. But arrays and maps are not. They can be made constant by
|
// by default. But arrays and maps are not. They can be made constant by
|
||||||
// declaring them "const".
|
// declaring them "const".
|
||||||
var example8A = const ["Example8 const array"],
|
var example8A = const ["Example8 const array"],
|
||||||
example8M = const {"someKey": "Example8 const map"};
|
example8M = const {"someKey": "Example8 const map"};
|
||||||
example8() {
|
example8() {
|
||||||
print(example8A[0]);
|
print(example8A[0]);
|
||||||
print(example8M["someKey"]);
|
print(example8M["someKey"]);
|
||||||
@ -245,7 +245,7 @@ example18() {
|
|||||||
// Strings with triple single-quotes or triple double-quotes span
|
// Strings with triple single-quotes or triple double-quotes span
|
||||||
// multiple lines and include line delimiters.
|
// multiple lines and include line delimiters.
|
||||||
example19() {
|
example19() {
|
||||||
print('''Example19 <a href="etc">
|
print('''Example19 <a href="etc">
|
||||||
Example19 Don't can't I'm Etc
|
Example19 Don't can't I'm Etc
|
||||||
Example19 </a>''');
|
Example19 </a>''');
|
||||||
}
|
}
|
||||||
@ -272,7 +272,7 @@ example20() {
|
|||||||
class Example21 {
|
class Example21 {
|
||||||
List<String> _names;
|
List<String> _names;
|
||||||
Example21() {
|
Example21() {
|
||||||
_names = ["a", "b"];
|
_names = ["a", "b"];
|
||||||
}
|
}
|
||||||
List<String> get names => _names;
|
List<String> get names => _names;
|
||||||
set names(List<String> list) {
|
set names(List<String> list) {
|
||||||
@ -498,7 +498,7 @@ main() {
|
|||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
|
||||||
Dart has a comprehenshive web-site. It covers API reference, tutorials, articles and more, including a
|
Dart has a comprehensive web-site. It covers API reference, tutorials, articles and more, including a
|
||||||
useful Try Dart online.
|
useful Try Dart online.
|
||||||
http://www.dartlang.org/
|
http://www.dartlang.org/
|
||||||
http://try.dartlang.org/
|
http://try.dartlang.org/
|
||||||
|
@ -28,18 +28,50 @@ echo Hello, world!
|
|||||||
echo 'Dies ist die erste Zeile'; echo 'Dies die zweite Zeile'
|
echo 'Dies ist die erste Zeile'; echo 'Dies die zweite Zeile'
|
||||||
|
|
||||||
# Variablen deklariert man so:
|
# Variablen deklariert man so:
|
||||||
VARIABLE="irgendein String"
|
Variable="irgendein String"
|
||||||
|
|
||||||
# Aber nicht so:
|
# Aber nicht so:
|
||||||
VARIABLE = "irgendein String"
|
Variable = "irgendein String"
|
||||||
# Bash wird VARIABLE für einen Befehl halten, den es ausführen soll. Es wird einen Fehler ausgeben,
|
# Bash wird 'Variable' für einen Befehl halten, den es ausführen soll. Es wird einen Fehler ausgeben,
|
||||||
# weil es den Befehl nicht findet.
|
# weil es den Befehl nicht findet.
|
||||||
|
|
||||||
|
# Und so auch nicht:
|
||||||
|
Variable= 'Some string'
|
||||||
|
# Bash wird 'Variable' wieder für einen Befehl halten, den es ausführen soll. Es wird einen Fehler ausgeben,
|
||||||
|
# Hier wird der Teil 'Variable=' als nur für diesen einen Befehl gültige Zuweisung an die Variable gesehen.
|
||||||
|
|
||||||
# Eine Variable wird so benutzt:
|
# Eine Variable wird so benutzt:
|
||||||
echo $VARIABLE
|
echo $Variable
|
||||||
echo "$VARIABLE"
|
echo "$Variable"
|
||||||
# Wenn du eine Variable selbst benutzt – ihr Werte zuweist, sie exportierst oder irgendetwas anders –,
|
echo ${Variable}
|
||||||
|
# aber
|
||||||
|
echo '$Variable'
|
||||||
|
# Wenn du eine Variable selbst benutzt – ihr Werte zuweist, sie exportierst oder irgendetwas anderes –,
|
||||||
# dann über ihren Namen ohne $. Aber wenn du ihren zugewiesenen Wert willst, dann musst du $ voranstellen.
|
# dann über ihren Namen ohne $. Aber wenn du ihren zugewiesenen Wert willst, dann musst du $ voranstellen.
|
||||||
|
# Beachte: ' (Hochkomma) verhindert das Interpretieren der Variablen
|
||||||
|
|
||||||
|
# Ersetzen von Zeichenketten in Variablen
|
||||||
|
echo ${Variable/irgendein/neuer}
|
||||||
|
# Ersetzt das erste Vorkommen von "irgendein" durch "neuer"
|
||||||
|
|
||||||
|
# Teil einer Zeichenkette
|
||||||
|
Laenge=7
|
||||||
|
echo ${Variable:0:Laenge}
|
||||||
|
# Gibt nur die ersten 7 Zeichen zurück
|
||||||
|
|
||||||
|
# Standardwert verwenden
|
||||||
|
echo ${Foo:-"ErsatzWennLeerOderUngesetzt"}
|
||||||
|
# Das funktioniert mit nicht gesetzten Variablen (Foo=) und leeren Zeichenketten (Foo="")
|
||||||
|
# Die Zahl 0 (Foo=0) liefert 0.
|
||||||
|
# Beachte: der wert der Variablen wird nicht geändert
|
||||||
|
|
||||||
|
# Eingebaute Variable (BUILTINS):
|
||||||
|
# Einige nützliche Beispiele
|
||||||
|
echo "Rückgabewert des letzten Befehls: $?"
|
||||||
|
echo "Die PID des skripts: $$"
|
||||||
|
echo "Anzahl der Argumente beim Aufruf: $#"
|
||||||
|
echo "Alle Argumente beim Aufruf: $@"
|
||||||
|
echo "Die Argumente in einzelnen Variablen: $1 $2..."
|
||||||
|
|
||||||
# Einen Wert aus der Eingabe lesen:
|
# Einen Wert aus der Eingabe lesen:
|
||||||
echo "Wie heisst du?"
|
echo "Wie heisst du?"
|
||||||
@ -47,14 +79,30 @@ read NAME # Wir mussten nicht mal eine neue Variable deklarieren
|
|||||||
echo Hello, $NAME!
|
echo Hello, $NAME!
|
||||||
|
|
||||||
# Wir haben die übliche if-Struktur:
|
# Wir haben die übliche if-Struktur:
|
||||||
if true
|
# 'man test' liefert weitere Informationen zu Bedingungen
|
||||||
|
if [ "$NAME" -ne $USER ]
|
||||||
then
|
then
|
||||||
echo "Wie erwartet"
|
echo "Dein Name ist nicht dein Login-Name"
|
||||||
else
|
else
|
||||||
echo "Und dies nicht"
|
echo "Dein Name ist dein Login-Name"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ausdrücke werden im folgenden Format festgehalten:
|
# Es gibt auch bedingte Ausführung
|
||||||
|
echo "immer ausgeführt" || echo "Nur ausgeführt wenn der erste Befehl fehlschlägt"
|
||||||
|
echo "immer ausgeführt" && echo "Nur ausgeführt wenn der erste Befehl Erfolg hat"
|
||||||
|
|
||||||
|
# Um && und || mit if statements zu verwenden, braucht man mehrfache Paare eckiger Klammern:
|
||||||
|
if [ $NAME == "Steve" ] && [ $Alter -eq 15 ]
|
||||||
|
then
|
||||||
|
echo "Wird ausgeführt wenn $NAME gleich 'Steve' UND $Alter gleich 15."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $Name == "Daniya" ] || [ $Name == "Zach" ]
|
||||||
|
then
|
||||||
|
echo "Wird ausgeführt wenn $NAME gleich 'Daniya' ODER $NAME gleich 'Zach'."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ausdrücke haben folgendes Format:
|
||||||
echo $(( 10 + 5 ))
|
echo $(( 10 + 5 ))
|
||||||
|
|
||||||
# Anders als andere Programmiersprachen ist Bash eine Shell – es arbeitet also im Kontext von Verzeichnissen.
|
# Anders als andere Programmiersprachen ist Bash eine Shell – es arbeitet also im Kontext von Verzeichnissen.
|
||||||
@ -69,13 +117,60 @@ ls -l # Liste alle Dateien und Unterverzeichnisse auf einer eigenen Zeile auf
|
|||||||
# txt-Dateien im aktuellen Verzeichnis auflisten:
|
# txt-Dateien im aktuellen Verzeichnis auflisten:
|
||||||
ls -l | grep "\.txt"
|
ls -l | grep "\.txt"
|
||||||
|
|
||||||
# Befehle können innerhalb anderer Befehle mit $( ) erstetzt werden:
|
# Ein- und Ausgabe können umgeleitet werden (stdin, stdout, and stderr).
|
||||||
|
# Von stdin lesen bis "EOF" allein in einer Zeile auftaucht
|
||||||
|
# und die Datei hello.py mit den Zeilen zwischen den beiden "EOF"
|
||||||
|
# überschreiben:
|
||||||
|
cat > hello.py << EOF
|
||||||
|
#!/usr/bin/env python
|
||||||
|
from __future__ import print_function
|
||||||
|
import sys
|
||||||
|
print("#stdout", file=sys.stdout)
|
||||||
|
print("#stderr", file=sys.stderr)
|
||||||
|
for line in sys.stdin:
|
||||||
|
print(line, file=sys.stdout)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Führe hello.py mit verschiedenen Umleitungen von
|
||||||
|
# stdin, stdout und stderr aus:
|
||||||
|
python hello.py < "input.in"
|
||||||
|
python hello.py > "output.out"
|
||||||
|
python hello.py 2> "error.err"
|
||||||
|
python hello.py > "output-and-error.log" 2>&1
|
||||||
|
python hello.py > /dev/null 2>&1
|
||||||
|
# Die Fehlerausgabe würde die Datei "error.err" überschreiben (falls sie existiert)
|
||||||
|
# verwende ">>" um stattdessen anzuhängen:
|
||||||
|
python hello.py >> "output.out" 2>> "error.err"
|
||||||
|
|
||||||
|
# Überschreibe output.out, hänge an error.err an und zähle die Zeilen beider Dateien:
|
||||||
|
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
|
||||||
|
wc -l output.out error.err
|
||||||
|
|
||||||
|
# Führe einen Befehl aus und gib dessen "file descriptor" (zB /dev/fd/123) aus
|
||||||
|
# siehe: man fd
|
||||||
|
echo <(echo "#helloworld")
|
||||||
|
|
||||||
|
# Mehrere Arten, um output.out mit "#helloworld" zu überschreiben:
|
||||||
|
cat > output.out <(echo "#helloworld")
|
||||||
|
echo "#helloworld" > output.out
|
||||||
|
echo "#helloworld" | cat > output.out
|
||||||
|
echo "#helloworld" | tee output.out >/dev/null
|
||||||
|
|
||||||
|
# Löschen der Hilfsdateien von oberhalb, mit Anzeige der Dateinamen
|
||||||
|
# (mit '-i' für "interactive" erfolgt für jede Date eine Rückfrage)
|
||||||
|
rm -v output.out error.err output-and-error.log
|
||||||
|
|
||||||
|
# Die Ausgabe von Befehlen kann mit Hilfe von $( ) in anderen Befehlen verwendet weden:
|
||||||
# Der folgende Befehl zeigt die Anzahl aller Dateien und Unterverzeichnisse
|
# Der folgende Befehl zeigt die Anzahl aller Dateien und Unterverzeichnisse
|
||||||
# im aktuellen Verzeichnis an.
|
# im aktuellen Verzeichnis an.
|
||||||
echo "Dieser Ordner beinhaltet $(ls | wc -l) Dateien und Verzeichnisse."
|
echo "Dieser Ordner beinhaltet $(ls | wc -l) Dateien und Verzeichnisse."
|
||||||
|
|
||||||
|
# Dasselbe kann man mit "backticks" `` erreichen, aber diese können
|
||||||
|
# nicht verschachtelt werden. $() ist die empfohlene Methode.
|
||||||
|
echo "Dieser Ordner beinhaltet `ls | wc -l` Dateien und Verzeichnisse."
|
||||||
|
|
||||||
# Bash nutzt einen case-Ausdruck, der sich ähnlich wie switch in Java oder C++ verhält.
|
# Bash nutzt einen case-Ausdruck, der sich ähnlich wie switch in Java oder C++ verhält.
|
||||||
case "$VARIABLE"
|
case "$Variable"
|
||||||
in
|
in
|
||||||
# Liste der Fälle, die unterschieden werden sollen
|
# Liste der Fälle, die unterschieden werden sollen
|
||||||
0) echo "Hier ist eine Null."
|
0) echo "Hier ist eine Null."
|
||||||
@ -83,10 +178,106 @@ in
|
|||||||
*) echo "Das ist nicht Null."
|
*) echo "Das ist nicht Null."
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# loops iterieren über die angegebene Zahl von Argumenten:
|
# 'for' Schleifen iterieren über die angegebene Zahl von Argumenten:
|
||||||
# Der Inhalt von $VARIABLE wird dreimal ausgedruckt.
|
# Der Inhalt von $Variable wird dreimal ausgedruckt.
|
||||||
for $VARIABLE in x y z
|
for $Variable in {1..3}
|
||||||
do
|
do
|
||||||
echo "$VARIABLE"
|
echo "$Variable"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Oder verwende die "traditionelle 'for'-Schleife":
|
||||||
|
for ((a=1; a <= 3; a++))
|
||||||
|
do
|
||||||
|
echo $a
|
||||||
|
done
|
||||||
|
|
||||||
|
# Schleifen können auch mit Dateien arbeiten:
|
||||||
|
# 'cat' zeigt zuerst file1 an und dann file2
|
||||||
|
for Variable in file1 file2
|
||||||
|
do
|
||||||
|
cat "$Variable"
|
||||||
|
done
|
||||||
|
|
||||||
|
# .. oder mit der Ausgabe eines Befehls:
|
||||||
|
# Ausgabe des Inhalts jeder Datei, die von 'ls' aufgezählt wird
|
||||||
|
for Output in $(ls)
|
||||||
|
do
|
||||||
|
cat "$Output"
|
||||||
|
done
|
||||||
|
|
||||||
|
# while Schleife:
|
||||||
|
while [ true ]
|
||||||
|
do
|
||||||
|
echo "Schleifenkörper..."
|
||||||
|
break
|
||||||
|
done
|
||||||
|
|
||||||
|
# Funktionen definieren
|
||||||
|
# Definition:
|
||||||
|
function foo ()
|
||||||
|
{
|
||||||
|
echo "Argumente funktionieren wie bei skripts: $@"
|
||||||
|
echo Und: $1 $2..."
|
||||||
|
echo "Dies ist eine Funktion"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# oder einfacher
|
||||||
|
bar ()
|
||||||
|
{
|
||||||
|
echo "Auch so kann man Funktionen deklarieren!"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Aufruf der Funktion:
|
||||||
|
foo "My name is" $Name
|
||||||
|
|
||||||
|
# Was du noch lernen könntest:
|
||||||
|
# Ausgabe der letzten 10 Zeilen von file.txt
|
||||||
|
tail -n 10 file.txt
|
||||||
|
# Ausgabe der ersten 10 Zeilen von file.txt
|
||||||
|
head -n 10 file.txt
|
||||||
|
# sortierte Ausgabe von file.txt
|
||||||
|
sort file.txt
|
||||||
|
# Mehrfachzeilen in sortierten Dateien unterdrücken
|
||||||
|
# oder (mit -d) nur diese ausgeben
|
||||||
|
uniq -d file.txt
|
||||||
|
# Ausgabe nur der ersten Spalte (vor dem ersten ',')
|
||||||
|
cut -d ',' -f 1 file.txt
|
||||||
|
# ersetze in file.txt jedes vorkommende 'gut' durch 'super' (versteht regex)
|
||||||
|
sed -i 's/gut/super/g' file.txt
|
||||||
|
# Ausgabe nach stdout aller Zeilen von file.txt, die auf eine regex passen
|
||||||
|
# Im Beispiel: Zeilen, die mit "foo" beginnen und mit "bar" enden
|
||||||
|
grep "^foo.*bar$" file.txt
|
||||||
|
# Mit der Option "-c" wird stattdessen die Anzahl der gefundenen Zeilen ausgegeben
|
||||||
|
grep -c "^foo.*bar$" file.txt
|
||||||
|
# verwende 'fgrep' oder 'grep -F' wenn du buchstäblich nach den Zeichen
|
||||||
|
# suchen willst, ohne sie als regex zu interpretieren
|
||||||
|
fgrep "^foo.*bar$" file.txt
|
||||||
|
|
||||||
|
# Dokumentation über die in bash eingebauten Befehle
|
||||||
|
# bekommst du mit dem eingebauten Befehl 'help'
|
||||||
|
help
|
||||||
|
help help
|
||||||
|
help for
|
||||||
|
help return
|
||||||
|
help source
|
||||||
|
help .
|
||||||
|
|
||||||
|
# Das bash-Handbuch liest du mit 'man'
|
||||||
|
apropos bash
|
||||||
|
man 1 bash
|
||||||
|
man bash
|
||||||
|
|
||||||
|
# Dann gibt es noch das 'info' System (drücke ? um Hilfe angezeigt zu bekommen)
|
||||||
|
apropos info | grep '^info.*('
|
||||||
|
man info
|
||||||
|
info info
|
||||||
|
info 5 info
|
||||||
|
|
||||||
|
# info Dokumentation über bash:
|
||||||
|
info bash
|
||||||
|
info bash 'Bash Features'
|
||||||
|
info bash 6
|
||||||
|
info --apropos bash
|
||||||
```
|
```
|
||||||
|
@ -248,7 +248,8 @@ zur nächsten Zeile, ""Wahnsinn!"", die Massen waren kaum zu bändigen";
|
|||||||
// Ternärer Operator
|
// Ternärer Operator
|
||||||
// Anstatt eines einfachen if/else lässt sich auch folgendes schreiben:
|
// Anstatt eines einfachen if/else lässt sich auch folgendes schreiben:
|
||||||
// <condition> ? <true> : <false>
|
// <condition> ? <true> : <false>
|
||||||
string isTrue = true ? "Ja" : "Nein";
|
int zumVergleich = 17;
|
||||||
|
string isTrue = zumVergleich == 17 ? "Ja" : "Nein";
|
||||||
|
|
||||||
// while-Schleife
|
// while-Schleife
|
||||||
int fooWhile = 0;
|
int fooWhile = 0;
|
||||||
@ -882,8 +883,8 @@ zur nächsten Zeile, ""Wahnsinn!"", die Massen waren kaum zu bändigen";
|
|||||||
* [LINQ](http://shop.oreilly.com/product/9780596519254.do)
|
* [LINQ](http://shop.oreilly.com/product/9780596519254.do)
|
||||||
* [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
|
* [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
|
||||||
* [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
|
* [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
|
||||||
* [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
|
* [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/overview/exploring-webmatrix)
|
||||||
* [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
|
* [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
|
||||||
* [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
|
* [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
|
||||||
|
|
||||||
[C# Coding Conventions](http://msdn.microsoft.com/de-de/library/vstudio/ff926074.aspx)
|
[C# Coding Conventions](http://msdn.microsoft.com/de-de/library/vstudio/ff926074.aspx)
|
||||||
|
@ -18,12 +18,12 @@ Anmerkung des Übersetzers: Einige englische Begriffe wie *Repository*, *Commit*
|
|||||||
|
|
||||||
### Was ist Versionsverwaltung?
|
### Was ist Versionsverwaltung?
|
||||||
|
|
||||||
Eine Versionskontrolle erfasst die Änderungen einer Datei oder eines Verzeichnisses im Verlauf der Zeit.
|
Eine Versionsverwaltung erfasst die Änderungen einer Datei oder eines Verzeichnisses im Verlauf der Zeit.
|
||||||
|
|
||||||
### Zentrale im Vergleich mit verteilter Versionverwaltung
|
### Zentrale im Vergleich mit verteilter Versionverwaltung
|
||||||
|
|
||||||
* Zentrale Versionskontrolle konzentriert sich auf das Synchronisieren, Verfolgen und Sichern von Dateien.
|
* Zentrale Versionsverwaltung konzentriert sich auf das Synchronisieren, Verfolgen und Sichern von Dateien.
|
||||||
* Verteilte Versionskontrolle konzentriert sich auf das Teilen der Änderungen. Jede Änderung hat eine eindeutige ID.
|
* Verteilte Versionsverwaltung konzentriert sich auf das Teilen der Änderungen. Jede Änderung hat eine eindeutige ID.
|
||||||
* Verteilte Systeme haben keine vorbestimmte Struktur. Ein SVN-ähnliches, zentrales System wäre mit Git ebenso umsetzbar.
|
* Verteilte Systeme haben keine vorbestimmte Struktur. Ein SVN-ähnliches, zentrales System wäre mit Git ebenso umsetzbar.
|
||||||
|
|
||||||
[Weiterführende Informationen](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
|
[Weiterführende Informationen](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
|
||||||
@ -48,7 +48,7 @@ Ein Repository besteht in Git aus dem .git-Verzeichnis und dem Arbeitsverzeichni
|
|||||||
|
|
||||||
### .git-Verzeichnis (Teil des Repositorys)
|
### .git-Verzeichnis (Teil des Repositorys)
|
||||||
|
|
||||||
Das .git-Verzeichnis enth? alle Einstellung, Logs, Branches, den HEAD und mehr.
|
Das .git-Verzeichnis enthält alle Einstellung, Logs, Branches, den HEAD und mehr.
|
||||||
[Ausführliche Übersicht](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
|
[Ausführliche Übersicht](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
|
||||||
|
|
||||||
### Arbeitsverzeichnis (Teil des Repositorys)
|
### Arbeitsverzeichnis (Teil des Repositorys)
|
||||||
@ -61,7 +61,7 @@ Der Index ist die die Staging-Area von Git. Es ist im Grunde eine Ebene, die Arb
|
|||||||
|
|
||||||
### Commit
|
### Commit
|
||||||
|
|
||||||
Ein Commit ist ein Schnappschuss von Uderungen in deinem Arbeitsverzeichnis. Wenn du zum Beispiel 5 Dateien hinzugefügt und 2 andere entfernt hast, werden diese Änderungen im Commit (Schnappschuss) enthalten sein. Dieser Commit kann dann in andere Repositorys gepusht werden. Oder nicht!
|
Ein Commit ist ein Schnappschuss von Änderungen in deinem Arbeitsverzeichnis. Wenn du zum Beispiel 5 Dateien hinzugefügt und 2 andere entfernt hast, werden diese Änderungen im Commit (Schnappschuss) enthalten sein. Dieser Commit kann dann in andere Repositories gepusht werden. Oder nicht!
|
||||||
|
|
||||||
### Branch
|
### Branch
|
||||||
|
|
||||||
@ -69,7 +69,9 @@ Ein Branch, ein Ast oder Zweig, ist im Kern ein Pointer auf den letzten Commit,
|
|||||||
|
|
||||||
### HEAD und head (Teil des .git-Verzeichnisses)
|
### HEAD und head (Teil des .git-Verzeichnisses)
|
||||||
|
|
||||||
HEAD ist ein Pointer auf den aktuellen Branch. Ein Repository hat nur einen *aktiven* HEAD. Ein head ist ein Pointer, der auf ein beliebige Zahl von heads zeigt.
|
HEAD ist ein Pointer auf den aktuellen Branch. Ein Repository hat nur einen *aktiven* HEAD.
|
||||||
|
|
||||||
|
Ein *head* ist ein Pointer, der auf einen beliebigen Commit zeigt. Ein Repository kann eine beliebige Zahl von *heads* enthalten.
|
||||||
|
|
||||||
### Konzeptionelle Hintergründe
|
### Konzeptionelle Hintergründe
|
||||||
|
|
||||||
@ -127,7 +129,7 @@ Zeigt die Unterschiede zwischen Index (im Grunde dein Arbeitsverzeichnis/-reposi
|
|||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Zeigt den Branch, nicht-verfolgte Dateien, Uderungen und andere Unterschiede an
|
# Zeigt den Branch, nicht-verfolgte Dateien, Änderungen und andere Unterschiede an
|
||||||
$ git status
|
$ git status
|
||||||
|
|
||||||
# Anderes Wissenswertes über git status anzeigen
|
# Anderes Wissenswertes über git status anzeigen
|
||||||
@ -151,7 +153,7 @@ $ git add ./*.java
|
|||||||
|
|
||||||
### branch
|
### branch
|
||||||
|
|
||||||
Verwalte alle Branches. Du kannst sie mit diesem Befehl ansehen, bearbeiten, neue erschaffen oder löschen.
|
Verwalte alle Branches. Du kannst sie mit diesem Befehl ansehen, bearbeiten, neue erzeugen oder löschen.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Liste alle bestehenden Branches und Remotes auf
|
# Liste alle bestehenden Branches und Remotes auf
|
||||||
@ -186,7 +188,7 @@ $ git checkout -b newBranch
|
|||||||
|
|
||||||
### clone
|
### clone
|
||||||
|
|
||||||
Ein bestehendes Repository in ein neues Verzeichnis klonen oder kopieren. Es fügt außerdem für hedes geklonte Repo remote-tracking Branches hinzu. Du kannst auf diese Remote-Branches pushen.
|
Ein bestehendes Repository in ein neues Verzeichnis klonen oder kopieren. Es fügt außerdem für jedes geklonte Repository remote-tracking Branches hinzu. Du kannst auf diese Remote-Branches pushen.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Klone learnxinyminutes-docs
|
# Klone learnxinyminutes-docs
|
||||||
@ -288,16 +290,16 @@ $ git mv -f myFile existingFile
|
|||||||
|
|
||||||
### pull
|
### pull
|
||||||
|
|
||||||
Führe einen Pull, zieht alle Daten, eines Repositorys und f?? einen Merge mit einem anderen Branch durch.
|
Führe einen Pull (zieht alle Daten eines Repositories) aus und führt einen Merge mit einem anderen Branch durch.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Update deines lokalen Repos, indem ein Merge der neuen Uderungen
|
# Update deines lokalen Repos, indem ein Merge der neuen Änderungen
|
||||||
# von den remote-liegenden "origin"- und "master"-Branches durchgef?? wird.
|
# von den remote-liegenden "origin"- und "master"-Branches durchgeführt wird.
|
||||||
# git pull <remote> <branch>
|
# git pull <remote> <branch>
|
||||||
# git pull => impliziter Verweis auf origin und master
|
# git pull => impliziter Verweis auf origin und master
|
||||||
$ git pull origin master
|
$ git pull origin master
|
||||||
|
|
||||||
# F?? einen Merge von Uderungen eines remote-Branch und ein Rebase
|
# Führt einen Merge von Änderungen eines remote-Branch und ein Rebase
|
||||||
# des Branch-Commits im lokalen Repo durch. Wie: pull <remote> <branch>, git rebase <branch>"
|
# des Branch-Commits im lokalen Repo durch. Wie: pull <remote> <branch>, git rebase <branch>"
|
||||||
$ git pull origin master --rebase
|
$ git pull origin master --rebase
|
||||||
```
|
```
|
||||||
@ -337,8 +339,8 @@ $ git reset
|
|||||||
# Setze die Staging-Area zurück, um dem letzten Commit zu entsprechen und überschreibe das Arbeitsverzeichnis
|
# Setze die Staging-Area zurück, um dem letzten Commit zu entsprechen und überschreibe das Arbeitsverzeichnis
|
||||||
$ git reset --hard
|
$ git reset --hard
|
||||||
|
|
||||||
# Bewegt die Spitze des Branches zu dem angegebenen Commit (das Verzeichnis bleibt unber??)
|
# Bewegt die Spitze des Branches zu dem angegebenen Commit (das Verzeichnis bleibt unberührt)
|
||||||
# Alle Uderungen bleiben im Verzeichnis erhalten
|
# Alle Änderungen bleiben im Verzeichnis erhalten
|
||||||
$ git reset 31f2bb1
|
$ git reset 31f2bb1
|
||||||
|
|
||||||
# Bewegt die Spitze des Branches zurück zu dem angegebenen Commit
|
# Bewegt die Spitze des Branches zurück zu dem angegebenen Commit
|
||||||
|
@ -3,6 +3,7 @@ language: Go
|
|||||||
filename: learngo-de.go
|
filename: learngo-de.go
|
||||||
contributors:
|
contributors:
|
||||||
- ["Joseph Adams", "https://github.com/jcla1"]
|
- ["Joseph Adams", "https://github.com/jcla1"]
|
||||||
|
- ["Dennis Keller", "https://github.com/denniskeller"]
|
||||||
lang: de-de
|
lang: de-de
|
||||||
---
|
---
|
||||||
Go wurde entwickelt, um Probleme zu lösen. Sie ist zwar nicht der neueste Trend in
|
Go wurde entwickelt, um Probleme zu lösen. Sie ist zwar nicht der neueste Trend in
|
||||||
@ -24,7 +25,7 @@ aktive Community.
|
|||||||
zeiliger Kommentar */
|
zeiliger Kommentar */
|
||||||
|
|
||||||
// Eine jede Quelldatei beginnt mit einer Paket-Klausel.
|
// Eine jede Quelldatei beginnt mit einer Paket-Klausel.
|
||||||
// "main" ist ein besonderer Pkaetname, da er ein ausführbares Programm
|
// "main" ist ein besonderer Paketname, da er ein ausführbares Programm
|
||||||
// einleitet, im Gegensatz zu jedem anderen Namen, der eine Bibliothek
|
// einleitet, im Gegensatz zu jedem anderen Namen, der eine Bibliothek
|
||||||
// deklariert.
|
// deklariert.
|
||||||
package main
|
package main
|
||||||
@ -37,7 +38,7 @@ import (
|
|||||||
"strconv" // Zeichenkettenmanipulation
|
"strconv" // Zeichenkettenmanipulation
|
||||||
)
|
)
|
||||||
|
|
||||||
// Es folgt die Definition einer Funktions, in diesem Fall von "main". Auch hier
|
// Es folgt die Definition einer Funktion, in diesem Fall von "main". Auch hier
|
||||||
// ist der Name wieder besonders. "main" markiert den Eintrittspunkt des
|
// ist der Name wieder besonders. "main" markiert den Eintrittspunkt des
|
||||||
// Programms. Vergessen Sie nicht die geschweiften Klammern!
|
// Programms. Vergessen Sie nicht die geschweiften Klammern!
|
||||||
func main() {
|
func main() {
|
||||||
@ -55,7 +56,7 @@ func beyondHello() {
|
|||||||
var x int // Deklaration einer Variable, muss vor Gebrauch geschehen.
|
var x int // Deklaration einer Variable, muss vor Gebrauch geschehen.
|
||||||
x = 3 // Zuweisung eines Werts.
|
x = 3 // Zuweisung eines Werts.
|
||||||
// Kurze Deklaration: Benutzen Sie ":=", um die Typisierung automatisch zu
|
// Kurze Deklaration: Benutzen Sie ":=", um die Typisierung automatisch zu
|
||||||
// folgern, die Variable zu deklarieren und ihr einen Wert zu zuweisen.
|
// folgern, die Variable zu deklarieren und ihr einen Wert zuzuweisen.
|
||||||
y := 4
|
y := 4
|
||||||
|
|
||||||
// Eine Funktion mit mehreren Rückgabewerten.
|
// Eine Funktion mit mehreren Rückgabewerten.
|
||||||
@ -146,7 +147,7 @@ func learnFlowControl() {
|
|||||||
if false {
|
if false {
|
||||||
// nicht hier
|
// nicht hier
|
||||||
} else {
|
} else {
|
||||||
// sonder hier! spielt die Musik
|
// sondern hier! spielt die Musik
|
||||||
}
|
}
|
||||||
|
|
||||||
// Benutzen Sie ein "switch" Statement anstatt eine Anreihung von if-s
|
// Benutzen Sie ein "switch" Statement anstatt eine Anreihung von if-s
|
||||||
@ -165,7 +166,7 @@ func learnFlowControl() {
|
|||||||
// Ab hier gilt wieder: x == 1
|
// Ab hier gilt wieder: x == 1
|
||||||
|
|
||||||
// For ist die einzige Schleifenform in Go, sie hat aber mehrere Formen:
|
// For ist die einzige Schleifenform in Go, sie hat aber mehrere Formen:
|
||||||
for { // Endloschleife
|
for { // Endlosschleife
|
||||||
break // nur ein Spaß
|
break // nur ein Spaß
|
||||||
continue // wird nie ausgeführt
|
continue // wird nie ausgeführt
|
||||||
}
|
}
|
||||||
@ -262,10 +263,10 @@ func learnConcurrency() {
|
|||||||
// Auslesen und dann Ausgeben der drei berechneten Werte.
|
// Auslesen und dann Ausgeben der drei berechneten Werte.
|
||||||
// Man kann nicht im voraus feststellen in welcher Reihenfolge die Werte
|
// Man kann nicht im voraus feststellen in welcher Reihenfolge die Werte
|
||||||
// ankommen.
|
// ankommen.
|
||||||
fmt.Println(<-c, <-c, <-c) // mit dem Kannal rechts ist <- der Empfangs-Operator
|
fmt.Println(<-c, <-c, <-c) // mit dem Kanal rechts ist <- der Empfangs-Operator
|
||||||
|
|
||||||
cs := make(chan string) // ein weiterer Kannal, diesmal für strings
|
cs := make(chan string) // ein weiterer Kanal, diesmal für strings
|
||||||
cc := make(chan chan string) // ein Kannal für string Kannäle
|
cc := make(chan chan string) // ein Kanal für string Kanäle
|
||||||
|
|
||||||
// Start einer neuen Goroutine, nur um einen Wert zu senden
|
// Start einer neuen Goroutine, nur um einen Wert zu senden
|
||||||
go func() { c <- 84 }()
|
go func() { c <- 84 }()
|
||||||
@ -282,7 +283,7 @@ func learnConcurrency() {
|
|||||||
fmt.Println("wird nicht passieren.")
|
fmt.Println("wird nicht passieren.")
|
||||||
}
|
}
|
||||||
// Hier wird eine der beiden Goroutines fertig sein, die andere nicht.
|
// Hier wird eine der beiden Goroutines fertig sein, die andere nicht.
|
||||||
// Sie wird warten bis der Wert den sie sendet von dem Kannal gelesen wird.
|
// Sie wird warten bis der Wert den sie sendet von dem Kanal gelesen wird.
|
||||||
|
|
||||||
learnWebProgramming() // Go kann es und Sie hoffentlich auch bald.
|
learnWebProgramming() // Go kann es und Sie hoffentlich auch bald.
|
||||||
}
|
}
|
||||||
@ -300,19 +301,19 @@ func learnWebProgramming() {
|
|||||||
// Methode implementieren: ServeHTTP
|
// Methode implementieren: ServeHTTP
|
||||||
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// Senden von Daten mit einer Methode des http.ResponseWriter
|
// Senden von Daten mit einer Methode des http.ResponseWriter
|
||||||
w.Write([]byte("Sie habe Go in Y Minuten gelernt!"))
|
w.Write([]byte("Sie haben Go in Y Minuten gelernt!"))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Weitere Resourcen
|
## Weitere Resourcen
|
||||||
Alles zu Go finden Sie auf der [offiziellen Go Webseite](http://golang.org/).
|
Alles zu Go finden Sie auf der [offiziellen Go Webseite](http://golang.org/).
|
||||||
Dort können sie der Tutorial folgen, interaktiv Quelltext ausprobieren und viel
|
Dort können sie dem Tutorial folgen, interaktiv Quelltext ausprobieren und viel
|
||||||
Dokumentation lesen.
|
Dokumentation lesen.
|
||||||
|
|
||||||
Auch zu empfehlen ist die Spezifikation von Go, die nach heutigen Standards sehr
|
Auch zu empfehlen ist die Spezifikation von Go, die nach heutigen Standards sehr
|
||||||
kurz und auch gut verständlich formuliert ist. Auf der Leseliste von Go-Neulingen
|
kurz und auch gut verständlich formuliert ist. Auf der Leseliste von Go-Neulingen
|
||||||
ist außerdem der Quelltext der [Go standard Bibliothek](http://golang.org/src/pkg/).
|
ist außerdem der Quelltext der [Go standard Bibliothek](http://golang.org/src/pkg/).
|
||||||
Gut documentiert, demonstriert sie leicht zu verstehendes und im idiomatischen Stil
|
Gut dokumentiert, demonstriert sie leicht zu verstehendes und im idiomatischen Stil
|
||||||
verfasstes Go. Erreichbar ist der Quelltext auch durch das Klicken der Funktionsnamen
|
verfasstes Go. Erreichbar ist der Quelltext auch durch das Klicken der Funktionsnamen
|
||||||
in der [offiziellen Dokumentation von Go](http://golang.org/pkg/).
|
in der [offiziellen Dokumentation von Go](http://golang.org/pkg/).
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ contributors:
|
|||||||
- ["Adit Bhargava", "http://adit.io"]
|
- ["Adit Bhargava", "http://adit.io"]
|
||||||
translators:
|
translators:
|
||||||
- ["Henrik Jürges", "https://github.com/santifa"]
|
- ["Henrik Jürges", "https://github.com/santifa"]
|
||||||
|
- ["Nikolai Weh", "http://weh.hamburg"]
|
||||||
filename: haskell-de.hs
|
filename: haskell-de.hs
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -58,12 +59,13 @@ not False -- True
|
|||||||
-- Strings und Zeichen
|
-- Strings und Zeichen
|
||||||
"Das ist ein String."
|
"Das ist ein String."
|
||||||
'a' -- Zeichen
|
'a' -- Zeichen
|
||||||
'Einfache Anfuehrungszeichen gehen nicht.' -- error!
|
'Einfache Anführungszeichen gehen nicht.' -- error!
|
||||||
|
|
||||||
-- Strings können konkateniert werden.
|
-- Strings können konkateniert werden.
|
||||||
"Hello " ++ "world!" -- "Hello world!"
|
"Hello " ++ "world!" -- "Hello world!"
|
||||||
|
|
||||||
-- Ein String ist eine Liste von Zeichen.
|
-- Ein String ist eine Liste von Zeichen.
|
||||||
|
['H', 'a', 'l', 'l', 'o', '!'] -- "Hallo!"
|
||||||
"Das ist eine String" !! 0 -- 'D'
|
"Das ist eine String" !! 0 -- 'D'
|
||||||
|
|
||||||
|
|
||||||
@ -76,11 +78,23 @@ not False -- True
|
|||||||
[1, 2, 3, 4, 5]
|
[1, 2, 3, 4, 5]
|
||||||
[1..5]
|
[1..5]
|
||||||
|
|
||||||
-- Haskell unterstuetzt unendliche Listen!
|
-- Die zweite Variante nennt sich die "range"-Syntax.
|
||||||
[1..] -- Die Liste aller natuerlichen Zahlen
|
-- Ranges sind recht flexibel:
|
||||||
|
['A'..'F'] -- "ABCDEF"
|
||||||
|
|
||||||
|
-- Es ist möglich eine Schrittweite anzugeben:
|
||||||
|
[0,2..10] -- [0,2,4,6,8,10]
|
||||||
|
[5..1] -- [], da Haskell standardmässig inkrementiert.
|
||||||
|
[5,4..1] -- [5,4,3,2,1]
|
||||||
|
|
||||||
|
-- Der "!!"-Operator extrahiert das Element an einem bestimmten Index:
|
||||||
|
[1..10] !! 3 -- 4
|
||||||
|
|
||||||
|
-- Haskell unterstützt unendliche Listen!
|
||||||
|
[1..] -- Die Liste aller natürlichen Zahlen
|
||||||
|
|
||||||
-- Unendliche Listen funktionieren in Haskell, da es "lazy evaluation"
|
-- Unendliche Listen funktionieren in Haskell, da es "lazy evaluation"
|
||||||
-- unterstuetzt. Haskell evaluiert erst etwas, wenn es benötigt wird.
|
-- unterstützt. Haskell evaluiert erst etwas, wenn es benötigt wird.
|
||||||
-- Somit kannst du nach dem 1000. Element fragen und Haskell gibt es dir:
|
-- Somit kannst du nach dem 1000. Element fragen und Haskell gibt es dir:
|
||||||
|
|
||||||
[1..] !! 999 -- 1000
|
[1..] !! 999 -- 1000
|
||||||
@ -92,12 +106,9 @@ not False -- True
|
|||||||
-- Zwei Listen konkatenieren
|
-- Zwei Listen konkatenieren
|
||||||
[1..5] ++ [6..10]
|
[1..5] ++ [6..10]
|
||||||
|
|
||||||
-- Ein Element als Head hinzufuegen
|
-- Ein Element als Head hinzufügen
|
||||||
0:[1..5] -- [0, 1, 2, 3, 4, 5]
|
0:[1..5] -- [0, 1, 2, 3, 4, 5]
|
||||||
|
|
||||||
-- Gibt den 5. Index zurueck
|
|
||||||
[0..] !! 5 -- 5
|
|
||||||
|
|
||||||
-- Weitere Listenoperationen
|
-- Weitere Listenoperationen
|
||||||
head [1..5] -- 1
|
head [1..5] -- 1
|
||||||
tail [1..5] -- [2, 3, 4, 5]
|
tail [1..5] -- [2, 3, 4, 5]
|
||||||
@ -114,7 +125,8 @@ last [1..5] -- 5
|
|||||||
-- Ein Tupel:
|
-- Ein Tupel:
|
||||||
("haskell", 1)
|
("haskell", 1)
|
||||||
|
|
||||||
-- Auf Elemente eines Tupels zugreifen:
|
-- Ein Paar (Pair) ist ein Tupel mit 2 Elementen, auf die man wie folgt
|
||||||
|
-- zugreifen kann:
|
||||||
fst ("haskell", 1) -- "haskell"
|
fst ("haskell", 1) -- "haskell"
|
||||||
snd ("haskell", 1) -- 1
|
snd ("haskell", 1) -- 1
|
||||||
|
|
||||||
@ -140,9 +152,9 @@ add 1 2 -- 3
|
|||||||
(//) a b = a `div` b
|
(//) a b = a `div` b
|
||||||
35 // 4 -- 8
|
35 // 4 -- 8
|
||||||
|
|
||||||
-- Guards sind eine einfache Möglichkeit fuer Fallunterscheidungen.
|
-- Guards sind eine einfache Möglichkeit für Fallunterscheidungen.
|
||||||
fib x
|
fib x
|
||||||
| x < 2 = x
|
| x < 2 = 1
|
||||||
| otherwise = fib (x - 1) + fib (x - 2)
|
| otherwise = fib (x - 1) + fib (x - 2)
|
||||||
|
|
||||||
-- Pattern Matching funktioniert ähnlich.
|
-- Pattern Matching funktioniert ähnlich.
|
||||||
@ -174,7 +186,7 @@ foldl1 (\acc x -> acc + x) [1..5] -- 15
|
|||||||
-- 4. Mehr Funktionen
|
-- 4. Mehr Funktionen
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
|
||||||
-- currying: Wenn man nicht alle Argumente an eine Funktion uebergibt,
|
-- currying: Wenn man nicht alle Argumente an eine Funktion übergibt,
|
||||||
-- so wird sie eine neue Funktion gebildet ("curried").
|
-- so wird sie eine neue Funktion gebildet ("curried").
|
||||||
-- Es findet eine partielle Applikation statt und die neue Funktion
|
-- Es findet eine partielle Applikation statt und die neue Funktion
|
||||||
-- nimmt die fehlenden Argumente auf.
|
-- nimmt die fehlenden Argumente auf.
|
||||||
@ -190,23 +202,28 @@ foo 5 -- 15
|
|||||||
-- Funktionskomposition
|
-- Funktionskomposition
|
||||||
-- Die (.) Funktion verkettet Funktionen.
|
-- Die (.) Funktion verkettet Funktionen.
|
||||||
-- Zum Beispiel, die Funktion Foo nimmt ein Argument addiert 10 dazu und
|
-- Zum Beispiel, die Funktion Foo nimmt ein Argument addiert 10 dazu und
|
||||||
-- multipliziert dieses Ergebnis mit 5.
|
-- multipliziert dieses Ergebnis mit 4.
|
||||||
foo = (*5) . (+10)
|
foo = (*4) . (+10)
|
||||||
|
|
||||||
-- (5 + 10) * 5 = 75
|
-- (5 + 10) * 4 = 60
|
||||||
foo 5 -- 75
|
foo 5 -- 60
|
||||||
|
|
||||||
|
|
||||||
-- Haskell hat eine Funktion `$`. Diese ändert den Vorrang,
|
-- Haskell hat einen Operator `$`, welcher Funktionsapplikation durchführt.
|
||||||
-- so dass alles links von ihr zuerst berechnet wird und
|
-- Im Gegenzug zu der Standard-Funktionsapplikation, welche linksassoziativ ist
|
||||||
-- und dann an die rechte Seite weitergegeben wird.
|
-- und die höchstmögliche Priorität von "10" hat, ist der `$`-Operator
|
||||||
-- Mit `.` und `$` kann man sich viele Klammern ersparen.
|
-- rechtsassoziativ und hat die Priorität 0. Dieses hat (idr.) den Effekt,
|
||||||
|
-- dass der `komplette` Ausdruck auf der rechten Seite als Parameter für die
|
||||||
|
-- Funktion auf der linken Seite verwendet wird.
|
||||||
|
-- Mit `.` und `$` kann man sich so viele Klammern ersparen.
|
||||||
|
|
||||||
-- Vorher
|
(even (fib 7)) -- false
|
||||||
(even (fib 7)) -- true
|
|
||||||
|
|
||||||
-- Danach
|
-- Äquivalent:
|
||||||
even . fib $ 7 -- true
|
even $ fib 7 -- false
|
||||||
|
|
||||||
|
-- Funktionskomposition:
|
||||||
|
even . fib $ 7 -- false
|
||||||
|
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
-- 5. Typensystem
|
-- 5. Typensystem
|
||||||
@ -221,31 +238,31 @@ even . fib $ 7 -- true
|
|||||||
True :: Bool
|
True :: Bool
|
||||||
|
|
||||||
-- Funktionen haben genauso Typen.
|
-- Funktionen haben genauso Typen.
|
||||||
-- `not` ist Funktion die ein Bool annimmt und ein Bool zurueckgibt:
|
-- `not` ist Funktion die ein Bool annimmt und ein Bool zurückgibt:
|
||||||
-- not :: Bool -> Bool
|
-- not :: Bool -> Bool
|
||||||
|
|
||||||
-- Eine Funktion die zwei Integer Argumente annimmt:
|
-- Eine Funktion die zwei Integer Argumente annimmt:
|
||||||
-- add :: Integer -> Integer -> Integer
|
-- add :: Integer -> Integer -> Integer
|
||||||
|
|
||||||
-- Es ist guter Stil zu jeder Funktionsdefinition eine
|
-- Es ist guter Stil zu jeder Funktionsdefinition eine
|
||||||
-- Typdefinition darueber zu schreiben:
|
-- Typdefinition darüber zu schreiben:
|
||||||
double :: Integer -> Integer
|
double :: Integer -> Integer
|
||||||
double x = x * 2
|
double x = x * 2
|
||||||
|
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
-- 6. If-Anweisung und Kontrollstrukturen
|
-- 6. If-Ausdrücke und Kontrollstrukturen
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
|
||||||
-- If-Anweisung:
|
-- If-Ausdruck:
|
||||||
haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
|
haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
|
||||||
|
|
||||||
-- If-Anweisungen können auch ueber mehrere Zeilen verteilt sein.
|
-- If-Ausdrücke können auch über mehrere Zeilen verteilt sein.
|
||||||
-- Das Einruecken ist dabei äußerst wichtig.
|
-- Die Einrückung ist dabei wichtig.
|
||||||
haskell = if 1 == 1
|
haskell = if 1 == 1
|
||||||
then "awesome"
|
then "awesome"
|
||||||
else "awful"
|
else "awful"
|
||||||
|
|
||||||
-- Case-Anweisung: Zum Beispiel "commandline" Argumente parsen.
|
-- Case-Ausdruck: Am Beispiel vom Parsen von "commandline"-Argumenten.
|
||||||
case args of
|
case args of
|
||||||
"help" -> printHelp
|
"help" -> printHelp
|
||||||
"start" -> startProgram
|
"start" -> startProgram
|
||||||
@ -276,7 +293,7 @@ foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
|
|||||||
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
|
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
|
||||||
|
|
||||||
-- die Abarbeitung sieht so aus:
|
-- die Abarbeitung sieht so aus:
|
||||||
(2 * 3 + (2 * 2 + (2 * 1 + 4)))
|
(2 * 1 + (2 * 2 + (2 * 3 + 4)))
|
||||||
|
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
-- 7. Datentypen
|
-- 7. Datentypen
|
||||||
@ -300,7 +317,7 @@ data Maybe a = Nothing | Just a
|
|||||||
-- Diese sind alle vom Typ Maybe:
|
-- Diese sind alle vom Typ Maybe:
|
||||||
Just "hello" -- vom Typ `Maybe String`
|
Just "hello" -- vom Typ `Maybe String`
|
||||||
Just 1 -- vom Typ `Maybe Int`
|
Just 1 -- vom Typ `Maybe Int`
|
||||||
Nothing -- vom Typ `Maybe a` fuer jedes `a`
|
Nothing -- vom Typ `Maybe a` für jedes `a`
|
||||||
|
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
-- 8. Haskell IO
|
-- 8. Haskell IO
|
||||||
@ -309,8 +326,8 @@ Nothing -- vom Typ `Maybe a` fuer jedes `a`
|
|||||||
-- IO kann nicht völlig erklärt werden ohne Monaden zu erklären,
|
-- IO kann nicht völlig erklärt werden ohne Monaden zu erklären,
|
||||||
-- aber man kann die grundlegenden Dinge erklären.
|
-- aber man kann die grundlegenden Dinge erklären.
|
||||||
|
|
||||||
-- Wenn eine Haskell Programm ausgefuehrt wird, so wird `main` aufgerufen.
|
-- Wenn eine Haskell Programm ausgeführt wird, so wird `main` aufgerufen.
|
||||||
-- Diese muss etwas vom Typ `IO ()` zurueckgeben. Zum Beispiel:
|
-- Diese muss etwas vom Typ `IO ()` zurückgeben. Zum Beispiel:
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = putStrLn $ "Hello, sky! " ++ (say Blue)
|
main = putStrLn $ "Hello, sky! " ++ (say Blue)
|
||||||
@ -338,10 +355,10 @@ sayHello = do
|
|||||||
-- an die Variable "name" gebunden
|
-- an die Variable "name" gebunden
|
||||||
putStrLn $ "Hello, " ++ name
|
putStrLn $ "Hello, " ++ name
|
||||||
|
|
||||||
-- Uebung: Schreibe deine eigene Version von `interact`,
|
-- Übung: Schreibe deine eigene Version von `interact`,
|
||||||
-- die nur eine Zeile einliest.
|
-- die nur eine Zeile einliest.
|
||||||
|
|
||||||
-- `sayHello` wird niemals ausgefuehrt, nur `main` wird ausgefuehrt.
|
-- `sayHello` wird niemals ausgeführt, nur `main` wird ausgeführt.
|
||||||
-- Um `sayHello` laufen zulassen kommentiere die Definition von `main`
|
-- Um `sayHello` laufen zulassen kommentiere die Definition von `main`
|
||||||
-- aus und ersetze sie mit:
|
-- aus und ersetze sie mit:
|
||||||
-- main = sayHello
|
-- main = sayHello
|
||||||
@ -359,7 +376,7 @@ action = do
|
|||||||
input1 <- getLine
|
input1 <- getLine
|
||||||
input2 <- getLine
|
input2 <- getLine
|
||||||
-- Der Typ von `do` ergibt sich aus der letzten Zeile.
|
-- Der Typ von `do` ergibt sich aus der letzten Zeile.
|
||||||
-- `return` ist eine Funktion und keine Schluesselwort
|
-- `return` ist eine Funktion und keine Schlüsselwort
|
||||||
return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
|
return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
|
||||||
|
|
||||||
-- Nun können wir `action` wie `getLine` benutzen:
|
-- Nun können wir `action` wie `getLine` benutzen:
|
||||||
@ -370,7 +387,7 @@ main'' = do
|
|||||||
putStrLn result
|
putStrLn result
|
||||||
putStrLn "This was all, folks!"
|
putStrLn "This was all, folks!"
|
||||||
|
|
||||||
-- Der Typ `IO` ist ein Beispiel fuer eine Monade.
|
-- Der Typ `IO` ist ein Beispiel für eine Monade.
|
||||||
-- Haskell benutzt Monaden Seiteneffekte zu kapseln und somit
|
-- Haskell benutzt Monaden Seiteneffekte zu kapseln und somit
|
||||||
-- eine rein funktional Sprache zu sein.
|
-- eine rein funktional Sprache zu sein.
|
||||||
-- Jede Funktion die mit der Außenwelt interagiert (z.B. IO)
|
-- Jede Funktion die mit der Außenwelt interagiert (z.B. IO)
|
||||||
@ -387,7 +404,7 @@ main'' = do
|
|||||||
|
|
||||||
-- Starte die REPL mit dem Befehl `ghci`
|
-- Starte die REPL mit dem Befehl `ghci`
|
||||||
-- Nun kann man Haskell Code eingeben.
|
-- Nun kann man Haskell Code eingeben.
|
||||||
-- Alle neuen Werte muessen mit `let` gebunden werden:
|
-- Alle neuen Werte müssen mit `let` gebunden werden:
|
||||||
|
|
||||||
let foo = 5
|
let foo = 5
|
||||||
|
|
||||||
@ -396,7 +413,7 @@ let foo = 5
|
|||||||
>:t foo
|
>:t foo
|
||||||
foo :: Integer
|
foo :: Integer
|
||||||
|
|
||||||
-- Auch jede `IO ()` Funktion kann ausgefuehrt werden.
|
-- Auch jede `IO ()` Funktion kann ausgeführt werden.
|
||||||
|
|
||||||
> sayHello
|
> sayHello
|
||||||
What is your name?
|
What is your name?
|
||||||
@ -420,6 +437,6 @@ qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
|
|||||||
Haskell ist sehr einfach zu installieren.
|
Haskell ist sehr einfach zu installieren.
|
||||||
Hohl es dir von [hier](http://www.haskell.org/platform/).
|
Hohl es dir von [hier](http://www.haskell.org/platform/).
|
||||||
|
|
||||||
Eine sehr viele langsamere Einfuehrung findest du unter:
|
Eine sehr viele langsamere Einführung findest du unter:
|
||||||
[Learn you a Haskell](http://learnyouahaskell.com/) oder
|
[Learn you a Haskell](http://learnyouahaskell.com/) oder
|
||||||
[Real World Haskell](http://book.realworldhaskell.org/).
|
[Real World Haskell](http://book.realworldhaskell.org/).
|
||||||
|
@ -479,9 +479,6 @@ myNumber === myNumberObj; // = false
|
|||||||
if (0){
|
if (0){
|
||||||
// Dieser Teil wird nicht ausgeführt, weil 0 'falsy' ist.
|
// Dieser Teil wird nicht ausgeführt, weil 0 'falsy' ist.
|
||||||
}
|
}
|
||||||
if (Number(0)){
|
|
||||||
// Dieser Teil des Codes wird ausgeführt, weil Number(0) zu wahr evaluiert.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Das Wrapper-Objekt und die regulären, eingebauten Typen, teilen sich einen
|
// Das Wrapper-Objekt und die regulären, eingebauten Typen, teilen sich einen
|
||||||
// Prototyp; so ist es möglich zum Beispiel einem String weitere Funktionen
|
// Prototyp; so ist es möglich zum Beispiel einem String weitere Funktionen
|
||||||
|
235
de-de/latex-de.html.markdown
Normal file
235
de-de/latex-de.html.markdown
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
---
|
||||||
|
language: latex
|
||||||
|
contributors:
|
||||||
|
- ["Chaitanya Krishna Ande", "http://icymist.github.io"]
|
||||||
|
- ["Colton Kohnke", "http://github.com/voltnor"]
|
||||||
|
- ["Sricharan Chiruvolu", "http://sricharan.xyz"]
|
||||||
|
translators:
|
||||||
|
- ["Moritz Kammerer", "https://github.com/phxql"]
|
||||||
|
lang: de-de
|
||||||
|
filename: latex-de.tex
|
||||||
|
---
|
||||||
|
```
|
||||||
|
% Alle Kommentare starten fangen mit % an
|
||||||
|
% Es gibt keine Kommentare über mehrere Zeilen
|
||||||
|
|
||||||
|
% LateX ist keine "What You See Is What You Get" Textverarbeitungssoftware wie z.B.
|
||||||
|
% MS Word oder OpenOffice Writer
|
||||||
|
|
||||||
|
% Jedes LateX-Kommando startet mit einem Backslash (\)
|
||||||
|
|
||||||
|
% LateX-Dokumente starten immer mit der Definition des Dokuments, die sie darstellen
|
||||||
|
% Weitere Dokumententypen sind z.B. book, report, presentations, etc.
|
||||||
|
% Optionen des Dokuments stehen zwischen den eckigen Klammern []. In diesem Fall
|
||||||
|
% wollen wir einen 12 Punkte-Font verwenden.
|
||||||
|
\documentclass[12pt]{article}
|
||||||
|
|
||||||
|
% Als nächstes definieren wir die Pakete, die wir verwenden wollen.
|
||||||
|
% Wenn du z.B. Grafiken, farbigen Text oder Quelltext in dein Dokument einbetten möchtest,
|
||||||
|
% musst du die Fähigkeiten von Latex durch Hinzufügen von Paketen erweitern.
|
||||||
|
% Wir verwenden die Pakete float und caption für Bilder.
|
||||||
|
\usepackage{caption}
|
||||||
|
\usepackage{float}
|
||||||
|
|
||||||
|
% Mit diesem Paket können leichter Umlaute getippt werden
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
|
||||||
|
% Es können durchaus noch weitere Optione für das Dokument gesetzt werden!
|
||||||
|
\author{Chaitanya Krishna Ande, Colton Kohnke \& Sricharan Chiruvolu}
|
||||||
|
\date{\today}
|
||||||
|
\title{Learn LaTeX in Y Minutes!}
|
||||||
|
|
||||||
|
% Nun kann's losgehen mit unserem Dokument.
|
||||||
|
% Alles vor dieser Zeile wird die Preamble genannt.
|
||||||
|
\begin{document}
|
||||||
|
% Wenn wir den Autor, das Datum und den Titel gesetzt haben, kann
|
||||||
|
% LateX für uns eine Titelseite generieren
|
||||||
|
\maketitle
|
||||||
|
|
||||||
|
% Die meisten Paper haben ein Abstract. LateX bietet dafür einen vorgefertigen Befehl an.
|
||||||
|
% Das Abstract sollte in der logischen Reihenfolge, also nach dem Titel, aber vor dem
|
||||||
|
% Inhalt erscheinen.
|
||||||
|
% Dieser Befehl ist in den Dokumentenklassen article und report verfügbar.
|
||||||
|
\begin{abstract}
|
||||||
|
LateX documentation geschrieben in LateX! Wie ungewöhnlich und garantiert nicht meine Idee!
|
||||||
|
\end{abstract}
|
||||||
|
|
||||||
|
% Section Befehle sind intuitiv.
|
||||||
|
% Alle Titel der sections werden automatisch in das Inhaltsverzeichnis übernommen.
|
||||||
|
\section{Einleitung}
|
||||||
|
Hi, mein Name ist Moritz und zusammen werden wir LateX erforschen!
|
||||||
|
|
||||||
|
\section{Noch eine section}
|
||||||
|
Das hier ist der Text für noch eine section. Ich glaube, wir brauchen eine subsection.
|
||||||
|
|
||||||
|
\subsection{Das ist eine subsection} % Subsections sind auch ziemlich intuitiv.
|
||||||
|
Ich glaube, wir brauchen noch eine.
|
||||||
|
|
||||||
|
\subsubsection{Pythagoras}
|
||||||
|
So ist's schon viel besser.
|
||||||
|
\label{subsec:pythagoras}
|
||||||
|
|
||||||
|
% Wenn wir den Stern nach section schreiben, dann unterdrückt LateX die Nummerierung.
|
||||||
|
% Das funktioniert auch bei anderen Befehlen.
|
||||||
|
\section*{Das ist eine unnummerierte section}
|
||||||
|
Es müssen nicht alle sections nummeriert sein!
|
||||||
|
|
||||||
|
\section{Ein paar Notizen}
|
||||||
|
LateX ist ziemlich gut darin, Text so zu platzieren, dass es gut aussieht.
|
||||||
|
Falls eine Zeile \\ mal \\ woanders \\ umgebrochen \\ werden \\ soll, füge
|
||||||
|
\textbackslash\textbackslash in den Code ein.\\
|
||||||
|
|
||||||
|
\section{Listen}
|
||||||
|
Listen sind eine der einfachsten Dinge in LateX. Ich muss morgen einkaufen gehen,
|
||||||
|
also lass uns eine Einkaufsliste schreiben:
|
||||||
|
\begin{enumerate} % Dieser Befehl erstellt eine "enumerate" Umgebung.
|
||||||
|
% \item bringt enumerate dazu, eins weiterzuzählen.
|
||||||
|
\item Salat.
|
||||||
|
\item 27 Wassermelonen.
|
||||||
|
\item einen Hasen.
|
||||||
|
% Wir können die Nummer des Eintrags durch [] überschreiben
|
||||||
|
\item[Wie viele?] Mittelgroße Wasserpistolen.
|
||||||
|
|
||||||
|
Kein Listeneintrag, aber immer noch Teil von enumerate.
|
||||||
|
|
||||||
|
\end{enumerate} % Alle Umgebungen müssen ein end haben.
|
||||||
|
|
||||||
|
\section{Mathe}
|
||||||
|
|
||||||
|
Einer der Haupteinsatzzwecke von LateX ist das Schreiben von akademischen
|
||||||
|
Artikeln oder Papern. Meistens stammen diese aus dem Bereich der Mathe oder
|
||||||
|
anderen Wissenschaften. Und deswegen müssen wir in der Lage sein, spezielle
|
||||||
|
Symbole zu unserem Paper hinzuzufügen! \\
|
||||||
|
|
||||||
|
Mathe kennt sehr viele Symbole, viel mehr als auf einer Tastatur zu finden sind;
|
||||||
|
Symbole für Mengen und relationen, Pfeile, Operatoren und Griechische Buchstaben,
|
||||||
|
um nur ein paar zu nennen.\\
|
||||||
|
|
||||||
|
Mengen und Relationen spielen eine sehr wichtige Rolle in vielen mathematischen
|
||||||
|
Papern. So schreibt man in LateX, dass alle y zu X gehören: $\forall$ y $\in$ X. \\
|
||||||
|
|
||||||
|
% Achte auf die $ Zeichen vor und nach den Symbolen. Wenn wir in LateX schreiben,
|
||||||
|
% geschieht dies standardmäßig im Textmodus. Die Mathe-Symbole existieren allerdings
|
||||||
|
% nur im Mathe-Modus. Wir können den Mathe-Modus durch das $ Zeichen aktivieren und
|
||||||
|
% ihn mit $ wieder verlassen. Variablen können auch im Mathe-Modus angezeigt werden.
|
||||||
|
|
||||||
|
Mein Lieblingsbuchstabe im Griechischen ist $\xi$. Ich mag auch $\beta$, $\gamma$ und $\sigma$.
|
||||||
|
Bis jetzt habe ich noch keinen griechischen Buchstaben gefunden, den LateX nicht kennt!
|
||||||
|
|
||||||
|
Operatoren sind ebenfalls wichtige Bestandteile von mathematischen Dokumenten:
|
||||||
|
Trigonometrische Funktionen ($\sin$, $\cos$, $\tan$),
|
||||||
|
Logarithmus und Exponenten ($\log$, $\exp$),
|
||||||
|
Grenzwerte ($\lim$), etc. haben vordefinierte Befehle.
|
||||||
|
Lass uns eine Gleichung schreiben: \\
|
||||||
|
|
||||||
|
$\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$\\
|
||||||
|
|
||||||
|
Brüche (Zähler / Nenner) können so geschrieben werden:
|
||||||
|
|
||||||
|
% 10 / 7
|
||||||
|
$^{10}/_{7}$
|
||||||
|
|
||||||
|
% Komplexere Brüche können so geschrieben werden:
|
||||||
|
% \frac{Zähler}{Nenner}
|
||||||
|
$\frac{n!}{k!(n - k)!}$ \\
|
||||||
|
|
||||||
|
Wir können Gleichungen auch in einer equation Umgebung verwenden.
|
||||||
|
|
||||||
|
% Dies zeigt Mathe in einer equation Umgebung an
|
||||||
|
\begin{equation} % Aktiviert automatisch den Mathe-Modus.
|
||||||
|
c^2 = a^2 + b^2.
|
||||||
|
\label{eq:pythagoras} % Pythagoras referenzieren
|
||||||
|
\end{equation} % Alle \begin Befehle müssen einen \end Befehl besitzen
|
||||||
|
|
||||||
|
Wir können nun unsere Gleichung referenzieren!
|
||||||
|
Gleichung ~\ref{eq:pythagoras} ist auch als das Theorem des Pythagoras bekannt. Dieses wird in
|
||||||
|
Abschnitt ~\ref{subsec:pythagoras} behandelt. Es können sehr viele Sachen mit Labels versehen werden:
|
||||||
|
Grafiken, Gleichungen, Sections, etc.
|
||||||
|
|
||||||
|
Summen und Integrale können mit den sum und int Befehlen dargestellt werden:
|
||||||
|
|
||||||
|
% Manche LateX-Compiler beschweren sich, wenn Leerzeilen in Gleichungen auftauchen
|
||||||
|
\begin{equation}
|
||||||
|
\sum_{i=0}^{5} f_{i}
|
||||||
|
\end{equation}
|
||||||
|
\begin{equation}
|
||||||
|
\int_{0}^{\infty} \mathrm{e}^{-x} \mathrm{d}x
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
\section{Grafiken}
|
||||||
|
|
||||||
|
Lass uns eine Grafik einfügen. Das Platzieren von Grafiken kann etwas trickreich sein.
|
||||||
|
Aber keine Sorge, ich muss auch jedes mal nachschauen, welche Option wie wirkt.
|
||||||
|
|
||||||
|
\begin{figure}[H] % H ist die Platzierungsoption
|
||||||
|
\centering % Zentriert die Grafik auf der Seite
|
||||||
|
% Fügt eine Grafik ein, die auf 80% der Seitenbreite einnimmt.
|
||||||
|
%\includegraphics[width=0.8\linewidth]{right-triangle.png}
|
||||||
|
% Auskommentiert, damit es nicht im Dokument auftaucht.
|
||||||
|
\caption{Dreieck mit den Seiten $a$, $b$, $c$}
|
||||||
|
\label{fig:right-triangle}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsection{Tabellen}
|
||||||
|
Wir können Tabellen genauso wie Grafiken einfügen.
|
||||||
|
|
||||||
|
\begin{table}[H]
|
||||||
|
\caption{Überschrift der Tabelle.}
|
||||||
|
% Die {} Argumente geben an, wie eine Zeile der Tabelle dargestellt werden soll.
|
||||||
|
% Auch hier muss ich jedes Mal nachschauen. Jedes. einzelne. Mal.
|
||||||
|
\begin{tabular}{c|cc}
|
||||||
|
Nummer & Nachname & Vorname \\ % Spalten werden durch & getrennt
|
||||||
|
\hline % Eine horizontale Linie
|
||||||
|
1 & Biggus & Dickus \\
|
||||||
|
2 & Monty & Python
|
||||||
|
\end{tabular}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
% \section{Links} % Kommen bald!
|
||||||
|
|
||||||
|
\section{Verhindern, dass LateX etwas kompiliert (z.B. Quelltext)}
|
||||||
|
Angenommen, wir wollen Quelltext in unserem LateX-Dokument. LateX soll
|
||||||
|
in diesem Fall nicht den Quelltext als LateX-Kommandos interpretieren,
|
||||||
|
sondern es einfach ins Dokument schreiben. Um das hinzubekommen, verwenden
|
||||||
|
wir eine verbatim Umgebung.
|
||||||
|
|
||||||
|
% Es gibt noch weitere Pakete für Quelltexte (z.B. minty, lstlisting, etc.)
|
||||||
|
% aber verbatim ist das simpelste.
|
||||||
|
\begin{verbatim}
|
||||||
|
print("Hello World!")
|
||||||
|
a%b; % Schau dir das an! Wir können % im verbatim verwenden!
|
||||||
|
random = 4; #decided by fair random dice roll
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
\section{Kompilieren}
|
||||||
|
|
||||||
|
Ich vermute, du wunderst dich, wie du dieses tolle Dokument in ein PDF
|
||||||
|
verwandeln kannst. (Ja, dieses Dokument kompiliert wirklich!) \\
|
||||||
|
|
||||||
|
Dafür musst du folgende Schritte durchführen:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Schreibe das Dokument. (den LateX-Quelltext).
|
||||||
|
\item Kompiliere den Quelltext in ein PDF.
|
||||||
|
Das Kompilieren sieht so ähnlich wie das hier aus (Linux): \\
|
||||||
|
\begin{verbatim}
|
||||||
|
$pdflatex learn-latex.tex learn-latex.pdf
|
||||||
|
\end{verbatim}
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
Manche LateX-Editoren kombinieren Schritt 1 und 2. Du siehst also nur Schritt 1 und Schritt
|
||||||
|
2 wird unsichtbar im Hintergrund ausgeführt.
|
||||||
|
|
||||||
|
Alle Formatierungsoptionen werden in Schritt 1 in den Quelltext geschrieben. Schritt 2 verwendet
|
||||||
|
dann diese Informationen und kümmert sich drum, dass das Dokument korrekt erstellt wird.
|
||||||
|
|
||||||
|
\section{Ende}
|
||||||
|
|
||||||
|
Das war's erst mal!
|
||||||
|
|
||||||
|
% Dokument beenden
|
||||||
|
\end{document}
|
||||||
|
```
|
||||||
|
## Mehr Informationen über LateX
|
||||||
|
|
||||||
|
* Das tolle LaTeX wikibook: [https://de.wikibooks.org/wiki/LaTeX-Kompendium](https://de.wikibooks.org/wiki/LaTeX-Kompendium)
|
||||||
|
* Ein Tutorial (englisch): [http://www.latex-tutorial.com/](http://www.latex-tutorial.com/)
|
613
de-de/ruby-de.html.markdown
Normal file
613
de-de/ruby-de.html.markdown
Normal file
@ -0,0 +1,613 @@
|
|||||||
|
---
|
||||||
|
language: ruby
|
||||||
|
contributors:
|
||||||
|
- ["David Underwood", "http://theflyingdeveloper.com"]
|
||||||
|
- ["Joel Walden", "http://joelwalden.net"]
|
||||||
|
- ["Luke Holder", "http://twitter.com/lukeholder"]
|
||||||
|
- ["Tristan Hume", "http://thume.ca/"]
|
||||||
|
- ["Nick LaMuro", "https://github.com/NickLaMuro"]
|
||||||
|
- ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
|
||||||
|
- ["Ariel Krakowski", "http://www.learneroo.com"]
|
||||||
|
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
|
||||||
|
- ["Levi Bostian", "https://github.com/levibostian"]
|
||||||
|
- ["Rahil Momin", "https://github.com/iamrahil"]
|
||||||
|
translators:
|
||||||
|
- ["Christian Albrecht", "https://github.com/coastalchief"]
|
||||||
|
filename: ruby-de.rb
|
||||||
|
lang: de-de
|
||||||
|
---
|
||||||
|
|
||||||
|
# Dies ist ein Kommentar
|
||||||
|
|
||||||
|
=begin
|
||||||
|
Dies sind multi-line
|
||||||
|
Kommentare. Niemand benutzt
|
||||||
|
die wirklich.
|
||||||
|
=end
|
||||||
|
|
||||||
|
# Objekte - Alles ist ein Objekt
|
||||||
|
|
||||||
|
## Zahlen sind Objekte
|
||||||
|
```
|
||||||
|
3.class #=> Fixnum
|
||||||
|
3.to_s #=> "3"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Simple Arithmetik
|
||||||
|
```
|
||||||
|
1 + 1 #=> 2
|
||||||
|
8 - 1 #=> 7
|
||||||
|
10 * 2 #=> 20
|
||||||
|
35 / 5 #=> 7
|
||||||
|
2**5 #=> 32
|
||||||
|
```
|
||||||
|
|
||||||
|
// Arithmetik ist aber eigentlich nur syntaktischer Zucker
|
||||||
|
// um eine Methode eines Objekt aufzurufen
|
||||||
|
```
|
||||||
|
1.+(3) #=> 4
|
||||||
|
10.* 5 #=> 50
|
||||||
|
```
|
||||||
|
|
||||||
|
## Special values sind Objekte
|
||||||
|
```
|
||||||
|
nil # Nothing to see here
|
||||||
|
true # truth
|
||||||
|
false # falsehood
|
||||||
|
|
||||||
|
nil.class #=> NilClass
|
||||||
|
true.class #=> TrueClass
|
||||||
|
false.class #=> FalseClass
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objektvergleiche
|
||||||
|
### Gleicheit
|
||||||
|
```
|
||||||
|
1 == 1 #=> true
|
||||||
|
2 == 1 #=> false
|
||||||
|
```
|
||||||
|
### Ungleichheit
|
||||||
|
```
|
||||||
|
1 != 1 #=> false
|
||||||
|
2 != 1 #=> true
|
||||||
|
```
|
||||||
|
### Neben false selbst, nil ist ein anderer 'falsey' Wert
|
||||||
|
```
|
||||||
|
!nil #=> true
|
||||||
|
!false #=> true
|
||||||
|
!0 #=> false
|
||||||
|
```
|
||||||
|
### Weitere Vergleiche
|
||||||
|
```
|
||||||
|
1 < 10 #=> true
|
||||||
|
1 > 10 #=> false
|
||||||
|
2 <= 2 #=> true
|
||||||
|
2 >= 2 #=> true
|
||||||
|
```
|
||||||
|
### Logische Operatoren
|
||||||
|
```
|
||||||
|
true && false #=> false
|
||||||
|
true || false #=> true
|
||||||
|
!true #=> false
|
||||||
|
```
|
||||||
|
|
||||||
|
Es gibt alternative Versionen der logischen Operatoren mit niedrigerer
|
||||||
|
Wertigkeit. Diese werden meistens bei Flow-Control eingesetzt, um
|
||||||
|
verschiedenen Ausdrücke zu verketten bis einer true oder false zurück
|
||||||
|
liefert.
|
||||||
|
|
||||||
|
#### and
|
||||||
|
##### `do_something_else` wird nur ausgewertet wenn `do_something` true ist.
|
||||||
|
do_something() and do_something_else()
|
||||||
|
|
||||||
|
#### or
|
||||||
|
#####`log_error` wird nur ausgewertet wenn `do_something` false ist.
|
||||||
|
do_something() or log_error()
|
||||||
|
|
||||||
|
## Strings sind Objekte
|
||||||
|
```
|
||||||
|
'I am a string'.class #=> String
|
||||||
|
"I am a string too".class #=> String
|
||||||
|
|
||||||
|
|
||||||
|
platzhalter = 'Ruby'
|
||||||
|
"Ich kann in #{placeholder} Platzhalter mit doppelten Anführungsstrichen füllen."
|
||||||
|
```
|
||||||
|
Einfache Anführungszeichen sollten bevorzugt werden.
|
||||||
|
Doppelte Anführungszeichen führen interne Berechnungen durch.
|
||||||
|
|
||||||
|
### Strings können verbunden werden, aber nicht mit Zahlen
|
||||||
|
```
|
||||||
|
'hello ' + 'world' #=> "hello world"
|
||||||
|
'hello ' + 3 #=> TypeError: can't convert Fixnum into String
|
||||||
|
```
|
||||||
|
#### Zahl muss in String konvertiert werden
|
||||||
|
```
|
||||||
|
'hello ' + 3.to_s #=> "hello 3"
|
||||||
|
```
|
||||||
|
### Text ausgeben
|
||||||
|
```
|
||||||
|
puts "I'm printing!"
|
||||||
|
```
|
||||||
|
# Variablen
|
||||||
|
## Zuweisungen
|
||||||
|
### Diese Zuweisung gibt den zugeordneten Wert zurück
|
||||||
|
```
|
||||||
|
x = 25 #=> 25
|
||||||
|
x #=> 25
|
||||||
|
```
|
||||||
|
### Damit funktionieren auch mehrfache Zuweisungen
|
||||||
|
```
|
||||||
|
x = y = 10 #=> 10
|
||||||
|
x #=> 10
|
||||||
|
y #=> 10
|
||||||
|
```
|
||||||
|
## Benennung
|
||||||
|
### Konvention ist snake_case
|
||||||
|
```
|
||||||
|
snake_case = true
|
||||||
|
```
|
||||||
|
### Benutze verständliche Variablennamen
|
||||||
|
```
|
||||||
|
path_to_project_root = '/good/name/'
|
||||||
|
path = '/bad/name/'
|
||||||
|
```
|
||||||
|
# Symbols (sind auch Objekte)
|
||||||
|
Symbols sind unveränderliche, wiederverwendbare Konstanten, welche intern
|
||||||
|
als integer repräsentiert werden. Sie werden häufig anstelle von Strings
|
||||||
|
verwendet, um sinnvoll Werte zu übermitteln.
|
||||||
|
Symbols werden mit dem Doppelpunkt gekennzeichnet.
|
||||||
|
|
||||||
|
```
|
||||||
|
:pending.class #=> Symbol
|
||||||
|
status = :pending
|
||||||
|
status == :pending #=> true
|
||||||
|
status == 'pending' #=> false
|
||||||
|
status == :approved #=> false
|
||||||
|
```
|
||||||
|
# Arrays
|
||||||
|
|
||||||
|
## Ein Array anlegen
|
||||||
|
```
|
||||||
|
array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Array können verschiedene Typen beinhalten
|
||||||
|
```
|
||||||
|
[1, 'hello', false] #=> [1, "hello", false]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Wie bei arithmetischen Ausdrücken auch wird beim Zugriff auf
|
||||||
|
## [0] eigentlich die Methode [] des Array Objekts aufgerufen.
|
||||||
|
```
|
||||||
|
array.[] 0 #=> 1
|
||||||
|
array.[] 12 #=> nil
|
||||||
|
```
|
||||||
|
|
||||||
|
## Arrays können von vorne indiziert werden
|
||||||
|
```
|
||||||
|
array[0] #=> 1
|
||||||
|
array[12] #=> nil
|
||||||
|
```
|
||||||
|
|
||||||
|
## Arrays können von hinten indiziert werden
|
||||||
|
```
|
||||||
|
array[-1] #=> 5
|
||||||
|
```
|
||||||
|
|
||||||
|
## Arrays können mit Stard Index und Länge indiziert werden
|
||||||
|
```
|
||||||
|
array[2, 3] #=> [3, 4, 5]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Arrays können mit einer Range indiziert werden
|
||||||
|
```
|
||||||
|
array[1..3] #=> [2, 3, 4]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Einen Wert hinzufügen
|
||||||
|
```
|
||||||
|
array << 6 #=> [1, 2, 3, 4, 5, 6]
|
||||||
|
array.push(6) #=> [1, 2, 3, 4, 5, 6]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testen, ob ein Element schon vorhanden ist
|
||||||
|
```
|
||||||
|
array.include?(1) #=> true
|
||||||
|
```
|
||||||
|
|
||||||
|
# Hashes
|
||||||
|
Hashes sind das Hauptfeature um Key/Values zu speichern
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ein Hash anlegen
|
||||||
|
```
|
||||||
|
hash = { 'color' => 'green', 'number' => 5 }
|
||||||
|
hash.keys #=> ['color', 'number']
|
||||||
|
```
|
||||||
|
|
||||||
|
## Wert per key herausfinden
|
||||||
|
```
|
||||||
|
hash['color'] #=> 'green'
|
||||||
|
hash['number'] #=> 5
|
||||||
|
hash['nothing here'] #=> nil
|
||||||
|
// Asking a hash for a key that doesn't exist returns nil:
|
||||||
|
```
|
||||||
|
|
||||||
|
## Symbols können auch keys sein
|
||||||
|
```
|
||||||
|
new_hash = { defcon: 3, action: true }
|
||||||
|
new_hash.keys #=> [:defcon, :action]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testen ob ein Key oder ein Value existiert
|
||||||
|
```
|
||||||
|
new_hash.has_key?(:defcon) #=> true
|
||||||
|
new_hash.has_value?(3) #=> true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tip: Arrays und Hashes sind Enumerable
|
||||||
|
### Und haben gemeinsame, hilfreiche Methoden wie:
|
||||||
|
### each, map, count, and more
|
||||||
|
|
||||||
|
# Kontrolstrukturen
|
||||||
|
## if
|
||||||
|
```
|
||||||
|
if true
|
||||||
|
'if statement'
|
||||||
|
elsif false
|
||||||
|
'else if, optional'
|
||||||
|
else
|
||||||
|
'else, also optional'
|
||||||
|
end
|
||||||
|
```
|
||||||
|
## for - Allerdings werden for Schleifen nicht oft vewendet.
|
||||||
|
```
|
||||||
|
for counter in 1..5
|
||||||
|
puts "iteration #{counter}"
|
||||||
|
end
|
||||||
|
```
|
||||||
|
## Stattdessen: "each" Methode und einen Bloch übergeben
|
||||||
|
Ein Block ist ein Codeteil, den man einer Methode übergeben kann
|
||||||
|
Ähnelt stark lambdas, anonymen Funktionen oder Closures in anderen
|
||||||
|
Programmiersprachen.
|
||||||
|
|
||||||
|
```
|
||||||
|
(1..5).each do |counter|
|
||||||
|
puts "iteration #{counter}"
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Die each Methode einer Range führt den Block für jedes Element der Range aus.
|
||||||
|
|
||||||
|
Dem Block wird ein "counter" parameter übergeben.
|
||||||
|
|
||||||
|
### Den Block kann man auch in geschweiften Klammern schreiben
|
||||||
|
```
|
||||||
|
(1..5).each { |counter| puts "iteration #{counter}" }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Each kann auch über den Inhalt von Datenstrukturen iterieren
|
||||||
|
```
|
||||||
|
array.each do |element|
|
||||||
|
puts "#{element} is part of the array"
|
||||||
|
end
|
||||||
|
hash.each do |key, value|
|
||||||
|
puts "#{key} is #{value}"
|
||||||
|
end
|
||||||
|
|
||||||
|
counter = 1
|
||||||
|
while counter <= 5 do
|
||||||
|
puts "iteration #{counter}"
|
||||||
|
counter += 1
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## case
|
||||||
|
```
|
||||||
|
grade = 'B'
|
||||||
|
|
||||||
|
case grade
|
||||||
|
when 'A'
|
||||||
|
puts 'Way to go kiddo'
|
||||||
|
when 'B'
|
||||||
|
puts 'Better luck next time'
|
||||||
|
when 'C'
|
||||||
|
puts 'You can do better'
|
||||||
|
when 'D'
|
||||||
|
puts 'Scraping through'
|
||||||
|
when 'F'
|
||||||
|
puts 'You failed!'
|
||||||
|
else
|
||||||
|
puts 'Alternative grading system, eh?'
|
||||||
|
end
|
||||||
|
=> "Better luck next time"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Case können auch ranges
|
||||||
|
```
|
||||||
|
grade = 82
|
||||||
|
case grade
|
||||||
|
when 90..100
|
||||||
|
puts 'Hooray!'
|
||||||
|
when 80...90
|
||||||
|
puts 'OK job'
|
||||||
|
else
|
||||||
|
puts 'You failed!'
|
||||||
|
end
|
||||||
|
=> "OK job"
|
||||||
|
```
|
||||||
|
|
||||||
|
# exception handling:
|
||||||
|
```
|
||||||
|
begin
|
||||||
|
# code here that might raise an exception
|
||||||
|
raise NoMemoryError, 'You ran out of memory.'
|
||||||
|
rescue NoMemoryError => exception_variable
|
||||||
|
puts 'NoMemoryError was raised', exception_variable
|
||||||
|
rescue RuntimeError => other_exception_variable
|
||||||
|
puts 'RuntimeError was raised now'
|
||||||
|
else
|
||||||
|
puts 'This runs if no exceptions were thrown at all'
|
||||||
|
ensure
|
||||||
|
puts 'This code always runs no matter what'
|
||||||
|
end
|
||||||
|
```
|
||||||
|
# Funktionen
|
||||||
|
```
|
||||||
|
def double(x)
|
||||||
|
x * 2
|
||||||
|
end
|
||||||
|
```
|
||||||
|
## Funktionen (und Blocks)
|
||||||
|
## geben implizit den Wert des letzten Statements zurück
|
||||||
|
```
|
||||||
|
double(2) #=> 4
|
||||||
|
```
|
||||||
|
|
||||||
|
### Klammern sind optional wenn das Ergebnis nicht mehdeutig ist
|
||||||
|
```
|
||||||
|
double 3 #=> 6
|
||||||
|
double double 3 #=> 12
|
||||||
|
def sum(x, y)
|
||||||
|
x + y
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Methoden Parameter werden per Komma getrennt
|
||||||
|
```
|
||||||
|
sum 3, 4 #=> 7
|
||||||
|
sum sum(3, 4), 5 #=> 12
|
||||||
|
```
|
||||||
|
|
||||||
|
## yield
|
||||||
|
### Alle Methoden haben einen impliziten, optionalen block Parameter
|
||||||
|
### Dieser wird mit dem Schlüsselword "yield" aufgerufen
|
||||||
|
```
|
||||||
|
def surround
|
||||||
|
puts '{'
|
||||||
|
yield
|
||||||
|
puts '}'
|
||||||
|
end
|
||||||
|
surround { puts 'hello world' }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Einen Block kann man auch einer Methoden übergeben
|
||||||
|
### "&" kennzeichnet die Referenz zum übergebenen Block
|
||||||
|
```
|
||||||
|
def guests(&block)
|
||||||
|
block.call 'some_argument'
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Eine Liste von Parametern kann man auch übergeben,
|
||||||
|
### Diese wird in ein Array konvertiert
|
||||||
|
### "*" kennzeichnet dies.
|
||||||
|
```
|
||||||
|
def guests(*array)
|
||||||
|
array.each { |guest| puts guest }
|
||||||
|
end
|
||||||
|
```
|
||||||
|
# Klassen
|
||||||
|
## Werden mit dem class Schlüsselwort definiert
|
||||||
|
```
|
||||||
|
class Human
|
||||||
|
```
|
||||||
|
|
||||||
|
### Konstruktor bzw. Initializer
|
||||||
|
```
|
||||||
|
def initialize(name, age = 0)
|
||||||
|
# Assign the argument to the "name" instance variable for the instance
|
||||||
|
@name = name
|
||||||
|
# If no age given, we will fall back to the default in the arguments list.
|
||||||
|
@age = age
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### setter Methode
|
||||||
|
```
|
||||||
|
def name=(name)
|
||||||
|
@name = name
|
||||||
|
end
|
||||||
|
```
|
||||||
|
### getter Methode
|
||||||
|
```
|
||||||
|
def name
|
||||||
|
@name
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
#### getter können mit der attr_accessor Methode vereinfacht definiert werden
|
||||||
|
```
|
||||||
|
attr_accessor :name
|
||||||
|
# Getter/setter methods can also be created individually like this
|
||||||
|
attr_reader :name
|
||||||
|
attr_writer :name
|
||||||
|
# A class method uses self to distinguish from instance methods.
|
||||||
|
# It can only be called on the class, not an instance.
|
||||||
|
def self.say(msg)
|
||||||
|
puts msg
|
||||||
|
end
|
||||||
|
def species
|
||||||
|
@@species
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Eine Klasse instanziieren
|
||||||
|
```
|
||||||
|
jim = Human.new('Jim Halpert')
|
||||||
|
dwight = Human.new('Dwight K. Schrute')
|
||||||
|
```
|
||||||
|
|
||||||
|
## Methodenaufrufe
|
||||||
|
```
|
||||||
|
jim.species #=> "H. sapiens"
|
||||||
|
jim.name #=> "Jim Halpert"
|
||||||
|
jim.name = "Jim Halpert II" #=> "Jim Halpert II"
|
||||||
|
jim.name #=> "Jim Halpert II"
|
||||||
|
dwight.species #=> "H. sapiens"
|
||||||
|
dwight.name #=> "Dwight K. Schrute"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Eine Klassenmethode aufrufen
|
||||||
|
```
|
||||||
|
Human.say('Hi') #=> "Hi"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Variable Gültigkeit
|
||||||
|
### Variablen die mit "$" starten, gelten global
|
||||||
|
```
|
||||||
|
$var = "I'm a global var"
|
||||||
|
defined? $var #=> "global-variable"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Variablen die mit "@" starten, gelten für die Instanz
|
||||||
|
```
|
||||||
|
@var = "I'm an instance var"
|
||||||
|
defined? @var #=> "instance-variable"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Variablen die mit "@@" starten, gelten für die Klasse
|
||||||
|
```
|
||||||
|
@@var = "I'm a class var"
|
||||||
|
defined? @@var #=> "class variable"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Variablen die mit einem Großbuchstaben anfangen, sind Konstanten
|
||||||
|
```
|
||||||
|
Var = "I'm a constant"
|
||||||
|
defined? Var #=> "constant"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Class ist auch ein Objekt
|
||||||
|
### Hat also auch Instanzvariablen
|
||||||
|
### Eine Klassenvariable wird innerhalb der Klasse und Ableitungen geteilt.
|
||||||
|
|
||||||
|
### Basis Klasse
|
||||||
|
```
|
||||||
|
class Human
|
||||||
|
@@foo = 0
|
||||||
|
def self.foo
|
||||||
|
@@foo
|
||||||
|
end
|
||||||
|
def self.foo=(value)
|
||||||
|
@@foo = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Abgeleitete Klasse
|
||||||
|
```
|
||||||
|
class Worker < Human
|
||||||
|
end
|
||||||
|
Human.foo # 0
|
||||||
|
Worker.foo # 0
|
||||||
|
Human.foo = 2 # 2
|
||||||
|
Worker.foo # 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Eine Klasseninstanzvariable wird nicht geteilt
|
||||||
|
```
|
||||||
|
class Human
|
||||||
|
@bar = 0
|
||||||
|
def self.bar
|
||||||
|
@bar
|
||||||
|
end
|
||||||
|
def self.bar=(value)
|
||||||
|
@bar = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
```
|
||||||
|
class Doctor < Human
|
||||||
|
end
|
||||||
|
```
|
||||||
|
```
|
||||||
|
Human.bar # 0
|
||||||
|
Doctor.bar # nil
|
||||||
|
```
|
||||||
|
```
|
||||||
|
module ModuleExample
|
||||||
|
def foo
|
||||||
|
'foo'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
### Module einbinden, heisst ihre Methoden an die Instanzen der Klasse zu binden
|
||||||
|
### Module erweitern, heisst ihre Mothden an die Klasse selbst zu binden
|
||||||
|
```
|
||||||
|
class Person
|
||||||
|
include ModuleExample
|
||||||
|
end
|
||||||
|
```
|
||||||
|
```
|
||||||
|
class Book
|
||||||
|
extend ModuleExample
|
||||||
|
end
|
||||||
|
```
|
||||||
|
```
|
||||||
|
Person.foo # => NoMethodError: undefined method `foo' for Person:Class
|
||||||
|
Person.new.foo # => 'foo'
|
||||||
|
Book.foo # => 'foo'
|
||||||
|
Book.new.foo # => NoMethodError: undefined method `foo'
|
||||||
|
```
|
||||||
|
### Callbacks werden ausgeführt, wenn ein Modul eingebunden oder erweitert wird
|
||||||
|
```
|
||||||
|
module ConcernExample
|
||||||
|
def self.included(base)
|
||||||
|
base.extend(ClassMethods)
|
||||||
|
base.send(:include, InstanceMethods)
|
||||||
|
end
|
||||||
|
module ClassMethods
|
||||||
|
def bar
|
||||||
|
'bar'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
module InstanceMethods
|
||||||
|
def qux
|
||||||
|
'qux'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
class Something
|
||||||
|
include ConcernExample
|
||||||
|
end
|
||||||
|
```
|
||||||
|
```
|
||||||
|
Something.bar # => 'bar'
|
||||||
|
Something.qux # => NoMethodError: undefined method `qux'
|
||||||
|
Something.new.bar # => NoMethodError: undefined method `bar'
|
||||||
|
Something.new.qux # => 'qux'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Weiterführende Hinweise
|
||||||
|
|
||||||
|
//EN
|
||||||
|
|
||||||
|
- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338) - A variant of this reference with in-browser challenges.
|
||||||
|
- [Official Documentation](http://www.ruby-doc.org/core-2.1.1/)
|
||||||
|
- [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/)
|
||||||
|
- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - An older [free edition](http://ruby-doc.com/docs/ProgrammingRuby/) is available online.
|
||||||
|
- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - A community-driven Ruby coding style guide.
|
149
de-de/ruby-ecosystem-de.html.markdown
Normal file
149
de-de/ruby-ecosystem-de.html.markdown
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
---
|
||||||
|
category: tool
|
||||||
|
tool: ruby ecosystem
|
||||||
|
contributors:
|
||||||
|
- ["Jon Smock", "http://github.com/jonsmock"]
|
||||||
|
- ["Rafal Chmiel", "http://github.com/rafalchmiel"]
|
||||||
|
translators:
|
||||||
|
- ["Christian Albrecht", "https://github.com/coastalchief"]
|
||||||
|
filename: ruby-ecosystem-de.txt
|
||||||
|
lang: de-de
|
||||||
|
---
|
||||||
|
|
||||||
|
Hier gibt es einen Überblick über die gängigsten Tools zur Verwaltung
|
||||||
|
von verschiedenen Ruby Versionen, Gems und Dependencies.
|
||||||
|
|
||||||
|
## Ruby Managers
|
||||||
|
|
||||||
|
Einige Betriebssysteme haben bereits eine Ruby Version vorinstalliert
|
||||||
|
oder bieten sie als Package zum Download an. Die meisten Rubyisten
|
||||||
|
benutzen diese aber eher nicht und wenn, dann um damit einen Ruby
|
||||||
|
Manager zu installieren. Damit kann man komfortabel zwischen den
|
||||||
|
verschiedenen Versionen hin und herspringen.
|
||||||
|
|
||||||
|
Dies sind die beliebtesten:
|
||||||
|
|
||||||
|
* [RVM](https://rvm.io/) - Installiert und wechselt zwischen rubies
|
||||||
|
RVM kennt verschiedene Ruby Versionen und hat das Konzept der gemsets,
|
||||||
|
um gem Abhängigkeiten pro Projekt zu managen.
|
||||||
|
* [ruby-build](https://github.com/sstephenson/ruby-build)
|
||||||
|
Installiert nur rubies, kann diese aber sehr gut verwalten
|
||||||
|
* [rbenv](https://github.com/sstephenson/rbenv) - Wechselt Ruby Versionen.
|
||||||
|
Wird zusammen mit ruby-build benutzt. Hiermit kann man kontrollieren,
|
||||||
|
wie rubies laden.
|
||||||
|
* [chruby](https://github.com/postmodern/chruby) - Wechselt Ruby Versionen.
|
||||||
|
Ähnlich rbenv.
|
||||||
|
|
||||||
|
## Ruby Versionen
|
||||||
|
|
||||||
|
Ruby wurde von Yukihiro "Matz" Matsumoto vor gut 20 Jahren veröffentlicht.
|
||||||
|
Matz ist nach wie vor in die Entwicklung involviert. Daher kommt auch der
|
||||||
|
Name der Referenzimplementierung: MRI (Matz' Reference Implementation).
|
||||||
|
|
||||||
|
Die aktuellste Version ist **2.2.3** und wurde im August 2015 veröffentlicht!
|
||||||
|
|
||||||
|
Hier eine kurze Versionshistorie:
|
||||||
|
|
||||||
|
* 2.0.0 - Release im Februar 2013 -- Release zum 20. Geburtstag der Sprache
|
||||||
|
[Rubies are forever](http://www.heise.de/developer/artikel/Ruby-2-0-als-Geschenk-zum-20-Geburtstag-1808109.html)
|
||||||
|
* 1.9.3 - Release im Oktober 2011
|
||||||
|
[End of Life](https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/)
|
||||||
|
* 1.8.7 - Release im Juni 2006
|
||||||
|
[End of Life](http://www.ruby-lang.org/en/news/2013/06/30/we-retire-1-8-7/).
|
||||||
|
|
||||||
|
Die Veränderung zwischen 1.8.7 und 1.9.x war sehr groß und eine Migration
|
||||||
|
nicht so einfach möglich. Der Versionssprung auf 2.0.0 war verglichen dazu
|
||||||
|
weit weniger dramatisch.
|
||||||
|
Beispielsweise hat 1.9. Encodings und eine Bytecode VM eingeführt.
|
||||||
|
Es gibt immer noch Projekte die auf der stabilen Version 1.8.7 laufen,
|
||||||
|
aber diese sind mittlerweile in der Minderheit. Die meisten Projekte
|
||||||
|
laufen auf 1.9.x oder auf 2.x.
|
||||||
|
|
||||||
|
## Ruby Implementierungen
|
||||||
|
|
||||||
|
Das Ruby Ecosystem beinhaltet viele verschiedene Implementierungen von Ruby,
|
||||||
|
jedes mit seinen eigenen Vorteilen und verschiedenen Graden von
|
||||||
|
Kompatibilität. Auch wenn alle diese Implementierungen in verschiedenen
|
||||||
|
Sprachen geschrieben sind, sind sie doch **alle Ruby**.
|
||||||
|
Jede Implementierung bietet neben ihren speziellen Features immer auch
|
||||||
|
die Möglichkeit normale ruby Dateien auszuführen.
|
||||||
|
|
||||||
|
Am ausgereiftesten und stabilsten:
|
||||||
|
|
||||||
|
* [MRI](https://github.com/ruby/ruby) - Geschrieben in C, das ist die Referenz Implementierung.
|
||||||
|
Sie ist 100% kompatibel (mit sich selbst ;-). Alle anderen rubies
|
||||||
|
bleiben kompatibel mit MRI (siehe [RubySpec](#rubyspec) weiter unten).
|
||||||
|
* [JRuby](http://jruby.org/) - Geschrieben in Java and Ruby, Robust und ziemlich schnell.
|
||||||
|
Der größte Vorteil von JRuby ist die Interoperabilität mit JVM/Java und damit die
|
||||||
|
Benutzung von Ruby im Java Ecosystem.
|
||||||
|
* [Rubinius](http://rubini.us/) - Geschrieben in Ruby mit C++ bytecode VM.
|
||||||
|
Auch sehr ausgereift und schnell.
|
||||||
|
|
||||||
|
Mittel ausgereift / kompatibel:
|
||||||
|
|
||||||
|
* [Maglev](http://maglev.github.io/) - Baut auf Gemstone, ein Smalltalk VM.
|
||||||
|
Dieses Projekt versucht das großartige Smalltalk Tooling in die Ruby Welt
|
||||||
|
zu bringen.
|
||||||
|
* [RubyMotion](http://www.rubymotion.com/) - Ruby in der iOS Entwicklung.
|
||||||
|
|
||||||
|
Weniger ausgereift/kompatibel:
|
||||||
|
|
||||||
|
* [Topaz](http://topazruby.com/) - Geschrieben in RPython (via PyPy)
|
||||||
|
Topaz ist noch ziemlich jung und versucht die schnellste Implementierung
|
||||||
|
zu werden.
|
||||||
|
* [IronRuby](http://ironruby.net/) - Geschrieben in C# für die .NET Plaftform
|
||||||
|
Das letzte Release von IronRuby ist mittlerweile 5 Jahre her.
|
||||||
|
|
||||||
|
Die Ruby Implementierungen haben ihre eigenen Versionsnummern, sind aber
|
||||||
|
trotzdem immer zu einer MRI Version kompatibel.
|
||||||
|
Viele können sogar zwischen verschiedenen Modi wechseln (1.8 mode -> 1.9 mode)
|
||||||
|
|
||||||
|
## RubySpec
|
||||||
|
|
||||||
|
Die meisten Ruby Implementierungen vertrauen der [RubySpec](http://rubyspec.org/).
|
||||||
|
sehr stark. Da Ruby keine offizielle Spezifikation hat, hat die
|
||||||
|
Community ausführbare Specs (in Ruby) geschrieben, um so die Kompatibilität
|
||||||
|
zur MRI testen zu können.
|
||||||
|
|
||||||
|
## RubyGems
|
||||||
|
|
||||||
|
[RubyGems](http://rubygems.org/) ist der Community Paket Manager von Ruby.
|
||||||
|
RubyGems kommt mit Ruby zusammen, so dass kein extra Tool nötig ist.
|
||||||
|
|
||||||
|
Ruby Pakete werden "gems" genannt und könnten auf RubyGems.org
|
||||||
|
veröffentlicht werden. Jedes Gem enthält den Source Code und Meta Daten,
|
||||||
|
wie die Versionsnummer, weitere Abhängigkeiten, Autoren und Lizenzen.
|
||||||
|
|
||||||
|
## Bundler
|
||||||
|
|
||||||
|
[Bundler](http://bundler.io/) ist ein Tool um Abhängigkeiten zwischen
|
||||||
|
Gems aufzulösen und zu managen. Dazu werden diese in einem gemfile
|
||||||
|
zusammengefasst und Bundler kümmert sich darum die Abhängigkeiten
|
||||||
|
untereinander rekursiv aufzulösen. Entweder es klappt und alle gems
|
||||||
|
konnten runtergeladen werden, oder es wird abgebrochen und
|
||||||
|
der Konflikt gemeldet.
|
||||||
|
Zum Beispiel:
|
||||||
|
Wenn Gem A die Version 3 oder höher von Gem Z braucht, aber Gem B
|
||||||
|
von Gem Z die Version 2, dann ist das ein Konflikt.
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
|
||||||
|
Test-Driven Development ist ein essentieller Teil der Ruby Kultur.
|
||||||
|
Ruby bringt sein eigenes Unit-Test framework mit, minitest. Darüberhinaus
|
||||||
|
gibt es noch viele weitere Testframeworks mit unterschiedlichsten Zielen:
|
||||||
|
|
||||||
|
* [TestUnit](http://ruby-doc.org/stdlib-1.8.7/libdoc/test/unit/rdoc/Test/Unit.html) - Eingebaut in Ruby 1.8
|
||||||
|
"Unit-style" Testframework
|
||||||
|
* [minitest](http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest.html) - Eingebaut in Ruby 1.9/2.0
|
||||||
|
"Unit-style" Testframework
|
||||||
|
* [RSpec](http://rspec.info/) - Ein Testframework welches auf verständliche Testdefinition setzt
|
||||||
|
* [Cucumber](http://cukes.info/) - Ein BDD Testframework welches Gherkin tests parsen kann
|
||||||
|
|
||||||
|
## Be Nice
|
||||||
|
Die Ruby Community ist stolz darauf eine offene, vielfältige und einladende
|
||||||
|
Community zu sein. Es gibt viele aktive Ruby User Gruppen und diverse
|
||||||
|
Ruby Konferenzen. Matz selbst ist so oft es geht dabei.
|
||||||
|
|
||||||
|
* [Euruko](http://www.euruko2015.org)
|
||||||
|
* [User Groups](https://www.ruby-lang.org/de/community/user-groups/)
|
||||||
|
|
840
de-de/scala-de.html.markdown
Normal file
840
de-de/scala-de.html.markdown
Normal file
@ -0,0 +1,840 @@
|
|||||||
|
---
|
||||||
|
language: Scala
|
||||||
|
contributors:
|
||||||
|
- ["George Petrov", "http://github.com/petrovg"]
|
||||||
|
- ["Dominic Bou-Samra", "http://dbousamra.github.com"]
|
||||||
|
- ["Geoff Liu", "http://geoffliu.me"]
|
||||||
|
- ["Ha-Duong Nguyen", "http://reference-error.org"]
|
||||||
|
- ["Dennis Keller", "github.com/denniskeller"]
|
||||||
|
translators:
|
||||||
|
- ["Christian Albrecht", "https://github.com/coastalchief"]
|
||||||
|
filename: learnscala-de.scala
|
||||||
|
lang: de-de
|
||||||
|
---
|
||||||
|
|
||||||
|
Scala ist eine funktionale und objektorientierte Programmiersprache
|
||||||
|
für die Java Virtual Machine (JVM), um allgemeine Programmieraufgaben
|
||||||
|
zu erledigen. Scala hat einen akademischen Hintergrund und wurde an
|
||||||
|
der EPFL (Lausanne / Schweiz) unter der Leitung von Martin Odersky entwickelt.
|
||||||
|
|
||||||
|
```scala
|
||||||
|
/*
|
||||||
|
Scala Umgebung einrichten:
|
||||||
|
|
||||||
|
1. Scala binaries herunterladen- http://www.scala-lang.org/downloads
|
||||||
|
2. Unzip/untar in ein Verzeichnis
|
||||||
|
3. das bin Unterverzeichnis der `PATH` Umgebungsvariable hinzufügen
|
||||||
|
4. Mit dem Kommando `scala` wird die REPL gestartet und zeigt als Prompt:
|
||||||
|
|
||||||
|
scala>
|
||||||
|
|
||||||
|
Die REPL (Read-Eval-Print Loop) ist der interaktive Scala Interpreter.
|
||||||
|
Hier kann man jeden Scala Ausdruck verwenden und das Ergebnis wird direkt
|
||||||
|
ausgegeben.
|
||||||
|
Als nächstes beschäftigen wir uns mit ein paar Scala Basics.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 1. Basics
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Einzeilige Kommentare beginnen mit zwei Slashes
|
||||||
|
|
||||||
|
/*
|
||||||
|
Mehrzeilige Kommentare, starten
|
||||||
|
mit einem Slash-Stern und enden mit einem Stern-Slash
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Einen Wert, und eine zusätzliche neue Zeile ausgeben
|
||||||
|
|
||||||
|
println("Hello world!")
|
||||||
|
println(10)
|
||||||
|
|
||||||
|
|
||||||
|
// Einen Wert, ohne eine zusätzliche neue Zeile ausgeben
|
||||||
|
|
||||||
|
print("Hello world")
|
||||||
|
|
||||||
|
/*
|
||||||
|
Variablen werden entweder mit var oder val deklariert.
|
||||||
|
Deklarationen mit val sind immutable, also unveränderlich
|
||||||
|
Deklarationen mit var sind mutable, also veränderlich
|
||||||
|
Immutability ist gut.
|
||||||
|
*/
|
||||||
|
val x = 10 // x ist 10
|
||||||
|
x = 20 // error: reassignment to val
|
||||||
|
var y = 10
|
||||||
|
y = 20 // y ist jetzt 20
|
||||||
|
|
||||||
|
/*
|
||||||
|
Scala ist eine statisch getypte Sprache, auch wenn wir in dem o.g. Beispiel
|
||||||
|
keine Typen an x und y geschrieben haben.
|
||||||
|
In Scala ist etwas eingebaut, was sich Type Inference nennt. Das heißt das der
|
||||||
|
Scala Compiler in den meisten Fällen erraten kann, von welchen Typ eine Variable ist,
|
||||||
|
so dass der Typ nicht jedes mal angegeben werden muss.
|
||||||
|
Einen Typ gibt man bei einer Variablendeklaration wie folgt an:
|
||||||
|
*/
|
||||||
|
val z: Int = 10
|
||||||
|
val a: Double = 1.0
|
||||||
|
|
||||||
|
|
||||||
|
// Bei automatischer Umwandlung von Int auf Double wird aus 10 eine 10.0
|
||||||
|
|
||||||
|
val b: Double = 10
|
||||||
|
|
||||||
|
|
||||||
|
// Boolean Werte
|
||||||
|
|
||||||
|
true
|
||||||
|
false
|
||||||
|
|
||||||
|
|
||||||
|
// Boolean Operationen
|
||||||
|
|
||||||
|
!true // false
|
||||||
|
!false // true
|
||||||
|
true == false // false
|
||||||
|
10 > 5 // true
|
||||||
|
|
||||||
|
|
||||||
|
// Mathematische Operationen sind wie gewohnt
|
||||||
|
|
||||||
|
1 + 1 // 2
|
||||||
|
2 - 1 // 1
|
||||||
|
5 * 3 // 15
|
||||||
|
6 / 2 // 3
|
||||||
|
6 / 4 // 1
|
||||||
|
6.0 / 4 // 1.5
|
||||||
|
|
||||||
|
|
||||||
|
// Die Auswertung eines Ausdrucks in der REPL gibt den Typ
|
||||||
|
// und das Ergebnis zurück.
|
||||||
|
|
||||||
|
scala> 1 + 7
|
||||||
|
res29: Int = 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
Das bedeutet, dass das Resultat der Auswertung von 1 + 7 ein Objekt
|
||||||
|
von Typ Int ist und einen Wert 0 hat.
|
||||||
|
"res29" ist ein sequentiell generierter name, um das Ergebnis des
|
||||||
|
Ausdrucks zu speichern. Dieser Wert kann bei Dir anders sein...
|
||||||
|
*/
|
||||||
|
|
||||||
|
"Scala strings werden in doppelten Anführungszeichen eingeschlossen"
|
||||||
|
'a' // A Scala Char
|
||||||
|
// 'Einzeln ge-quotete strings gibt es nicht!' <= This causes an error
|
||||||
|
|
||||||
|
// Für Strings gibt es die üblichen Java Methoden
|
||||||
|
|
||||||
|
"hello world".length
|
||||||
|
"hello world".substring(2, 6)
|
||||||
|
"hello world".replace("C", "3")
|
||||||
|
|
||||||
|
|
||||||
|
// Zusätzlich gibt es noch extra Scala Methoden
|
||||||
|
// siehe: scala.collection.immutable.StringOps
|
||||||
|
|
||||||
|
"hello world".take(5)
|
||||||
|
"hello world".drop(5)
|
||||||
|
|
||||||
|
|
||||||
|
// String interpolation: prefix "s"
|
||||||
|
|
||||||
|
val n = 45
|
||||||
|
s"We have $n apples" // => "We have 45 apples"
|
||||||
|
|
||||||
|
|
||||||
|
// Ausdrücke im Innern von interpolierten Strings gibt es auch
|
||||||
|
|
||||||
|
val a = Array(11, 9, 6)
|
||||||
|
val n = 100
|
||||||
|
s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old."
|
||||||
|
s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples."
|
||||||
|
s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4"
|
||||||
|
|
||||||
|
|
||||||
|
// Formatierung der interpolierten Strings mit dem prefix "f"
|
||||||
|
|
||||||
|
f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25"
|
||||||
|
f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454"
|
||||||
|
|
||||||
|
|
||||||
|
// Raw Strings, ignorieren Sonderzeichen.
|
||||||
|
|
||||||
|
raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r."
|
||||||
|
|
||||||
|
|
||||||
|
// Manche Zeichen müssen "escaped" werden, z.B.
|
||||||
|
// ein doppeltes Anführungszeichen in innern eines Strings.
|
||||||
|
|
||||||
|
"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown""
|
||||||
|
|
||||||
|
|
||||||
|
// Dreifache Anführungszeichen erlauben es, dass ein String über mehrere Zeilen geht
|
||||||
|
// und Anführungszeichen enthalten kann.
|
||||||
|
|
||||||
|
val html = """<form id="daform">
|
||||||
|
<p>Press belo', Joe</p>
|
||||||
|
<input type="submit">
|
||||||
|
</form>"""
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 2. Funktionen
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Funktionen werden so definiert
|
||||||
|
//
|
||||||
|
// def functionName(args...): ReturnType = { body... }
|
||||||
|
//
|
||||||
|
// Beachte: Es gibt kein return Schlüsselwort. In Scala ist der letzte Ausdruck
|
||||||
|
// in einer Funktion der Rückgabewert.
|
||||||
|
|
||||||
|
def sumOfSquares(x: Int, y: Int): Int = {
|
||||||
|
val x2 = x * x
|
||||||
|
val y2 = y * y
|
||||||
|
x2 + y2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Die geschweiften Klammern können weggelassen werden, wenn
|
||||||
|
// die Funktion nur aus einem einzigen Ausdruck besteht:
|
||||||
|
|
||||||
|
def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y
|
||||||
|
|
||||||
|
|
||||||
|
// Syntax für Funktionsaufrufe:
|
||||||
|
|
||||||
|
sumOfSquares(3, 4) // => 25
|
||||||
|
|
||||||
|
|
||||||
|
// In den meisten Fällen (mit Ausnahme von rekursiven Funktionen), können
|
||||||
|
// Rückgabetypen auch weggelassen werden, da dieselbe Typ Inference, wie bei
|
||||||
|
// Variablen, auch bei Funktionen greift:
|
||||||
|
|
||||||
|
def sq(x: Int) = x * x // Compiler errät, dass der return type Int ist
|
||||||
|
|
||||||
|
|
||||||
|
// Funktionen können default parameter haben:
|
||||||
|
|
||||||
|
def addWithDefault(x: Int, y: Int = 5) = x + y
|
||||||
|
addWithDefault(1, 2) // => 3
|
||||||
|
addWithDefault(1) // => 6
|
||||||
|
|
||||||
|
|
||||||
|
// Anonyme Funktionen sehen so aus:
|
||||||
|
|
||||||
|
(x: Int) => x * x
|
||||||
|
|
||||||
|
|
||||||
|
// Im Gegensatz zu def bei normalen Funktionen, kann bei anonymen Funktionen
|
||||||
|
// sogar der Eingabetyp weggelassen werden, wenn der Kontext klar ist.
|
||||||
|
// Beachte den Typ "Int => Int", dies beschreibt eine Funktion,
|
||||||
|
// welche Int als Parameter erwartet und Int zurückgibt.
|
||||||
|
|
||||||
|
val sq: Int => Int = x => x * x
|
||||||
|
|
||||||
|
|
||||||
|
// Anonyme Funktionen benutzt man ganz normal:
|
||||||
|
|
||||||
|
sq(10) // => 100
|
||||||
|
|
||||||
|
|
||||||
|
// Wenn ein Parameter einer anonymen Funktion nur einmal verwendet wird,
|
||||||
|
// bietet Scala einen sehr kurzen Weg diesen Parameter zu benutzen,
|
||||||
|
// indem die Parameter als Unterstrich "_" in der Parameterreihenfolge
|
||||||
|
// verwendet werden. Diese anonymen Funktionen werden sehr häufig
|
||||||
|
// verwendet.
|
||||||
|
|
||||||
|
val addOne: Int => Int = _ + 1
|
||||||
|
val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
|
||||||
|
addOne(5) // => 6
|
||||||
|
weirdSum(2, 4) // => 16
|
||||||
|
|
||||||
|
|
||||||
|
// Es gibt einen keyword return in Scala. Allerdings ist seine Verwendung
|
||||||
|
// nicht immer ratsam und kann fehlerbehaftet sein. "return" gibt nur aus
|
||||||
|
// dem innersten def, welches den return Ausdruck umgibt, zurück.
|
||||||
|
// "return" hat keinen Effekt in anonymen Funktionen:
|
||||||
|
|
||||||
|
def foo(x: Int): Int = {
|
||||||
|
val anonFunc: Int => Int = { z =>
|
||||||
|
if (z > 5)
|
||||||
|
return z // Zeile macht z zum return Wert von foo
|
||||||
|
else
|
||||||
|
z + 2 // Zeile ist der return Wert von anonFunc
|
||||||
|
}
|
||||||
|
anonFunc(x) // Zeile ist der return Wert von foo
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 3. Flow Control
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Wertebereiche und Schleifen
|
||||||
|
|
||||||
|
1 to 5
|
||||||
|
val r = 1 to 5
|
||||||
|
r.foreach(println)
|
||||||
|
r foreach println
|
||||||
|
(5 to 1 by -1) foreach (println)
|
||||||
|
|
||||||
|
// Scala ist syntaktisch sehr großzügig, Semikolons am Zeilenende
|
||||||
|
// sind optional, beim Aufruf von Methoden können die Punkte
|
||||||
|
// und Klammern entfallen und Operatoren sind im Grunde austauschbare Methoden
|
||||||
|
|
||||||
|
// while Schleife
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
while (i < 10) { println("i " + i); i += 1 }
|
||||||
|
i // i ausgeben, res3: Int = 10
|
||||||
|
|
||||||
|
|
||||||
|
// Beachte: while ist eine Schleife im klassischen Sinne -
|
||||||
|
// Sie läuft sequentiell ab und verändert die loop-Variable.
|
||||||
|
// While in Scala läuft schneller ab als in Java und die o.g.
|
||||||
|
// Kombinatoren und Zusammenlegungen sind einfacher zu verstehen
|
||||||
|
// und zu parellelisieren.
|
||||||
|
|
||||||
|
// Ein do while Schleife
|
||||||
|
|
||||||
|
do {
|
||||||
|
println("x ist immer noch weniger wie 10")
|
||||||
|
x += 1
|
||||||
|
} while (x < 10)
|
||||||
|
|
||||||
|
|
||||||
|
// Endrekursionen sind ideomatisch um sich wiederholende
|
||||||
|
// Dinge in Scala zu lösen. Rekursive Funtionen benötigen explizit einen
|
||||||
|
// return Typ, der Compiler kann ihn nicht erraten.
|
||||||
|
// Unit, in diesem Beispiel.
|
||||||
|
|
||||||
|
def showNumbersInRange(a: Int, b: Int): Unit = {
|
||||||
|
print(a)
|
||||||
|
if (a < b)
|
||||||
|
showNumbersInRange(a + 1, b)
|
||||||
|
}
|
||||||
|
showNumbersInRange(1, 14)
|
||||||
|
|
||||||
|
|
||||||
|
// Conditionals
|
||||||
|
|
||||||
|
val x = 10
|
||||||
|
if (x == 1) println("yeah")
|
||||||
|
if (x == 10) println("yeah")
|
||||||
|
if (x == 11) println("yeah")
|
||||||
|
if (x == 11) println ("yeah") else println("nay")
|
||||||
|
println(if (x == 10) "yeah" else "nope")
|
||||||
|
val text = if (x == 10) "yeah" else "nope"
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 4. Daten Strukturen (Array, Map, Set, Tuples)
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Array
|
||||||
|
|
||||||
|
val a = Array(1, 2, 3, 5, 8, 13)
|
||||||
|
a(0)
|
||||||
|
a(3)
|
||||||
|
a(21) // Exception
|
||||||
|
|
||||||
|
|
||||||
|
// Map - Speichert Key-Value-Paare
|
||||||
|
|
||||||
|
val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
|
||||||
|
m("fork")
|
||||||
|
m("spoon")
|
||||||
|
m("bottle") // Exception
|
||||||
|
val safeM = m.withDefaultValue("no lo se")
|
||||||
|
safeM("bottle")
|
||||||
|
|
||||||
|
// Set - Speichert Unikate, unsortiert (sortiert -> SortedSet)
|
||||||
|
|
||||||
|
val s = Set(1, 3, 7)
|
||||||
|
s(0) //false
|
||||||
|
s(1) //true
|
||||||
|
val s = Set(1,1,3,3,7)
|
||||||
|
s: scala.collection.immutable.Set[Int] = Set(1, 3, 7)
|
||||||
|
|
||||||
|
// Tuple - Speichert beliebige Daten und "verbindet" sie miteinander
|
||||||
|
// Ein Tuple ist keine Collection.
|
||||||
|
|
||||||
|
(1, 2)
|
||||||
|
(4, 3, 2)
|
||||||
|
(1, 2, "three")
|
||||||
|
(a, 2, "three")
|
||||||
|
|
||||||
|
|
||||||
|
// Hier ist der Rückgabewert der Funktion ein Tuple
|
||||||
|
// Die Funktion gibt das Ergebnis, so wie den Rest zurück.
|
||||||
|
|
||||||
|
val divideInts = (x: Int, y: Int) => (x / y, x % y)
|
||||||
|
divideInts(10, 3)
|
||||||
|
|
||||||
|
|
||||||
|
// Um die Elemente eines Tuples anzusprechen, benutzt man diese
|
||||||
|
// Notation: _._n wobei n der index des Elements ist (Index startet bei 1)
|
||||||
|
|
||||||
|
val d = divideInts(10, 3)
|
||||||
|
d._1
|
||||||
|
d._2
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 5. Objektorientierte Programmierung
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bislang waren alle gezeigten Sprachelemente einfache Ausdrücke, welche zwar
|
||||||
|
zum Ausprobieren und Lernen in der REPL gut geeignet sind, jedoch in
|
||||||
|
einem Scala file selten alleine zu finden sind.
|
||||||
|
Die einzigen Top-Level Konstrukte in Scala sind nämlich:
|
||||||
|
|
||||||
|
- Klassen (classes)
|
||||||
|
- Objekte (objects)
|
||||||
|
- case classes
|
||||||
|
- traits
|
||||||
|
|
||||||
|
Diesen Sprachelemente wenden wir uns jetzt zu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Klassen
|
||||||
|
|
||||||
|
// Zum Erstellen von Objekten benötigt man eine Klasse, wie in vielen
|
||||||
|
// anderen Sprachen auch.
|
||||||
|
|
||||||
|
// erzeugt Klasse mit default Konstruktor
|
||||||
|
|
||||||
|
class Hund
|
||||||
|
scala> val t = new Hund
|
||||||
|
t: Hund = Hund@7103745
|
||||||
|
|
||||||
|
|
||||||
|
// Der Konstruktor wird direkt hinter dem Klassennamen deklariert.
|
||||||
|
|
||||||
|
class Hund(sorte: String)
|
||||||
|
scala> val t = new Hund("Dackel")
|
||||||
|
t: Hund = Hund@14be750c
|
||||||
|
scala> t.sorte //error: value sorte is not a member of Hund
|
||||||
|
|
||||||
|
|
||||||
|
// Per val wird aus dem Attribut ein unveränderliches Feld der Klasse
|
||||||
|
// Per var wird aus dem Attribut ein veränderliches Feld der Klasse
|
||||||
|
|
||||||
|
class Hund(val sorte: String)
|
||||||
|
scala> val t = new Hund("Dackel")
|
||||||
|
t: Hund = Hund@74a85515
|
||||||
|
scala> t.sorte
|
||||||
|
res18: String = Dackel
|
||||||
|
|
||||||
|
|
||||||
|
// Methoden werden mit def geschrieben
|
||||||
|
|
||||||
|
def bark = "Woof, woof!"
|
||||||
|
|
||||||
|
|
||||||
|
// Felder und Methoden können public, protected und private sein
|
||||||
|
// default ist public
|
||||||
|
// private ist nur innerhalb des deklarierten Bereichs sichtbar
|
||||||
|
|
||||||
|
class Hund {
|
||||||
|
private def x = ...
|
||||||
|
def y = ...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// protected ist nur innerhalb des deklarierten und aller
|
||||||
|
// erbenden Bereiche sichtbar
|
||||||
|
|
||||||
|
class Hund {
|
||||||
|
protected def x = ...
|
||||||
|
}
|
||||||
|
class Dackel extends Hund {
|
||||||
|
// x ist sichtbar
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object
|
||||||
|
// Wird ein Objekt ohne das Schlüsselwort "new" instanziert, wird das sog.
|
||||||
|
// "companion object" aufgerufen. Mit dem "object" Schlüsselwort wird so
|
||||||
|
// ein Objekt (Typ UND Singleton) erstellt. Damit kann man dann eine Klasse
|
||||||
|
// benutzen ohne ein Objekt instanziieren zu müssen.
|
||||||
|
// Ein gültiges companion Objekt einer Klasse ist es aber erst dann, wenn
|
||||||
|
// es genauso heisst und in derselben Datei wie die Klasse definiert wurde.
|
||||||
|
|
||||||
|
object Hund {
|
||||||
|
def alleSorten = List("Pitbull", "Dackel", "Retriever")
|
||||||
|
def createHund(sorte: String) = new Hund(sorte)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case classes
|
||||||
|
// Fallklassen bzw. Case classes sind Klassen die normale Klassen um extra
|
||||||
|
// Funktionalität erweitern. Mit Case Klassen bekommt man ein paar
|
||||||
|
// Dinge einfach dazu, ohne sich darum kümmern zu müssen. Z.B.
|
||||||
|
// ein companion object mit den entsprechenden Methoden,
|
||||||
|
// Hilfsmethoden wie toString(), equals() und hashCode() und auch noch
|
||||||
|
// Getter für unsere Attribute (das Angeben von val entfällt dadurch)
|
||||||
|
|
||||||
|
class Person(val name: String)
|
||||||
|
class Hund(val sorte: String, val farbe: String, val halter: Person)
|
||||||
|
|
||||||
|
|
||||||
|
// Es genügt das Schlüsselwort case vor die Klasse zu schreiben.
|
||||||
|
|
||||||
|
case class Person(name: String)
|
||||||
|
case class Hund(sorte: String, farbe: String, halter: Person)
|
||||||
|
|
||||||
|
|
||||||
|
// Für neue Instanzen brauch man kein "new"
|
||||||
|
|
||||||
|
val dackel = Hund("dackel", "grau", Person("peter"))
|
||||||
|
val dogge = Hund("dogge", "grau", Person("peter"))
|
||||||
|
|
||||||
|
|
||||||
|
// getter
|
||||||
|
|
||||||
|
dackel.halter // => Person = Person(peter)
|
||||||
|
|
||||||
|
|
||||||
|
// equals
|
||||||
|
|
||||||
|
dogge == dackel // => false
|
||||||
|
|
||||||
|
|
||||||
|
// copy
|
||||||
|
// otherGeorge == Person("george", "9876")
|
||||||
|
|
||||||
|
val otherGeorge = george.copy(phoneNumber = "9876")
|
||||||
|
|
||||||
|
// Traits
|
||||||
|
// Ähnlich wie Java interfaces, definiert man mit traits einen Objekttyp
|
||||||
|
// und Methodensignaturen. Scala erlaubt allerdings das teilweise
|
||||||
|
// implementieren dieser Methoden. Konstruktorparameter sind nicht erlaubt.
|
||||||
|
// Traits können von anderen Traits oder Klassen erben, aber nur von
|
||||||
|
// parameterlosen.
|
||||||
|
|
||||||
|
trait Hund {
|
||||||
|
def sorte: String
|
||||||
|
def farbe: String
|
||||||
|
def bellen: Boolean = true
|
||||||
|
def beissen: Boolean
|
||||||
|
}
|
||||||
|
class Bernhardiner extends Hund{
|
||||||
|
val sorte = "Bernhardiner"
|
||||||
|
val farbe = "braun"
|
||||||
|
def beissen = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
scala> b
|
||||||
|
res0: Bernhardiner = Bernhardiner@3e57cd70
|
||||||
|
scala> b.sorte
|
||||||
|
res1: String = Bernhardiner
|
||||||
|
scala> b.bellen
|
||||||
|
res2: Boolean = true
|
||||||
|
scala> b.beissen
|
||||||
|
res3: Boolean = false
|
||||||
|
|
||||||
|
|
||||||
|
// Traits können auch via Mixins (Schlüsselwort "with") eingebunden werden
|
||||||
|
|
||||||
|
trait Bellen {
|
||||||
|
def bellen: String = "Woof"
|
||||||
|
}
|
||||||
|
trait Hund {
|
||||||
|
def sorte: String
|
||||||
|
def farbe: String
|
||||||
|
}
|
||||||
|
class Bernhardiner extends Hund with Bellen{
|
||||||
|
val sorte = "Bernhardiner"
|
||||||
|
val farbe = "braun"
|
||||||
|
}
|
||||||
|
scala> val b = new Bernhardiner
|
||||||
|
b: Bernhardiner = Bernhardiner@7b69c6ba
|
||||||
|
scala> b.bellen
|
||||||
|
res0: String = Woof
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 6. Pattern Matching
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Pattern matching in Scala ist ein sehr nützliches und wesentlich
|
||||||
|
// mächtigeres Feature als Vergleichsfunktionen in Java. In Scala
|
||||||
|
// benötigt ein case Statement kein "break", ein fall-through gibt es nicht.
|
||||||
|
// Mehrere Überprüfungen können mit einem Statement gemacht werden.
|
||||||
|
// Pattern matching wird mit dem Schlüsselwort "match" gemacht.
|
||||||
|
|
||||||
|
val x = ...
|
||||||
|
x match {
|
||||||
|
case 2 =>
|
||||||
|
case 3 =>
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Pattern Matching kann auf beliebige Typen prüfen
|
||||||
|
|
||||||
|
val any: Any = ...
|
||||||
|
val gleicht = any match {
|
||||||
|
case 2 | 3 | 5 => "Zahl"
|
||||||
|
case "woof" => "String"
|
||||||
|
case true | false => "Boolean"
|
||||||
|
case 45.35 => "Double"
|
||||||
|
case _ => "Unbekannt"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// und auf Objektgleichheit
|
||||||
|
|
||||||
|
def matchPerson(person: Person): String = person match {
|
||||||
|
case Person("George", nummer) => "George! Die Nummer ist " + number
|
||||||
|
case Person("Kate", nummer) => "Kate! Die Nummer ist " + nummer
|
||||||
|
case Person(name, nummer) => "Irgendjemand: " + name + ", Telefon: " + nummer
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Und viele mehr...
|
||||||
|
|
||||||
|
val email = "(.*)@(.*)".r // regex
|
||||||
|
def matchEverything(obj: Any): String = obj match {
|
||||||
|
// Werte:
|
||||||
|
case "Hello world" => "Got the string Hello world"
|
||||||
|
// Typen:
|
||||||
|
case x: Double => "Got a Double: " + x
|
||||||
|
// Conditions:
|
||||||
|
case x: Int if x > 10000 => "Got a pretty big number!"
|
||||||
|
// Case Classes:
|
||||||
|
case Person(name, number) => s"Got contact info for $name!"
|
||||||
|
// RegEx:
|
||||||
|
case email(name, domain) => s"Got email address $name@$domain"
|
||||||
|
// Tuples:
|
||||||
|
case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c"
|
||||||
|
// Strukturen:
|
||||||
|
case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
|
||||||
|
// Patterns kann man ineinander schachteln:
|
||||||
|
case List(List((1, 2, "YAY"))) => "Got a list of list of tuple"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Jedes Objekt mit einer "unapply" Methode kann per Pattern geprüft werden
|
||||||
|
// Ganze Funktionen können Patterns sein
|
||||||
|
|
||||||
|
val patternFunc: Person => String = {
|
||||||
|
case Person("George", number) => s"George's number: $number"
|
||||||
|
case Person(name, number) => s"Random person's number: $number"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 37. Higher-order functions
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Scala erlaubt, das Methoden und Funktion wiederum Funtionen und Methoden
|
||||||
|
als Aufrufparameter oder Return Wert verwenden. Diese Methoden heissen
|
||||||
|
higher-order functions
|
||||||
|
Es gibt zahlreiche higher-order functions nicht nur für Listen, auch für
|
||||||
|
die meisten anderen Collection Typen, sowie andere Klassen in Scala
|
||||||
|
Nennenswerte sind:
|
||||||
|
"filter", "map", "reduce", "foldLeft"/"foldRight", "exists", "forall"
|
||||||
|
|
||||||
|
## List
|
||||||
|
|
||||||
|
def isGleichVier(a:Int) = a == 4
|
||||||
|
val list = List(1, 2, 3, 4)
|
||||||
|
val resultExists4 = list.exists(isEqualToFour)
|
||||||
|
|
||||||
|
|
||||||
|
## map
|
||||||
|
// map nimmt eine Funktion und führt sie auf jedem Element aus und erzeugt
|
||||||
|
// eine neue Liste
|
||||||
|
|
||||||
|
// Funktion erwartet ein Int und returned ein Int
|
||||||
|
|
||||||
|
val add10: Int => Int = _ + 10
|
||||||
|
|
||||||
|
|
||||||
|
// add10 wird auf jedes Element angewendet
|
||||||
|
|
||||||
|
List(1, 2, 3) map add10 // => List(11, 12, 13)
|
||||||
|
|
||||||
|
|
||||||
|
// Anonyme Funktionen können anstatt definierter Funktionen verwendet werden
|
||||||
|
|
||||||
|
List(1, 2, 3) map (x => x + 10)
|
||||||
|
|
||||||
|
|
||||||
|
// Der Unterstrich wird anstelle eines Parameters einer anonymen Funktion
|
||||||
|
// verwendet. Er wird an die Variable gebunden.
|
||||||
|
|
||||||
|
List(1, 2, 3) map (_ + 10)
|
||||||
|
|
||||||
|
|
||||||
|
// Wenn der anonyme Block und die Funtion beide EIN Argument erwarten,
|
||||||
|
// kann sogar der Unterstrich weggelassen werden.
|
||||||
|
|
||||||
|
List("Dom", "Bob", "Natalia") foreach println
|
||||||
|
|
||||||
|
|
||||||
|
// filter
|
||||||
|
// filter nimmt ein Prädikat (eine Funktion von A -> Boolean) und findet
|
||||||
|
// alle Elemente die auf das Prädikat passen
|
||||||
|
|
||||||
|
List(1, 2, 3) filter (_ > 2) // => List(3)
|
||||||
|
case class Person(name: String, age: Int)
|
||||||
|
List(
|
||||||
|
Person(name = "Dom", age = 23),
|
||||||
|
Person(name = "Bob", age = 30)
|
||||||
|
).filter(_.age > 25) // List(Person("Bob", 30))
|
||||||
|
|
||||||
|
|
||||||
|
// reduce
|
||||||
|
// reduce nimmt zwei Elemente und kombiniert sie zu einem Element,
|
||||||
|
// und zwar solange bis nur noch ein Element da ist.
|
||||||
|
|
||||||
|
// foreach
|
||||||
|
// foreach gibt es für einige Collections
|
||||||
|
|
||||||
|
val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
|
||||||
|
aListOfNumbers foreach (x => println(x))
|
||||||
|
aListOfNumbers foreach println
|
||||||
|
|
||||||
|
// For comprehensions
|
||||||
|
// Eine for-comprehension definiert eine Beziehung zwischen zwei Datensets.
|
||||||
|
// Dies ist keine for-Schleife.
|
||||||
|
|
||||||
|
for { n <- s } yield sq(n)
|
||||||
|
val nSquared2 = for { n <- s } yield sq(n)
|
||||||
|
for { n <- nSquared2 if n < 10 } yield n
|
||||||
|
for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 8. Implicits
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// **ACHTUNG:**
|
||||||
|
// Implicits sind ein sehr mächtiges Sprachfeature von Scala.
|
||||||
|
// Es sehr einfach
|
||||||
|
// sie falsch zu benutzen und Anfänger sollten sie mit Vorsicht oder am
|
||||||
|
// besten erst dann benutzen, wenn man versteht wie sie funktionieren.
|
||||||
|
// Dieses Tutorial enthält Implicits, da sie in Scala an jeder Stelle
|
||||||
|
// vorkommen und man auch mit einer Lib die Implicits benutzt nichts sinnvolles
|
||||||
|
// machen kann.
|
||||||
|
// Hier soll ein Grundverständnis geschaffen werden, wie sie funktionieren.
|
||||||
|
|
||||||
|
// Mit dem Schlüsselwort implicit können Methoden, Werte, Funktion, Objekte
|
||||||
|
// zu "implicit Methods" werden.
|
||||||
|
|
||||||
|
implicit val myImplicitInt = 100
|
||||||
|
implicit def myImplicitFunction(sorte: String) = new Hund("Golden " + sorte)
|
||||||
|
|
||||||
|
|
||||||
|
// implicit ändert nicht das Verhalten eines Wertes oder einer Funktion
|
||||||
|
|
||||||
|
myImplicitInt + 2 // => 102
|
||||||
|
myImplicitFunction("Pitbull").sorte // => "Golden Pitbull"
|
||||||
|
|
||||||
|
|
||||||
|
// Der Unterschied ist, dass diese Werte ausgewählt werden können, wenn ein
|
||||||
|
// anderer Codeteil einen implicit Wert benötigt, zum Beispiel innerhalb von
|
||||||
|
// implicit Funktionsparametern
|
||||||
|
|
||||||
|
// Diese Funktion hat zwei Parameter: einen normalen und einen implicit
|
||||||
|
|
||||||
|
def sendGreetings(toWhom: String)(implicit howMany: Int) =
|
||||||
|
s"Hello $toWhom, $howMany blessings to you and yours!"
|
||||||
|
|
||||||
|
|
||||||
|
// Werden beide Parameter gefüllt, verhält sich die Funktion wie erwartet
|
||||||
|
|
||||||
|
sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!"
|
||||||
|
|
||||||
|
|
||||||
|
// Wird der implicit Parameter jedoch weggelassen, wird ein anderer
|
||||||
|
// implicit Wert vom gleichen Typ genommen. Der Compiler sucht im
|
||||||
|
// lexikalischen Scope und im companion object nach einem implicit Wert,
|
||||||
|
// der vom Typ passt, oder nach einer implicit Methode mit der er in den
|
||||||
|
// geforderten Typ konvertieren kann.
|
||||||
|
|
||||||
|
// Hier also: "myImplicitInt", da ein Int gesucht wird
|
||||||
|
|
||||||
|
sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
|
||||||
|
|
||||||
|
|
||||||
|
// bzw. "myImplicitFunction"
|
||||||
|
// Der String wird erst mit Hilfe der Funktion in Hund konvertiert, und
|
||||||
|
// dann wird die Methode aufgerufen
|
||||||
|
|
||||||
|
"Retriever".sorte // => "Golden Retriever"
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 19. Misc
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// Importe
|
||||||
|
|
||||||
|
import scala.collection.immutable.List
|
||||||
|
|
||||||
|
|
||||||
|
// Importiere alle Unterpackages
|
||||||
|
|
||||||
|
import scala.collection.immutable._
|
||||||
|
|
||||||
|
|
||||||
|
// Importiere verschiedene Klassen mit einem Statement
|
||||||
|
|
||||||
|
import scala.collection.immutable.{List, Map}
|
||||||
|
|
||||||
|
|
||||||
|
// Einen Import kann man mit '=>' umbenennen
|
||||||
|
|
||||||
|
import scala.collection.immutable.{List => ImmutableList}
|
||||||
|
|
||||||
|
|
||||||
|
// Importiere alle Klasses, mit Ausnahem von....
|
||||||
|
// Hier ohne: Map and Set:
|
||||||
|
|
||||||
|
import scala.collection.immutable.{Map => _, Set => _, _}
|
||||||
|
|
||||||
|
// Main
|
||||||
|
|
||||||
|
object Application {
|
||||||
|
def main(args: Array[String]): Unit = {
|
||||||
|
// Sachen kommen hierhin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// I/O
|
||||||
|
// Eine Datei Zeile für Zeile lesen
|
||||||
|
|
||||||
|
import scala.io.Source
|
||||||
|
for(line <- Source.fromFile("myfile.txt").getLines())
|
||||||
|
println(line)
|
||||||
|
|
||||||
|
|
||||||
|
// Eine Datei schreiben
|
||||||
|
|
||||||
|
val writer = new PrintWriter("myfile.txt")
|
||||||
|
writer.write("Schreibe Zeile" + util.Properties.lineSeparator)
|
||||||
|
writer.write("Und noch eine Zeile" + util.Properties.lineSeparator)
|
||||||
|
writer.close()
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Weiterführende Hinweise
|
||||||
|
|
||||||
|
// DE
|
||||||
|
* [Scala Tutorial](https://scalatutorial.wordpress.com)
|
||||||
|
* [Scala Tutorial](http://scalatutorial.de)
|
||||||
|
|
||||||
|
// EN
|
||||||
|
* [Scala for the impatient](http://horstmann.com/scala/)
|
||||||
|
* [Twitter Scala school](http://twitter.github.io/scala_school/)
|
||||||
|
* [The scala documentation](http://docs.scala-lang.org/)
|
||||||
|
* [Try Scala in your browser](http://scalatutorials.com/tour/)
|
||||||
|
* [Neophytes Guide to Scala](http://danielwestheide.com/scala/neophytes.html)
|
||||||
|
* Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user)
|
@ -30,7 +30,7 @@ null_Wert: null
|
|||||||
Schlüssel mit Leerzeichen: value
|
Schlüssel mit Leerzeichen: value
|
||||||
# Strings müssen nicht immer mit Anführungszeichen umgeben sein, können aber:
|
# Strings müssen nicht immer mit Anführungszeichen umgeben sein, können aber:
|
||||||
jedoch: "Ein String in Anführungzeichen"
|
jedoch: "Ein String in Anführungzeichen"
|
||||||
"Ein Schlüssel in Anführungszeichen": "Nützlich, wenn du einen Doppelpunkt im Schluessel haben willst."
|
"Ein Schlüssel in Anführungszeichen": "Nützlich, wenn du einen Doppelpunkt im Schlüssel haben willst."
|
||||||
|
|
||||||
# Mehrzeilige Strings schreibst du am besten als 'literal block' (| gefolgt vom Text)
|
# Mehrzeilige Strings schreibst du am besten als 'literal block' (| gefolgt vom Text)
|
||||||
# oder ein 'folded block' (> gefolgt vom text).
|
# oder ein 'folded block' (> gefolgt vom text).
|
||||||
@ -64,7 +64,7 @@ eine_verschachtelte_map:
|
|||||||
hallo: hallo
|
hallo: hallo
|
||||||
|
|
||||||
# Schlüssel müssen nicht immer String sein.
|
# Schlüssel müssen nicht immer String sein.
|
||||||
0.25: ein Float-Wert als Schluessel
|
0.25: ein Float-Wert als Schlüssel
|
||||||
|
|
||||||
# Schlüssel können auch mehrzeilig sein, ? symbolisiert den Anfang des Schlüssels
|
# Schlüssel können auch mehrzeilig sein, ? symbolisiert den Anfang des Schlüssels
|
||||||
? |
|
? |
|
||||||
|
108
edn.html.markdown
Normal file
108
edn.html.markdown
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
---
|
||||||
|
language: edn
|
||||||
|
filename: learnedn.edn
|
||||||
|
contributors:
|
||||||
|
- ["Jason Yeo", "https://github.com/jsyeo"]
|
||||||
|
---
|
||||||
|
|
||||||
|
Extensible Data Notation (EDN) is a format for serializing data.
|
||||||
|
|
||||||
|
The notation is used internally by Clojure to represent programs. It is also
|
||||||
|
used as a data transfer format like JSON. Though it is more commonly used in
|
||||||
|
Clojure, there are implementations of EDN for many other languages.
|
||||||
|
|
||||||
|
The main benefit of EDN over JSON and YAML is that it is extensible. We
|
||||||
|
will see how it is extended later on.
|
||||||
|
|
||||||
|
```Clojure
|
||||||
|
; Comments start with a semicolon.
|
||||||
|
; Anything after the semicolon is ignored.
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;; Basic Types ;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
nil ; also known in other languages as null
|
||||||
|
|
||||||
|
; Booleans
|
||||||
|
true
|
||||||
|
false
|
||||||
|
|
||||||
|
; Strings are enclosed in double quotes
|
||||||
|
"hungarian breakfast"
|
||||||
|
"farmer's cheesy omelette"
|
||||||
|
|
||||||
|
; Characters are preceeded by backslashes
|
||||||
|
\g \r \a \c \e
|
||||||
|
|
||||||
|
; Keywords start with a colon. They behave like enums. Kind of
|
||||||
|
; like symbols in Ruby.
|
||||||
|
:eggs
|
||||||
|
:cheese
|
||||||
|
:olives
|
||||||
|
|
||||||
|
; Symbols are used to represent identifiers. They start with #.
|
||||||
|
; You can namespace symbols by using /. Whatever preceeds / is
|
||||||
|
; the namespace of the name.
|
||||||
|
#spoon
|
||||||
|
#kitchen/spoon ; not the same as #spoon
|
||||||
|
#kitchen/fork
|
||||||
|
#github/fork ; you can't eat with this
|
||||||
|
|
||||||
|
; Integers and floats
|
||||||
|
42
|
||||||
|
3.14159
|
||||||
|
|
||||||
|
; Lists are sequences of values
|
||||||
|
(:bun :beef-patty 9 "yum!")
|
||||||
|
|
||||||
|
; Vectors allow random access
|
||||||
|
[:gelato 1 2 -2]
|
||||||
|
|
||||||
|
; Maps are associative data structures that associate the key with its value
|
||||||
|
{:eggs 2
|
||||||
|
:lemon-juice 3.5
|
||||||
|
:butter 1}
|
||||||
|
|
||||||
|
; You're not restricted to using keywords as keys
|
||||||
|
{[1 2 3 4] "tell the people what she wore",
|
||||||
|
[5 6 7 8] "the more you see the more you hate"}
|
||||||
|
|
||||||
|
; You may use commas for readability. They are treated as whitespace.
|
||||||
|
|
||||||
|
; Sets are collections that contain unique elements.
|
||||||
|
#{:a :b 88 "huat"}
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;; Tagged Elements ;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
; EDN can be extended by tagging elements with # symbols.
|
||||||
|
|
||||||
|
#MyYelpClone/MenuItem {:name "eggs-benedict" :rating 10}
|
||||||
|
|
||||||
|
; Let me explain this with a clojure example. Suppose I want to transform that
|
||||||
|
; piece of EDN into a MenuItem record.
|
||||||
|
|
||||||
|
(defrecord MenuItem [name rating])
|
||||||
|
|
||||||
|
; To transform EDN to clojure values, I will need to use the built in EDN
|
||||||
|
; reader, edn/read-string
|
||||||
|
|
||||||
|
(edn/read-string "{:eggs 2 :butter 1 :flour 5}")
|
||||||
|
; -> {:eggs 2 :butter 1 :flour 5}
|
||||||
|
|
||||||
|
; To transform tagged elements, define the reader function and pass a map
|
||||||
|
; that maps tags to reader functions to edn/read-string like so
|
||||||
|
|
||||||
|
(edn/read-string {:readers {'MyYelpClone/MenuItem map->menu-item}}
|
||||||
|
"#MyYelpClone/MenuItem {:name \"eggs-benedict\" :rating 10}")
|
||||||
|
; -> #user.MenuItem{:name "eggs-benedict", :rating 10}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
# References
|
||||||
|
|
||||||
|
- [EDN spec](https://github.com/edn-format/edn)
|
||||||
|
- [Implementations](https://github.com/edn-format/edn/wiki/Implementations)
|
||||||
|
- [Tagged Elements](http://www.compoundtheory.com/clojure-edn-walkthrough/)
|
243
el-gr/css-gr.html.markdown
Normal file
243
el-gr/css-gr.html.markdown
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
---
|
||||||
|
language: css
|
||||||
|
contributors:
|
||||||
|
- ["Kostas Bariotis", "http://kostasbariotis.com"]
|
||||||
|
filename: css-gr.html.markdown
|
||||||
|
lang: el-gr
|
||||||
|
---
|
||||||
|
|
||||||
|
Η αρχική μορφή του Παγκόσμιου Ιστού αποτελούταν απο καθαρό κείμενο, χωρίς οπτικά αντικείμενα. Με το πέρας
|
||||||
|
του χρόνου και την εξέλιξη των Φυλλομετρητών, οι πλούσιες σελίδες, σε οπτικά και πολυμεσικά αντικείμενα,
|
||||||
|
γίναν καθημερινότητα.
|
||||||
|
|
||||||
|
Η CSS μας βοηθάει να διαχωρήσουμε το περιεχόμενο της σελίδας μας (HTML) απο την οπτική της περιγραφή.
|
||||||
|
|
||||||
|
Με την CSS ορίζουμε οπτικές ιδιότητες (χρώμα, μέγεθος, κλπ) σε HTML αντικείμενα (H1, div, κλπ).
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Σχόλια εμφανίζονται εντός καθέτου-αστερίσκου, όπως εδώ.
|
||||||
|
Δεν υπάρχουν σχόλια μια γραμμής και πολλών. */
|
||||||
|
|
||||||
|
/* ####################
|
||||||
|
## ΚΑΝΟΝΕΣ
|
||||||
|
#################### */
|
||||||
|
|
||||||
|
/* ένας κανόνας χρησιμοποιείτε για να στοχεύσουμε ένα αντικείμενο (selector).
|
||||||
|
selector { property: value; /* περισσότερες ιδιότητες...*/ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
Αυτό είναι ενα παράδειγμα αντικειμένου¨
|
||||||
|
|
||||||
|
<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' />
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Μπορούμε να το στοχεύσουμε με την χρήση CSS κλάσεων */
|
||||||
|
.class1 { }
|
||||||
|
|
||||||
|
/* Ή και με τις δύο κλάσεις! */
|
||||||
|
.class1.class2 { }
|
||||||
|
|
||||||
|
/* Και με το όνομα του */
|
||||||
|
div { }
|
||||||
|
|
||||||
|
/* Ή με το id του */
|
||||||
|
#anID { }
|
||||||
|
|
||||||
|
/* Ή με το γεγονός ότι περιέχει ενα attribute */
|
||||||
|
[attr] { font-size:smaller; }
|
||||||
|
|
||||||
|
/* Ή οτι το attribute αυτό έχει μια συγκεκριμένη τιμή */
|
||||||
|
[attr='value'] { font-size:smaller; }
|
||||||
|
|
||||||
|
/* Ξεκινάει απο το λεκτικό (CSS 3) */
|
||||||
|
[attr^='val'] { font-size:smaller; }
|
||||||
|
|
||||||
|
/* Καταλήγει σε αυτο το λεκτικό (CSS 3) */
|
||||||
|
[attr$='ue'] { font-size:smaller; }
|
||||||
|
|
||||||
|
/* Περιέχει κάποιο λεκτικό */
|
||||||
|
[otherAttr~='foo'] { }
|
||||||
|
[otherAttr~='bar'] { }
|
||||||
|
|
||||||
|
/* περιέχει το λεκτικό σε λίστα χωρισμένη με παύλες, δηλαδή: "-" (U+002D) */
|
||||||
|
[otherAttr|='en'] { font-size:smaller; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Μπορούμε να προσθέσουμε μεταξύ τους selectors για να δημιουργήσουμε πιο αυστηρούς.
|
||||||
|
Δεν βάζουμε κενά ανάμεσα. */
|
||||||
|
div.some-class[attr$='ue'] { }
|
||||||
|
|
||||||
|
/* Μπορούμε να επιλέξουμε αντικείμενα που βρίσκονται μέσα σε άλλα. */
|
||||||
|
div.some-parent > .class-name { }
|
||||||
|
|
||||||
|
/* Ή κάποιο αντικείμενο απόγονο ανεξαρτήτου του βάθους της σχέσης τους. */
|
||||||
|
div.some-parent .class-name { }
|
||||||
|
|
||||||
|
/* ΠΡΟΣΟΧΗ: ο ίδιος selector χωρίς κενά έχει άλλο νόημα. (Άσκηση προς τον αναγνώστη) */
|
||||||
|
div.some-parent.class-name { }
|
||||||
|
|
||||||
|
/* Μπορούμε να επιλέξουμε αντικείμενα με βάση το αμέσως επόμενο αντικείμενο στο ίδιο επίπεδο. */
|
||||||
|
.i-am-just-before + .this-element { }
|
||||||
|
|
||||||
|
/* Ή οποιοδήποτε αντικείμενο που προηγείται */
|
||||||
|
.i-am-any-element-before ~ .this-element { }
|
||||||
|
|
||||||
|
/* Με την βοήθεια των ψευδο-κλάσεων μπορούμε να επιλέξουμε αντικείμενα που βρίσκονται σε μια
|
||||||
|
ορισμένη κατάασταση. */
|
||||||
|
|
||||||
|
/* π.χ. όταν ο κέρσορας είναι πάνω απο ένα αντικείμενο */
|
||||||
|
selector:hover { }
|
||||||
|
|
||||||
|
/* ή ένας υπερσύνδεσμος που πατήθηκε */
|
||||||
|
selector:visited { }
|
||||||
|
|
||||||
|
/* ή που δεν πατήθηκε */
|
||||||
|
selected:link { }
|
||||||
|
|
||||||
|
/* ή ένα αντικείμενο που επιλέχθηκε */
|
||||||
|
selected:focus { }
|
||||||
|
|
||||||
|
/* οποιοδήποτε αντικείμενο είναι το πρώτο παιδί των γονέων του */
|
||||||
|
selector:first-child {}
|
||||||
|
|
||||||
|
/* οποιοδήποτε αντικείμενο είναι το πρώτοτελευταίο παιδί των γονέων του */
|
||||||
|
selector:last-child {}
|
||||||
|
|
||||||
|
/* Όπως και με τις ψευδο-κλάσεις, τα ψευδο-αντικείμενα μας επιτρέπουν τα τροποοιήσουμε συγκεκριμένα
|
||||||
|
κομμάτια της σελίδας */
|
||||||
|
|
||||||
|
/* επιλέγει το ψευδο-αντικείμενο ακριβώς πριν απο το αντικείμενο */
|
||||||
|
selector::before {}
|
||||||
|
|
||||||
|
/* επιλέγει το ψευδο-αντικείμενο ακριβώς μετά απο τον αντικείμενο */
|
||||||
|
selector::after {}
|
||||||
|
|
||||||
|
/* Σε σωστά σημεία (όχι πολύ ψηλά στην ιεραρχία) ο αστερίσκος μπορείς να χρησιμοποιηθεί για να
|
||||||
|
επιλέξουμε όλα τα αντικείμενα */
|
||||||
|
* { } /* όλα τα αντικείμενα της σελίδας */
|
||||||
|
.parent * { } /* όλους τους απόγονους */
|
||||||
|
.parent > * { } /* όλους τους απόγονους πρώτου επιπέδου */
|
||||||
|
|
||||||
|
/* ####################
|
||||||
|
## Ιδιότητες
|
||||||
|
#################### */
|
||||||
|
|
||||||
|
selector {
|
||||||
|
|
||||||
|
/* Οι μονάδες μπορούν να είναι είτε απόλυτες είτε σχετικές */
|
||||||
|
|
||||||
|
/* Σχετικές μονάδες */
|
||||||
|
width: 50%; /* ποσοστό επί του πλάτους του γονέα */
|
||||||
|
font-size: 2em; /* πολλαπλασιαστής της αρχικής τιμής του αντικειμένου */
|
||||||
|
font-size: 2rem; /* ή της τιμής του πρώτου αντικειμένου στην ιεραρχία */
|
||||||
|
font-size: 2vw; /* πολλαπλαστιαστής του 1% του οπτικού πλάτους */
|
||||||
|
font-size: 2vh; /* ή τους ύψους */
|
||||||
|
font-size: 2vmin; /* οποιοδήποτε απο αυτα τα δύο είναι το μικρότερο */
|
||||||
|
font-size: 2vmax; /* ή το μεγαλύτερο */
|
||||||
|
|
||||||
|
/* Απόλυτες μονάδες */
|
||||||
|
width: 200px; /* pixels */
|
||||||
|
font-size: 20pt; /* στιγμες */
|
||||||
|
width: 5cm; /* εκατοστά */
|
||||||
|
min-width: 50mm; /* χιλιοστά */
|
||||||
|
max-width: 5in; /* ίντσες */
|
||||||
|
|
||||||
|
/* Χρώματα */
|
||||||
|
color: #F6E; /* σύντομη δεκαεξαδική μορφή */
|
||||||
|
color: #FF66EE; /* δεκαεξαδική μορφή */
|
||||||
|
color: tomato; /* χρώμα με το όνομα του (συγκεκριμένα χρώματα) */
|
||||||
|
color: rgb(255, 255, 255); /* τιμή RGB */
|
||||||
|
color: rgb(10%, 20%, 50%); /* τιμή RGB με ποσοστά */
|
||||||
|
color: rgba(255, 0, 0, 0.3); /* τιμή RGBA (CSS3) σσ. 0 < a < 1 */
|
||||||
|
color: transparent; /* όπως και το παραπάνω με a = 0 */
|
||||||
|
color: hsl(0, 100%, 50%); /* τιμή hsl με ποσοστά (CSS 3) */
|
||||||
|
color: hsla(0, 100%, 50%, 0.3); /* τιμή hsla με ποσοστά και a */
|
||||||
|
|
||||||
|
/* Εικόνες μπορούν να τοποθετηθούν στον φόντο ενός αντικειμένου */
|
||||||
|
background-image: url(/img-path/img.jpg);
|
||||||
|
|
||||||
|
/* Γραμματοσειρές */
|
||||||
|
font-family: Arial;
|
||||||
|
/* εάν η γραμματοσειρα περιέχει κενά */
|
||||||
|
font-family: "Courier New";
|
||||||
|
/* εάν η πρώτη γραμματοσειρα δε βρεθεί εγκατεστημένη στο Λειτουργικό Σύστυμα, αυτόματα
|
||||||
|
επιλέγετε η δεύτερη, κ.κ.ε. */
|
||||||
|
font-family: "Courier New", Trebuchet, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Χρήση
|
||||||
|
|
||||||
|
Αποθηκεύουμε ένα αρχείο CSS με την επέκταση `.css`.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- Πρέπει να συμπεριλάβουμε το αρχείο στην επικεφαλίδα(head) ενος HTML αρχείου.
|
||||||
|
σσ. http://stackoverflow.com/questions/8284365 -->
|
||||||
|
<link rel='stylesheet' type='text/css' href='path/to/style.css' />
|
||||||
|
|
||||||
|
<!-- Μπορούμε να το ενσωματώσουμε -->
|
||||||
|
<style>
|
||||||
|
a { color: purple; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Ή απευθείας σε κάποιο αντικείμενο (inline) -->
|
||||||
|
<div style="border: 1px solid red;">
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ειδικότητα των κανόνων (Cascading απο το αγγλικό τίτλο Cascading Style Sheets)
|
||||||
|
|
||||||
|
Ένα αντικείμενο μπορεί να στοχευθεί απο πολλούς κανόνες και μπορεί η ίδια ιδιότητα να
|
||||||
|
περιλαμβάνετε σε πολλούς κανόνες. Σε αυτές της περιπτώσεις υπερισχύει πάντα ο πιο ειδικός
|
||||||
|
κανόνας και απο αυτούς, αυτός που εμφανίζεται τελευταίος.
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* A */
|
||||||
|
p.class1[attr='value']
|
||||||
|
|
||||||
|
/* B */
|
||||||
|
p.class1 { }
|
||||||
|
|
||||||
|
/* C */
|
||||||
|
p.class2 { }
|
||||||
|
|
||||||
|
/* D */
|
||||||
|
p { }
|
||||||
|
|
||||||
|
/* E */
|
||||||
|
p { property: value !important; }
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<p style='/*F*/ property:value;' class='class1 class2' attr='value' />
|
||||||
|
```
|
||||||
|
|
||||||
|
Η σειρά θα είναι:
|
||||||
|
|
||||||
|
* `E` έχει μεγαλύτερο βάρος λόγω του `!important`. Κάλες πρακτικές λένε να το αποφεύγουμε.
|
||||||
|
* `F` επόμενο λόγω του inline κανόνα.
|
||||||
|
* `A` επόμενο λόγω του το οτι είναι πιο ειδικό. Περιέχει τρεις selectors.
|
||||||
|
* `C` επόμενο, λόγω του οτι εμφανίζεται μετα το Β και ας έχει την ίδια ειδικότητα.
|
||||||
|
* `B` επόμενο.
|
||||||
|
* `D` τελευταίο.
|
||||||
|
|
||||||
|
## Συμβατότητα
|
||||||
|
|
||||||
|
Τα περισσότερα απο τα παραπάνω ήδη υποστηρίζονται απο τους γνωστούς φυλλομετρητές. Άλλα θα πρέπει
|
||||||
|
πάντα να ελέγχουμε πρωτου τους χρησιμοποιήσουμε.
|
||||||
|
|
||||||
|
## Περισσότερα
|
||||||
|
|
||||||
|
* Έλεγχος συμβατότητας, [CanIUse](http://caniuse.com).
|
||||||
|
* CSS Playground [Dabblet](http://dabblet.com/).
|
||||||
|
* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS)
|
||||||
|
* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/)
|
||||||
|
|
||||||
|
## Μελέτη
|
||||||
|
|
||||||
|
* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/)
|
||||||
|
* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/)
|
||||||
|
* [QuirksMode CSS](http://www.quirksmode.org/css/)
|
||||||
|
* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context)
|
||||||
|
* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing
|
||||||
|
* [CSS-Tricks](https://css-tricks.com)
|
@ -31,12 +31,12 @@ H Racket είναι μια γενικού σκοπού, πολυ-υποδειγ
|
|||||||
|
|
||||||
;; Τα σχόλια S-expression (εκφράσεις S) comments απορρίπτουν την
|
;; Τα σχόλια S-expression (εκφράσεις S) comments απορρίπτουν την
|
||||||
;; έκφραση που ακολουθεί, δυνατότητα που είναι χρήσιμη για να
|
;; έκφραση που ακολουθεί, δυνατότητα που είναι χρήσιμη για να
|
||||||
;; κάνουμε σχόλια κάποιες εκφράσεις κατα τη διάρκεια του debugging
|
;; κάνουμε σχόλια κάποιες εκφράσεις κατά τη διάρκεια του debugging
|
||||||
|
|
||||||
#; (αυτή η έκφραση δεν θα εκτελεστεί)
|
#; (αυτή η έκφραση δεν θα εκτελεστεί)
|
||||||
|
|
||||||
;; (Αν δεν καταλαβαίνεται τι είναι οι εκφράσεις , περιμένετε... Θα το μάθουμε
|
;; (Αν δεν καταλαβαίνεται τι είναι οι εκφράσεις , περιμένετε... Θα το μάθουμε
|
||||||
;; πολύ συντομα!)
|
;; πολύ σύντομα!)
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
@ -57,8 +57,8 @@ H Racket είναι μια γενικού σκοπού, πολυ-υποδειγ
|
|||||||
;; όπου το f είναι η συνάρτηση και τα x y z
|
;; όπου το f είναι η συνάρτηση και τα x y z
|
||||||
;; είναι οι όροι που η συνάρτηση δέχεται
|
;; είναι οι όροι που η συνάρτηση δέχεται
|
||||||
;; ως ορίσματα. Αν θέλουμε να δημιουργήσουμε
|
;; ως ορίσματα. Αν θέλουμε να δημιουργήσουμε
|
||||||
;; μια λίστα στην κυριολεξία απο δίαφορα δεδομένα,
|
;; μια λίστα στην κυριολεξία από δίαφορα δεδομένα,
|
||||||
;; χρησιμοποιούμε το ' για να το εμποδίσουμε απο το να
|
;; χρησιμοποιούμε το ' για να το εμποδίσουμε από το να
|
||||||
;; αξιολογηθεί σαν έκφραση. Για παράδειγμα:
|
;; αξιολογηθεί σαν έκφραση. Για παράδειγμα:
|
||||||
'(+ 1 2) ; => Παραμένει (+ 1 2) και δεν γίνεται η πράξη
|
'(+ 1 2) ; => Παραμένει (+ 1 2) και δεν γίνεται η πράξη
|
||||||
;; Τώρα , ας κάνουμε μερικές πράξεις
|
;; Τώρα , ας κάνουμε μερικές πράξεις
|
||||||
@ -88,15 +88,15 @@ H Racket είναι μια γενικού σκοπού, πολυ-υποδειγ
|
|||||||
;;; Τα αλφαριθμητικά είναι πίνακες χαρακτήρων συγκεκριμένου μήκους
|
;;; Τα αλφαριθμητικά είναι πίνακες χαρακτήρων συγκεκριμένου μήκους
|
||||||
"Hello, world!"
|
"Hello, world!"
|
||||||
"Benjamin \"Bugsy\" Siegel" ; Το backslash είναι χαρακτήρας διαφυγής
|
"Benjamin \"Bugsy\" Siegel" ; Το backslash είναι χαρακτήρας διαφυγής
|
||||||
"Foo\tbar\41\x21\u0021\a\r\n" ; Συμπεριλαμβάνονται οι χαρακτήες διαφυγής της C,
|
"Foo\tbar\41\x21\u0021\a\r\n" ; Συμπεριλαμβάνονται οι χαρακτήρες διαφυγής της C,
|
||||||
; σε Unicode
|
; σε Unicode
|
||||||
"λx:(μα.α→α).xx" ; Μπορούν να υπάρχουν και Unicode χαρακτήρες
|
"λx:(μα.α→α).xx" ; Μπορούν να υπάρχουν και Unicode χαρακτήρες
|
||||||
|
|
||||||
;; Μπορούμε να εννώσουμε αλφαριθμητικά!
|
;; Μπορούμε να ενώσουμε αλφαριθμητικά!
|
||||||
(string-append "Hello " "world!") ; => "Hello world!"
|
(string-append "Hello " "world!") ; => "Hello world!"
|
||||||
|
|
||||||
;; Ένα αλφαριθμητικό μπορούμε να το χρησιμοπιησουμε
|
;; Ένα αλφαριθμητικό μπορούμε να το χρησιμοποιήσουμε
|
||||||
;; όπως και μια λίστα απο χαρακτήρες
|
;; όπως και μια λίστα από χαρακτήρες
|
||||||
(string-ref "Apple" 0) ; => #\A ;; Παίρνουμε το πρώτο στοιχείο
|
(string-ref "Apple" 0) ; => #\A ;; Παίρνουμε το πρώτο στοιχείο
|
||||||
|
|
||||||
;; Η συνάρτηση format μπορεί να χρησιμοποιηθεί για
|
;; Η συνάρτηση format μπορεί να χρησιμοποιηθεί για
|
||||||
@ -117,18 +117,18 @@ H Racket είναι μια γενικού σκοπού, πολυ-υποδειγ
|
|||||||
some-var ; => 5
|
some-var ; => 5
|
||||||
|
|
||||||
;; Μπορούμε επίσης να χρησιμοποιήσουμε unicode χαρακτήρες.
|
;; Μπορούμε επίσης να χρησιμοποιήσουμε unicode χαρακτήρες.
|
||||||
(define ⊆ subset?) ;; Εδώ ουστιαστικά δίνουμε στη ήδη ύπαρχουσα συνάρτηση subset?
|
(define ⊆ subset?) ;; Εδώ ουσιαστικά δίνουμε στη ήδη υπάρχουσα συνάρτηση subset?
|
||||||
;; ένα νέο όνομα ⊆ , και παρακάτω την καλούμε με το νέο της όνομα.
|
;; ένα νέο όνομα ⊆ , και παρακάτω την καλούμε με το νέο της όνομα.
|
||||||
(⊆ (set 3 2) (set 1 2 3)) ; => #t
|
(⊆ (set 3 2) (set 1 2 3)) ; => #t
|
||||||
|
|
||||||
;; Αν ζητήσουμε μια μεταβλητή που δεν έχει οριστεί πρίν π.χ
|
;; Αν ζητήσουμε μια μεταβλητή που δεν έχει οριστεί πριν π.χ.
|
||||||
(printf name)
|
(printf name)
|
||||||
;; θα πάρουμε το παρακάτω μήνυμα
|
;; θα πάρουμε το παρακάτω μήνυμα
|
||||||
;name: undefined;
|
;name: undefined;
|
||||||
; cannot reference undefined identifier
|
; cannot reference undefined identifier
|
||||||
; context...:
|
; context...:
|
||||||
|
|
||||||
;; Η τοπική δέσμευση : `me' δευσμεύεται με το "Bob" μόνο μέσα στο (let ...)
|
;; Η τοπική δέσμευση : `me' δεσμεύεται με το "Bob" μόνο μέσα στο (let ...)
|
||||||
(let ([me "Bob"])
|
(let ([me "Bob"])
|
||||||
"Alice"
|
"Alice"
|
||||||
me) ; => "Bob"
|
me) ; => "Bob"
|
||||||
@ -156,7 +156,7 @@ my-pet ; => #<dog>
|
|||||||
;;; Λίστες
|
;;; Λίστες
|
||||||
|
|
||||||
;; Οι λίστες είναι linked-list δομές δεδομένων,
|
;; Οι λίστες είναι linked-list δομές δεδομένων,
|
||||||
;; που έχουν δημιουργηθεί απο ζευγάρια 'cons'
|
;; που έχουν δημιουργηθεί από ζευγάρια 'cons'
|
||||||
;; και τελειώνουν με 'null' (ή αλλιώς '()) για να
|
;; και τελειώνουν με 'null' (ή αλλιώς '()) για να
|
||||||
;; δηλώσουν ότι αυτό είναι το τέλος της λίστας
|
;; δηλώσουν ότι αυτό είναι το τέλος της λίστας
|
||||||
(cons 1 (cons 2 (cons 3 null))) ; => '(1 2 3)
|
(cons 1 (cons 2 (cons 3 null))) ; => '(1 2 3)
|
||||||
@ -191,12 +191,12 @@ my-pet ; => #<dog>
|
|||||||
;; Τα διανύσματα είναι πίνακες σταθερού μήκους
|
;; Τα διανύσματα είναι πίνακες σταθερού μήκους
|
||||||
#(1 2 3) ; => '#(1 2 3)
|
#(1 2 3) ; => '#(1 2 3)
|
||||||
|
|
||||||
;; Χρησιμοποιύμε το `vector-append' για να προσθέσουμε διανύσματα
|
;; Χρησιμοποιούμε το `vector-append' για να προσθέσουμε διανύσματα
|
||||||
(vector-append #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
|
(vector-append #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
|
||||||
|
|
||||||
;;; Σύνολα
|
;;; Σύνολα
|
||||||
|
|
||||||
;; Δημιουργούμε ένα σύνολο απο μία λίστα
|
;; Δημιουργούμε ένα σύνολο από μία λίστα
|
||||||
(list->set '(1 2 3 1 2 3 3 2 1 3 2 1)) ; => (set 1 2 3)
|
(list->set '(1 2 3 1 2 3 3 2 1 3 2 1)) ; => (set 1 2 3)
|
||||||
|
|
||||||
;; Προσθέτουμε έναν αριθμό στο σύνολο χρησιμοποιώντας το `set-add'
|
;; Προσθέτουμε έναν αριθμό στο σύνολο χρησιμοποιώντας το `set-add'
|
||||||
@ -214,10 +214,10 @@ my-pet ; => #<dog>
|
|||||||
;; Δημιουργήστε ένα αμετάβλητο πίνακα κατακερματισμού
|
;; Δημιουργήστε ένα αμετάβλητο πίνακα κατακερματισμού
|
||||||
(define m (hash 'a 1 'b 2 'c 3))
|
(define m (hash 'a 1 'b 2 'c 3))
|
||||||
|
|
||||||
;; Παίρνουμε μια τιμή απο τον πίνακα
|
;; Παίρνουμε μια τιμή από τον πίνακα
|
||||||
(hash-ref m 'a) ; => 1
|
(hash-ref m 'a) ; => 1
|
||||||
|
|
||||||
;; Άν ζητήσουμε μια τιμή που δέν υπάρχει παίρνουμε μία εξαίρεση
|
;; Αν ζητήσουμε μια τιμή που δεν υπάρχει παίρνουμε μία εξαίρεση
|
||||||
; (hash-ref m 'd) => no value found for key
|
; (hash-ref m 'd) => no value found for key
|
||||||
|
|
||||||
;; Μπορούμε να δώσουμε μια default τιμή για τα κλειδιά που λείπουν
|
;; Μπορούμε να δώσουμε μια default τιμή για τα κλειδιά που λείπουν
|
||||||
@ -234,7 +234,7 @@ m2 ; => '#hash((b . 2) (a . 1) (d . 4) (c . 3))
|
|||||||
m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
|
m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
|
||||||
|
|
||||||
;; Χρησιμοποιούμε το `hash-remove' για να αφαιρέσουμε
|
;; Χρησιμοποιούμε το `hash-remove' για να αφαιρέσουμε
|
||||||
;; κλειδία
|
;; κλειδιά
|
||||||
(hash-remove m 'a) ; => '#hash((b . 2) (c . 3))
|
(hash-remove m 'a) ; => '#hash((b . 2) (c . 3))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
@ -247,12 +247,12 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
|
|||||||
;; Μπορούμε επίσης να χρησιμοποιήσουμε το `λ'
|
;; Μπορούμε επίσης να χρησιμοποιήσουμε το `λ'
|
||||||
(λ () "Hello World") ; => Ίδια συνάρτηση
|
(λ () "Hello World") ; => Ίδια συνάρτηση
|
||||||
|
|
||||||
;; Χρησιμοποιύμε τις παρενθέσεις για να καλέσουμε όλες τις συναρτήσεις
|
;; Χρησιμοποιούμε τις παρενθέσεις για να καλέσουμε όλες τις συναρτήσεις
|
||||||
;; συμπεριλαμβανομένων και των εκφράσεων 'λάμδα'
|
;; συμπεριλαμβανομένων και των εκφράσεων 'λάμδα'
|
||||||
((lambda () "Hello World")) ; => "Hello World"
|
((lambda () "Hello World")) ; => "Hello World"
|
||||||
((λ () "Hello World")) ; => "Hello World"
|
((λ () "Hello World")) ; => "Hello World"
|
||||||
|
|
||||||
;; Εκχωρούμε σε μια μετάβλητη την συνάρτηση
|
;; Εκχωρούμε σε μια μεταβλητή την συνάρτηση
|
||||||
(define hello-world (lambda () "Hello World"))
|
(define hello-world (lambda () "Hello World"))
|
||||||
(hello-world) ; => "Hello World"
|
(hello-world) ; => "Hello World"
|
||||||
|
|
||||||
@ -302,7 +302,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
|
|||||||
(lambda (name . args)
|
(lambda (name . args)
|
||||||
(format "Hello ~a, you passed ~a extra args" name (length args))))
|
(format "Hello ~a, you passed ~a extra args" name (length args))))
|
||||||
|
|
||||||
;; Και με λέξεις κλειδία
|
;; Και με λέξεις κλειδιά
|
||||||
(define (hello-k #:name [name "World"] #:greeting [g "Hello"] . args)
|
(define (hello-k #:name [name "World"] #:greeting [g "Hello"] . args)
|
||||||
(format "~a ~a, ~a extra args" g name (length args)))
|
(format "~a ~a, ~a extra args" g name (length args)))
|
||||||
(hello-k) ; => "Hello World, 0 extra args"
|
(hello-k) ; => "Hello World, 0 extra args"
|
||||||
@ -347,7 +347,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
|
|||||||
|
|
||||||
(eq? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #f
|
(eq? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #f
|
||||||
|
|
||||||
;; Το `eqv?' υποστηρίζει την σύκριση αριθμών αλλα και χαρακτήρων
|
;; Το `eqv?' υποστηρίζει την σύγκριση αριθμών αλλά και χαρακτήρων
|
||||||
;; Για άλλα ήδη μεταβλητών το `eqv?' και το `eq?' επιστρέφουν το ίδιο.
|
;; Για άλλα ήδη μεταβλητών το `eqv?' και το `eq?' επιστρέφουν το ίδιο.
|
||||||
(eqv? 3 3.0) ; => #f
|
(eqv? 3 3.0) ; => #f
|
||||||
(eqv? (expt 2 100) (expt 2 100)) ; => #t
|
(eqv? (expt 2 100) (expt 2 100)) ; => #t
|
||||||
@ -365,12 +365,12 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
|
|||||||
(equal? (list 3) (list 3)) ; => #t
|
(equal? (list 3) (list 3)) ; => #t
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; 5. Έλεχγος Ροής
|
;; 5. Έλεγχος Ροής
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;;; Συνθήκες (conditionals)
|
;;; Συνθήκες (conditionals)
|
||||||
|
|
||||||
(if #t ; έκφραση ελέχγου
|
(if #t ; έκφραση ελέγχου
|
||||||
"this is true" ; έκφραση then
|
"this is true" ; έκφραση then
|
||||||
"this is false") ; έκφραση else
|
"this is false") ; έκφραση else
|
||||||
; => "this is true"
|
; => "this is true"
|
||||||
@ -483,7 +483,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
|
|||||||
(values i (number->string i)))
|
(values i (number->string i)))
|
||||||
; => '#hash((1 . "1") (2 . "2") (3 . "3"))
|
; => '#hash((1 . "1") (2 . "2") (3 . "3"))
|
||||||
|
|
||||||
;; Υπάρχουν πολλά είδη απο προϋπάρχοντες τρόπους για να συλλέγουμε
|
;; Υπάρχουν πολλά είδη από προϋπάρχοντες τρόπους για να συλλέγουμε
|
||||||
;; τιμές από τους βρόχους
|
;; τιμές από τους βρόχους
|
||||||
|
|
||||||
(for/sum ([i 10]) (* i i)) ; => 285
|
(for/sum ([i 10]) (* i i)) ; => 285
|
||||||
@ -491,7 +491,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
|
|||||||
(for/and ([i 10] [j (in-range 10 20)]) (< i j)) ; => #t
|
(for/and ([i 10] [j (in-range 10 20)]) (< i j)) ; => #t
|
||||||
(for/or ([i 10] [j (in-range 0 20 2)]) (= i j)) ; => #t
|
(for/or ([i 10] [j (in-range 0 20 2)]) (= i j)) ; => #t
|
||||||
|
|
||||||
;; Και για να χρησιμοποιήσουμε ένα αφθαίρετο συνδιασμό χρησιμοποιούμε
|
;; Και για να χρησιμοποιήσουμε ένα αυθαίρετο συνδυασμό χρησιμοποιούμε
|
||||||
;; το 'for/fold'
|
;; το 'for/fold'
|
||||||
(for/fold ([sum 0]) ([i '(1 2 3 4)]) (+ sum i)) ; => 10
|
(for/fold ([sum 0]) ([i '(1 2 3 4)]) (+ sum i)) ; => 10
|
||||||
|
|
||||||
@ -524,17 +524,17 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- δεν υπάρχει `d'
|
|||||||
(set! n (add1 n))
|
(set! n (add1 n))
|
||||||
n ; => 6
|
n ; => 6
|
||||||
|
|
||||||
;; Χρησιμοποιούμε τα boxes για να δηλώσουμε ρητά ότι μια μεταβητή
|
;; Χρησιμοποιούμε τα boxes για να δηλώσουμε ρητά ότι μια μεταβλητή
|
||||||
;; θα είναι mutable (θα μπορεί να αλλάξη η τιμή της)
|
;; θα είναι mutable (θα μπορεί να αλλάξει η τιμή της)
|
||||||
;; Αυτό είναι παρόμοιο με τους pointers σε άλλες γλώσσες
|
;; Αυτό είναι παρόμοιο με τους pointers σε άλλες γλώσσες
|
||||||
(define n* (box 5))
|
(define n* (box 5))
|
||||||
(set-box! n* (add1 (unbox n*)))
|
(set-box! n* (add1 (unbox n*)))
|
||||||
(unbox n*) ; => 6
|
(unbox n*) ; => 6
|
||||||
|
|
||||||
|
|
||||||
;; Πολλοί τύποι μεταβλητών στη Racket είναι αμετάβλητοι πχ τα ζεύγη, οι
|
;; Πολλοί τύποι μεταβλητών στη Racket είναι αμετάβλητοι π.χ. τα ζεύγη, οι
|
||||||
;; λίστες κτλ. Άλλοι υπάρχουν και σε μεταβλητή και σε αμετάβλητη μορφή
|
;; λίστες κτλ. Άλλοι υπάρχουν και σε μεταβλητή και σε αμετάβλητη μορφή
|
||||||
;; πχ αλφαριθμητικά, διανύσματα κτλ
|
;; π.χ. αλφαριθμητικά, διανύσματα κτλ.
|
||||||
(define vec (vector 2 2 3 4))
|
(define vec (vector 2 2 3 4))
|
||||||
(define wall (make-vector 100 'bottle-of-beer))
|
(define wall (make-vector 100 'bottle-of-beer))
|
||||||
;; Χρησιμοποιούμε το 'vector-set!' για να ανεώσουμε κάποια
|
;; Χρησιμοποιούμε το 'vector-set!' για να ανεώσουμε κάποια
|
||||||
@ -579,7 +579,7 @@ vec ; => #(1 2 3 4)
|
|||||||
(printf fmt (make-string n ch))
|
(printf fmt (make-string n ch))
|
||||||
(newline)))
|
(newline)))
|
||||||
|
|
||||||
;; Χρησιμοποιομε το 'require' για να πάρουμε όλα τα
|
;; Χρησιμοποιουμε το 'require' για να πάρουμε όλα τα
|
||||||
;; παρεχόμενα ονόματα από μία ενότητα
|
;; παρεχόμενα ονόματα από μία ενότητα
|
||||||
(require 'cake) ; το ' είναι για τοπική υποενότητα
|
(require 'cake) ; το ' είναι για τοπική υποενότητα
|
||||||
(print-cake 3)
|
(print-cake 3)
|
||||||
@ -634,7 +634,7 @@ vec ; => #(1 2 3 4)
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;; Οι μακροεντολές μας επιτρέπουν να επεκτείνουμε
|
;; Οι μακροεντολές μας επιτρέπουν να επεκτείνουμε
|
||||||
;; το συντακτικό μιάς γλώσσας.
|
;; το συντακτικό μιας γλώσσας.
|
||||||
|
|
||||||
;; Ας προσθέσουμε έναν βρόχο while
|
;; Ας προσθέσουμε έναν βρόχο while
|
||||||
(define-syntax-rule (while condition body ...)
|
(define-syntax-rule (while condition body ...)
|
||||||
@ -664,20 +664,20 @@ vec ; => #(1 2 3 4)
|
|||||||
;; (set! tmp other)
|
;; (set! tmp other)
|
||||||
;; (set! other tmp_1))
|
;; (set! other tmp_1))
|
||||||
|
|
||||||
;; Αλλά ακόμα υπάρχουν ακόμη μετασχηματισμοί του κώδικα, π.χ:
|
;; Αλλά ακόμα υπάρχουν ακόμη μετασχηματισμοί του κώδικα, π.χ.:
|
||||||
(define-syntax-rule (bad-while condition body ...)
|
(define-syntax-rule (bad-while condition body ...)
|
||||||
(when condition
|
(when condition
|
||||||
body ...
|
body ...
|
||||||
(bad-while condition body ...)))
|
(bad-while condition body ...)))
|
||||||
;; αυτή η μακροεντολή είναι χαλασμένη: δημιουγεί ατέρμονα βρόχο
|
;; αυτή η μακροεντολή είναι χαλασμένη: δημιουργεί ατέρμονα βρόχο
|
||||||
;; και αν προσπαθήσουμε να το χρησιμοποιήσουμε, ο μεταγλωττιστής
|
;; και αν προσπαθήσουμε να το χρησιμοποιήσουμε, ο μεταγλωττιστής
|
||||||
;; θα μπεί στον ατέρμονα βρόχο.
|
;; θα μπει στον ατέρμονα βρόχο.
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; 10. Συμβόλαια (Contracts)
|
;; 10. Συμβόλαια (Contracts)
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;; Τα συμβόλαια βάζουν περιορισμόυς σε τιμές που προέρχονται
|
;; Τα συμβόλαια βάζουν περιορισμούς σε τιμές που προέρχονται
|
||||||
;; από ενότητες (modules)
|
;; από ενότητες (modules)
|
||||||
(module bank-account racket
|
(module bank-account racket
|
||||||
(provide (contract-out
|
(provide (contract-out
|
||||||
@ -719,7 +719,7 @@ vec ; => #(1 2 3 4)
|
|||||||
(displayln "Hola mundo" out-port)
|
(displayln "Hola mundo" out-port)
|
||||||
(close-output-port out-port)
|
(close-output-port out-port)
|
||||||
|
|
||||||
;; Διαβάζουμε απο αρχείο ξανά
|
;; Διαβάζουμε από αρχείο ξανά
|
||||||
(define in-port (open-input-file "/tmp/tmp.txt"))
|
(define in-port (open-input-file "/tmp/tmp.txt"))
|
||||||
(displayln (read-line in-port))
|
(displayln (read-line in-port))
|
||||||
; => "Hello World"
|
; => "Hello World"
|
||||||
|
@ -40,7 +40,7 @@ Scala - Η επεκτάσιμη γλώσσα
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Τα σχόλια που επεκτείνονται σε πολλές γραμμές , όπως μπορείτε
|
Τα σχόλια που επεκτείνονται σε πολλές γραμμές , όπως μπορείτε
|
||||||
να δείτε , φαίνοται κάπως έτσι.
|
να δείτε , φαίνονται κάπως έτσι.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Εκτύπωση με νέα γραμμή στην επόμενη εκτύπωση
|
// Εκτύπωση με νέα γραμμή στην επόμενη εκτύπωση
|
||||||
@ -59,12 +59,12 @@ var y = 10
|
|||||||
y = 20 // το y είναι τώρα 20
|
y = 20 // το y είναι τώρα 20
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Η Scala είναι στατικού τύπου γλώσσα, εν τούτις προσέξτε ότι στις παραπάνω
|
Η Scala είναι στατικού τύπου γλώσσα, εν τούτοις προσέξτε ότι στις παραπάνω
|
||||||
δηλώσεις , δεν προσδιορίσαμε κάποιον τύπο. Αυτό συμβαίνει λόγω ενός
|
δηλώσεις , δεν προσδιορίσαμε κάποιον τύπο. Αυτό συμβαίνει λόγω ενός
|
||||||
χαρακτηριστικού της Scala που λέγεται συμπερασματολογία τύπων. Στις
|
χαρακτηριστικού της Scala που λέγεται συμπερασματολογία τύπων. Στις
|
||||||
περισσότερες των περιπτώσεων, ο μεταγλωττιστής της Scala μπορεί να
|
περισσότερες των περιπτώσεων, ο μεταγλωττιστής της Scala μπορεί να
|
||||||
μαντέψει ποιός είναι ο τύπος μιας μεταβλητής. Μπορούμε να δηλώσουμε
|
μαντέψει ποιος είναι ο τύπος μιας μεταβλητής. Μπορούμε να δηλώσουμε
|
||||||
αναλυτικά τον τύπο μιάς μεταβλητής ως εξής:
|
αναλυτικά τον τύπο μιας μεταβλητής ως εξής:
|
||||||
*/
|
*/
|
||||||
val z: Int = 10
|
val z: Int = 10
|
||||||
val a: Double = 1.0
|
val a: Double = 1.0
|
||||||
@ -85,7 +85,7 @@ false
|
|||||||
true == false // false
|
true == false // false
|
||||||
10 > 5 // true
|
10 > 5 // true
|
||||||
|
|
||||||
// Η αριθμιτική είναι όπως τα συνηθισμένα
|
// Η αριθμητική είναι όπως τα συνηθισμένα
|
||||||
1 + 1 // 2
|
1 + 1 // 2
|
||||||
2 - 1 // 1
|
2 - 1 // 1
|
||||||
5 * 3 // 15
|
5 * 3 // 15
|
||||||
@ -117,14 +117,14 @@ true == false // false
|
|||||||
"Τα αλφαριθμητικά στην Scala περικλείονται από διπλά εισαγωγικά"
|
"Τα αλφαριθμητικά στην Scala περικλείονται από διπλά εισαγωγικά"
|
||||||
'a' // Ένας χαρακτήρας στην Scala
|
'a' // Ένας χαρακτήρας στην Scala
|
||||||
// res30: Char = a
|
// res30: Char = a
|
||||||
// 'Αλφαριθημτικά με μονά εισαγωγικά δεν υφίστανται <= Αυτό θα προκαλέσει σφάλμα.
|
// Αλφαριθημτικά με μονά εισαγωγικά δεν υφίστανται <= Αυτό θα προκαλέσει σφάλμα.
|
||||||
|
|
||||||
// Τα αλφαριθμητικά έχουν τις συνηθισμένες μεθόδους της Java ορισμένες πάνω τους.
|
// Τα αλφαριθμητικά έχουν τις συνηθισμένες μεθόδους της Java ορισμένες πάνω τους.
|
||||||
"hello world".length
|
"hello world".length
|
||||||
"hello world".substring(2, 6)
|
"hello world".substring(2, 6)
|
||||||
"hello world".replace("C", "3")
|
"hello world".replace("C", "3")
|
||||||
|
|
||||||
// Έχουν επίσης μερικές επιπλένον μεθόδους Scala.
|
// Έχουν επίσης μερικές επιπλέον μεθόδους Scala.
|
||||||
// Δείτε επίσης : scala.collection.immutable.StringOps
|
// Δείτε επίσης : scala.collection.immutable.StringOps
|
||||||
"hello world".take(5)
|
"hello world".take(5)
|
||||||
"hello world".drop(5)
|
"hello world".drop(5)
|
||||||
@ -253,7 +253,7 @@ r foreach println
|
|||||||
var i = 0
|
var i = 0
|
||||||
while (i < 10) { println("i " + i); i+=1 }
|
while (i < 10) { println("i " + i); i+=1 }
|
||||||
|
|
||||||
while (i < 10) { println("i " + i); i+=1 } // Ναι ξανά! Τι συνέβει; Γιατί;
|
while (i < 10) { println("i " + i); i+=1 } // Ναι ξανά! Τι συνέβη; Γιατί;
|
||||||
|
|
||||||
i // Εμφάνισε την τιμή του i. Σημειώστε ότι ένας βρόχος while είναι βρόχος
|
i // Εμφάνισε την τιμή του i. Σημειώστε ότι ένας βρόχος while είναι βρόχος
|
||||||
// με την κλασική έννοια - εκτελείται σειριακά καθώς αλλάζει η μεταβλητή
|
// με την κλασική έννοια - εκτελείται σειριακά καθώς αλλάζει η μεταβλητή
|
||||||
@ -268,8 +268,8 @@ do {
|
|||||||
} while (x < 10)
|
} while (x < 10)
|
||||||
|
|
||||||
// Η αναδρομή ουράς είναι ένας ιδιωματικός τρόπος να κάνεις επαναλαμβανόμενα
|
// Η αναδρομή ουράς είναι ένας ιδιωματικός τρόπος να κάνεις επαναλαμβανόμενα
|
||||||
// πράγματα στην Scala. Οι αναδρομικές συναρτήσεις απαιτούν να γράφτεί
|
// πράγματα στην Scala. Οι αναδρομικές συναρτήσεις απαιτούν να γραφτεί
|
||||||
// ρητά ο τύπος που θα επιστρέψουν , αλλιώς ο μεταγλωττιστής δεν μπορεί
|
// ρητά ο τύπος που θα επιστρέψουν, αλλιώς ο μεταγλωττιστής δεν μπορεί
|
||||||
// αλλιώς να τον συνάγει. Παρακάτω είναι μια συνάρτηση που επιστρέφει Unit.
|
// αλλιώς να τον συνάγει. Παρακάτω είναι μια συνάρτηση που επιστρέφει Unit.
|
||||||
def showNumbersInRange(a:Int, b:Int):Unit = {
|
def showNumbersInRange(a:Int, b:Int):Unit = {
|
||||||
print(a)
|
print(a)
|
||||||
@ -332,7 +332,7 @@ s(1)
|
|||||||
val divideInts = (x:Int, y:Int) => (x / y, x % y)
|
val divideInts = (x:Int, y:Int) => (x / y, x % y)
|
||||||
|
|
||||||
divideInts(10,3) // Η συνάρτηση divideInts επιστρέφει το αποτέλεσμα
|
divideInts(10,3) // Η συνάρτηση divideInts επιστρέφει το αποτέλεσμα
|
||||||
// της ακαίρεας διαίρεσης και το υπόλοιπο.
|
// της ακέραιας διαίρεσης και το υπόλοιπο.
|
||||||
|
|
||||||
// Για να έχουμε πρόσβαση στα στοιχεία μιας πλειάδας, χρησιμοποιούμε το _._n
|
// Για να έχουμε πρόσβαση στα στοιχεία μιας πλειάδας, χρησιμοποιούμε το _._n
|
||||||
// όπου το n είναι ο δείκτης με βάση το 1 του στοιχείου.
|
// όπου το n είναι ο δείκτης με βάση το 1 του στοιχείου.
|
||||||
@ -349,7 +349,7 @@ d._2
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Ότι έχουμε κάνει ως τώρα σε αυτό το tutorial ήταν απλές εκφράσεις
|
Ότι έχουμε κάνει ως τώρα σε αυτό το tutorial ήταν απλές εκφράσεις
|
||||||
(τιμές , συναρτήσεις , κτλ). Αυτές οι εκφράσεις βολεύουν όταν τις
|
(τιμές, συναρτήσεις, κτλ.). Αυτές οι εκφράσεις βολεύουν όταν τις
|
||||||
γράφουμε στο REPL για γρήγορες δοκιμές, αλλά δεν μπορούν να υπάρχουν
|
γράφουμε στο REPL για γρήγορες δοκιμές, αλλά δεν μπορούν να υπάρχουν
|
||||||
από μόνες τους σε ένα αρχείο Scala. Για παράδειγμα , δεν μπορούμε να
|
από μόνες τους σε ένα αρχείο Scala. Για παράδειγμα , δεν μπορούμε να
|
||||||
έχουμε μόνο ένα "val x = 5" στο αρχείο Scala. Αντί αυτού , τα μόνα
|
έχουμε μόνο ένα "val x = 5" στο αρχείο Scala. Αντί αυτού , τα μόνα
|
||||||
@ -394,7 +394,7 @@ println(mydog.bark) // => "Woof, woof!"
|
|||||||
// αυτές καθ' αυτές, αλλά η συμπρεριφορά που σχετίζεται με όλα τα instances
|
// αυτές καθ' αυτές, αλλά η συμπρεριφορά που σχετίζεται με όλα τα instances
|
||||||
// της κλάσης πάνε μέσα στο object. Η διαφορά είναι παρόμοια με τις
|
// της κλάσης πάνε μέσα στο object. Η διαφορά είναι παρόμοια με τις
|
||||||
// μεθόδους κλάσεων σε σχέση με στατικές μεθόδους σε άλλες γλώσσες.
|
// μεθόδους κλάσεων σε σχέση με στατικές μεθόδους σε άλλες γλώσσες.
|
||||||
// Προσέξτε οτι τα objects και οι κλάσεις μπορούν να έχουν το ίδιο όνομα.
|
// Προσέξτε ότι τα objects και οι κλάσεις μπορούν να έχουν το ίδιο όνομα.
|
||||||
object Dog {
|
object Dog {
|
||||||
def allKnownBreeds = List("pitbull", "shepherd", "retriever")
|
def allKnownBreeds = List("pitbull", "shepherd", "retriever")
|
||||||
def createDog(breed: String) = new Dog(breed)
|
def createDog(breed: String) = new Dog(breed)
|
||||||
@ -402,7 +402,7 @@ object Dog {
|
|||||||
|
|
||||||
// Οι κλάσεις περίπτωσης (case classes) είναι που έχουν την επιπλέον
|
// Οι κλάσεις περίπτωσης (case classes) είναι που έχουν την επιπλέον
|
||||||
// λειτουργικότητα ενσωματωμένη. Μιά συνήθης ερώτηση για αρχάριους στην
|
// λειτουργικότητα ενσωματωμένη. Μιά συνήθης ερώτηση για αρχάριους στην
|
||||||
// Scala είναι πότε να χρησιμοπούνται κλάσεις και πότε case κλάσεις.
|
// Scala είναι πότε να χρησιμοποιούνται κλάσεις και πότε case κλάσεις.
|
||||||
// Γενικά οι κλάσεις τείνουν να εστιάζουν στην ενθυλάκωση, τον
|
// Γενικά οι κλάσεις τείνουν να εστιάζουν στην ενθυλάκωση, τον
|
||||||
// πολυμορφισμό και τη συμπεριφορά. Οι τιμές μέσα σε αυτές τις κλάσεις
|
// πολυμορφισμό και τη συμπεριφορά. Οι τιμές μέσα σε αυτές τις κλάσεις
|
||||||
// τείνουν να είναι private , και μόνο οι μέθοδοι είναι εκτεθειμένες.
|
// τείνουν να είναι private , και μόνο οι μέθοδοι είναι εκτεθειμένες.
|
||||||
@ -411,7 +411,7 @@ object Dog {
|
|||||||
// έχουν παρενέργειες.
|
// έχουν παρενέργειες.
|
||||||
case class Person(name: String, phoneNumber: String)
|
case class Person(name: String, phoneNumber: String)
|
||||||
|
|
||||||
// Δημιουργία ενός instance. Πραρατηρήστε ότι τα case classes
|
// Δημιουργία ενός instance. Παρατηρήστε ότι τα case classes
|
||||||
// δεν χρειάζονται την λέξη "new" .
|
// δεν χρειάζονται την λέξη "new" .
|
||||||
val george = Person("George", "1234")
|
val george = Person("George", "1234")
|
||||||
val kate = Person("Kate", "4567")
|
val kate = Person("Kate", "4567")
|
||||||
@ -419,7 +419,7 @@ val kate = Person("Kate", "4567")
|
|||||||
// Με τα case classes, παίρνεις μερικά προνόμια δωρεάν , όπως:
|
// Με τα case classes, παίρνεις μερικά προνόμια δωρεάν , όπως:
|
||||||
george.phoneNumber // => "1234"
|
george.phoneNumber // => "1234"
|
||||||
|
|
||||||
// Ελέχγεται η ισότητα για κάθε πεδίο (δεν χρειάζεται να
|
// Ελέγχεται η ισότητα για κάθε πεδίο (δεν χρειάζεται να
|
||||||
// κάνουμε override στο .equals)
|
// κάνουμε override στο .equals)
|
||||||
Person("George", "1234") == Person("Kate", "1236") // => false
|
Person("George", "1234") == Person("Kate", "1236") // => false
|
||||||
|
|
||||||
@ -509,7 +509,7 @@ List(1, 2, 3) map (x => x + 10)
|
|||||||
// ένα όρισμα στην ανώνυμη συνάρτηση. Έτσι δεσμεύεται ως η μεταβλητή.
|
// ένα όρισμα στην ανώνυμη συνάρτηση. Έτσι δεσμεύεται ως η μεταβλητή.
|
||||||
List(1, 2, 3) map (_ + 10)
|
List(1, 2, 3) map (_ + 10)
|
||||||
|
|
||||||
// Αν το μπλόκ της ανώνυμης συνάρτησης ΚΑΙ η συνάρτηση που εφαρμόζεται
|
// Αν το μπλοκ της ανώνυμης συνάρτησης ΚΑΙ η συνάρτηση που εφαρμόζεται
|
||||||
// (στην περίπτωσή μας το foreach και το println) παίρνουν ένα όρισμα
|
// (στην περίπτωσή μας το foreach και το println) παίρνουν ένα όρισμα
|
||||||
// μπορείτε να παραλείψετε την κάτω παύλα.
|
// μπορείτε να παραλείψετε την κάτω παύλα.
|
||||||
List("Dom", "Bob", "Natalia") foreach println
|
List("Dom", "Bob", "Natalia") foreach println
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
language: elisp
|
language: elisp
|
||||||
contributors:
|
contributors:
|
||||||
- ["Bastien Guerry", "http://bzg.fr"]
|
- ["Bastien Guerry", "http://bzg.fr"]
|
||||||
|
- ["Saurabh Sandav", "http://github.com/SaurabhSandav"]
|
||||||
filename: learn-emacs-lisp.el
|
filename: learn-emacs-lisp.el
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ filename: learn-emacs-lisp.el
|
|||||||
;;
|
;;
|
||||||
;; Going through this tutorial won't damage your computer unless
|
;; Going through this tutorial won't damage your computer unless
|
||||||
;; you get so angry that you throw it on the floor. In that case,
|
;; you get so angry that you throw it on the floor. In that case,
|
||||||
;; I hereby decline any responsability. Have fun!
|
;; I hereby decline any responsibility. Have fun!
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;
|
;;
|
||||||
|
@ -343,6 +343,7 @@ rescue
|
|||||||
RuntimeError -> "rescued a runtime error"
|
RuntimeError -> "rescued a runtime error"
|
||||||
_error -> "this will rescue any error"
|
_error -> "this will rescue any error"
|
||||||
end
|
end
|
||||||
|
#=> "rescued a runtime error"
|
||||||
|
|
||||||
# All exceptions have a message
|
# All exceptions have a message
|
||||||
try do
|
try do
|
||||||
@ -351,6 +352,7 @@ rescue
|
|||||||
x in [RuntimeError] ->
|
x in [RuntimeError] ->
|
||||||
x.message
|
x.message
|
||||||
end
|
end
|
||||||
|
#=> "some error"
|
||||||
|
|
||||||
## ---------------------------
|
## ---------------------------
|
||||||
## -- Concurrency
|
## -- Concurrency
|
||||||
@ -369,6 +371,13 @@ spawn(f) #=> #PID<0.40.0>
|
|||||||
# messages to the process. To do message passing we use the `send` operator.
|
# messages to the process. To do message passing we use the `send` operator.
|
||||||
# For all of this to be useful we need to be able to receive messages. This is
|
# For all of this to be useful we need to be able to receive messages. This is
|
||||||
# achieved with the `receive` mechanism:
|
# achieved with the `receive` mechanism:
|
||||||
|
|
||||||
|
# The `receive do` block is used to listen for messages and process
|
||||||
|
# them when they are received. A `receive do` block will only
|
||||||
|
# process one received message. In order to process multiple
|
||||||
|
# messages, a function with a `receive do` block must recursively
|
||||||
|
# call itself to get into the `receive do` block again.
|
||||||
|
|
||||||
defmodule Geometry do
|
defmodule Geometry do
|
||||||
def area_loop do
|
def area_loop do
|
||||||
receive do
|
receive do
|
||||||
@ -384,6 +393,8 @@ end
|
|||||||
|
|
||||||
# Compile the module and create a process that evaluates `area_loop` in the shell
|
# Compile the module and create a process that evaluates `area_loop` in the shell
|
||||||
pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
|
pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
|
||||||
|
# Alternatively
|
||||||
|
pid = spawn(Geometry, :area_loop, [])
|
||||||
|
|
||||||
# Send a message to `pid` that will match a pattern in the receive statement
|
# Send a message to `pid` that will match a pattern in the receive statement
|
||||||
send pid, {:rectangle, 2, 3}
|
send pid, {:rectangle, 2, 3}
|
||||||
|
346
elm.html.markdown
Normal file
346
elm.html.markdown
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
---
|
||||||
|
language: Elm
|
||||||
|
contributors:
|
||||||
|
- ["Max Goldstein", "http://maxgoldste.in/"]
|
||||||
|
---
|
||||||
|
|
||||||
|
Elm is a functional reactive programming language that compiles to (client-side)
|
||||||
|
JavaScript. Elm is statically typed, meaning that the compiler catches most
|
||||||
|
errors immediately and provides a clear and understandable error message. Elm is
|
||||||
|
great for designing user interfaces and games for the web.
|
||||||
|
|
||||||
|
|
||||||
|
```haskell
|
||||||
|
-- Single line comments start with two dashes.
|
||||||
|
{- Multiline comments can be enclosed in a block like this.
|
||||||
|
{- They can be nested. -}
|
||||||
|
-}
|
||||||
|
|
||||||
|
{-- The Basics --}
|
||||||
|
|
||||||
|
-- Arithmetic
|
||||||
|
1 + 1 -- 2
|
||||||
|
8 - 1 -- 7
|
||||||
|
10 * 2 -- 20
|
||||||
|
|
||||||
|
-- Every number literal without a decimal point can be either an Int or a Float.
|
||||||
|
33 / 2 -- 16.5 with floating point division
|
||||||
|
33 // 2 -- 16 with integer division
|
||||||
|
|
||||||
|
-- Exponents
|
||||||
|
5 ^ 2 -- 25
|
||||||
|
|
||||||
|
-- Booleans
|
||||||
|
not True -- False
|
||||||
|
not False -- True
|
||||||
|
1 == 1 -- True
|
||||||
|
1 /= 1 -- False
|
||||||
|
1 < 10 -- True
|
||||||
|
|
||||||
|
-- Strings and characters
|
||||||
|
"This is a string."
|
||||||
|
'a' -- character
|
||||||
|
'You cant use single quotes for strings.' -- error!
|
||||||
|
|
||||||
|
-- Strings can be appended
|
||||||
|
"Hello " ++ "world!" -- "Hello world!"
|
||||||
|
|
||||||
|
{-- Lists, Tuples, and Records --}
|
||||||
|
|
||||||
|
-- Every element in a list must have the same type.
|
||||||
|
["the", "quick", "brown", "fox"]
|
||||||
|
[1, 2, 3, 4, 5]
|
||||||
|
-- The second example can also be written with two dots.
|
||||||
|
[1..5]
|
||||||
|
|
||||||
|
-- Append lists just like strings
|
||||||
|
[1..5] ++ [6..10] == [1..10] -- True
|
||||||
|
|
||||||
|
-- To add one item, use "cons"
|
||||||
|
0 :: [1..5] -- [0, 1, 2, 3, 4, 5]
|
||||||
|
|
||||||
|
-- The head and tail of a list are returned as a Maybe. Instead of checking
|
||||||
|
-- every value to see if it's null, you deal with missing values explicitly.
|
||||||
|
List.head [1..5] -- Just 1
|
||||||
|
List.tail [1..5] -- Just [2, 3, 4, 5]
|
||||||
|
List.head [] -- Nothing
|
||||||
|
|
||||||
|
-- Every element in a tuple can be a different type, but a tuple has a
|
||||||
|
-- fixed length.
|
||||||
|
("elm", 42)
|
||||||
|
|
||||||
|
-- Access the elements of a pair with the first and second functions.
|
||||||
|
-- (This is a shortcut; we'll come to the "real way" in a bit.)
|
||||||
|
fst ("elm", 42) -- "elm"
|
||||||
|
snd ("elm", 42) -- 42
|
||||||
|
|
||||||
|
-- Records are like tuples but the fields have names.
|
||||||
|
-- Notice that equals signs, not colons, are used.
|
||||||
|
{ x = 3, y = 7}
|
||||||
|
|
||||||
|
-- Access a field with a dot and the field name.
|
||||||
|
{ x = 3, y = 7}.x -- 3
|
||||||
|
|
||||||
|
-- Or with an accessor fuction, a dot and then the field name.
|
||||||
|
.y { x = 3, y = 7} -- 7
|
||||||
|
|
||||||
|
-- Update the fields of a record. (It must have the fields already.)
|
||||||
|
{ person |
|
||||||
|
name = "George" }
|
||||||
|
|
||||||
|
{ physics |
|
||||||
|
position = physics.position + physics.velocity,
|
||||||
|
velocity = physics.velocity + physics.acceleration }
|
||||||
|
|
||||||
|
{-- Control Flow --}
|
||||||
|
|
||||||
|
-- If statements always have an else, and the branches must be the same type.
|
||||||
|
if powerLevel > 9000 then
|
||||||
|
"WHOA!"
|
||||||
|
else
|
||||||
|
"meh"
|
||||||
|
|
||||||
|
-- If statements can be chained.
|
||||||
|
if n < 0 then
|
||||||
|
"n is negative"
|
||||||
|
else if n > 0 then
|
||||||
|
"n is positive"
|
||||||
|
else
|
||||||
|
"n is zero"
|
||||||
|
|
||||||
|
-- Use case statements to pattern match on different possibilities.
|
||||||
|
case aList of
|
||||||
|
[] -> "matches the empty list"
|
||||||
|
x::xs -> "matches a list of at least one item whose head is " ++ toString x
|
||||||
|
|
||||||
|
case List.head aList of
|
||||||
|
Just x -> "The head is " ++ toString x
|
||||||
|
Nothing -> "The list was empty"
|
||||||
|
|
||||||
|
{-- Functions --}
|
||||||
|
|
||||||
|
-- Elm's syntax for functions is very minimal, relying mostly on whitespace
|
||||||
|
-- rather than parentheses and curly brackets. There is no "return" keyword.
|
||||||
|
|
||||||
|
-- Define a function with its name, arguments, an equals sign, and the body.
|
||||||
|
multiply a b =
|
||||||
|
a * b
|
||||||
|
|
||||||
|
-- Apply (call) a function by passing it arguments (no commas necessay).
|
||||||
|
multiply 7 6 -- 42
|
||||||
|
|
||||||
|
-- Partially apply a function by passing only some of its arguments.
|
||||||
|
-- Then give that function a new name.
|
||||||
|
double =
|
||||||
|
multiply 2
|
||||||
|
|
||||||
|
-- Constants are similar, except there are no arguments.
|
||||||
|
answer =
|
||||||
|
42
|
||||||
|
|
||||||
|
-- Pass functions as arguments to other functions.
|
||||||
|
List.map double [1..4] -- [2, 4, 6, 8]
|
||||||
|
|
||||||
|
-- Or write an anonymous function.
|
||||||
|
List.map (\a -> a * 2) [1..4] -- [2, 4, 6, 8]
|
||||||
|
|
||||||
|
-- You can pattern match in function definitions when there's only one case.
|
||||||
|
-- This function takes one tuple rather than two arguments.
|
||||||
|
area (width, height) =
|
||||||
|
width * height
|
||||||
|
|
||||||
|
area (6, 7) -- 42
|
||||||
|
|
||||||
|
-- Use curly brackets to pattern match record field names
|
||||||
|
-- Use let to define intermediate values
|
||||||
|
volume {width, height, depth} =
|
||||||
|
let
|
||||||
|
area = width * height
|
||||||
|
in
|
||||||
|
area * depth
|
||||||
|
|
||||||
|
volume { width = 3, height = 2, depth = 7 } -- 42
|
||||||
|
|
||||||
|
-- Functions can be recursive
|
||||||
|
fib n =
|
||||||
|
if n < 2 then
|
||||||
|
1
|
||||||
|
else
|
||||||
|
fib (n - 1) + fib (n - 2)
|
||||||
|
|
||||||
|
List.map fib [0..8] -- [1, 1, 2, 3, 5, 8,13, 21, 34]
|
||||||
|
|
||||||
|
listLength aList =
|
||||||
|
case aList of
|
||||||
|
[] -> 0
|
||||||
|
x::xs -> 1 + listLength xs
|
||||||
|
|
||||||
|
-- Function application happens before any infix operation
|
||||||
|
cos (degrees 30) ^ 2 + sin (degrees 30) ^ 2 -- 1
|
||||||
|
-- First degrees is applied to 30, then the result is passed to the trig
|
||||||
|
-- functions, which is then squared, and the addition happens last.
|
||||||
|
|
||||||
|
{-- Types and Type Annotations --}
|
||||||
|
|
||||||
|
-- The compiler will infer the type of every value in your program.
|
||||||
|
-- Types are always uppercase. Read x : T as "x has type T".
|
||||||
|
-- Some common types, which you might see in Elm's REPL.
|
||||||
|
5 : Int
|
||||||
|
6.7 : Float
|
||||||
|
"hello" : String
|
||||||
|
True : Bool
|
||||||
|
|
||||||
|
-- Functions have types too. Read -> as "goes to". Think of the rightmost type
|
||||||
|
-- as the type of the return value.
|
||||||
|
not : Bool -> Bool
|
||||||
|
round : Float -> Int
|
||||||
|
|
||||||
|
-- When you define a value, it's good practice to write its type above it.
|
||||||
|
-- The annotation is a form of documentation, which is verified by the compiler.
|
||||||
|
double : Int -> Int
|
||||||
|
double x = x * 2
|
||||||
|
|
||||||
|
-- Function arguments are passed in parentheses.
|
||||||
|
-- Lowercase types are type variables: they can be any type, as long as each
|
||||||
|
-- call is consistent.
|
||||||
|
List.map : (a -> b) -> List a -> List b
|
||||||
|
-- "List dot map has type a-goes-to-b, goes to list of a, goes to list of b."
|
||||||
|
|
||||||
|
-- There are three special lowercase types: number, comparable, and appendable.
|
||||||
|
-- Numbers allow you to use arithmetic on Ints and Floats.
|
||||||
|
-- Comparable allows you to order numbers and strings, like a < b.
|
||||||
|
-- Appendable things can be combined with a ++ b.
|
||||||
|
|
||||||
|
{-- Type Aliases and Union Types --}
|
||||||
|
|
||||||
|
-- When you write a record or tuple, its type already exists.
|
||||||
|
-- (Notice that record types use colon and record values use equals.)
|
||||||
|
origin : { x : Float, y : Float, z : Float }
|
||||||
|
origin =
|
||||||
|
{ x = 0, y = 0, z = 0 }
|
||||||
|
|
||||||
|
-- You can give existing types a nice name with a type alias.
|
||||||
|
type alias Point3D = { x : Float, y : Float, z : Float }
|
||||||
|
|
||||||
|
-- If you alias a record, you can use the name as a constructor function.
|
||||||
|
otherOrigin : Point3D
|
||||||
|
otherOrigin = Point3D 0 0 0
|
||||||
|
|
||||||
|
-- But it's still the same type, you can equate them
|
||||||
|
origin == otherOrigin -- True
|
||||||
|
|
||||||
|
-- By contrast, defining a union type creates a type that didn't exist before.
|
||||||
|
-- A union type is so called because it can be one of many possibilities.
|
||||||
|
-- Each of the possibilities is represented as a "tag".
|
||||||
|
type Direction = North | South | East | West
|
||||||
|
|
||||||
|
-- Tags can carry other values of known type. This can work recursively.
|
||||||
|
type IntTree = Leaf | Node Int IntTree IntTree
|
||||||
|
|
||||||
|
-- "Leaf" and "Node" are the tags. Everything following a tag is a type.
|
||||||
|
-- Tags can be used as values or functions.
|
||||||
|
root : IntTree
|
||||||
|
root = Node 7 Leaf Leaf
|
||||||
|
|
||||||
|
-- Union types (and type aliases) can use type variables.
|
||||||
|
type Tree a = Leaf | Node a (Tree a) (Tree a)
|
||||||
|
|
||||||
|
-- You can pattern match union tags. The uppercase tags must be matched exactly.
|
||||||
|
-- The lowercase variables will match anything. Underscore also matches
|
||||||
|
-- anything, but signifies that you aren't using it.
|
||||||
|
leftmostElement : Tree a -> Maybe a
|
||||||
|
leftmostElement tree =
|
||||||
|
case tree of
|
||||||
|
Leaf -> Nothing
|
||||||
|
Node x Leaf _ -> Just x
|
||||||
|
Node _ subtree _ -> leftmostElement subtree
|
||||||
|
|
||||||
|
-- That's pretty much it for the language itself. Now let's see how to organize
|
||||||
|
-- and run your code.
|
||||||
|
|
||||||
|
{-- Modules and Imports --}
|
||||||
|
|
||||||
|
-- The core libraries are organized into modulues, as are any third-party
|
||||||
|
-- libraries you may use. For large projects, you can define your own modulues.
|
||||||
|
|
||||||
|
-- Put this at the top of the file. If omitted, you're in Main.
|
||||||
|
module Name where
|
||||||
|
|
||||||
|
-- By default, everything is exported.
|
||||||
|
-- Limit what values and types are exported
|
||||||
|
module Name (Type, value) where
|
||||||
|
|
||||||
|
-- One common pattern is to export a union type but not its tags. This is known
|
||||||
|
-- as an "opaque type", and is frequently used in libraries.
|
||||||
|
|
||||||
|
-- Import code from other modules to use it in this one
|
||||||
|
-- Places Dict in scope, so you can call Dict.insert
|
||||||
|
import Dict
|
||||||
|
|
||||||
|
-- Imports the Dict module and the Dict type, so your annotations don't have to
|
||||||
|
-- say Dict.Dict. You can still use Dict.insert.
|
||||||
|
import Dict exposing (Dict)
|
||||||
|
|
||||||
|
-- Rename an import.
|
||||||
|
import Graphics.Collage as C
|
||||||
|
|
||||||
|
{-- Ports --}
|
||||||
|
|
||||||
|
-- A port indicates that you will be communicating with the outside world.
|
||||||
|
-- Ports are only allowed in the Main module.
|
||||||
|
|
||||||
|
-- An incoming port is just a type signature.
|
||||||
|
port clientID : Int
|
||||||
|
|
||||||
|
-- An outgoing port has a defintion.
|
||||||
|
port clientOrders : List String
|
||||||
|
port clientOrders = ["Books", "Groceries", "Furniture"]
|
||||||
|
|
||||||
|
-- We won't go into the details, but you set up callbacks in JavaScript to send
|
||||||
|
-- on incoming ports and receive on outgoing ports.
|
||||||
|
|
||||||
|
{-- Command Line Tools --}
|
||||||
|
|
||||||
|
-- Compile a file.
|
||||||
|
$ elm make MyFile.elm
|
||||||
|
|
||||||
|
-- The first time you do this, Elm will install the core libraries and create
|
||||||
|
-- elm-package.json, where information about your project is kept.
|
||||||
|
|
||||||
|
-- The reactor is a server that compiles and runs your files.
|
||||||
|
-- Click the wrench next to file names to enter the time-travelling debugger!
|
||||||
|
$ elm reactor
|
||||||
|
|
||||||
|
-- Experiment with simple expressions in a Read-Eval-Print Loop.
|
||||||
|
$ elm repl
|
||||||
|
|
||||||
|
-- Packages are identified by GitHub username and repo name.
|
||||||
|
-- Install a new package, and record it in elm-package.json.
|
||||||
|
$ elm package install evancz/elm-html
|
||||||
|
|
||||||
|
-- Elm's package manager enforces semantic versioning, so minor version bumps
|
||||||
|
-- will never break your build!
|
||||||
|
```
|
||||||
|
|
||||||
|
The Elm language is surprisingly small. You can now look through almost any Elm
|
||||||
|
source code and have a rough idea of what is going on. However, the possibilties
|
||||||
|
for error-resistant and easy-to-refactor code are endless!
|
||||||
|
|
||||||
|
Here are some useful resources.
|
||||||
|
|
||||||
|
* The [Elm website](http://elm-lang.org/). Includes:
|
||||||
|
* Links to the [installers](http://elm-lang.org/install)
|
||||||
|
* [Documentation guides](http://elm-lang.org/docs), including the [syntax reference](http://elm-lang.org/docs/syntax)
|
||||||
|
* Lots of helpful [examples](http://elm-lang.org/examples)
|
||||||
|
|
||||||
|
* Documentation for [Elm's core libraries](http://package.elm-lang.org/packages/elm-lang/core/latest/). Take note of:
|
||||||
|
* [Basics](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics), which is imported by default
|
||||||
|
* Data structures like [Array](http://package.elm-lang.org/packages/elm-lang/core/latest/Array), [Dict](http://package.elm-lang.org/packages/elm-lang/core/latest/Dict), and [Set](http://package.elm-lang.org/packages/elm-lang/core/latest/Set)
|
||||||
|
* JSON [encoding](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Encode) and [decoding](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode)
|
||||||
|
|
||||||
|
* [The Elm Architecture](https://github.com/evancz/elm-architecture-tutorial#the-elm-architecture). An essay with examples on how to organize code into components.
|
||||||
|
|
||||||
|
* The [Elm mailing list](https://groups.google.com/forum/#!forum/elm-discuss). Everyone is friendly and helpful.
|
||||||
|
|
||||||
|
|
||||||
|
Go out and write some Elm!
|
@ -25,6 +25,7 @@ filename: learnerlang.erl
|
|||||||
%% 1. Variables and pattern matching.
|
%% 1. Variables and pattern matching.
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
% In Erlang new variables are bound with an `=` statement.
|
||||||
Num = 42. % All variable names must start with an uppercase letter.
|
Num = 42. % All variable names must start with an uppercase letter.
|
||||||
|
|
||||||
% Erlang has single-assignment variables; if you try to assign a different
|
% Erlang has single-assignment variables; if you try to assign a different
|
||||||
@ -32,9 +33,11 @@ Num = 42. % All variable names must start with an uppercase letter.
|
|||||||
Num = 43. % ** exception error: no match of right hand side value 43
|
Num = 43. % ** exception error: no match of right hand side value 43
|
||||||
|
|
||||||
% In most languages, `=` denotes an assignment statement. In Erlang, however,
|
% In most languages, `=` denotes an assignment statement. In Erlang, however,
|
||||||
% `=` denotes a pattern-matching operation. `Lhs = Rhs` really means this:
|
% `=` denotes a pattern-matching operation. When an empty variable is used on the
|
||||||
% evaluate the right side (`Rhs`), and then match the result against the
|
% left hand side of the `=` operator to is bound (assigned), but when a bound
|
||||||
% pattern on the left side (`Lhs`).
|
% variable is used on the left hand side the following behaviour is observed.
|
||||||
|
% `Lhs = Rhs` really means this: evaluate the right side (`Rhs`), and then
|
||||||
|
% match the result against the pattern on the left side (`Lhs`).
|
||||||
Num = 7 * 6.
|
Num = 7 * 6.
|
||||||
|
|
||||||
% Floating-point number.
|
% Floating-point number.
|
||||||
@ -174,7 +177,7 @@ is_dog(A) -> false.
|
|||||||
% A guard sequence is either a single guard or a series of guards, separated
|
% A guard sequence is either a single guard or a series of guards, separated
|
||||||
% by semicolons (`;`). The guard sequence `G1; G2; ...; Gn` is true if at
|
% by semicolons (`;`). The guard sequence `G1; G2; ...; Gn` is true if at
|
||||||
% least one of the guards `G1`, `G2`, ..., `Gn` evaluates to `true`.
|
% least one of the guards `G1`, `G2`, ..., `Gn` evaluates to `true`.
|
||||||
is_pet(A) when is_atom(A), (A =:= dog) or (A =:= cat) -> true;
|
is_pet(A) when is_atom(A), (A =:= dog);(A =:= cat) -> true;
|
||||||
is_pet(A) -> false.
|
is_pet(A) -> false.
|
||||||
|
|
||||||
% Warning: not all valid Erlang expressions can be used as guard expressions;
|
% Warning: not all valid Erlang expressions can be used as guard expressions;
|
||||||
@ -289,7 +292,7 @@ calculateArea() ->
|
|||||||
_ ->
|
_ ->
|
||||||
io:format("We can only calculate area of rectangles or circles.")
|
io:format("We can only calculate area of rectangles or circles.")
|
||||||
end.
|
end.
|
||||||
|
|
||||||
% Compile the module and create a process that evaluates `calculateArea` in the
|
% Compile the module and create a process that evaluates `calculateArea` in the
|
||||||
% shell.
|
% shell.
|
||||||
c(calculateGeometry).
|
c(calculateGeometry).
|
||||||
@ -299,6 +302,39 @@ CalculateArea ! {circle, 2}. % 12.56000000000000049738
|
|||||||
% The shell is also a process; you can use `self` to get the current pid.
|
% The shell is also a process; you can use `self` to get the current pid.
|
||||||
self(). % <0.41.0>
|
self(). % <0.41.0>
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%% 5. Testing with EUnit
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
% Unit tests can be written using EUnits's test generators and assert macros
|
||||||
|
-module(fib).
|
||||||
|
-export([fib/1]).
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
fib(0) -> 1;
|
||||||
|
fib(1) -> 1;
|
||||||
|
fib(N) when N > 1 -> fib(N-1) + fib(N-2).
|
||||||
|
|
||||||
|
fib_test_() ->
|
||||||
|
[?_assert(fib(0) =:= 1),
|
||||||
|
?_assert(fib(1) =:= 1),
|
||||||
|
?_assert(fib(2) =:= 2),
|
||||||
|
?_assert(fib(3) =:= 3),
|
||||||
|
?_assert(fib(4) =:= 5),
|
||||||
|
?_assert(fib(5) =:= 8),
|
||||||
|
?_assertException(error, function_clause, fib(-1)),
|
||||||
|
?_assert(fib(31) =:= 2178309)
|
||||||
|
].
|
||||||
|
|
||||||
|
% EUnit will automatically export to a test() function to allow running the tests
|
||||||
|
% in the erlang shell
|
||||||
|
fib:test()
|
||||||
|
|
||||||
|
% The popular erlang build tool Rebar is also compatible with EUnit
|
||||||
|
% ```
|
||||||
|
% rebar eunit
|
||||||
|
% ```
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
214
es-es/amd-es.html.markdown
Normal file
214
es-es/amd-es.html.markdown
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
category: tool
|
||||||
|
tool: amd
|
||||||
|
contributors:
|
||||||
|
- ["Frederik Ring", "https://github.com/m90"]
|
||||||
|
|
||||||
|
translators:
|
||||||
|
- ["Damaso Sanoja", "https://github.com/damasosanoja"]
|
||||||
|
filename: learnamd-es.js
|
||||||
|
lang: es-es
|
||||||
|
---
|
||||||
|
|
||||||
|
## Iniciando con AMD
|
||||||
|
|
||||||
|
El API del **Módulo de Definición Asíncrono** especifica un mecanismo para definir módulos JavaScript de manera tal que tanto el módulo como sus dependencias puedan ser cargadas de manera asíncrona. Esto es particularmente adecuado para el entorno del navegador donde la carga sincronizada de los módulos genera problemas de rendimiento, usabilidad, depuración y acceso de multi-dominios.
|
||||||
|
|
||||||
|
### Conceptos básicos
|
||||||
|
```javascript
|
||||||
|
// El API básico de AMD consiste en tan solo dos métodos: `define` y `require`
|
||||||
|
// y se basa en la definición y consumo de los módulos:
|
||||||
|
// `define(id?, dependencias?, fábrica)` define un módulo
|
||||||
|
// `require(dependencias, callback)` importa un conjunto de dependencias y
|
||||||
|
// las consume al invocar el callback
|
||||||
|
|
||||||
|
// Comencemos usando define para definir un nuevo módulo
|
||||||
|
// que no posee dependencias. Lo haremos enviando un nombre
|
||||||
|
// y una función fábrica para definirla:
|
||||||
|
define('awesomeAMD', function(){
|
||||||
|
var isAMDAwesome = function(){
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
// El valor que regresa la función fábrica del módulo será
|
||||||
|
// lo que los otros módulos o llamados require recibirán cuando
|
||||||
|
// soliciten nuestro módulo `awesomeAMD`.
|
||||||
|
// El valor exportado puede ser cualquier cosa, funciones (constructores),
|
||||||
|
// objetos, primitivos, incluso indefinidos (aunque eso no ayuda mucho).
|
||||||
|
return isAMDAwesome;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ahora definamos otro módulo que dependa de nuestro módulo `awesomeAMD`.
|
||||||
|
// Observe que ahora hay un argumento adicional que define
|
||||||
|
// las dependencias de nuestro módulo:
|
||||||
|
define('loudmouth', ['awesomeAMD'], function(awesomeAMD){
|
||||||
|
// las dependencias serán enviadas a los argumentos de la fábrica
|
||||||
|
// en el orden que sean especificadas
|
||||||
|
var tellEveryone = function(){
|
||||||
|
if (awesomeAMD()){
|
||||||
|
alert('This is sOoOo rad!');
|
||||||
|
} else {
|
||||||
|
alert('Pretty dull, isn\'t it?');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return tellEveryone;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Como ya sabemos utilizar define usemos ahora `require` para poner en marcha
|
||||||
|
// nuestro programa. La firma de `require` es `(arrayOfDependencies, callback)`.
|
||||||
|
require(['loudmouth'], function(loudmouth){
|
||||||
|
loudmouth();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Para hacer que este tutorial corra código, vamos a implementar una
|
||||||
|
// versión muy básica (no-asíncrona) de AMD justo aquí:
|
||||||
|
function define(name, deps, factory){
|
||||||
|
// observa como son manejados los módulos sin dependencias
|
||||||
|
define[name] = require(factory ? deps : [], factory || deps);
|
||||||
|
}
|
||||||
|
|
||||||
|
function require(deps, callback){
|
||||||
|
var args = [];
|
||||||
|
// primero recuperemos todas las dependencias que necesita
|
||||||
|
// el llamado require
|
||||||
|
for (var i = 0; i < deps.length; i++){
|
||||||
|
args[i] = define[deps[i]];
|
||||||
|
}
|
||||||
|
// satisfacer todas las dependencias del callback
|
||||||
|
return callback.apply(null, args);
|
||||||
|
}
|
||||||
|
// puedes ver este código en acción aquí: http://jsfiddle.net/qap949pd/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Uso en el mundo real con require.js
|
||||||
|
|
||||||
|
En contraste con el ejemplo introductorio, `require.js` (la librería AMD más popular) implementa la **A** de **AMD**, permitiéndote cargar los módulos y sus dependencias asincrónicamente via XHR:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/* file: app/main.js */
|
||||||
|
require(['modules/someClass'], function(SomeClass){
|
||||||
|
// el callback es diferido hasta que la dependencia sea cargada
|
||||||
|
var thing = new SomeClass();
|
||||||
|
});
|
||||||
|
console.log('So here we are, waiting!'); // esto correrá primero
|
||||||
|
```
|
||||||
|
|
||||||
|
Por convención, usualmente guardas un módulo en un fichero. `require.js` puede resolver los nombres de los módulos basados en rutas de archivo, de forma que no tienes que nombrar tus módulos, simplemente referenciarlos usando su ubicación. En el ejemplo `someClass` asumimos que se ubica en la carpeta `modules`, relativa a tu `baseUrl` configurada:
|
||||||
|
|
||||||
|
* app/
|
||||||
|
* main.js
|
||||||
|
* modules/
|
||||||
|
* someClass.js
|
||||||
|
* someHelpers.js
|
||||||
|
* ...
|
||||||
|
* daos/
|
||||||
|
* things.js
|
||||||
|
* ...
|
||||||
|
|
||||||
|
Esto significa que podemos definir `someClass` sin especificar su id de módulo:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/* file: app/modules/someClass.js */
|
||||||
|
define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){
|
||||||
|
// definición de módulo, por supuesto, ocurrirá también asincrónicamente
|
||||||
|
function SomeClass(){
|
||||||
|
this.method = function(){/**/};
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
return SomeClass;
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Para alterar el comportamiento del mapeo de ruta usa `requirejs.config(configObj)` en tu `main.js`:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/* file: main.js */
|
||||||
|
requirejs.config({
|
||||||
|
baseUrl : 'app',
|
||||||
|
paths : {
|
||||||
|
// también puedes cargar módulos desde otras ubicaciones
|
||||||
|
jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min',
|
||||||
|
coolLibFromBower : '../bower_components/cool-lib/coollib'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){
|
||||||
|
// un fichero `main` necesita llamar a require al menos una vez,
|
||||||
|
// de otra forma jamás correrá el código
|
||||||
|
coolLib.doFancyStuffWith(helpers.transform($('#foo')));
|
||||||
|
});
|
||||||
|
```
|
||||||
|
Las aplicaciones basadas en `require.js` usualmente tendrán un solo punto de entrada (`main.js`) que se pasa a la etiqueta del script `require.js` como un atributo de datos. Será cargado y ejecutado automáticamente al cargar la página:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Cien etiquetas de script? Nunca más!</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="require.js" data-main="app/main"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optimizar todo un proyecto usando r.js
|
||||||
|
|
||||||
|
Muchas personas prefieren usar AMD para la organización del código durante el desarrollo, pero quieren enviar para producción un solo fichero en vez de ejecutar cientos de XHRs en las cargas de página.
|
||||||
|
|
||||||
|
`require.js` incluye un script llamado `r.js` (el que probablemente correrás en node.js, aunque Rhino también es soportado) que puede analizar el gráfico de dependencias de tu proyecto, y armar un solo fichero que contenga todos tus módulos (adecuadamente nombrados), minificado y listo para consumo.
|
||||||
|
|
||||||
|
Instálalo usando `npm`:
|
||||||
|
```shell
|
||||||
|
$ npm install requirejs -g
|
||||||
|
```
|
||||||
|
|
||||||
|
Ahora puedes alimentarlo con un fichero de configuración:
|
||||||
|
```shell
|
||||||
|
$ r.js -o app.build.js
|
||||||
|
```
|
||||||
|
|
||||||
|
Para nuestro ejemplo anterior el archivo de configuración luciría así:
|
||||||
|
```javascript
|
||||||
|
/* file : app.build.js */
|
||||||
|
({
|
||||||
|
name : 'main', // nombre del punto de entrada
|
||||||
|
out : 'main-built.js', // nombre del fichero donde se escribirá la salida
|
||||||
|
baseUrl : 'app',
|
||||||
|
paths : {
|
||||||
|
// `empty:` le dice a r.js que esto aún debe ser cargado desde el CDN, usando
|
||||||
|
// la ubicación especificada en `main.js`
|
||||||
|
jquery : 'empty:',
|
||||||
|
coolLibFromBower : '../bower_components/cool-lib/coollib'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Para usar el fichero creado en producción, simplemente intercambia `data-main`:
|
||||||
|
```html
|
||||||
|
<script src="require.js" data-main="app/main-built"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Un increíblemente detallado [resumen de opciones de generación](https://github.com/jrburke/r.js/blob/master/build/example.build.js) está disponible en el repositorio de GitHub.
|
||||||
|
|
||||||
|
### Tópicos no cubiertos en este tutorial
|
||||||
|
* [Cargador de plugins / transformaciones](http://requirejs.org/docs/plugins.html)
|
||||||
|
* [Cargando y exportando estilos CommonJS](http://requirejs.org/docs/commonjs.html)
|
||||||
|
* [Configuración avanzada](http://requirejs.org/docs/api.html#config)
|
||||||
|
* [Configuración de Shim (cargando módulos no-AMD)](http://requirejs.org/docs/api.html#config-shim)
|
||||||
|
* [Cargando y optimizando CSS con require.js](http://requirejs.org/docs/optimization.html#onecss)
|
||||||
|
* [Usando almond.js para construcciones](https://github.com/jrburke/almond)
|
||||||
|
|
||||||
|
### Otras lecturas:
|
||||||
|
|
||||||
|
* [Especificaciones oficiales](https://github.com/amdjs/amdjs-api/wiki/AMD)
|
||||||
|
* [¿Por qué AMD?](http://requirejs.org/docs/whyamd.html)
|
||||||
|
* [Definición Universal de Módulos](https://github.com/umdjs/umd)
|
||||||
|
|
||||||
|
### Implementaciones:
|
||||||
|
|
||||||
|
* [require.js](http://requirejs.org)
|
||||||
|
* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/)
|
||||||
|
* [cujo.js](http://cujojs.com/)
|
||||||
|
* [curl.js](https://github.com/cujojs/curl)
|
||||||
|
* [lsjs](https://github.com/zazl/lsjs)
|
||||||
|
* [mmd](https://github.com/alexlawrence/mmd)
|
@ -9,8 +9,10 @@ lang: es-es
|
|||||||
---
|
---
|
||||||
|
|
||||||
Brainfuck (con mayúscula sólo al inicio de una oración) es un
|
Brainfuck (con mayúscula sólo al inicio de una oración) es un
|
||||||
lenguaje de programación mínimo, computacionalmente universal
|
lenguaje de programación extremadamente pequeño, Turing completo con sólo 8 comandos.
|
||||||
en tamaño con sólo 8 comandos.
|
|
||||||
|
Puedes probar brainfuck en tu navegador con [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/).
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -18,7 +20,7 @@ Cualquier caracter que no sea "><+-.,[]" (sin incluir las comillas)
|
|||||||
será ignorado.
|
será ignorado.
|
||||||
|
|
||||||
Brainfuck es representado por un arreglo de 30,000 celdas inicializadas
|
Brainfuck es representado por un arreglo de 30,000 celdas inicializadas
|
||||||
en cero y un apuntador en la celda actual.
|
en cero y un puntero apuntando la celda actual.
|
||||||
|
|
||||||
Existen ocho comandos:
|
Existen ocho comandos:
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ Existen ocho comandos:
|
|||||||
- : Decrementa 1 al valor de la celda actual.
|
- : Decrementa 1 al valor de la celda actual.
|
||||||
> : Mueve el apuntador a la siguiente celda. (a la derecha)
|
> : Mueve el apuntador a la siguiente celda. (a la derecha)
|
||||||
< : Mueve el apuntador a la celda anterior. (a la izquierda)
|
< : Mueve el apuntador a la celda anterior. (a la izquierda)
|
||||||
. : Imprime el valor en ASCII de la celda actual (i.e. 65 = 'A')
|
. : Imprime el valor en ASCII de la celda actual (p.e. 65 = 'A')
|
||||||
, : Lee un caracter como input y lo escribe en la celda actual.
|
, : Lee un caracter como input y lo escribe en la celda actual.
|
||||||
[ : Si el valor en la celda actual es cero mueve el apuntador
|
[ : Si el valor en la celda actual es cero mueve el apuntador
|
||||||
hasta el primer ']' que encuentre. Si no es cero sigue a la
|
hasta el primer ']' que encuentre. Si no es cero sigue a la
|
||||||
@ -37,7 +39,7 @@ Existen ocho comandos:
|
|||||||
|
|
||||||
[ y ] forman un while. Obviamente, deben estar balanceados.
|
[ y ] forman un while. Obviamente, deben estar balanceados.
|
||||||
|
|
||||||
Ahora unos ejemplos de programas escritos con brainfuck.
|
Estos son algunos ejemplos de programas escritos con brainfuck.
|
||||||
|
|
||||||
++++++ [ > ++++++++++ < - ] > +++++ .
|
++++++ [ > ++++++++++ < - ] > +++++ .
|
||||||
|
|
||||||
@ -63,7 +65,7 @@ Esto continúa hasta que la celda #1 contenga un cero. Cuando #1 contenga un
|
|||||||
cero la celda #2 tendrá el valor inicial de #1. Como este ciclo siempre
|
cero la celda #2 tendrá el valor inicial de #1. Como este ciclo siempre
|
||||||
terminara en la celda #1 nos movemos a la celda #2 e imprimimos (.).
|
terminara en la celda #1 nos movemos a la celda #2 e imprimimos (.).
|
||||||
|
|
||||||
Ten en mente que los espacios son sólo para fines de legibilidad.
|
Ten en cuenta que los espacios son sólo para fines de legibilidad.
|
||||||
Es lo mismo escribir el ejemplo de arriba que esto:
|
Es lo mismo escribir el ejemplo de arriba que esto:
|
||||||
,[>+<-]>.
|
,[>+<-]>.
|
||||||
|
|
||||||
@ -81,7 +83,7 @@ hasta la próxima vez. Para resolver este problema también incrementamos la
|
|||||||
celda #4 y luego copiamos la celda #4 a la celda #2. La celda #3 contiene
|
celda #4 y luego copiamos la celda #4 a la celda #2. La celda #3 contiene
|
||||||
el resultado.
|
el resultado.
|
||||||
```
|
```
|
||||||
Y eso es brainfuck. ¿No tan difícil o sí? Como diversión, puedes escribir
|
Y eso es brainfuck. No es tan difícil, ¿verdad? Como diversión, puedes escribir
|
||||||
tu propio intérprete de brainfuck o tu propio programa en brainfuck. El
|
tu propio intérprete de brainfuck o tu propio programa en brainfuck. El
|
||||||
intérprete es relativamente sencillo de hacer, pero si eres masoquista,
|
intérprete es relativamente sencillo de hacer, pero si eres masoquista,
|
||||||
intenta construir tu proprio intérprete de brainfuck... en brainfuck.
|
puedes intentar construir tu propio intérprete de brainfuck... en brainfuck.
|
||||||
|
829
es-es/c++-es.html.markdown
Normal file
829
es-es/c++-es.html.markdown
Normal file
@ -0,0 +1,829 @@
|
|||||||
|
---
|
||||||
|
language: c++
|
||||||
|
filename: learncpp.cpp
|
||||||
|
contributors:
|
||||||
|
- ["Steven Basart", "http://github.com/xksteven"]
|
||||||
|
- ["Matt Kline", "https://github.com/mrkline"]
|
||||||
|
- ["Geoff Liu", "http://geoffliu.me"]
|
||||||
|
- ["Connor Waters", "http://github.com/connorwaters"]
|
||||||
|
translators:
|
||||||
|
- ["Gerson Lázaro", "https://gersonlazaro.com"]
|
||||||
|
lang: es-es
|
||||||
|
---
|
||||||
|
|
||||||
|
C++ es un lenguaje de programación de sistemas que,
|
||||||
|
[de acuerdo a su inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
|
||||||
|
fue diseñado para
|
||||||
|
|
||||||
|
- ser un "mejor C"
|
||||||
|
- soportar abstracción de datos
|
||||||
|
- soportar programación orientada a objetos
|
||||||
|
- soportar programación genérica
|
||||||
|
|
||||||
|
Aunque su sintaxis puede ser más difícil o compleja que los nuevos lenguajes,
|
||||||
|
es ampliamente utilizado, ya que compila instrucciones nativas que pueden ser
|
||||||
|
directamente ejecutadas por el procesador y ofrece un estricto control sobre
|
||||||
|
el hardware (como C), mientras ofrece características de alto nivel como
|
||||||
|
genericidad, excepciones, y clases. Esta combinación de velocidad y
|
||||||
|
funcionalidad hace de C ++ uno de los lenguajes de programación más utilizados.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
////////////////////
|
||||||
|
// Comparación con C
|
||||||
|
////////////////////
|
||||||
|
|
||||||
|
// C ++ es _casi_ un superconjunto de C y comparte su sintaxis básica para las
|
||||||
|
// declaraciones de variables, tipos primitivos y funciones.
|
||||||
|
|
||||||
|
// Al igual que en C, el punto de entrada de tu programa es una función llamada
|
||||||
|
// main con un retorno de tipo entero.
|
||||||
|
// Este valor sirve como código de salida del programa.
|
||||||
|
// Mira http://en.wikipedia.org/wiki/Exit_status para mayor información.
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
// Los argumentos de la línea de comandos se pasan por argc y argv de la
|
||||||
|
// misma manera que en C.
|
||||||
|
// argc indica el número de argumentos,
|
||||||
|
// y argv es un arreglo de strings de estilo C (char*)
|
||||||
|
// representando los argumentos.
|
||||||
|
// El primer argumento es el nombre con el que el programa es llamado.
|
||||||
|
// argc y argv pueden omitirse si no te preocupan los argumentos,
|
||||||
|
// dejando la definición de la función como int main ()
|
||||||
|
|
||||||
|
// Un estado de salida 0 indica éxito.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sin embargo, C ++ varía en algunas de las siguientes maneras:
|
||||||
|
|
||||||
|
// En C++, los caracteres literales son caracteres
|
||||||
|
sizeof('c') == sizeof(char) == 1
|
||||||
|
|
||||||
|
// En C, los caracteres literales son enteros
|
||||||
|
sizeof('c') == sizeof(int)
|
||||||
|
|
||||||
|
|
||||||
|
// C++ tiene prototipado estricto
|
||||||
|
void func(); // función que no acepta argumentos
|
||||||
|
|
||||||
|
// En C
|
||||||
|
void func(); // función que puede aceptar cualquier número de argumentos
|
||||||
|
|
||||||
|
// Use nullptr en lugar de NULL en C++
|
||||||
|
int* ip = nullptr;
|
||||||
|
|
||||||
|
// Las cabeceras (headers) estándar de C están disponibles en C ++,
|
||||||
|
// pero tienen el prefijo "c" y no tienen sufijo .h.
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
printf("Hola mundo!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// Sobrecarga de funciones
|
||||||
|
//////////////////////////
|
||||||
|
|
||||||
|
// C++ soporta sobrecarga de funciones
|
||||||
|
// siempre que cada función tenga diferentes parámetros.
|
||||||
|
|
||||||
|
void print(char const* myString)
|
||||||
|
{
|
||||||
|
printf("String %s\n", myString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(int myInt)
|
||||||
|
{
|
||||||
|
printf("Mi entero es %d", myInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
print("Hello"); // Resolves to void print(const char*)
|
||||||
|
print(15); // Resolves to void print(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////
|
||||||
|
// Argumentos de función por defecto
|
||||||
|
////////////////////////////////////
|
||||||
|
|
||||||
|
// Puedes proporcionar argumentos por defecto para una función si no son
|
||||||
|
// proporcionados por quien la llama.
|
||||||
|
|
||||||
|
void doSomethingWithInts(int a = 1, int b = 4)
|
||||||
|
{
|
||||||
|
// Hacer algo con los enteros aqui
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
doSomethingWithInts(); // a = 1, b = 4
|
||||||
|
doSomethingWithInts(20); // a = 20, b = 4
|
||||||
|
doSomethingWithInts(20, 5); // a = 20, b = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
// Los argumentos predeterminados deben estar al final de la lista de argumentos.
|
||||||
|
|
||||||
|
void invalidDeclaration(int a = 1, int b) // Error!
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// Espacios de nombre
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
// Espacios de nombres proporcionan ámbitos separados para variable, función y
|
||||||
|
// otras declaraciones.
|
||||||
|
// Los espacios de nombres se pueden anidar.
|
||||||
|
|
||||||
|
namespace First {
|
||||||
|
namespace Nested {
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
printf("Esto es First::Nested::foo\n");
|
||||||
|
}
|
||||||
|
} // fin del nombre de espacio Nested
|
||||||
|
} // fin del nombre de espacio First
|
||||||
|
|
||||||
|
namespace Second {
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
printf("Esto es Second::foo\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
printf("Este es global: foo\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Incluye todos los símbolos del espacio de nombre Second en el ámbito
|
||||||
|
// actual. Tenga en cuenta que simplemente foo() no funciona, ya que ahora
|
||||||
|
// es ambigua si estamos llamando a foo en espacio de nombres Second o en
|
||||||
|
// el nivel superior.
|
||||||
|
using namespace Second;
|
||||||
|
|
||||||
|
Second::foo(); // imprime "Esto es Second::foo"
|
||||||
|
First::Nested::foo(); // imprime "Esto es First::Nested::foo"
|
||||||
|
::foo(); // imprime "Este es global: foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
// Entrada/Salida
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
// La entrada y salida de C++ utiliza flujos (streams)
|
||||||
|
// cin, cout, y cerr representan a stdin, stdout, y stderr.
|
||||||
|
// << es el operador de inserción >> es el operador de extracción.
|
||||||
|
|
||||||
|
|
||||||
|
#include <iostream> // Incluir para el flujo de entrada/salida
|
||||||
|
|
||||||
|
using namespace std; // Los streams estan en std namespace (libreria estandar)
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int myInt;
|
||||||
|
|
||||||
|
// Imprime a la stdout (o terminal/pantalla)
|
||||||
|
cout << "Ingresa tu número favorito:\n";
|
||||||
|
// Toma una entrada
|
||||||
|
cin >> myInt;
|
||||||
|
|
||||||
|
// cout puede también ser formateado
|
||||||
|
cout << "Tu número favorito es " << myInt << "\n";
|
||||||
|
// imprime "Tu número favorito es <myInt>"
|
||||||
|
|
||||||
|
cerr << "Usado para mensajes de error";
|
||||||
|
}
|
||||||
|
////////////////////
|
||||||
|
// Cadenas (Strings)
|
||||||
|
////////////////////
|
||||||
|
|
||||||
|
// Las cadenas en C++ son objetos y tienen muchas funciones
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std; // Strings también estan en namespace std
|
||||||
|
|
||||||
|
string myString = "Hola";
|
||||||
|
string myOtherString = " Mundo";
|
||||||
|
|
||||||
|
// + es usado para concatenar.
|
||||||
|
cout << myString + myOtherString; // "Hola Mundo"
|
||||||
|
|
||||||
|
cout << myString + " Tu"; // "Hola Tu"
|
||||||
|
|
||||||
|
// Las cadenas en C++ son mutables y tienen valor semántico.
|
||||||
|
myString.append(" Perro");
|
||||||
|
cout << myString; // "Hola Perro"
|
||||||
|
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// Referencias
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
// Además de punteros como los de C,
|
||||||
|
// C++ tiene _references_.
|
||||||
|
// Estos tipos de puntero no pueden ser reasignados una vez establecidos
|
||||||
|
// Y no pueden ser nulos.
|
||||||
|
// También tienen la misma sintaxis que la propia variable:
|
||||||
|
// No es necesaria * para eliminar la referencia y
|
||||||
|
// & (dirección) no se utiliza para la asignación.
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
string foo = "Yo soy foo";
|
||||||
|
string bar = "Yo soy bar";
|
||||||
|
|
||||||
|
string& fooRef = foo; // Crea una referencia a foo.
|
||||||
|
fooRef += ". Hola!"; // Modifica foo través de la referencia
|
||||||
|
cout << fooRef; // Imprime "Yo soy foo. Hola!"
|
||||||
|
|
||||||
|
// No trate de reasignar "fooRef". Esto es lo mismo que "foo = bar", y
|
||||||
|
// foo == "Yo soy bar"
|
||||||
|
// después de esta linea.
|
||||||
|
fooRef = bar;
|
||||||
|
|
||||||
|
const string& barRef = bar; // Crea una referencia constante a bar.
|
||||||
|
// Como en C, los valores constantes (y punteros y referencias) no pueden ser
|
||||||
|
// modificados.
|
||||||
|
barRef += ". Hola!"; // Error, referencia constante no puede ser modificada.
|
||||||
|
|
||||||
|
// Sidetrack: Antes de hablar más sobre referencias, hay que introducir un
|
||||||
|
// concepto llamado objeto temporal. Supongamos que tenemos el siguiente código:
|
||||||
|
string tempObjectFun() { ... }
|
||||||
|
string retVal = tempObjectFun();
|
||||||
|
|
||||||
|
// Lo que pasa en la segunda línea es en realidad:
|
||||||
|
// - Un objeto de cadena es retornado desde tempObjectFun
|
||||||
|
// - Una nueva cadena se construye con el objeto devuelto como argumento al
|
||||||
|
// constructor
|
||||||
|
// - El objeto devuelto es destruido
|
||||||
|
// El objeto devuelto se llama objeto temporal. Objetos temporales son
|
||||||
|
// creados cada vez que una función devuelve un objeto, y es destruido en el
|
||||||
|
// fin de la evaluación de la expresión que encierra (Bueno, esto es lo que la
|
||||||
|
// norma dice, pero los compiladores están autorizados a cambiar este
|
||||||
|
// comportamiento. Busca "return value optimization" para ver mas detalles).
|
||||||
|
// Así que en este código:
|
||||||
|
foo(bar(tempObjectFun()))
|
||||||
|
|
||||||
|
// Suponiendo que foo y bar existen, el objeto retornado de tempObjectFun es
|
||||||
|
// pasado al bar, y se destruye antes de llamar foo.
|
||||||
|
|
||||||
|
// Ahora, de vuelta a las referencias. La excepción a la regla "en el extremo
|
||||||
|
// de la expresión encerrada" es si un objeto temporal se une a una
|
||||||
|
// referencia constante, en cuyo caso su vida se extiende al ámbito actual:
|
||||||
|
|
||||||
|
void constReferenceTempObjectFun() {
|
||||||
|
// ConstRef obtiene el objeto temporal, y es válido hasta el final de esta
|
||||||
|
// función.
|
||||||
|
const string& constRef = tempObjectFun();
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otro tipo de referencia introducida en C ++ 11 es específicamente para
|
||||||
|
// objetos temporales. No se puede tener una variable de este tipo, pero tiene
|
||||||
|
// prioridad en resolución de sobrecarga:
|
||||||
|
|
||||||
|
void someFun(string& s) { ... } // Referencia regular
|
||||||
|
void someFun(string&& s) { ... } // Referencia a objeto temporal
|
||||||
|
|
||||||
|
string foo;
|
||||||
|
someFun(foo); // Llama la función con referencia regular
|
||||||
|
someFun(tempObjectFun()); // Llama la versión con referencia temporal
|
||||||
|
|
||||||
|
// Por ejemplo, puedes ver estas dos versiones de constructores para
|
||||||
|
// std::basic_string:
|
||||||
|
basic_string(const basic_string& other);
|
||||||
|
basic_string(basic_string&& other);
|
||||||
|
|
||||||
|
// La idea es que si estamos construyendo una nueva cadena de un objeto temporal
|
||||||
|
// (que va a ser destruido pronto de todos modos), podemos tener un constructor
|
||||||
|
// mas eficiente que "rescata" partes de esa cadena temporal. Usted verá este
|
||||||
|
// Concepto denominado "movimiento semántico".
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
// Clases y programación orientada a objetos
|
||||||
|
////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Primer ejemplo de clases
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// Declara una clase.
|
||||||
|
// Las clases son usualmente declaradas en archivos de cabeceras (.h o .hpp)
|
||||||
|
class Dog {
|
||||||
|
// Variables y funciones de la clase son privados por defecto.
|
||||||
|
std::string name;
|
||||||
|
int weight;
|
||||||
|
|
||||||
|
// Todos los miembros siguientes de este son públicos
|
||||||
|
// Hasta que se encuentre "private" o "protected".
|
||||||
|
// All members following this are public
|
||||||
|
// until "private:" or "protected:" is found.
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructor por defecto
|
||||||
|
Dog();
|
||||||
|
|
||||||
|
// Declaraciones de funciones de la clase (implementaciones a seguir)
|
||||||
|
// Nota que usamos std::string aquí en lugar de colocar
|
||||||
|
// using namespace std;
|
||||||
|
// arriba.
|
||||||
|
// Nunca ponga una declaración "using namespace" en un encabezado.
|
||||||
|
void setName(const std::string& dogsName);
|
||||||
|
|
||||||
|
void setWeight(int dogsWeight);
|
||||||
|
// Funciones que no modifican el estado del objeto
|
||||||
|
// Deben marcarse como const.
|
||||||
|
// Esto le permite llamarlas si se envia una referencia constante al objeto.
|
||||||
|
// También tenga en cuenta que las funciones deben ser declaradas
|
||||||
|
// explícitamente como _virtual_ para que sea reemplazada en las clases
|
||||||
|
// derivadas.
|
||||||
|
// Las funciones no son virtuales por defecto por razones de rendimiento.
|
||||||
|
virtual void print() const;
|
||||||
|
|
||||||
|
// Las funciones también se pueden definir en el interior
|
||||||
|
// del cuerpo de la clase.
|
||||||
|
// Funciones definidas como tales están entre líneas automáticamente.
|
||||||
|
void bark() const { std::cout << name << " barks!\n"; }
|
||||||
|
|
||||||
|
// Junto a los constructores, C++ proporciona destructores.
|
||||||
|
// Estos son llamados cuando un objeto se elimina o está fuera del ámbito.
|
||||||
|
// Esto permite paradigmas potentes como RAII
|
||||||
|
// (mira abajo)
|
||||||
|
// El destructor debe ser virtual si una clase es dervada desde el;
|
||||||
|
// Si no es virtual, entonces la clase derivada destructor
|
||||||
|
// No será llamada si el objeto se destruye a través de una referencia de
|
||||||
|
// la clase base o puntero.
|
||||||
|
virtual ~Dog();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}; // Un punto y coma debe seguir la definición de clase.
|
||||||
|
|
||||||
|
// Las funciones de una clase son normalmente implementados en archivos .cpp.
|
||||||
|
Dog::Dog()
|
||||||
|
{
|
||||||
|
std::cout << "Un perro ha sido construido\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Objetos (tales como cadenas) deben ser pasados por referencia
|
||||||
|
// Si los estas modificando o referencia constante en caso contrario.
|
||||||
|
void Dog::setName(const std::string& dogsName)
|
||||||
|
{
|
||||||
|
name = dogsName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dog::setWeight(int dogsWeight)
|
||||||
|
{
|
||||||
|
weight = dogsWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nota que "virtual" sólo se necesita en la declaración, no en la definición.
|
||||||
|
void Dog::print() const
|
||||||
|
{
|
||||||
|
std::cout << "El perro es " << name << " y pesa " << weight << "kg\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
Dog::~Dog()
|
||||||
|
{
|
||||||
|
cout << "Adiós " << name << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Dog myDog; // imprime "Un perro ha sido construido"
|
||||||
|
myDog.setName("Barkley");
|
||||||
|
myDog.setWeight(10);
|
||||||
|
myDog.print(); // imprime "El perro es Barkley y pesa 10 kg"
|
||||||
|
return 0;
|
||||||
|
} // imprime "Adiós Barkley"
|
||||||
|
|
||||||
|
// Herencia:
|
||||||
|
|
||||||
|
// Esta clase hereda todo lo público y protegido de la clase Dog
|
||||||
|
class OwnedDog : public Dog {
|
||||||
|
|
||||||
|
void setOwner(const std::string& dogsOwner);
|
||||||
|
|
||||||
|
// Reemplaza el comportamiento de la función de impresión
|
||||||
|
// de todos los OwnedDogs. Mira
|
||||||
|
// http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
|
||||||
|
// Para una introducción más general si no está familiarizado con el
|
||||||
|
// polimorfismo de subtipo.
|
||||||
|
// La palabra clave override es opcional, pero asegura que estás
|
||||||
|
// reemplazando el método de una clase base.
|
||||||
|
void print() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mientras tanto, en el archivo .cpp correspondiente:
|
||||||
|
|
||||||
|
void OwnedDog::setOwner(const std::string& dogsOwner)
|
||||||
|
{
|
||||||
|
owner = dogsOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OwnedDog::print() const
|
||||||
|
{
|
||||||
|
Dog::print(); // Llama a la función de impresión en la clase base Dog
|
||||||
|
std::cout << "El perro es de " << owner << "\n";
|
||||||
|
// Imprime "El perro es <name> y pesa <weight>"
|
||||||
|
// "El perro es de <owner>"
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
// Inicialización y sobrecarga de operadores
|
||||||
|
////////////////////////////////////////////
|
||||||
|
|
||||||
|
// En C ++ se puede sobrecargar el comportamiento
|
||||||
|
// de los operadores como +, -, *, /, etc.
|
||||||
|
// Esto se hace mediante la definición de una función que es llamada
|
||||||
|
// cada vez que se utiliza el operador.
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class Point {
|
||||||
|
public:
|
||||||
|
// Las variables de la clase pueden dar valores por defecto de esta manera.
|
||||||
|
double x = 0;
|
||||||
|
double y = 0;
|
||||||
|
|
||||||
|
// Define un constructor por defecto que no hace nada
|
||||||
|
// pero inicializa el punto al valor por defecto (0, 0)
|
||||||
|
Point() { };
|
||||||
|
|
||||||
|
// The following syntax is known as an initialization list
|
||||||
|
// and is the proper way to initialize class member values
|
||||||
|
Point (double a, double b) :
|
||||||
|
x(a),
|
||||||
|
y(b)
|
||||||
|
{ /* No hace nada excepto inicializar los valores */ }
|
||||||
|
|
||||||
|
// Sobrecarga el operador +
|
||||||
|
Point operator+(const Point& rhs) const;
|
||||||
|
|
||||||
|
// Sobrecarga el operador +=
|
||||||
|
Point& operator+=(const Point& rhs);
|
||||||
|
|
||||||
|
// También tendría sentido añadir los operadores - y -=,
|
||||||
|
// Pero vamos a omitirlos por razones de brevedad.
|
||||||
|
};
|
||||||
|
|
||||||
|
Point Point::operator+(const Point& rhs) const
|
||||||
|
{
|
||||||
|
// Crea un nuevo punto que es la suma de este y rhs.
|
||||||
|
return Point(x + rhs.x, y + rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point& Point::operator+=(const Point& rhs)
|
||||||
|
{
|
||||||
|
x += rhs.x;
|
||||||
|
y += rhs.y;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main () {
|
||||||
|
Point up (0,1);
|
||||||
|
Point right (1,0);
|
||||||
|
// Llama al operador + de Point
|
||||||
|
// Point llama la función + con right como parámetro
|
||||||
|
Point result = up + right;
|
||||||
|
// Prints "Result is upright (1,1)"
|
||||||
|
cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// Plantillas (Templates)
|
||||||
|
/////////////////////////
|
||||||
|
|
||||||
|
// Las plantillas en C++ se utilizan sobre todo en la programación genérica,
|
||||||
|
// a pesar de que son mucho más poderoso que los constructores genéricos
|
||||||
|
// en otros lenguajes. Ellos también soportan especialización explícita y
|
||||||
|
// parcial y clases de tipo estilo funcional; de hecho, son un lenguaje
|
||||||
|
// funcional Turing-completo incrustado en C ++!
|
||||||
|
|
||||||
|
// Empezamos con el tipo de programación genérica que podría estar
|
||||||
|
// familiarizado.
|
||||||
|
// Para definir una clase o función que toma un parámetro de tipo:
|
||||||
|
template<class T>
|
||||||
|
class Box {
|
||||||
|
public:
|
||||||
|
// En este caso, T puede ser usado como cualquier otro tipo.
|
||||||
|
void insert(const T&) { ... }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Durante la compilación, el compilador realmente genera copias de cada
|
||||||
|
// plantilla con parámetros sustituidos, por lo que la definición completa
|
||||||
|
// de la clase debe estar presente en cada invocación.
|
||||||
|
// Es por esto que usted verá clases de plantilla definidas
|
||||||
|
// Enteramente en archivos de cabecera.
|
||||||
|
|
||||||
|
//Para crear una instancia de una clase de plantilla en la pila:
|
||||||
|
Box<int> intBox;
|
||||||
|
|
||||||
|
y puedes utilizarlo como era de esperar:
|
||||||
|
intBox.insert(123);
|
||||||
|
|
||||||
|
// Puedes, por supuesto, anidar plantillas:
|
||||||
|
Box<Box<int> > boxOfBox;
|
||||||
|
boxOfBox.insert(intBox);
|
||||||
|
|
||||||
|
// Hasta C++11, había que colocar un espacio entre los dos '>'s,
|
||||||
|
// de lo contrario '>>' serían analizados como el operador de desplazamiento
|
||||||
|
// a la derecha.
|
||||||
|
|
||||||
|
|
||||||
|
// A veces verás
|
||||||
|
// template<typename T>
|
||||||
|
// en su lugar. La palabra clave "class" y las palabras clave "typename" son
|
||||||
|
// mayormente intercambiables en este caso. Para la explicación completa, mira
|
||||||
|
// http://en.wikipedia.org/wiki/Typename
|
||||||
|
// (sí, esa palabra clave tiene su propia página de Wikipedia).
|
||||||
|
|
||||||
|
// Del mismo modo, una plantilla de función:
|
||||||
|
template<class T>
|
||||||
|
void barkThreeTimes(const T& input)
|
||||||
|
{
|
||||||
|
input.bark();
|
||||||
|
input.bark();
|
||||||
|
input.bark();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Observe que no se especifica nada acerca de los tipos de parámetros aquí.
|
||||||
|
// El compilador generará y comprobará cada invocación de la plantilla,
|
||||||
|
// por lo que la función anterior funciona con cualquier tipo "T"
|
||||||
|
// que tenga un método 'bark' constante!
|
||||||
|
|
||||||
|
|
||||||
|
Dog fluffy;
|
||||||
|
fluffy.setName("Fluffy")
|
||||||
|
barkThreeTimes(fluffy); // Imprime "Fluffy barks" 3 veces.
|
||||||
|
|
||||||
|
Los parámetros de la plantilla no tienen que ser las clases:
|
||||||
|
template<int Y>
|
||||||
|
void printMessage() {
|
||||||
|
cout << "Aprende C++ en " << Y << " minutos!" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Y usted puede especializar explícitamente plantillas
|
||||||
|
// para código más eficiente.
|
||||||
|
// Por supuesto, la mayor parte del mundo real que utiliza una especialización
|
||||||
|
// no son tan triviales como esta.
|
||||||
|
// Tenga en cuenta que usted todavía tiene que declarar la función (o clase)
|
||||||
|
// como plantilla incluso si ha especificado de forma explícita todos
|
||||||
|
// los parámetros.
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void printMessage<10>() {
|
||||||
|
cout << "Aprende C++ rapido en solo 10 minutos!" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
printMessage<20>(); // Prints "Aprende C++ en 20 minutos!"
|
||||||
|
printMessage<10>(); // Prints "Aprende C++ rapido en solo 10 minutos!"
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// Manejador de excepciones
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
// La biblioteca estándar proporciona algunos tipos de excepción
|
||||||
|
// (mira http://en.cppreference.com/w/cpp/error/exception)
|
||||||
|
// pero cualquier tipo puede ser lanzado como una excepción
|
||||||
|
#include <exception>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
//Todas las excepciones lanzadas dentro del bloque _try_ pueden ser
|
||||||
|
// capturados por los siguientes manejadores _catch_.
|
||||||
|
try {
|
||||||
|
// No asignar excepciones en el heap usando _new_.
|
||||||
|
throw std::runtime_error("Ocurrió un problema");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Captura excepciones por referencia const si son objetos
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
std::cout << ex.what();
|
||||||
|
}
|
||||||
|
********************************************************************************
|
||||||
|
// Captura cualquier excepción no capturada por bloques _catch_ anteriores
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cout << "Excepción desconocida capturada";
|
||||||
|
throw; // Re-lanza la excepción
|
||||||
|
}
|
||||||
|
|
||||||
|
///////
|
||||||
|
// RAII
|
||||||
|
///////
|
||||||
|
|
||||||
|
// RAII significa "Resource Acquisition Is Initialization"
|
||||||
|
// (Adquisición de recursos es inicialización).
|
||||||
|
// A menudo se considera el paradigma más poderoso en C++
|
||||||
|
// Y el concepto es simple: un constructor de un objeto
|
||||||
|
// Adquiere recursos de ese objeto y el destructor les libera.
|
||||||
|
|
||||||
|
// Para entender cómo esto es útil,
|
||||||
|
// Considere una función que utiliza un identificador de archivo C:
|
||||||
|
void doSomethingWithAFile(const char* filename)
|
||||||
|
{
|
||||||
|
// Para empezar, asuma que nada puede fallar.
|
||||||
|
|
||||||
|
FILE* fh = fopen(filename, "r"); // Abre el archivo en modo lectura
|
||||||
|
|
||||||
|
doSomethingWithTheFile(fh);
|
||||||
|
doSomethingElseWithIt(fh);
|
||||||
|
|
||||||
|
fclose(fh); // Cierra el manejador de archivos
|
||||||
|
}
|
||||||
|
|
||||||
|
// Por desgracia, las cosas se complican rápidamente por el control de errores.
|
||||||
|
// Supongamos que fopen puede fallar, y que doSomethingWithTheFile y
|
||||||
|
// DoSomethingElseWithIt retornan códigos de error si fallan.
|
||||||
|
// (Excepciones son la mejor forma de manejar los fallos,
|
||||||
|
// pero algunos programadores, especialmente los que tienen un fondo C,
|
||||||
|
// estan en desacuerdo sobre la utilidad de las excepciones).
|
||||||
|
// Ahora tenemos que comprobar cada llamado por fallos y cerrar el manejador
|
||||||
|
// del archivo si se ha producido un problema.
|
||||||
|
bool doSomethingWithAFile(const char* filename)
|
||||||
|
{
|
||||||
|
FILE* fh = fopen(filename, "r"); // Abre el archivo en modo lectura
|
||||||
|
if (fh == nullptr) // El puntero retornado es nulo o falla.
|
||||||
|
return false; // Reporta el fallo a quien hizo el llamado.
|
||||||
|
|
||||||
|
// Asume que cada función retorna falso si falla
|
||||||
|
if (!doSomethingWithTheFile(fh)) {
|
||||||
|
fclose(fh); // Cierre el manejador de archivo para que no se filtre.
|
||||||
|
return false; // Propaga el error.
|
||||||
|
}
|
||||||
|
if (!doSomethingElseWithIt(fh)) {
|
||||||
|
fclose(fh); // Cierre el manejador de archivo para que no se filtre.
|
||||||
|
return false; // Propaga el error.
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fh); // Cierre el archivo.
|
||||||
|
return true; // Indica que todo funcionó correctamente.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Programadores C suelen limpiar esto un poco usando goto:
|
||||||
|
bool doSomethingWithAFile(const char* filename)
|
||||||
|
{
|
||||||
|
FILE* fh = fopen(filename, "r");
|
||||||
|
if (fh == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!doSomethingWithTheFile(fh))
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
if (!doSomethingElseWithIt(fh))
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
fclose(fh); // Cierre el archivo.
|
||||||
|
return true; // Indica que todo funcionó correctamente.
|
||||||
|
|
||||||
|
failure:
|
||||||
|
fclose(fh);
|
||||||
|
return false; // Propagate el error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si las funciones indican errores mediante excepciones,
|
||||||
|
// Las cosas son un poco más claras, pero pueden optimizarse mas.
|
||||||
|
void doSomethingWithAFile(const char* filename)
|
||||||
|
{
|
||||||
|
FILE* fh = fopen(filename, "r"); // Abrir el archivo en modo lectura
|
||||||
|
if (fh == nullptr)
|
||||||
|
throw std::runtime_error("No puede abrirse el archivo.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
doSomethingWithTheFile(fh);
|
||||||
|
doSomethingElseWithIt(fh);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
fclose(fh); // Asegúrese de cerrar el archivo si se produce un error.
|
||||||
|
throw; // Luego vuelve a lanzar la excepción.
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fh); // Cierra el archivo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare esto con el uso de la clase de flujo de archivos de C++ (fstream)
|
||||||
|
// fstream utiliza su destructor para cerrar el archivo.
|
||||||
|
// Los destructores son llamados automáticamente
|
||||||
|
// cuando un objeto queda fuera del ámbito.
|
||||||
|
void doSomethingWithAFile(const std::string& filename)
|
||||||
|
{
|
||||||
|
// ifstream es la abreviatura de el input file stream
|
||||||
|
std::ifstream fh(filename); // Abre el archivo
|
||||||
|
|
||||||
|
// Hacer algo con el archivo
|
||||||
|
doSomethingWithTheFile(fh);
|
||||||
|
doSomethingElseWithIt(fh);
|
||||||
|
|
||||||
|
} // El archivo se cierra automáticamente aquí por el destructor
|
||||||
|
|
||||||
|
|
||||||
|
// Esto tiene ventajas _enormes_:
|
||||||
|
// 1. No importa lo que pase,
|
||||||
|
// El recurso (en este caso el manejador de archivo) será limpiado.
|
||||||
|
// Una vez que escribes el destructor correctamente,
|
||||||
|
// Es _imposible_ olvidar cerrar el identificador y permitir
|
||||||
|
// fugas del recurso.
|
||||||
|
// 2. Tenga en cuenta que el código es mucho más limpio.
|
||||||
|
// El destructor se encarga de cerrar el archivo detrás de cámaras
|
||||||
|
// Sin que tenga que preocuparse por ello.
|
||||||
|
// 3. El código es seguro.
|
||||||
|
// Una excepción puede ser lanzado en cualquier lugar de la función
|
||||||
|
// y la limpieza ocurrirá.
|
||||||
|
|
||||||
|
// Todo el código idiomático C++ utiliza RAII ampliamente para todos los
|
||||||
|
// recursos.
|
||||||
|
// Otros ejemplos incluyen
|
||||||
|
// - Memoria usando unique_ptr y shared_ptr
|
||||||
|
// - Contenedores (Containers) - la biblioteca estándar linked list,
|
||||||
|
// vector (es decir, array con auto-cambio de tamaño), hash maps, etc.
|
||||||
|
// Destruimos todos sus contenidos de forma automática
|
||||||
|
// cuando quedan fuera del ámbito.
|
||||||
|
// - Mutex utilizando lock_guard y unique_lock
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// Cosas divertidas
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
// Aspectos de C ++ que pueden sorprender a los recién llegados
|
||||||
|
// (e incluso algunos veteranos).
|
||||||
|
// Esta sección es, por desgracia, salvajemente incompleta;
|
||||||
|
// C++ es uno de los lenguajes con los que mas facil te disparas en el pie.
|
||||||
|
|
||||||
|
// Tu puedes sobreescribir métodos privados!
|
||||||
|
class Foo {
|
||||||
|
virtual void bar();
|
||||||
|
};
|
||||||
|
class FooSub : public Foo {
|
||||||
|
virtual void bar(); // Sobreescribe Foo::bar!
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 0 == false == NULL (La mayoria de las veces)!
|
||||||
|
bool* pt = new bool;
|
||||||
|
*pt = 0; // Establece los puntos de valor de 'pt' en falso.
|
||||||
|
pt = 0; // Establece 'pt' al apuntador nulo. Ambas lineas compilan sin error.
|
||||||
|
|
||||||
|
// nullptr se supone que arregla un poco de ese tema:
|
||||||
|
int* pt2 = new int;
|
||||||
|
*pt2 = nullptr; // No compila
|
||||||
|
pt2 = nullptr; // Establece pt2 como null.
|
||||||
|
|
||||||
|
// Hay una excepción para los valores bool.
|
||||||
|
// Esto es para permitir poner a prueba punteros nulos con if (!ptr),
|
||||||
|
// pero como consecuencia se puede asignar nullptr a un bool directamente!
|
||||||
|
*pt = nullptr; // Esto todavía compila, a pesar de que '*pt' es un bool!
|
||||||
|
|
||||||
|
// '=' != '=' != '='!
|
||||||
|
// Llama Foo::Foo(const Foo&) o alguna variante (mira movimientos semanticos)
|
||||||
|
// copia del constructor.
|
||||||
|
Foo f2;
|
||||||
|
Foo f1 = f2;
|
||||||
|
|
||||||
|
// Llama Foo::Foo(const Foo&) o variante, pero solo copia el 'Foo' parte de
|
||||||
|
// 'fooSub'. Cualquier miembro extra de 'fooSub' se descarta. Este
|
||||||
|
// comportamiento horrible se llama "Corte de objetos."
|
||||||
|
FooSub fooSub;
|
||||||
|
Foo f1 = fooSub;
|
||||||
|
|
||||||
|
// Llama a Foo::operator=(Foo&) o variantes.
|
||||||
|
Foo f1;
|
||||||
|
f1 = f2;
|
||||||
|
|
||||||
|
|
||||||
|
// Cómo borrar realmente un contenedor:
|
||||||
|
class Foo { ... };
|
||||||
|
vector<Foo> v;
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
v.push_back(Foo());
|
||||||
|
// La siguiente línea establece el tamaño de v en 0,
|
||||||
|
// pero los destructores no son llamados y los recursos no se liberan!
|
||||||
|
|
||||||
|
v.empty();
|
||||||
|
v.push_back(Foo()); // Nuevo valor se copia en el primer Foo que insertamos
|
||||||
|
|
||||||
|
// En verdad destruye todos los valores en v.
|
||||||
|
// Consulta la sección acerca de los objetos temporales para la
|
||||||
|
// explicación de por qué esto funciona.
|
||||||
|
v.swap(vector<Foo>());
|
||||||
|
|
||||||
|
```
|
||||||
|
Otras lecturas:
|
||||||
|
|
||||||
|
Una referencia del lenguaje hasta a la fecha se puede encontrar en
|
||||||
|
<http://cppreference.com/w/cpp>
|
||||||
|
|
||||||
|
Recursos adicionales se pueden encontrar en <http://cplusplus.com>
|
@ -11,18 +11,18 @@ lang: es-es
|
|||||||
---
|
---
|
||||||
|
|
||||||
Git es un sistema de control de versiones distribuido diseñado para manejar
|
Git es un sistema de control de versiones distribuido diseñado para manejar
|
||||||
cualquier tipo de proyecto ya sea largos o pequeños, con velocidad y eficiencia.
|
cualquier tipo de proyecto, ya sea grande o pequeño, con velocidad y eficiencia.
|
||||||
|
|
||||||
Git realiza esto haciendo "snapshots" del proyecto, con ello permite
|
Git realiza esto haciendo "snapshots" del proyecto, con ello permite
|
||||||
versionar y administrar nuestro código fuente.
|
versionar y administrar nuestro código fuente.
|
||||||
|
|
||||||
## Versionamiento, conceptos.
|
## Versionamiento, conceptos.
|
||||||
|
|
||||||
### Que es el control de versiones?
|
### ¿Qué es el control de versiones?
|
||||||
El control de versiones es un sistema que guarda todos los cambios realizados a
|
El control de versiones es un sistema que guarda todos los cambios realizados en
|
||||||
uno o varios archivos, a lo largo del tiempo.
|
uno o varios archivos, a lo largo del tiempo.
|
||||||
|
|
||||||
### Versionamiento centralizado vs Versionamiento Distribuido.
|
### Versionamiento centralizado vs versionamiento distribuido.
|
||||||
|
|
||||||
+ El versionamiento centralizado se enfoca en sincronizar, rastrear, y respaldar
|
+ El versionamiento centralizado se enfoca en sincronizar, rastrear, y respaldar
|
||||||
archivos.
|
archivos.
|
||||||
@ -31,15 +31,15 @@ uno o varios archivos, a lo largo del tiempo.
|
|||||||
+ El versionamiento distribuido no tiene una estructura definida, incluso se
|
+ El versionamiento distribuido no tiene una estructura definida, incluso se
|
||||||
puede mantener el estilo de los repositorios SVN con git.
|
puede mantener el estilo de los repositorios SVN con git.
|
||||||
|
|
||||||
[Informacion adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones)
|
[Información adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones)
|
||||||
|
|
||||||
### Por que usar Git?
|
### ¿Por qué usar Git?
|
||||||
|
|
||||||
* Se puede trabajar sin conexion.
|
* Se puede trabajar sin conexión.
|
||||||
* Colaborar con otros es sencillo!.
|
* ¡Colaborar con otros es sencillo!.
|
||||||
* Derivar, Crear ramas del proyecto (aka: Branching) es facil!.
|
* Derivar, crear ramas del proyecto (aka: Branching) es fácil.
|
||||||
* Combinar (aka: Merging)
|
* Combinar (aka: Merging)
|
||||||
* Git es rapido.
|
* Git es rápido.
|
||||||
* Git es flexible.
|
* Git es flexible.
|
||||||
|
|
||||||
## Arquitectura de Git.
|
## Arquitectura de Git.
|
||||||
@ -47,11 +47,11 @@ uno o varios archivos, a lo largo del tiempo.
|
|||||||
### Repositorio
|
### Repositorio
|
||||||
|
|
||||||
Un repositorio es un conjunto de archivos, directorios, registros, cambios (aka:
|
Un repositorio es un conjunto de archivos, directorios, registros, cambios (aka:
|
||||||
comits), y encabezados (aka: heads). Imagina que un repositorio es una clase,
|
commits), y encabezados (aka: heads). Imagina que un repositorio es una clase,
|
||||||
y que sus atributos otorgan acceso al historial del elemento, ademas de otras
|
y que sus atributos otorgan acceso al historial del elemento, además de otras
|
||||||
cosas.
|
cosas.
|
||||||
|
|
||||||
Un repositorio esta compuesto por la carpeta .git y un "arbol de trabajo".
|
Un repositorio esta compuesto por la carpeta .git y un "árbol de trabajo".
|
||||||
|
|
||||||
### Directorio .git (componentes del repositorio)
|
### Directorio .git (componentes del repositorio)
|
||||||
|
|
||||||
@ -62,38 +62,38 @@ y mas.
|
|||||||
|
|
||||||
### Directorio de trabajo (componentes del repositorio)
|
### Directorio de trabajo (componentes del repositorio)
|
||||||
|
|
||||||
Es basicamente los directorios y archivos dentro del repositorio. La mayorioa de
|
Es básicamente los directorios y archivos dentro del repositorio. La mayoría de
|
||||||
las veces se le llama "directorio de trabajo".
|
las veces se le llama "directorio de trabajo".
|
||||||
|
|
||||||
### Inidice (componentes del directorio .git)
|
### Índice (componentes del directorio .git)
|
||||||
|
|
||||||
El inidice es la area de inicio en git. Es basicamente la capa que separa el
|
El índice es el área de inicio en git. Es básicamente la capa que separa el
|
||||||
directorio de trabajo, del repositorio en git. Esto otorga a los desarrolladores
|
directorio de trabajo del repositorio en git. Esto otorga a los desarrolladores
|
||||||
mas poder sobre lo que envia y recibe en el repositorio.
|
más poder sobre lo que se envía y se recibe del repositorio.
|
||||||
|
|
||||||
### Commit (aka: cambios)
|
### Commit (aka: cambios)
|
||||||
|
|
||||||
Un commit es una captura de un conjunto de cambios, o modificaciones hechas en
|
Un commit es una captura de un conjunto de cambios, o modificaciones hechas en
|
||||||
el directorio de trabajo. Por ejemplo, si se añaden 5 archivos, se remueven 2,
|
el directorio de trabajo. Por ejemplo, si se añaden 5 archivos, se eliminan 2,
|
||||||
estos cambios se almacenaran en un commit (aka: captura). Este commit puede ser o
|
estos cambios se almacenarán en un commit (aka: captura). Este commit puede ser o
|
||||||
no ser enviado (aka: "pusheado") hacia un repositorio.
|
no ser enviado (aka: "pusheado") hacia un repositorio.
|
||||||
|
|
||||||
### Branch (rama)
|
### Branch (rama)
|
||||||
|
|
||||||
Un "branch", es escencialmente un apuntador hacia el ultimo commit (cambio
|
Un "branch", es escencialmente un apuntador hacia el último commit (cambio
|
||||||
registrado) que se ha realizado. A medida que se realizan mas commits, este
|
registrado) que se ha realizado. A medida que se realizan más commits, este
|
||||||
apuntador se actualizara automaticamente hacia el ultimo commit.
|
apuntador se actualizará automaticamente hacia el ultimo commit.
|
||||||
|
|
||||||
### "HEAD" y "head" (component of .git dir)
|
### "HEAD" y "head" (componentes del directorio .git)
|
||||||
|
|
||||||
"HEAD" es un apuntador hacia la rama (branch) que se esta utilizando. Un
|
"HEAD" es un apuntador hacia la rama (branch) que se esta utilizando. Un
|
||||||
repositorio solo puede tener un HEAD activo. En cambio "head", es un apuntador a
|
repositorio solo puede tener un HEAD activo. En cambio "head", es un apuntador a
|
||||||
cualquier commit realizado, un repositorio puede tener cualquier numero de
|
cualquier commit realizado, un repositorio puede tener cualquier número de
|
||||||
"heads".
|
"heads".
|
||||||
|
|
||||||
### conceptos - recursos.
|
### conceptos - recursos.
|
||||||
|
|
||||||
* [Git para informaticos](http://eagain.net/articles/git-for-computer-scientists/)
|
* [Git para informáticos](http://eagain.net/articles/git-for-computer-scientists/)
|
||||||
* [Git para diseñadores](http://hoth.entp.com/output/git_for_designers.html)
|
* [Git para diseñadores](http://hoth.entp.com/output/git_for_designers.html)
|
||||||
|
|
||||||
|
|
||||||
@ -102,8 +102,8 @@ cualquier commit realizado, un repositorio puede tener cualquier numero de
|
|||||||
|
|
||||||
### init
|
### init
|
||||||
|
|
||||||
Crear un repositorio de git vacio. Las configuraciones, informacion almacenada y
|
Crear un repositorio de git vacio. Las configuraciones, información almacenada y
|
||||||
demas son almacenadas en el directorio ".git".
|
demás son almacenadas en el directorio ".git".
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git init
|
$ git init
|
||||||
@ -115,7 +115,7 @@ Se utiliza para configurar las opciones ya sea globalmente, o solamente en el
|
|||||||
repositorio.
|
repositorio.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Imprime y guarda algunas variables de configuracion basicas. (Globalmente)
|
# Imprime y guarda algunas variables de configuracion básicas. (Globalmente)
|
||||||
$ git config --global user.email
|
$ git config --global user.email
|
||||||
$ git config --global user.name
|
$ git config --global user.name
|
||||||
|
|
||||||
@ -123,15 +123,15 @@ $ git config --global user.email "corre@gmail.com"
|
|||||||
$ git config --global user.name "nombre"
|
$ git config --global user.name "nombre"
|
||||||
```
|
```
|
||||||
|
|
||||||
[Mas sobre git config.](http://git-scm.com/book/es/Personalizando-Git-Configuración-de-Git)
|
[Más sobre git config.](http://git-scm.com/book/es/Personalizando-Git-Configuración-de-Git)
|
||||||
|
|
||||||
### help
|
### help
|
||||||
|
|
||||||
Otorga un accceso rapido a una guia extremadamente detallada de cada comando en
|
Otorga un accceso rápido a una guía extremadamente detallada de cada comando en
|
||||||
git. O puede ser usada simplemente como un recordatorio de estos.
|
git. O puede ser usada simplemente como un recordatorio de estos.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Una vista rapido de los comandos disponibles.
|
# Una vista rápida de los comandos disponibles.
|
||||||
$ git help
|
$ git help
|
||||||
|
|
||||||
# Chequear todos los comandos disponibles
|
# Chequear todos los comandos disponibles
|
||||||
@ -146,12 +146,12 @@ $ git help init
|
|||||||
|
|
||||||
### status
|
### status
|
||||||
|
|
||||||
Muestra las diferencias entre el archivo indice y el commit al cual apunta el
|
Muestra las diferencias entre el archivo índice y el commit al cual apunta el
|
||||||
HEAD actualmente.
|
HEAD actualmente.
|
||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Mostrara el "branch", archivos sin añadir a la repo, cambios y otras
|
# Mostrará el "branch", archivos sin añadir al repo, cambios y otras
|
||||||
# diferencias
|
# diferencias
|
||||||
$ git status
|
$ git status
|
||||||
|
|
||||||
@ -161,9 +161,9 @@ $ git help status
|
|||||||
|
|
||||||
### add
|
### add
|
||||||
|
|
||||||
Para añadir archivos al arbol (directorio, repositorio) de trabajo. Si no se
|
Para añadir archivos al árbol (directorio, repositorio) de trabajo. Si no se
|
||||||
utiliza `git add`, los nuevos archivos no se añadiran al arbol de trabajo, por
|
utiliza `git add`, los nuevos archivos no se añadirán al arbol de trabajo, por
|
||||||
lo que no se incluiran en los commits (cambios).
|
lo que no se incluirán en los commits (cambios).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Añade un archivo en el directorio de trabajo actual.
|
# Añade un archivo en el directorio de trabajo actual.
|
||||||
@ -178,31 +178,31 @@ $ git add ./*.py
|
|||||||
|
|
||||||
### branch
|
### branch
|
||||||
|
|
||||||
Administra las ramas del repositorios ("branches"). Puedes ver, editar, crear y
|
Administra las ramas del repositorio ("branches"). Puedes ver, editar, crear y
|
||||||
borrar ramas ("branches"), usando este comando.
|
borrar ramas ("branches"), usando este comando.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# lista todas las ramas (remotas y locales)
|
# lista todas las ramas (remotas y locales)
|
||||||
$ git branch -a
|
$ git branch -a
|
||||||
|
|
||||||
# Añada una nueva rama ("branch").
|
# Añadir una nueva rama ("branch").
|
||||||
$ git branch branchNueva
|
$ git branch branchNueva
|
||||||
|
|
||||||
# Eliminar una rama.
|
# Eliminar una rama.
|
||||||
$ git branch -d branchFoo
|
$ git branch -d branchFoo
|
||||||
|
|
||||||
# Renombra una rama.
|
# Renombrar una rama.
|
||||||
# git branch -m <anterior> <nuevo>
|
# git branch -m <anterior> <nuevo>
|
||||||
$ git branch -m youngling padawan
|
$ git branch -m youngling padawan
|
||||||
|
|
||||||
# Edita la descripcion de la rama.
|
# Editar la descripcion de la rama.
|
||||||
$ git branch master --edit-description
|
$ git branch master --edit-description
|
||||||
```
|
```
|
||||||
|
|
||||||
### checkout
|
### checkout
|
||||||
|
|
||||||
Actualiza todos los archivos en el directorio de trabajo para que sean igual que
|
Actualiza todos los archivos en el directorio de trabajo para que sean igual que
|
||||||
las versiones almacenadas en el indice, o en un arbol de trabajo especificado.
|
las versiones almacenadas en el índice, o en un árbol de trabajo especificado.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Despachar un repositorio. - Por defecto la master branch. (la rama principal llamada 'master')
|
# Despachar un repositorio. - Por defecto la master branch. (la rama principal llamada 'master')
|
||||||
@ -215,8 +215,8 @@ $ git checkout -b jdei
|
|||||||
|
|
||||||
### clone
|
### clone
|
||||||
|
|
||||||
Clona, o copia, una repo existente en un nuevo directorio. Tambien añada el
|
Clona, o copia, un repositorio existente en un nuevo directorio. También añade el
|
||||||
seguimiento hacia las ramas existentes del repo que ha sido clonada, lo que
|
seguimiento hacia las ramas existentes del repositorio que ha sido clonado, lo que
|
||||||
permite subir (push) los archivos hacia una rama remota.
|
permite subir (push) los archivos hacia una rama remota.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -226,60 +226,60 @@ $ git clone https://github.com/jquery/jquery.git
|
|||||||
|
|
||||||
### commit
|
### commit
|
||||||
|
|
||||||
Almacena los cambios que almacenados en el indice en un nuevo "commit". Este
|
Almacena el contenido actual del índice en un nuevo "commit". Este
|
||||||
commit contiene los cambios hechos mas un resumen hecho por el desarrollador.
|
commit contiene los cambios hechos más un resumen proporcionado por el desarrollador.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# commit with a message
|
|
||||||
# realizar un commit y añadirle un mensaje.
|
# realizar un commit y añadirle un mensaje.
|
||||||
$ git commit -m "jedi anakin wil be - jedis.list"
|
$ git commit -m "jedi anakin wil be - jedis.list"
|
||||||
```
|
```
|
||||||
|
|
||||||
### diff
|
### diff
|
||||||
|
|
||||||
Muestra las diferencias entre un archivo en el directorio de trabajo, el indice
|
Muestra las diferencias entre un archivo en el directorio de trabajo, el índice
|
||||||
y commits.
|
y los commits.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Muestra la diferencia entre un directorio de trabajo y el indice.
|
# Muestra la diferencia entre un directorio de trabajo y el índice.
|
||||||
$ git diff
|
$ git diff
|
||||||
|
|
||||||
# Muestra la diferencia entre el indice y los commits mas recientes.
|
# Muestra la diferencia entre el índice y los commits más recientes.
|
||||||
$ git diff --cached
|
$ git diff --cached
|
||||||
|
|
||||||
# Muestra la diferencia entre el directorio de trabajo y el commit mas reciente.
|
# Muestra la diferencia entre el directorio de trabajo y el commit más reciente.
|
||||||
$ git diff HEAD
|
$ git diff HEAD
|
||||||
```
|
```
|
||||||
|
|
||||||
### grep
|
### grep
|
||||||
|
|
||||||
Permite realizar una busqueda rapida en un repositorio.
|
Permite realizar una busqueda rápida en un repositorio.
|
||||||
|
|
||||||
Configuracion opcionales:
|
Configuraciones opcionales:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Gracias a Travis Jeffery por compartir lo siguiente.
|
# Gracias a Travis Jeffery por compartir lo siguiente.
|
||||||
# Permite mostrar numeros de lineas en la salida de grep.
|
# Permite mostrar numeros de lineas en la salida de grep.
|
||||||
$ git config --global grep.lineNumber true
|
$ git config --global grep.lineNumber true
|
||||||
|
|
||||||
# Realiza una busqueda mas lejible, incluyendo agrupacion.
|
# Realiza una búsqueda mas legible, incluyendo agrupación.
|
||||||
$ git config --global alias.g "grep --break --heading --line-number"
|
$ git config --global alias.g "grep --break --heading --line-number"
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Busca por "unaVariable" en todos los archivos ,java
|
# Busca por "unaVariable" en todos los archivos .java
|
||||||
$ git grep 'unaVariable' -- '*.java'
|
$ git grep 'unaVariable' -- '*.java'
|
||||||
|
|
||||||
# Busca por una linea que contenga "nombreArreglo" y , "agregar" o "remover"
|
# Busca por una línea que contenga "nombreArreglo" y "agregar" o "remover"
|
||||||
$ git grep -e 'nombreArreglo' --and \( -e agregar -e remover \)
|
$ git grep -e 'nombreArreglo' --and \( -e agregar -e remover \)
|
||||||
```
|
```
|
||||||
|
|
||||||
Mas ejemplos:
|
Más ejemplos:
|
||||||
[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
|
||||||
|
|
||||||
Muestra los commits (cambios) registrados en el repositotrio.
|
Muestra los commits (cambios) registrados en el repositorio.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Muestra todos los commits.
|
# Muestra todos los commits.
|
||||||
@ -288,7 +288,7 @@ $ git log
|
|||||||
# Muestra un numero x de commits.
|
# Muestra un numero x de commits.
|
||||||
$ git log -n 10
|
$ git log -n 10
|
||||||
|
|
||||||
# Muestra solo los commits que se han combinado en el hisotrial
|
# Muestra solo los commits que se han combinado en el historial.
|
||||||
$ git log --merges
|
$ git log --merges
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -301,7 +301,7 @@ que se trabaja.
|
|||||||
# Combina la rama especificada en la rama actual.
|
# Combina la rama especificada en la rama actual.
|
||||||
$ git merge jediMaster
|
$ git merge jediMaster
|
||||||
|
|
||||||
# Siempre genere un solo merge commit cuando se utilizar merge.
|
# Siempre genere un solo merge commit cuando se utiliza merge.
|
||||||
$ git merge --no-ff jediMaster
|
$ git merge --no-ff jediMaster
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -310,7 +310,7 @@ $ git merge --no-ff jediMaster
|
|||||||
Renombra o mueve un archivo
|
Renombra o mueve un archivo
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Renombrando un archivo
|
# Renombrando un archivo.
|
||||||
$ git mv HolaMundo.c AdiosMundo.c
|
$ git mv HolaMundo.c AdiosMundo.c
|
||||||
|
|
||||||
# Moviendo un archivo.
|
# Moviendo un archivo.
|
||||||
@ -322,33 +322,31 @@ $ git mv -f archivoA archivoB
|
|||||||
|
|
||||||
### pull
|
### pull
|
||||||
|
|
||||||
Sube (Empuja) de un repositorio y lo combina en otro en una rama diferente.
|
Trae los cambios de un repositorio y los combina en otro en una rama diferente.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Actualiza el repositorio local, combinando los nuevos cambios.
|
# Actualiza el repositorio local, combinando los nuevos cambios
|
||||||
# de las ramas remotas "origin" y "master".
|
# de las ramas remotas "origin" y "master".
|
||||||
# from the remote "origin" and "master" branch.
|
|
||||||
# git pull <remota> <rama>
|
# git pull <remota> <rama>
|
||||||
$ git pull origin master
|
$ git pull origin master
|
||||||
```
|
```
|
||||||
|
|
||||||
### push
|
### push
|
||||||
|
|
||||||
Push and merge changes from a branch to a remote & branch.
|
Envía y combina los cambios de un repositorio local a un repositorio y rama remotos.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Push and merge changes from a local repo to a
|
# Envía y combina cambios de un repositorio local hacia un repositorio remoto
|
||||||
# Empuja y combina cambios de un repositorio local hacian un repositorio remoto
|
|
||||||
# llamados "origin" y "master", respectivamente.
|
# llamados "origin" y "master", respectivamente.
|
||||||
# git push <remota> <rama>
|
# git push <remota> <rama>
|
||||||
# git push => por defecto es lo mismo que poner => git push origin master
|
# git push => por defecto es lo mismo que poner => git push origin master
|
||||||
$ git push origin master
|
$ git push origin master
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### rebase
|
||||||
|
|
||||||
Toma todos los cambios que fueron registrados en una rama, y los repite dentro
|
Toma todos los cambios que fueron registrados en una rama, y los repite dentro
|
||||||
de otra rama.
|
de otra rama. *No reescribe los commits que se han empujado antes a un repositorio público.*
|
||||||
*No reescribe los commits que se han empujado antes a un repositorio publico*
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Integrar ramaExperimento dentro de la rama "master"
|
# Integrar ramaExperimento dentro de la rama "master"
|
||||||
@ -356,47 +354,47 @@ de otra rama.
|
|||||||
$ git rebase master experimentBranch
|
$ git rebase master experimentBranch
|
||||||
```
|
```
|
||||||
|
|
||||||
[Informacion adicional.](http://git-scm.com/book/es/Ramificaciones-en-Git-Procedimientos-básicos-para-ramificar-y-fusionar)
|
[Información adicional.](http://git-scm.com/book/es/Ramificaciones-en-Git-Procedimientos-básicos-para-ramificar-y-fusionar)
|
||||||
|
|
||||||
### reset (precaucion)
|
### reset (precaución)
|
||||||
|
|
||||||
Reinicia el cabezal actual hacia un estado especificado. Esto permite desacer
|
Reinicia el HEAD actual hacia un estado especificado. Esto permite deshacer
|
||||||
combinaciones (merges), pulls, commits, adds y mas. Es un comando util, pero
|
combinaciones (merges), pulls, commits, adds y más. Es un comando útil, pero
|
||||||
tambien peligrosa si no se sabe lo que se hace.
|
tambien peligroso si no se sabe lo que se hace.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Reinica el area principal, con el ultimo cambio registrado. (deja los
|
# Reinicia el área principal, con el último cambio registrado. (deja los
|
||||||
# directorios sin cambios)
|
# directorios sin cambios)
|
||||||
$ git reset
|
$ git reset
|
||||||
|
|
||||||
# Reinica el area principal, con el ultimo cambio registrado, y reescribe el
|
# Reinicia el área principal, con el último cambio registrado, y reescribe el
|
||||||
# directorio de trabajo.
|
# directorio de trabajo.
|
||||||
$ git reset --hard
|
$ git reset --hard
|
||||||
|
|
||||||
# Mueve la rama actual hacia el commit especificado (no realiza cambios a los
|
# Mueve la rama actual hacia el commit especificado (no realiza cambios a los
|
||||||
# directorios), todos los cambios aun existen el directorio.
|
# directorios), todos los cambios aún existen el directorio.
|
||||||
$ git reset 31f2bb1
|
$ git reset 31f2bb1
|
||||||
|
|
||||||
# Mueve la rama actual devuelta a un commit especificado asi como el
|
# Mueve la rama actual devuelta a un commit especificado, así como el
|
||||||
# directorios (borra todos los cambios que no fueron registros y todos los
|
# directorio (borra todos los cambios que no fueron registrados y todos los
|
||||||
# cambios realizados despues del commit especificado).
|
# cambios realizados después del commit especificado).
|
||||||
$ git reset --hard 31f2bb1
|
$ git reset --hard 31f2bb1
|
||||||
```
|
```
|
||||||
|
|
||||||
### rm
|
### rm
|
||||||
|
|
||||||
Lo contrario de git add, git rm remueve los archivos del directorio de trabajo
|
Lo contrario de git add, git rm elimina los archivos del directorio de trabajo
|
||||||
actual.
|
actual.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Remueve FooBar.c
|
# Elimina FooBar.c
|
||||||
$ git rm FooBar.c
|
$ git rm FooBar.c
|
||||||
|
|
||||||
# Remueve un archivo de un directorio.
|
# Elimina un archivo de un directorio.
|
||||||
$ git rm /directorio/del/archivo/FooBar.c
|
$ git rm /directorio/del/archivo/FooBar.c
|
||||||
```
|
```
|
||||||
|
|
||||||
## Informacion Adicional
|
## Información Adicional
|
||||||
|
|
||||||
* [tryGit - Una forma entretenida y rapida de aprender Git.](http://try.github.io/levels/1/challenges/1)
|
* [tryGit - Una forma entretenida y rapida de aprender Git.](http://try.github.io/levels/1/challenges/1)
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ con Java para aplicaciones más complejas. Debido a su integracion estrecha con
|
|||||||
web y soporte por defecto de los navegadores modernos se ha vuelto mucho más común
|
web y soporte por defecto de los navegadores modernos se ha vuelto mucho más común
|
||||||
para front-end que Java.
|
para front-end que Java.
|
||||||
|
|
||||||
JavaScript no sólo se limita a los navegadores web, aunque: Node.js, Un proyecto que proporciona un entorno de ejecución independiente para el motor V8 de Google Chrome, se está volviendo más y más popular.
|
Aunque JavaScript no sólo se limita a los navegadores web: Node.js, Un proyecto que proporciona un entorno de ejecución independiente para el motor V8 de Google Chrome, se está volviendo más y más popular.
|
||||||
|
|
||||||
¡La retroalimentación es bienvenida! Puedes encontrarme en:
|
¡La retroalimentación es bienvenida! Puedes encontrarme en:
|
||||||
[@adambrenecki](https://twitter.com/adambrenecki), o
|
[@adambrenecki](https://twitter.com/adambrenecki), o
|
||||||
@ -30,7 +30,7 @@ JavaScript no sólo se limita a los navegadores web, aunque: Node.js, Un proyect
|
|||||||
// Cada sentencia puede ser terminada con punto y coma ;
|
// Cada sentencia puede ser terminada con punto y coma ;
|
||||||
hazAlgo();
|
hazAlgo();
|
||||||
|
|
||||||
// ... aunque no es necesario, ya que el punto y coma se agrega automaticamente
|
// ... aunque no es necesario, ya que el punto y coma se agrega automáticamente
|
||||||
// cada que se detecta una nueva línea, a excepción de algunos casos.
|
// cada que se detecta una nueva línea, a excepción de algunos casos.
|
||||||
hazAlgo()
|
hazAlgo()
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ null == undefined; // = true
|
|||||||
null === undefined; // false
|
null === undefined; // false
|
||||||
|
|
||||||
// Los Strings funcionan como arreglos de caracteres
|
// Los Strings funcionan como arreglos de caracteres
|
||||||
// Puedes accesar a cada caracter con la función charAt()
|
// Puedes acceder a cada caracter con la función charAt()
|
||||||
"Este es un String".charAt(0); // = 'E'
|
"Este es un String".charAt(0); // = 'E'
|
||||||
|
|
||||||
// ...o puedes usar la función substring() para acceder a pedazos más grandes
|
// ...o puedes usar la función substring() para acceder a pedazos más grandes
|
||||||
@ -124,7 +124,7 @@ undefined; // usado para indicar que un valor no está presente actualmente
|
|||||||
// (aunque undefined es un valor en sí mismo)
|
// (aunque undefined es un valor en sí mismo)
|
||||||
|
|
||||||
// false, null, undefined, NaN, 0 y "" es false; todo lo demás es true.
|
// false, null, undefined, NaN, 0 y "" es false; todo lo demás es true.
|
||||||
// Note que 0 is false y "0" es true, a pesar de que 0 == "0".
|
// Note que 0 es false y "0" es true, a pesar de que 0 == "0".
|
||||||
// Aunque 0 === "0" sí es false.
|
// Aunque 0 === "0" sí es false.
|
||||||
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
@ -186,7 +186,7 @@ miObjeto.miLlave; // = "miValor"
|
|||||||
// agregar nuevas llaves.
|
// agregar nuevas llaves.
|
||||||
miObjeto.miTerceraLlave = true;
|
miObjeto.miTerceraLlave = true;
|
||||||
|
|
||||||
// Si intentas accesar con una llave que aún no está asignada tendrás undefined.
|
// Si intentas acceder con una llave que aún no está asignada tendrás undefined.
|
||||||
miObjeto.miCuartaLlave; // = undefined
|
miObjeto.miCuartaLlave; // = undefined
|
||||||
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
@ -301,7 +301,7 @@ i; // = 5 - en un lenguaje que da ámbitos por bloque esto sería undefined, per
|
|||||||
//inmediatamente", que preveé variables temporales de fugarse al ámbito global
|
//inmediatamente", que preveé variables temporales de fugarse al ámbito global
|
||||||
(function(){
|
(function(){
|
||||||
var temporal = 5;
|
var temporal = 5;
|
||||||
// Podemos accesar al ámbito global asignando al 'objeto global', el cual
|
// Podemos acceder al ámbito global asignando al 'objeto global', el cual
|
||||||
// en un navegador siempre es 'window'. El objeto global puede tener
|
// en un navegador siempre es 'window'. El objeto global puede tener
|
||||||
// un nombre diferente en ambientes distintos, por ejemplo Node.js .
|
// un nombre diferente en ambientes distintos, por ejemplo Node.js .
|
||||||
window.permanente = 10;
|
window.permanente = 10;
|
||||||
@ -321,7 +321,7 @@ function decirHolaCadaCincoSegundos(nombre){
|
|||||||
alert(texto);
|
alert(texto);
|
||||||
}
|
}
|
||||||
setTimeout(interna, 5000);
|
setTimeout(interna, 5000);
|
||||||
// setTimeout es asíncrono, así que la funcion decirHolaCadaCincoSegundos
|
// setTimeout es asíncrono, así que la función decirHolaCadaCincoSegundos
|
||||||
// terminará inmediatamente, y setTimeout llamará a interna() a los cinco segundos
|
// terminará inmediatamente, y setTimeout llamará a interna() a los cinco segundos
|
||||||
// Como interna está "cerrada dentro de" decirHolaCadaCindoSegundos, interna todavía tiene
|
// Como interna está "cerrada dentro de" decirHolaCadaCindoSegundos, interna todavía tiene
|
||||||
// acceso a la variable 'texto' cuando es llamada.
|
// acceso a la variable 'texto' cuando es llamada.
|
||||||
@ -339,7 +339,7 @@ var miObjeto = {
|
|||||||
};
|
};
|
||||||
miObjeto.miFuncion(); // = "¡Hola Mundo!"
|
miObjeto.miFuncion(); // = "¡Hola Mundo!"
|
||||||
|
|
||||||
// Cuando las funciones de un objeto son llamadas, pueden accesar a las variables
|
// Cuando las funciones de un objeto son llamadas, pueden acceder a las variables
|
||||||
// del objeto con la palabra clave 'this'.
|
// del objeto con la palabra clave 'this'.
|
||||||
miObjeto = {
|
miObjeto = {
|
||||||
miString: "¡Hola Mundo!",
|
miString: "¡Hola Mundo!",
|
||||||
@ -401,11 +401,11 @@ var MiConstructor = function(){
|
|||||||
miNuevoObjeto = new MiConstructor(); // = {miNumero: 5}
|
miNuevoObjeto = new MiConstructor(); // = {miNumero: 5}
|
||||||
miNuevoObjeto.miNumero; // = 5
|
miNuevoObjeto.miNumero; // = 5
|
||||||
|
|
||||||
// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a accesar a una
|
// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a acceder a una
|
||||||
// propiedad en un objeto que no existe en el objeto el intérprete buscará en
|
// propiedad en un objeto que no existe en el objeto el intérprete buscará en
|
||||||
// el prototipo.
|
// el prototipo.
|
||||||
|
|
||||||
// Algunas implementaciones de JavaScript te permiten accesar al prototipo de
|
// Algunas implementaciones de JavaScript te permiten acceder al prototipo de
|
||||||
// un objeto con la propiedad __proto__. Mientras que esto es útil para explicar
|
// un objeto con la propiedad __proto__. Mientras que esto es útil para explicar
|
||||||
// prototipos, no es parte del estándar; veremos formas estándar de usar prototipos
|
// prototipos, no es parte del estándar; veremos formas estándar de usar prototipos
|
||||||
// más adelante.
|
// más adelante.
|
||||||
@ -440,7 +440,7 @@ miPrototipo.sentidoDeLaVida = 43;
|
|||||||
miObjeto.sentidoDeLaVida; // = 43
|
miObjeto.sentidoDeLaVida; // = 43
|
||||||
|
|
||||||
// Mencionabamos anteriormente que __proto__ no está estandarizado, y que no
|
// Mencionabamos anteriormente que __proto__ no está estandarizado, y que no
|
||||||
// existe una forma estándar de accesar al prototipo de un objeto. De todas formas.
|
// existe una forma estándar de acceder al prototipo de un objeto. De todas formas.
|
||||||
// hay dos formas de crear un nuevo objeto con un prototipo dado.
|
// hay dos formas de crear un nuevo objeto con un prototipo dado.
|
||||||
|
|
||||||
// El primer método es Object.create, el cual es una adición reciente a JavaScript,
|
// El primer método es Object.create, el cual es una adición reciente a JavaScript,
|
||||||
@ -476,10 +476,7 @@ typeof miNumero; // = 'number'
|
|||||||
typeof miNumeroObjeto; // = 'object'
|
typeof miNumeroObjeto; // = 'object'
|
||||||
miNumero === miNumeroObjeyo; // = false
|
miNumero === miNumeroObjeyo; // = false
|
||||||
if (0){
|
if (0){
|
||||||
// Este código no se ejecutara porque 0 es false.
|
// Este código no se ejecutará porque 0 es false.
|
||||||
}
|
|
||||||
if (Number(0)){
|
|
||||||
// Este código sí se ejecutara, puesto que Number(0) es true.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aún así, los objetos que envuelven y los prototipos por defecto comparten
|
// Aún así, los objetos que envuelven y los prototipos por defecto comparten
|
||||||
|
@ -21,22 +21,22 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead
|
|||||||
"llaves": "siempre debe estar entre comillas (ya sean dobles o simples)",
|
"llaves": "siempre debe estar entre comillas (ya sean dobles o simples)",
|
||||||
"numeros": 0,
|
"numeros": 0,
|
||||||
"strings": "Høla, múndo. Todo el unicode está permitido, así como \"escapar\".",
|
"strings": "Høla, múndo. Todo el unicode está permitido, así como \"escapar\".",
|
||||||
"soporta booleanos?": true,
|
"¿soporta booleanos?": true,
|
||||||
"vacios": null,
|
"vacíos": null,
|
||||||
|
|
||||||
"numero grande": 1.2e+100,
|
"numero grande": 1.2e+100,
|
||||||
|
|
||||||
"objetos": {
|
"objetos": {
|
||||||
"comentario": "La mayoria de tu estructura vendra de objetos.",
|
"comentario": "La mayoría de tu estructura vendrá de objetos.",
|
||||||
|
|
||||||
"arreglo": [0, 1, 2, 3, "Los arreglos pueden contener cualquier cosa.", 5],
|
"arreglo": [0, 1, 2, 3, "Los arreglos pueden contener cualquier cosa.", 5],
|
||||||
|
|
||||||
"otro objeto": {
|
"otro objeto": {
|
||||||
"comentario": "Estas cosas pueden estar anidadas, muy util."
|
"comentario": "Estas cosas pueden estar anidadas, muy útil."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"tonteria": [
|
"tontería": [
|
||||||
{
|
{
|
||||||
"fuentes de potasio": ["bananas"]
|
"fuentes de potasio": ["bananas"]
|
||||||
},
|
},
|
||||||
@ -50,10 +50,10 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead
|
|||||||
|
|
||||||
"estilo alternativo": {
|
"estilo alternativo": {
|
||||||
"comentario": "Mira esto!"
|
"comentario": "Mira esto!"
|
||||||
, "posicion de la coma": "no importa - mientras este antes del valor, entonces sera valido"
|
, "posición de la coma": "no importa - mientras este antes del valor, entonces sera válido"
|
||||||
, "otro comentario": "que lindo"
|
, "otro comentario": "qué lindo"
|
||||||
},
|
},
|
||||||
|
|
||||||
"eso fue rapido": "Y, estas listo. Ahora sabes todo lo que JSON tiene para ofrecer."
|
"eso fue rapido": "Y, estás listo. Ahora sabes todo lo que JSON tiene para ofrecer."
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -11,7 +11,7 @@ lang: es-es
|
|||||||
Markdown fue creado por John Gruber en 2004. Su propósito es ser una sintaxis fácil de leer y escribir que se convierta
|
Markdown fue creado por John Gruber en 2004. Su propósito es ser una sintaxis fácil de leer y escribir que se convierta
|
||||||
fácilmente a HTML (y, actualmente, otros formatos también).
|
fácilmente a HTML (y, actualmente, otros formatos también).
|
||||||
|
|
||||||
¡Denme todo la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests!
|
¡Denme toda la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests!
|
||||||
|
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
@ -44,7 +44,7 @@ Esto es un h2
|
|||||||
-------------
|
-------------
|
||||||
|
|
||||||
<!-- Estilos para texto plano -->
|
<!-- Estilos para texto plano -->
|
||||||
<!-- El texto puede ser fácilmente estilizaedo con italicas, negritas o tachado
|
<!-- El texto puede ser fácilmente estilizado con italicas, negritas o tachado
|
||||||
usando markdown -->
|
usando markdown -->
|
||||||
|
|
||||||
*Este texto está en itálicas.*
|
*Este texto está en itálicas.*
|
||||||
@ -62,7 +62,7 @@ Markdown en Github, también tenemos: -->
|
|||||||
|
|
||||||
~~Este texto está tachado.~~
|
~~Este texto está tachado.~~
|
||||||
|
|
||||||
<!-- Los párrafos son una o múltuples líneas de texto adyacentes separadas por
|
<!-- Los párrafos son una o múltiples líneas de texto adyacentes separadas por
|
||||||
una o múltiples líneas en blanco-->
|
una o múltiples líneas en blanco-->
|
||||||
|
|
||||||
Este es un párrafo. Estoy escribiendo un párrafo, ¿No es divertido?
|
Este es un párrafo. Estoy escribiendo un párrafo, ¿No es divertido?
|
||||||
|
@ -97,7 +97,7 @@ not False # => True
|
|||||||
None # => None
|
None # => None
|
||||||
|
|
||||||
# No uses el símbolo de igualdad `==` para comparar objetos con None
|
# No uses el símbolo de igualdad `==` para comparar objetos con None
|
||||||
# Usa `is` en lugar de
|
# Usa `is` en su lugar
|
||||||
"etc" is None #=> False
|
"etc" is None #=> False
|
||||||
None is None #=> True
|
None is None #=> True
|
||||||
|
|
||||||
@ -383,7 +383,7 @@ def keyword_args(**kwargs):
|
|||||||
keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"}
|
keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"}
|
||||||
|
|
||||||
|
|
||||||
# You can do both at once, if you like# Puedes hacer ambas a la vez si quieres
|
# Puedes hacer ambas a la vez si quieres
|
||||||
def todos_los_argumentos(*args, **kwargs):
|
def todos_los_argumentos(*args, **kwargs):
|
||||||
print args
|
print args
|
||||||
print kwargs
|
print kwargs
|
||||||
@ -478,7 +478,7 @@ Humano.roncar() #=> "*roncar*"
|
|||||||
|
|
||||||
# Puedes importar módulos
|
# Puedes importar módulos
|
||||||
import math
|
import math
|
||||||
print(math.sqrt(16)) #=> 4
|
print(math.sqrt(16)) #=> 4.0
|
||||||
|
|
||||||
# Puedes obtener funciones específicas desde un módulo
|
# Puedes obtener funciones específicas desde un módulo
|
||||||
from math import ceil, floor
|
from math import ceil, floor
|
||||||
@ -511,7 +511,7 @@ def duplicar_numeros(iterable):
|
|||||||
for i in iterable:
|
for i in iterable:
|
||||||
yield i + i
|
yield i + i
|
||||||
|
|
||||||
# Un generador cera valores sobre la marcha.
|
# Un generador crea valores sobre la marcha.
|
||||||
# En vez de generar y retornar todos los valores de una vez, crea uno en cada iteración.
|
# En vez de generar y retornar todos los valores de una vez, crea uno en cada iteración.
|
||||||
# Esto significa que valores más grandes que 15 no serán procesados en 'duplicar_numeros'.
|
# Esto significa que valores más grandes que 15 no serán procesados en 'duplicar_numeros'.
|
||||||
# Fíjate que 'range' es un generador. Crear una lista 1-900000000 tomaría mucho tiempo en crearse.
|
# Fíjate que 'range' es un generador. Crear una lista 1-900000000 tomaría mucho tiempo en crearse.
|
||||||
|
@ -5,8 +5,18 @@ contributors:
|
|||||||
- ["David Underwood", "http://theflyingdeveloper.com"]
|
- ["David Underwood", "http://theflyingdeveloper.com"]
|
||||||
- ["Joel Walden", "http://joelwalden.net"]
|
- ["Joel Walden", "http://joelwalden.net"]
|
||||||
- ["Luke Holder", "http://twitter.com/lukeholder"]
|
- ["Luke Holder", "http://twitter.com/lukeholder"]
|
||||||
|
- ["Tristan Hume", "http://thume.ca/"]
|
||||||
|
- ["Nick LaMuro", "https://github.com/NickLaMuro"]
|
||||||
|
- ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
|
||||||
|
- ["Ariel Krakowski", "http://www.learneroo.com"]
|
||||||
|
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
|
||||||
|
- ["Levi Bostian", "https://github.com/levibostian"]
|
||||||
|
- ["Rahil Momin", "https://github.com/iamrahil"]
|
||||||
|
- ["Gabriel Halley", "https://github.com/ghalley"]
|
||||||
|
- ["Persa Zula", "http://persazula.com"]
|
||||||
translators:
|
translators:
|
||||||
- ["Camilo Garrido", "http://www.twitter.com/hirohope"]
|
- ["Camilo Garrido", "http://www.twitter.com/hirohope"]
|
||||||
|
- ["Erick Bernal", "http://www.twitter.com/billowkib"]
|
||||||
lang: es-es
|
lang: es-es
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -19,7 +29,7 @@ Nadie los usa.
|
|||||||
Tu tampoco deberías
|
Tu tampoco deberías
|
||||||
=end
|
=end
|
||||||
|
|
||||||
# Lo primero y principal: Todo es un objeto
|
# En primer lugar: Todo es un objeto
|
||||||
|
|
||||||
# Los números son objetos
|
# Los números son objetos
|
||||||
|
|
||||||
@ -33,6 +43,8 @@ Tu tampoco deberías
|
|||||||
8 - 1 #=> 7
|
8 - 1 #=> 7
|
||||||
10 * 2 #=> 20
|
10 * 2 #=> 20
|
||||||
35 / 5 #=> 7
|
35 / 5 #=> 7
|
||||||
|
2**5 #=> 32
|
||||||
|
5 % 3 #=> 2
|
||||||
|
|
||||||
# La aritmética es sólo azúcar sintáctico
|
# La aritmética es sólo azúcar sintáctico
|
||||||
# para llamar un método de un objeto
|
# para llamar un método de un objeto
|
||||||
@ -55,8 +67,6 @@ false.class #=> FalseClass
|
|||||||
# Desigualdad
|
# Desigualdad
|
||||||
1 != 1 #=> false
|
1 != 1 #=> false
|
||||||
2 != 1 #=> true
|
2 != 1 #=> true
|
||||||
!true #=> false
|
|
||||||
!false #=> true
|
|
||||||
|
|
||||||
# Además de 'false', 'nil' es otro valor falso
|
# Además de 'false', 'nil' es otro valor falso
|
||||||
|
|
||||||
@ -70,14 +80,29 @@ false.class #=> FalseClass
|
|||||||
2 <= 2 #=> true
|
2 <= 2 #=> true
|
||||||
2 >= 2 #=> true
|
2 >= 2 #=> true
|
||||||
|
|
||||||
|
# Operadores lógicos
|
||||||
|
true && false #=> false
|
||||||
|
true || false #=> true
|
||||||
|
!true #=> false
|
||||||
|
|
||||||
|
# Existen versiones alternativas de los operadores lógicos con menor prioridad
|
||||||
|
# Estos son usados como constructores controladores de flujo que encadenan
|
||||||
|
# sentencias hasta que una de ellas retorne verdadero o falso
|
||||||
|
|
||||||
|
# `has_otra_cosa` solo se llama si `has_algo` retorna verdadero.
|
||||||
|
has_algo() and has_otra_cosa()
|
||||||
|
# `registra_error` solo se llama si `has_algo` falla
|
||||||
|
has_algo() or registra_error()
|
||||||
|
|
||||||
|
|
||||||
# Los strings son objetos
|
# Los strings son objetos
|
||||||
|
|
||||||
'Soy un string'.class #=> String
|
'Soy un string'.class #=> String
|
||||||
"Soy un string también".class #=> String
|
"Soy un string también".class #=> String
|
||||||
|
|
||||||
referente = "usar interpolacion de strings"
|
referente = "usar interpolación de strings"
|
||||||
"Yo puedo #{referente} usando strings de comillas dobles"
|
"Yo puedo #{referente} usando strings de comillas dobles"
|
||||||
#=> "Yo puedo usar interpolacion de strings usando strings de comillas dobles"
|
#=> "Yo puedo usar interpolación de strings usando strings de comillas dobles"
|
||||||
|
|
||||||
|
|
||||||
# Imprime a la salida estándar
|
# Imprime a la salida estándar
|
||||||
@ -103,7 +128,7 @@ ruta = '/mal/nombre/'
|
|||||||
|
|
||||||
# Los símbolos (son objetos)
|
# Los símbolos (son objetos)
|
||||||
# Los símbolos son inmutables, constantes reusables representadas internamente por un
|
# Los símbolos son inmutables, constantes reusables representadas internamente por un
|
||||||
# valor entero. Son usalmente usados en vez de strings para expresar eficientemente
|
# valor entero. Son normalmente usados en vez de strings para expresar eficientemente
|
||||||
# valores específicos y significativos
|
# valores específicos y significativos
|
||||||
|
|
||||||
:pendiente.class #=> Symbol
|
:pendiente.class #=> Symbol
|
||||||
@ -119,18 +144,19 @@ status == :aprovado #=> false
|
|||||||
# Arreglos
|
# Arreglos
|
||||||
|
|
||||||
# Esto es un arreglo
|
# Esto es un arreglo
|
||||||
[1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
|
arreglo = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
|
||||||
|
|
||||||
# Arreglos pueden contener elementos de distintos tipos
|
# Arreglos pueden contener elementos de distintos tipos
|
||||||
|
|
||||||
arreglo = [1, "hola", false] #=> => [1, "hola", false]
|
[1, "hola", false] #=> => [1, "hola", false]
|
||||||
|
|
||||||
# Arreglos pueden ser indexados
|
# Arreglos pueden ser indexados
|
||||||
# Desde el frente
|
# Desde el frente
|
||||||
arreglo[0] #=> 1
|
arreglo[0] #=> 1
|
||||||
|
arreglo.first #=> 1
|
||||||
arreglo[12] #=> nil
|
arreglo[12] #=> nil
|
||||||
|
|
||||||
# Tal como la aritmética, el acceso como variable[índice]
|
# Al igual que en aritmética, el acceso como variable[índice]
|
||||||
# es sólo azúcar sintáctica
|
# es sólo azúcar sintáctica
|
||||||
# para llamar el método [] de un objeto
|
# para llamar el método [] de un objeto
|
||||||
arreglo.[] 0 #=> 1
|
arreglo.[] 0 #=> 1
|
||||||
@ -138,15 +164,25 @@ arreglo.[] 12 #=> nil
|
|||||||
|
|
||||||
# Desde el final
|
# Desde el final
|
||||||
arreglo[-1] #=> 5
|
arreglo[-1] #=> 5
|
||||||
|
arreglo.last #=> 5
|
||||||
|
|
||||||
# Con un índice de inicio y final
|
# Con un índice de inicio y longitud
|
||||||
arreglo[2, 4] #=> [3, 4, 5]
|
arreglo[2, 3] #=> [3, 4, 5]
|
||||||
|
|
||||||
|
# Invertir un arreglo
|
||||||
|
a = [1, 2, 3]
|
||||||
|
a.reverse! #=> [3, 2, 1]
|
||||||
|
|
||||||
# O con rango
|
# O con rango
|
||||||
arreglo[1..3] #=> [2, 3, 4]
|
arreglo[1..3] #=> [2, 3, 4]
|
||||||
|
|
||||||
# Añade elementos a un arreglo así
|
# Añade elementos a un arreglo así
|
||||||
arreglo << 6 #=> [1, 2, 3, 4, 5, 6]
|
arreglo << 6 #=> [1, 2, 3, 4, 5, 6]
|
||||||
|
# O así
|
||||||
|
arreglo.push(6) #=> [1, 2, 3, 4, 5, 6]
|
||||||
|
|
||||||
|
#Verifica si un elemento ya existe en ese arreglo
|
||||||
|
arreglo.include?(1) #=> true
|
||||||
|
|
||||||
# Hashes son los diccionarios principales de Ruby con pares llave/valor.
|
# Hashes son los diccionarios principales de Ruby con pares llave/valor.
|
||||||
# Hashes se denotan con llaves:
|
# Hashes se denotan con llaves:
|
||||||
@ -161,17 +197,16 @@ hash['numero'] #=> 5
|
|||||||
# Preguntarle a un hash por una llave que no existe retorna 'nil':
|
# Preguntarle a un hash por una llave que no existe retorna 'nil':
|
||||||
hash['nada aqui'] #=> nil
|
hash['nada aqui'] #=> nil
|
||||||
|
|
||||||
# Itera sobre un hash con el método 'each':
|
|
||||||
hash.each do |k, v|
|
|
||||||
puts "#{k} is #{v}"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Desde Ruby 1.9, hay una sintaxis especial cuando se usa un símbolo como llave:
|
# Desde Ruby 1.9, hay una sintaxis especial cuando se usa un símbolo como llave:
|
||||||
|
|
||||||
nuevo_hash = { defcon: 3, accion: true}
|
nuevo_hash = { defcon: 3, accion: true}
|
||||||
|
|
||||||
nuevo_hash.keys #=> [:defcon, :accion]
|
nuevo_hash.keys #=> [:defcon, :accion]
|
||||||
|
|
||||||
|
# Verifica la existencia de llaves y valores en el hash
|
||||||
|
new_hash.has_key?(:defcon) #=> true
|
||||||
|
new_hash.has_value?(3) #=> true
|
||||||
|
|
||||||
# Tip: Tanto los arreglos como los hashes son Enumerable (enumerables)
|
# Tip: Tanto los arreglos como los hashes son Enumerable (enumerables)
|
||||||
# Comparten muchos métodos útiles tales como 'each', 'map', 'count', y más
|
# Comparten muchos métodos útiles tales como 'each', 'map', 'count', y más
|
||||||
|
|
||||||
@ -194,9 +229,15 @@ end
|
|||||||
#=> iteracion 4
|
#=> iteracion 4
|
||||||
#=> iteracion 5
|
#=> iteracion 5
|
||||||
|
|
||||||
# Aunque
|
# SIN EMBARGO, nadie usa ciclos `for`
|
||||||
# Nadie usa los ciclos `for`
|
# En su lugar debes usar el método "each" y pasarle un block (bloque).
|
||||||
# Usa `each`, así:
|
# Un bloque es un fragmento código que puedes pasar a métodos como `each`.
|
||||||
|
# Es símilar a las funciones lambda, funciones anónimas o `closures` en otros
|
||||||
|
# lenguajes de programación.
|
||||||
|
#
|
||||||
|
# El método `each` de un Range (rango) ejecuta el bloque una vez por cada elemento.
|
||||||
|
# Al bloque se le pasa un contador como parametro.
|
||||||
|
# Usar el método `each` con un bloque se ve así:
|
||||||
|
|
||||||
(1..5).each do |contador|
|
(1..5).each do |contador|
|
||||||
puts "iteracion #{contador}"
|
puts "iteracion #{contador}"
|
||||||
@ -207,10 +248,27 @@ end
|
|||||||
#=> iteracion 4
|
#=> iteracion 4
|
||||||
#=> iteracion 5
|
#=> iteracion 5
|
||||||
|
|
||||||
counter = 1
|
# También puedes envolver el bloque entre llaves:
|
||||||
while counter <= 5 do
|
(1..5).each { |counter| puts "iteración #{contador}" }
|
||||||
puts "iteracion #{counter}"
|
|
||||||
counter += 1
|
#El contenido de las estructuras de datos en ruby puede ser iterado usando `each`.
|
||||||
|
arreglo.each do |elemento|
|
||||||
|
puts "#{elemento} es parte del arreglo"
|
||||||
|
end
|
||||||
|
hash.each do |llave, valor|
|
||||||
|
puts "#{llave} es #{valor}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Si aún necesitas un índice puedes usar "each_with_index" y definir una variable
|
||||||
|
# índice.
|
||||||
|
arreglo.each_with_index do |element, index|
|
||||||
|
puts "#{element} tiene la posición #{index} en el arreglo"
|
||||||
|
end
|
||||||
|
|
||||||
|
contador = 1
|
||||||
|
while contador <= 5 do
|
||||||
|
puts "iteracion #{contador}"
|
||||||
|
contador += 1
|
||||||
end
|
end
|
||||||
#=> iteracion 1
|
#=> iteracion 1
|
||||||
#=> iteracion 2
|
#=> iteracion 2
|
||||||
@ -218,6 +276,19 @@ end
|
|||||||
#=> iteracion 4
|
#=> iteracion 4
|
||||||
#=> iteracion 5
|
#=> iteracion 5
|
||||||
|
|
||||||
|
# Hay una gran variedad de otras funciones iterativas útiles en Ruby,
|
||||||
|
# por ejemplo `map`, `reduce`, `inject`, entre otras. Map, por ejemplo,
|
||||||
|
# toma el arreglo sobre el cuál está iterando, le hace cambios
|
||||||
|
# definidos en el bloque, y retorna un arreglo completamente nuevo.
|
||||||
|
arreglo = [1,2,3,4,5]
|
||||||
|
duplicado = array.map do |elemento|
|
||||||
|
elemento * 2
|
||||||
|
end
|
||||||
|
puts duplicado
|
||||||
|
#=> [2,4,6,8,10]
|
||||||
|
puts array
|
||||||
|
#=> [1,2,3,4,5]
|
||||||
|
|
||||||
nota = 'B'
|
nota = 'B'
|
||||||
|
|
||||||
case nota
|
case nota
|
||||||
@ -234,6 +305,34 @@ when 'F'
|
|||||||
else
|
else
|
||||||
puts "Sistema alternativo de notas, ¿eh?"
|
puts "Sistema alternativo de notas, ¿eh?"
|
||||||
end
|
end
|
||||||
|
#=> "Mejor suerte para la proxima"
|
||||||
|
|
||||||
|
# Los casos también pueden usar rangos
|
||||||
|
nota = 82
|
||||||
|
|
||||||
|
case nota
|
||||||
|
when 90..100
|
||||||
|
puts 'Excelente!'
|
||||||
|
when 80..100
|
||||||
|
puts 'Buen trabajo'
|
||||||
|
else
|
||||||
|
puts '¡Reprobaste!'
|
||||||
|
end
|
||||||
|
#=> "Buen trabajo"
|
||||||
|
|
||||||
|
# Manejo de excepciones
|
||||||
|
begin
|
||||||
|
# código que podría causar excepción
|
||||||
|
raise NoMemoryError, 'Se te acabó la memoria'
|
||||||
|
rescue NoMemoryError => variable_de_excepcion
|
||||||
|
puts 'El error NoMemoryError ocurrió', variable_de_excepcion
|
||||||
|
rescue RuntimeError => otra_variable_de_excepcion
|
||||||
|
puts 'El error RuntimeError ocurrió'
|
||||||
|
else
|
||||||
|
puts 'Esto se ejecuta si ningun error ocurrió'
|
||||||
|
ensure
|
||||||
|
puts 'Este código siempre se ejecuta, sin importar que'
|
||||||
|
end
|
||||||
|
|
||||||
# Funciones
|
# Funciones
|
||||||
|
|
||||||
@ -244,7 +343,7 @@ end
|
|||||||
# Funciones (y todos los bloques) implícitamente retornan el valor de la última instrucción
|
# Funciones (y todos los bloques) implícitamente retornan el valor de la última instrucción
|
||||||
doble(2) #=> 4
|
doble(2) #=> 4
|
||||||
|
|
||||||
# Paréntesis son opcionales cuando el resultado es ambiguo
|
# Paréntesis son opcionales cuando el resultado no es ambiguo
|
||||||
doble 3 #=> 6
|
doble 3 #=> 6
|
||||||
|
|
||||||
doble doble 3 #=> 12
|
doble doble 3 #=> 12
|
||||||
@ -259,7 +358,7 @@ suma 3, 4 #=> 7
|
|||||||
suma suma(3,4), 5 #=> 12
|
suma suma(3,4), 5 #=> 12
|
||||||
|
|
||||||
# yield
|
# yield
|
||||||
# Todos los métodos tienen un parámetro de bloqueo opcional e implícitp
|
# Todos los métodos tienen un parámetro bloque opcional e implícito
|
||||||
# puede llamarse con la palabra clave 'yield'
|
# puede llamarse con la palabra clave 'yield'
|
||||||
|
|
||||||
def alrededor
|
def alrededor
|
||||||
@ -274,6 +373,17 @@ alrededor { puts 'hola mundo' }
|
|||||||
# hola mundo
|
# hola mundo
|
||||||
# }
|
# }
|
||||||
|
|
||||||
|
# Puedes pasar un bloque a una función
|
||||||
|
# '&' representa una referencia a un bloque
|
||||||
|
def visitantes(&bloque)
|
||||||
|
bloque.call
|
||||||
|
end
|
||||||
|
|
||||||
|
# Puedes pasar una lista de argumentos, que serán convertidos en un arreglo
|
||||||
|
# Para eso sirve el operador ('*')
|
||||||
|
def visitantes(*arreglo)
|
||||||
|
arreglo.each { |visitante| puts visitante }
|
||||||
|
end
|
||||||
|
|
||||||
# Define una clase con la palabra clave 'class'
|
# Define una clase con la palabra clave 'class'
|
||||||
class Humano
|
class Humano
|
||||||
@ -299,16 +409,26 @@ class Humano
|
|||||||
@nombre
|
@nombre
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# La funcionalidad anterior puede ser encapsulada usando el método attr_accessor
|
||||||
|
# de la siguiente manera
|
||||||
|
|
||||||
|
attr_accessor :name
|
||||||
|
|
||||||
|
# Los métodos de tipo getter y setter también se pueden crear de manera individual
|
||||||
|
# de la siguiente manera
|
||||||
|
|
||||||
|
attr_reader :name
|
||||||
|
attr_writer :name
|
||||||
|
|
||||||
# Un método de clase usa 'self' (sí mismo) para distinguirse de métodos de instancia.
|
# Un método de clase usa 'self' (sí mismo) para distinguirse de métodos de instancia.
|
||||||
# Sólo puede ser llamado en la clase, no por una instancia.
|
# Sólo puede ser llamado en la clase, no por una instancia.
|
||||||
def self.decir(mensaje)
|
def self.decir(mensaje)
|
||||||
puts "#{mensaje}"
|
puts mensaje
|
||||||
end
|
end
|
||||||
|
|
||||||
def especie
|
def especie
|
||||||
@@especie
|
@@especie
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -328,6 +448,23 @@ dwight.nombre #=> "Dwight K. Schrute"
|
|||||||
# Llama el método de clase
|
# Llama el método de clase
|
||||||
Humano.decir("Hi") #=> "Hi"
|
Humano.decir("Hi") #=> "Hi"
|
||||||
|
|
||||||
|
# El alcance de las variables es definido por la manera en que las nombramos.
|
||||||
|
# Las variables que inician con $ tienen un alcance global
|
||||||
|
$var = "Soy una variable global"
|
||||||
|
defined? $var #=> "global-variable"
|
||||||
|
|
||||||
|
# Las variables que empiezan con @ tienen un alcance de instancia
|
||||||
|
@var = "Soy una variable de instancia"
|
||||||
|
defined? @var #=> "instance-variable"
|
||||||
|
|
||||||
|
# Variables que empiezan con @@ tienen un alcance de clase
|
||||||
|
@@var = "Soy una variable de clase"
|
||||||
|
defined? @@var #=> "class variable"
|
||||||
|
|
||||||
|
# Las variables que empiezan con letra mayuscula son constantes
|
||||||
|
Var = "Soy una constante"
|
||||||
|
defined? Var #=> "constant"
|
||||||
|
|
||||||
# Las clases también son un objeto en ruby. Por lo cual, las clases también pueden tener variables de instancia.
|
# Las clases también son un objeto en ruby. Por lo cual, las clases también pueden tener variables de instancia.
|
||||||
# Variables de clase son compartidas a través de la clase y todos sus descendientes.
|
# Variables de clase son compartidas a través de la clase y todos sus descendientes.
|
||||||
|
|
||||||
@ -371,7 +508,67 @@ end
|
|||||||
class Doctor < Humano
|
class Doctor < Humano
|
||||||
end
|
end
|
||||||
|
|
||||||
Human.bar # 0
|
Humano.bar # 0
|
||||||
Doctor.bar # nil
|
Doctor.bar # nil
|
||||||
|
|
||||||
|
module ModuloEjemplo
|
||||||
|
def foo
|
||||||
|
'foo'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Al incluir un módulo sus métodos se comparten con las instancias de la clase
|
||||||
|
# Al extender un módulo sus métodos se comparten con la clase misma
|
||||||
|
|
||||||
|
class Persona
|
||||||
|
include ModuloEjemplo
|
||||||
|
end
|
||||||
|
|
||||||
|
class Libro
|
||||||
|
extend ModuloEjemplo
|
||||||
|
end
|
||||||
|
|
||||||
|
Persona.foo # => NoMethodError: undefined method `foo' for Persona:Class
|
||||||
|
Persona.new.foo # => 'foo'
|
||||||
|
Libro.foo # => 'foo'
|
||||||
|
Libro.new.foo # => NoMethodError: undefined method `foo'
|
||||||
|
|
||||||
|
# Las llamadas de retorno (callbacks) son ejecutadas cuando se incluye o
|
||||||
|
# extiende un módulo
|
||||||
|
module EjemploConcern
|
||||||
|
def self.incluido(base)
|
||||||
|
base.extend(MetodosClase)
|
||||||
|
base.send(:include, MetodosInstancia)
|
||||||
|
end
|
||||||
|
|
||||||
|
module MetodosClase
|
||||||
|
def bar
|
||||||
|
'bar'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module MetodosInstancia
|
||||||
|
def qux
|
||||||
|
'qux'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Algo
|
||||||
|
include EjemploConcern
|
||||||
|
end
|
||||||
|
|
||||||
|
Algo.bar #=> 'bar'
|
||||||
|
Algo.qux #=> NoMethodError: undefined method `qux'
|
||||||
|
Algo.new.bar # => NoMethodError: undefined method `bar'
|
||||||
|
Algo.new.qux # => 'qux'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Recursos adicionales
|
||||||
|
- [Aprende Ruby Mediante Ejemplo con Ejercicios](http://www.learneroo.com/modules/61/nodes/338) - Una variante de
|
||||||
|
esta referencia con ejercicios en navegador.
|
||||||
|
- [Documentación Oficial](http://www.ruby-doc.org/core-2.1.1/)
|
||||||
|
- [Ruby desde otros lenguajes](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/)
|
||||||
|
- [Programando Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - Una
|
||||||
|
[edición antigua](http://ruby-doc.com/docs/ProgrammingRuby/) gratuita disponible en línea.
|
||||||
|
- [Guía de estilo de Ruby](https://github.com/bbatsov/ruby-style-guide) - Guía de estilo creada por la comunidad.
|
||||||
|
596
es-es/swift-es.html.markdown
Normal file
596
es-es/swift-es.html.markdown
Normal file
@ -0,0 +1,596 @@
|
|||||||
|
---
|
||||||
|
language: swift
|
||||||
|
contributors:
|
||||||
|
- ["Grant Timmerman", "http://github.com/grant"]
|
||||||
|
- ["Christopher Bess", "http://github.com/cbess"]
|
||||||
|
- ["Joey Huang", "http://github.com/kamidox"]
|
||||||
|
- ["Anthony Nguyen", "http://github.com/anthonyn60"]
|
||||||
|
translators:
|
||||||
|
- ["David Hsieh", "http://github.com/deivuh"]
|
||||||
|
lang: es-es
|
||||||
|
filename: learnswift-es.swift
|
||||||
|
---
|
||||||
|
|
||||||
|
Swift es un lenguaje de programación para el desarrollo en iOS y OS X creado
|
||||||
|
por Apple. Diseñado para coexistir con Objective-C y ser más resistente contra
|
||||||
|
el código erroneo, Swift fue introducido en el 2014 en el WWDC, la conferencia
|
||||||
|
de desarrolladores de Apple.
|
||||||
|
|
||||||
|
Véase también la guía oficial de Apple, [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/), el cual tiene un completo tutorial de Swift.
|
||||||
|
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// Importar un módulo
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: Básicos
|
||||||
|
//
|
||||||
|
|
||||||
|
// XCode soporta referencias para anotar tu código y agregarlos a lista de la
|
||||||
|
// barra de saltos.
|
||||||
|
// MARK: Marca de sección
|
||||||
|
// TODO: Hacer algo pronto
|
||||||
|
// FIXME: Arreglar este código
|
||||||
|
|
||||||
|
// En Swift 2, println y print fueron combinados en un solo método print.
|
||||||
|
// Print añade una nueva línea automáticamente.
|
||||||
|
print("Hola, mundo") // println ahora es print
|
||||||
|
print("Hola, mundo", appendNewLine: false) // print sin agregar nueva línea
|
||||||
|
|
||||||
|
// Valores de variables (var) pueden cambiar después de ser asignados
|
||||||
|
// Valores de constrantes (let) no pueden cambiarse después de ser asignados
|
||||||
|
|
||||||
|
var myVariable = 42
|
||||||
|
let øπΩ = "value" // nombres de variable unicode
|
||||||
|
let π = 3.1415926
|
||||||
|
let convenience = "keyword" // nombre de variable contextual
|
||||||
|
// Las declaraciones pueden ser separadas por punto y coma (;)
|
||||||
|
let weak = "keyword"; let override = "another keyword"
|
||||||
|
// Los acentos abiertos (``) permiten utilizar palabras clave como nombres de
|
||||||
|
// variable
|
||||||
|
let `class` = "keyword"
|
||||||
|
let explicitDouble: Double = 70
|
||||||
|
let intValue = 0007 // 7
|
||||||
|
let largeIntValue = 77_000 // 77000
|
||||||
|
let label = "some text " + String(myVariable) // Conversión (casting)
|
||||||
|
let piText = "Pi = \(π), Pi 2 = \(π * 2)" // Interpolación de string
|
||||||
|
|
||||||
|
// Valores específicos de la compilación (build)
|
||||||
|
// utiliza la configuración -D
|
||||||
|
#if false
|
||||||
|
print("No impreso")
|
||||||
|
let buildValue = 3
|
||||||
|
#else
|
||||||
|
let buildValue = 7
|
||||||
|
#endif
|
||||||
|
print("Build value: \(buildValue)") // Build value: 7
|
||||||
|
|
||||||
|
/*
|
||||||
|
Las opcionales son un aspecto del lenguaje Swift que permite el
|
||||||
|
almacenamiento de un valor `Some` (algo) o `None` (nada).
|
||||||
|
|
||||||
|
Debido a que Swift requiere que cada propiedad tenga un valor,
|
||||||
|
hasta un valor 'nil' debe de ser explicitamente almacenado como un
|
||||||
|
valor opcional.
|
||||||
|
|
||||||
|
Optional<T> es un enum.
|
||||||
|
*/
|
||||||
|
var someOptionalString: String? = "opcional" // Puede ser nil
|
||||||
|
// Al igual que lo anterior, pero ? es un operador postfix (sufijo)
|
||||||
|
var someOptionalString2: Optional<String> = "opcional"
|
||||||
|
|
||||||
|
if someOptionalString != nil {
|
||||||
|
// No soy nil
|
||||||
|
if someOptionalString!.hasPrefix("opt") {
|
||||||
|
print("Tiene el prefijo")
|
||||||
|
}
|
||||||
|
|
||||||
|
let empty = someOptionalString?.isEmpty
|
||||||
|
}
|
||||||
|
someOptionalString = nil
|
||||||
|
|
||||||
|
// Opcional implícitamente desenvuelto
|
||||||
|
var unwrappedString: String! = "Un valor esperado."
|
||||||
|
// Al igual que lo anterior, pero ! es un operador postfix (sufijo)
|
||||||
|
var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Un valor esperado."
|
||||||
|
|
||||||
|
if let someOptionalStringConstant = someOptionalString {
|
||||||
|
// tiene valor `Some` (algo), no nil
|
||||||
|
if !someOptionalStringConstant.hasPrefix("ok") {
|
||||||
|
// No tiene el prefijo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swift tiene soporte de almacenamiento para cualquier tipo de valor.
|
||||||
|
// AnyObject == id
|
||||||
|
// A diferencia de Objective-C `id`, AnyObject funciona con cualquier
|
||||||
|
// valor (Class, Int, struct, etc)
|
||||||
|
var anyObjectVar: AnyObject = 7
|
||||||
|
anyObjectVar = "Cambiado a un valor string, no es buena práctica, pero posible."
|
||||||
|
|
||||||
|
/*
|
||||||
|
Comentar aquí
|
||||||
|
|
||||||
|
/*
|
||||||
|
Comentarios anidados también son soportados
|
||||||
|
*/
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: Colecciones
|
||||||
|
//
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tipos Array (arreglo) y Dictionary (diccionario) son structs (estructuras).
|
||||||
|
Así que `let` y `var` también indican si son mudables (var) o
|
||||||
|
inmutables (let) durante la declaración de sus tipos.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Array (arreglo)
|
||||||
|
var shoppingList = ["catfish", "water", "lemons"]
|
||||||
|
shoppingList[1] = "bottle of water"
|
||||||
|
let emptyArray = [String]() // let == inmutable
|
||||||
|
let emptyArray2 = Array<String>() // igual que lo anterior
|
||||||
|
var emptyMutableArray = [String]() // var == mudable
|
||||||
|
|
||||||
|
|
||||||
|
// Dictionary (diccionario)
|
||||||
|
var occupations = [
|
||||||
|
"Malcolm": "Captain",
|
||||||
|
"kaylee": "Mechanic"
|
||||||
|
]
|
||||||
|
occupations["Jayne"] = "Public Relations"
|
||||||
|
let emptyDictionary = [String: Float]() // let == inmutable
|
||||||
|
let emptyDictionary2 = Dictionary<String, Float>() // igual que lo anterior
|
||||||
|
var emptyMutableDictionary = [String: Float]() // var == mudable
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: Flujo de control
|
||||||
|
//
|
||||||
|
|
||||||
|
// Ciclo for (array)
|
||||||
|
let myArray = [1, 1, 2, 3, 5]
|
||||||
|
for value in myArray {
|
||||||
|
if value == 1 {
|
||||||
|
print("Uno!")
|
||||||
|
} else {
|
||||||
|
print("No es uno!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ciclo for (dictionary)
|
||||||
|
var dict = ["uno": 1, "dos": 2]
|
||||||
|
for (key, value) in dict {
|
||||||
|
print("\(key): \(value)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ciclo for (range)
|
||||||
|
for i in -1...shoppingList.count {
|
||||||
|
print(i)
|
||||||
|
}
|
||||||
|
shoppingList[1...2] = ["steak", "peacons"]
|
||||||
|
// Utilizar ..< para excluir el último valor
|
||||||
|
|
||||||
|
// Ciclo while
|
||||||
|
var i = 1
|
||||||
|
while i < 1000 {
|
||||||
|
i *= 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ciclo do-while
|
||||||
|
do {
|
||||||
|
print("Hola")
|
||||||
|
} while 1 == 2
|
||||||
|
|
||||||
|
// Switch
|
||||||
|
// Muy potente, se puede pensar como declaraciones `if` con _azúcar sintáctico_
|
||||||
|
// Soportan String, instancias de objetos, y primitivos (Int, Double, etc)
|
||||||
|
let vegetable = "red pepper"
|
||||||
|
switch vegetable {
|
||||||
|
case "celery":
|
||||||
|
let vegetableComment = "Add some raisins and make ants on a log."
|
||||||
|
case "cucumber", "watercress":
|
||||||
|
let vegetableComment = "That would make a good tea sandwich."
|
||||||
|
case let localScopeValue where localScopeValue.hasSuffix("pepper"):
|
||||||
|
let vegetableComment = "Is it a spicy \(localScopeValue)?"
|
||||||
|
default: // obligatorio (se debe cumplir con todos los posibles valores de entrada)
|
||||||
|
let vegetableComment = "Everything tastes good in soup."
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: Funciones
|
||||||
|
//
|
||||||
|
|
||||||
|
// Funciones son un tipo de primera-clase, quiere decir que pueden ser anidados
|
||||||
|
// en funciones y pueden ser pasados como parámetros
|
||||||
|
|
||||||
|
// Función en documentación de cabeceras Swift (formato reStructedText)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Una operación de saludo
|
||||||
|
|
||||||
|
- Una viñeta en la documentación
|
||||||
|
- Otra viñeta en la documentación
|
||||||
|
|
||||||
|
:param: name Un nombre
|
||||||
|
:param: day Un día
|
||||||
|
:returns: Un string que contiene el valor de name y day
|
||||||
|
*/
|
||||||
|
func greet(name: String, day: String) -> String {
|
||||||
|
return "Hola \(name), hoy es \(day)."
|
||||||
|
}
|
||||||
|
greet("Bob", "Martes")
|
||||||
|
|
||||||
|
// Similar a lo anterior, a excepción del compartamiento de los parámetros
|
||||||
|
// de la función
|
||||||
|
func greet2(requiredName: String, externalParamName localParamName: String) -> String {
|
||||||
|
return "Hola \(requiredName), hoy es el día \(localParamName)"
|
||||||
|
}
|
||||||
|
greet2(requiredName:"John", externalParamName: "Domingo")
|
||||||
|
|
||||||
|
// Función que devuelve múltiples valores en una tupla
|
||||||
|
func getGasPrices() -> (Double, Double, Double) {
|
||||||
|
return (3.59, 3.69, 3.79)
|
||||||
|
}
|
||||||
|
let pricesTuple = getGasPrices()
|
||||||
|
let price = pricesTuple.2 // 3.79
|
||||||
|
// Ignorar tupla (u otros) valores utilizando _ (guión bajo)
|
||||||
|
let (_, price1, _) = pricesTuple // price1 == 3.69
|
||||||
|
print(price1 == pricesTuple.1) // true
|
||||||
|
print("Gas price: \(price)")
|
||||||
|
|
||||||
|
// Cantidad variable de argumentos
|
||||||
|
func setup(numbers: Int...) {
|
||||||
|
// Es un arreglo
|
||||||
|
let number = numbers[0]
|
||||||
|
let argCount = numbers.count
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pasando y devolviendo funciones
|
||||||
|
func makeIncrementer() -> (Int -> Int) {
|
||||||
|
func addOne(number: Int) -> Int {
|
||||||
|
return 1 + number
|
||||||
|
}
|
||||||
|
return addOne
|
||||||
|
}
|
||||||
|
var increment = makeIncrementer()
|
||||||
|
increment(7)
|
||||||
|
|
||||||
|
// Pasando como referencia
|
||||||
|
func swapTwoInts(inout a: Int, inout b: Int) {
|
||||||
|
let tempA = a
|
||||||
|
a = b
|
||||||
|
b = tempA
|
||||||
|
}
|
||||||
|
var someIntA = 7
|
||||||
|
var someIntB = 3
|
||||||
|
swapTwoInts(&someIntA, &someIntB)
|
||||||
|
print(someIntB) // 7
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: Closures (Clausuras)
|
||||||
|
//
|
||||||
|
var numbers = [1, 2, 6]
|
||||||
|
|
||||||
|
// Las funciones son un caso especial de closure ({})
|
||||||
|
|
||||||
|
// Ejemplo de closure.
|
||||||
|
// `->` Separa los argumentos del tipo de retorno
|
||||||
|
// `in` Separa la cabecera del cuerpo del closure
|
||||||
|
numbers.map({
|
||||||
|
(number: Int) -> Int in
|
||||||
|
let result = 3 * number
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
|
||||||
|
// Cuando se conoce el tipo, como en lo anterior, se puede hacer esto
|
||||||
|
numbers = numbers.map({ number in 3 * number })
|
||||||
|
// o esto
|
||||||
|
//numbers = numbers.map({ $0 * 3 })
|
||||||
|
|
||||||
|
print(numbers) // [3, 6, 18]
|
||||||
|
|
||||||
|
// Closure restante
|
||||||
|
numbers = sorted(numbers) { $0 > $1 }
|
||||||
|
|
||||||
|
print(numbers) // [18, 6, 3]
|
||||||
|
|
||||||
|
// Bastante corto, debido a que el operador < infiere los tipos
|
||||||
|
|
||||||
|
numbers = sorted(numbers, < )
|
||||||
|
|
||||||
|
print(numbers) // [3, 6, 18]
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: Estructuras
|
||||||
|
//
|
||||||
|
|
||||||
|
// Las estructuras y las clases tienen capacidades similares
|
||||||
|
struct NamesTable {
|
||||||
|
let names = [String]()
|
||||||
|
|
||||||
|
// Subscript personalizado
|
||||||
|
subscript(index: Int) -> String {
|
||||||
|
return names[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Las estructuras tienen un inicializador designado autogenerado (implícitamente)
|
||||||
|
let namesTable = NamesTable(names: ["Me", "Them"])
|
||||||
|
let name = namesTable[1]
|
||||||
|
print("Name is \(name)") // Name is Them
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: Clases
|
||||||
|
//
|
||||||
|
|
||||||
|
// Las clases, las estructuras y sus miembros tienen tres niveles de control de acceso
|
||||||
|
// Éstos son: internal (predeterminado), public, private
|
||||||
|
|
||||||
|
public class Shape {
|
||||||
|
public func getArea() -> Int {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todos los métodos y las propiedades de una clase son public (públicas)
|
||||||
|
// Si solo necesitas almacenar datos en un objecto estructurado,
|
||||||
|
// debes de utilizar `struct`
|
||||||
|
|
||||||
|
internal class Rect: Shape {
|
||||||
|
var sideLength: Int = 1
|
||||||
|
|
||||||
|
// Getter y setter personalizado
|
||||||
|
private var perimeter: Int {
|
||||||
|
get {
|
||||||
|
return 4 * sideLength
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
// `newValue` es una variable implícita disponible para los setters
|
||||||
|
sideLength = newValue / 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lazily loading (inicialización bajo demanda) a una propiedad
|
||||||
|
// subShape queda como nil (sin inicializar) hasta que getter es llamado
|
||||||
|
lazy var subShape = Rect(sideLength: 4)
|
||||||
|
|
||||||
|
// Si no necesitas un getter y setter personalizado
|
||||||
|
// pero aún quieres ejecutar código antes y después de hacer get o set
|
||||||
|
// a una propiedad, puedes utilizar `willSet` y `didSet`
|
||||||
|
var identifier: String = "defaultID" {
|
||||||
|
// El argumento `willSet` será el nombre de variable para el nuevo valor
|
||||||
|
willSet(someIdentifier) {
|
||||||
|
print(someIdentifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init(sideLength: Int) {
|
||||||
|
self.sideLength = sideLength
|
||||||
|
// Siempre poner super.init de último al momento de inicializar propiedades
|
||||||
|
// personalizadas
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
func shrink() {
|
||||||
|
if sideLength > 0 {
|
||||||
|
--sideLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func getArea() -> Int {
|
||||||
|
return sideLength * sideLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Una clase simple `Square` que extiende de `Rect`
|
||||||
|
class Square: Rect {
|
||||||
|
convenience init() {
|
||||||
|
self.init(sideLength: 5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var mySquare = Square()
|
||||||
|
print(mySquare.getArea()) // 25
|
||||||
|
mySquare.shrink()
|
||||||
|
print(mySquare.sideLength) // 4
|
||||||
|
|
||||||
|
// Conversión de tipo de instancia
|
||||||
|
let aShape = mySquare as Shape
|
||||||
|
|
||||||
|
// Comparar instancias, no es igual a == que compara objetos (equal to)
|
||||||
|
if mySquare === mySquare {
|
||||||
|
print("Yep, it's mySquare")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicialización (init) opcional
|
||||||
|
class Circle: Shape {
|
||||||
|
var radius: Int
|
||||||
|
override func getArea() -> Int {
|
||||||
|
return 3 * radius * radius
|
||||||
|
}
|
||||||
|
|
||||||
|
// Un signo de interrogación como sufijo después de `init` es un init opcional
|
||||||
|
// que puede devolver nil
|
||||||
|
init?(radius: Int) {
|
||||||
|
self.radius = radius
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
if radius <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var myCircle = Circle(radius: 1)
|
||||||
|
print(myCircle?.getArea()) // Optional(3)
|
||||||
|
print(myCircle!.getArea()) // 3
|
||||||
|
var myEmptyCircle = Circle(radius: -1)
|
||||||
|
print(myEmptyCircle?.getArea()) // "nil"
|
||||||
|
if let circle = myEmptyCircle {
|
||||||
|
// no será ejecutado debido a que myEmptyCircle es nil
|
||||||
|
print("circle is not nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: Enums
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
// Los enums pueden ser opcionalmente de un tipo específico o de su propio tipo
|
||||||
|
// Al igual que las clases, pueden contener métodos
|
||||||
|
|
||||||
|
enum Suit {
|
||||||
|
case Spades, Hearts, Diamonds, Clubs
|
||||||
|
func getIcon() -> String {
|
||||||
|
switch self {
|
||||||
|
case .Spades: return "♤"
|
||||||
|
case .Hearts: return "♡"
|
||||||
|
case .Diamonds: return "♢"
|
||||||
|
case .Clubs: return "♧"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Los valores de enum permite la sintaxis corta, sin necesidad de poner
|
||||||
|
// el tipo del enum cuando la variable es declarada de manera explícita
|
||||||
|
var suitValue: Suit = .Hearts
|
||||||
|
|
||||||
|
// Enums de tipo no-entero requiere asignaciones de valores crudas directas
|
||||||
|
enum BookName: String {
|
||||||
|
case John = "John"
|
||||||
|
case Luke = "Luke"
|
||||||
|
}
|
||||||
|
print("Name: \(BookName.John.rawValue)")
|
||||||
|
|
||||||
|
// Enum con valores asociados
|
||||||
|
enum Furniture {
|
||||||
|
// Asociación con Int
|
||||||
|
case Desk(height: Int)
|
||||||
|
// Asociación con String e Int
|
||||||
|
case Chair(String, Int)
|
||||||
|
|
||||||
|
func description() -> String {
|
||||||
|
switch self {
|
||||||
|
case .Desk(let height):
|
||||||
|
return "Desk with \(height) cm"
|
||||||
|
case .Chair(let brand, let height):
|
||||||
|
return "Chair of \(brand) with \(height) cm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var desk: Furniture = .Desk(height: 80)
|
||||||
|
print(desk.description()) // "Desk with 80 cm"
|
||||||
|
var chair = Furniture.Chair("Foo", 40)
|
||||||
|
print(chair.description()) // "Chair of Foo with 40 cm"
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: Protocolos
|
||||||
|
//
|
||||||
|
|
||||||
|
// `protocol` puede requerir que los tipos tengan propiedades
|
||||||
|
// de instancia específicas, métodos de instancia, métodos de tipo,
|
||||||
|
// operadores, y subscripts
|
||||||
|
|
||||||
|
|
||||||
|
protocol ShapeGenerator {
|
||||||
|
var enabled: Bool { get set }
|
||||||
|
func buildShape() -> Shape
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protocolos declarados con @objc permiten funciones opcionales,
|
||||||
|
// que te permite evaluar conformidad
|
||||||
|
@objc protocol TransformShape {
|
||||||
|
optional func reshaped()
|
||||||
|
optional func canReshape() -> Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyShape: Rect {
|
||||||
|
var delegate: TransformShape?
|
||||||
|
|
||||||
|
func grow() {
|
||||||
|
sideLength += 2
|
||||||
|
|
||||||
|
// Pon un signo de interrogación después de la propiedad opcional,
|
||||||
|
// método, o subscript para ignorar un valor nil y devolver nil
|
||||||
|
// en lugar de tirar un error de tiempo de ejecución
|
||||||
|
// ("optional chaining")
|
||||||
|
if let allow = self.delegate?.canReshape?() {
|
||||||
|
// test for delegate then for method
|
||||||
|
self.delegate?.reshaped?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: Otros
|
||||||
|
//
|
||||||
|
|
||||||
|
// `extension`: Agrega funcionalidades a tipos existentes
|
||||||
|
|
||||||
|
// Square ahora se "conforma" al protocolo `Printable`
|
||||||
|
extension Square: Printable {
|
||||||
|
var description: String {
|
||||||
|
return "Area: \(self.getArea()) - ID: \(self.identifier)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Square: \(mySquare)")
|
||||||
|
|
||||||
|
// También puedes hacer extend a tipos prefabricados (built-in)
|
||||||
|
extension Int {
|
||||||
|
var customProperty: String {
|
||||||
|
return "This is \(self)"
|
||||||
|
}
|
||||||
|
|
||||||
|
func multiplyBy(num: Int) -> Int {
|
||||||
|
return num * self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print(7.customProperty) // "This is 7"
|
||||||
|
print(14.multiplyBy(3)) // 42
|
||||||
|
|
||||||
|
// Generics: Similar Java y C#. Utiliza la palabra clave `where` para
|
||||||
|
// especificar los requerimientos de los genéricos.
|
||||||
|
|
||||||
|
func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
|
||||||
|
for (index, value) in enumerate(array) {
|
||||||
|
if value == valueToFind {
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
let foundAtIndex = findIndex([1, 2, 3, 4], 3)
|
||||||
|
print(foundAtIndex == 2) // true
|
||||||
|
|
||||||
|
// Operadores:
|
||||||
|
// Operadores personalizados puede empezar con los siguientes caracteres:
|
||||||
|
// / = - + * % < > ! & | ^ . ~
|
||||||
|
// o
|
||||||
|
// Caracteres unicode: math, symbol, arrow, dingbat, y line/box.
|
||||||
|
prefix operator !!! {}
|
||||||
|
|
||||||
|
// Un operador prefix que triplica la longitud del lado cuando es utilizado
|
||||||
|
prefix func !!! (inout shape: Square) -> Square {
|
||||||
|
shape.sideLength *= 3
|
||||||
|
return shape
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valor actual
|
||||||
|
print(mySquare.sideLength) // 4
|
||||||
|
|
||||||
|
// Cambiar la longitud del lado utilizando el operador !!!,
|
||||||
|
// incrementa el tamaño por 3
|
||||||
|
!!!mySquare
|
||||||
|
print(mySquare.sideLength) // 12
|
||||||
|
```
|
253
es-es/tmux-es.html.markdown
Normal file
253
es-es/tmux-es.html.markdown
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
---
|
||||||
|
category: tool
|
||||||
|
tool: tmux
|
||||||
|
contributors:
|
||||||
|
- ["mdln", "https://github.com/mdln"]
|
||||||
|
filename: LearnTmux-es.txt
|
||||||
|
translators:
|
||||||
|
- ["Damaso Sanoja", "https://github.com/damasosanoja"]
|
||||||
|
lang: es-es
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
[tmux](http://tmux.sourceforge.net)
|
||||||
|
es un terminal multiplexor: habilita la creación, acceso y control
|
||||||
|
de múltiples terminales controlados desde una sola pantalla. tmux
|
||||||
|
puede ser separado de una pantalla y continuar corriendo en el fondo
|
||||||
|
y luego ser insertado nuevamente.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
tmux [command] # Corre un comando
|
||||||
|
# 'tmux' sin comandos creará una nueva sesión
|
||||||
|
|
||||||
|
new # Crea una nueva sesión
|
||||||
|
-s "Session" # Crea sesión con nombre
|
||||||
|
-n "Window" # Crea ventana con nombre
|
||||||
|
-c "/dir" # Comienza en el directorio destino
|
||||||
|
|
||||||
|
attach # Adjunta sesión última/disponible
|
||||||
|
-t "#" # Adjunta sesión destino
|
||||||
|
-d # Separa la sesión de otras instancias
|
||||||
|
|
||||||
|
ls # Lista las sesiones abiertas
|
||||||
|
-a # Lista todas las sesiones abiertas
|
||||||
|
|
||||||
|
lsw # Lista las ventanas
|
||||||
|
-a # Lista todas las ventanas
|
||||||
|
-s # Lista todas las ventanas en la sesión
|
||||||
|
|
||||||
|
lsp # Lista los páneles
|
||||||
|
-a # Lista todos los páneles
|
||||||
|
-s # Lista todos los páneles de la sesión
|
||||||
|
-t # Lista los páneles de aplicación en el destino
|
||||||
|
|
||||||
|
kill-window # Cierra la ventana actual
|
||||||
|
-t "#" # Cierra la ventana destino
|
||||||
|
-a # Cierra todas las ventanas
|
||||||
|
-a -t "#" # Cierra todas las ventanas menos el destino
|
||||||
|
|
||||||
|
kill-session # Cierra la sesión actual
|
||||||
|
-t "#" # Cierra la sesión destino
|
||||||
|
-a # Cierra todas las sesiones
|
||||||
|
-a -t "#" # Cierra todas las sesiones menos el destino
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Atajos de Teclado
|
||||||
|
|
||||||
|
El método para controlar una sesión adjunta tmux es mediante
|
||||||
|
combinaciones de teclas llamadas teclas 'Prefijo'.
|
||||||
|
|
||||||
|
```
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
(C-b) = Ctrl + b # combinación 'Prefijo' necesaria para usar atajos
|
||||||
|
|
||||||
|
(M-1) = Meta + 1 -o- Alt + 1
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
? # Lista todos los atajos de teclado
|
||||||
|
: # Entra en la línea de comandos tmux
|
||||||
|
r # Fuerza el redibujado del cliente adjuntado
|
||||||
|
c # Crea una nueva ventana
|
||||||
|
|
||||||
|
! # Separa el panel actual fuera de la ventana.
|
||||||
|
% # Separa el panel actual en dos, izquierdo y derecho
|
||||||
|
" # Separa el panel actual en dos, superior e inferior
|
||||||
|
|
||||||
|
n # Cambia a la siguiente ventana
|
||||||
|
p # Cambia a la ventana previa
|
||||||
|
{ # Intercambia el panel actual con el anterior
|
||||||
|
} # Intercambia el panel actual con el próximo
|
||||||
|
|
||||||
|
s # Selecciona una nueva sesión para el cliente adjuntado
|
||||||
|
interactivamente
|
||||||
|
w # Elegir la ventana actual interactivamente
|
||||||
|
0 al 9 # Seleccionar ventanas 0 al 9
|
||||||
|
|
||||||
|
d # Separa el cliente actual
|
||||||
|
D # Elige un cliente para separar
|
||||||
|
|
||||||
|
& # Cierra la ventana actual
|
||||||
|
x # Cierra el panel actual
|
||||||
|
|
||||||
|
Up, Down # Cambia al panel superior, inferior, izquierdo, o derecho
|
||||||
|
Left, Right
|
||||||
|
|
||||||
|
M-1 to M-5 # Organizar páneles:
|
||||||
|
# 1) uniformes horizontales
|
||||||
|
# 2) uniformes verticales
|
||||||
|
# 3) principal horizontal
|
||||||
|
# 4) principal vertical
|
||||||
|
# 5) mozaico
|
||||||
|
|
||||||
|
C-Up, C-Down # Redimensiona el panel actual en pasos de una celda
|
||||||
|
C-Left, C-Right
|
||||||
|
|
||||||
|
M-Up, M-Down # Redimensiona el panel actual en pasos de cinco celdas
|
||||||
|
M-Left, M-Right
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Configurando ~/.tmux.conf
|
||||||
|
|
||||||
|
tmux.conf puede usarse para establecer opciones automáticas al arrancar, parecido a como .vimrc o init.el hacen.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Ejemplo de tmux.conf
|
||||||
|
# 2014.10
|
||||||
|
|
||||||
|
|
||||||
|
### General
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
# Habilita UTF-8
|
||||||
|
setw -g utf8 on
|
||||||
|
set-option -g status-utf8 on
|
||||||
|
|
||||||
|
# Fuera de pantalla/Historia límite
|
||||||
|
set -g history-limit 2048
|
||||||
|
|
||||||
|
# Comienzo de índice
|
||||||
|
set -g base-index 1
|
||||||
|
|
||||||
|
# Ratón
|
||||||
|
set-option -g mouse-select-pane on
|
||||||
|
|
||||||
|
# Forza recarga de fichero de configuración
|
||||||
|
unbind r
|
||||||
|
bind r source-file ~/.tmux.conf
|
||||||
|
|
||||||
|
|
||||||
|
### Atajos de teclado
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
# Desvincula C-b como el prefijo por defecto
|
||||||
|
unbind C-b
|
||||||
|
|
||||||
|
# Establece el nuevo prefijo
|
||||||
|
set-option -g prefix `
|
||||||
|
|
||||||
|
# Regresa a la ventana previa cuando el prefijo es accionado dos veces
|
||||||
|
bind C-a last-window
|
||||||
|
bind ` last-window
|
||||||
|
|
||||||
|
# Permite intercambiar C-a y ` usando F11/F12
|
||||||
|
bind F11 set-option -g prefix C-a
|
||||||
|
bind F12 set-option -g prefix `
|
||||||
|
|
||||||
|
# Preferencias de atajos
|
||||||
|
setw -g mode-keys vi
|
||||||
|
set-option -g status-keys vi
|
||||||
|
|
||||||
|
# Moviéndose entre paneles con movimientos de teclas vim
|
||||||
|
bind h select-pane -L
|
||||||
|
bind j select-pane -D
|
||||||
|
bind k select-pane -U
|
||||||
|
bind l select-pane -R
|
||||||
|
|
||||||
|
# Ciclo/Intercambio de Ventana
|
||||||
|
bind e previous-window
|
||||||
|
bind f next-window
|
||||||
|
bind E swap-window -t -1
|
||||||
|
bind F swap-window -t +1
|
||||||
|
|
||||||
|
# División rápida de paneles
|
||||||
|
bind = split-window -h
|
||||||
|
bind - split-window -v
|
||||||
|
unbind '"'
|
||||||
|
unbind %
|
||||||
|
|
||||||
|
# Activar sesión mas interna (cuando se anida tmux) para enviar comandos
|
||||||
|
bind a send-prefix
|
||||||
|
|
||||||
|
|
||||||
|
### Temas
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
# Paleta de Colores de la Barra de estado
|
||||||
|
set-option -g status-justify left
|
||||||
|
set-option -g status-bg black
|
||||||
|
set-option -g status-fg white
|
||||||
|
set-option -g status-left-length 40
|
||||||
|
set-option -g status-right-length 80
|
||||||
|
|
||||||
|
# Paleta de Colores del Borde del Panel
|
||||||
|
set-option -g pane-active-border-fg green
|
||||||
|
set-option -g pane-active-border-bg black
|
||||||
|
set-option -g pane-border-fg white
|
||||||
|
set-option -g pane-border-bg black
|
||||||
|
|
||||||
|
# Paleta de Colores de Mensajes
|
||||||
|
set-option -g message-fg black
|
||||||
|
set-option -g message-bg green
|
||||||
|
|
||||||
|
# Paleta de Colores de la Ventana
|
||||||
|
setw -g window-status-bg black
|
||||||
|
setw -g window-status-current-fg green
|
||||||
|
setw -g window-status-bell-attr default
|
||||||
|
setw -g window-status-bell-fg red
|
||||||
|
setw -g window-status-content-attr default
|
||||||
|
setw -g window-status-content-fg yellow
|
||||||
|
setw -g window-status-activity-attr default
|
||||||
|
setw -g window-status-activity-fg yellow
|
||||||
|
|
||||||
|
|
||||||
|
### UI
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
# Notificación
|
||||||
|
setw -g monitor-activity on
|
||||||
|
set -g visual-activity on
|
||||||
|
set-option -g bell-action any
|
||||||
|
set-option -g visual-bell off
|
||||||
|
|
||||||
|
# Establece automáticamente títulos de ventanas
|
||||||
|
set-option -g set-titles on
|
||||||
|
set-option -g set-titles-string '#H:#S.#I.#P #W #T' # window number,program name,active (or not)
|
||||||
|
|
||||||
|
# Ajustes de barra de estado
|
||||||
|
set -g status-left "#[fg=red] #H#[fg=green]:#[fg=white]#S#[fg=green] |#[default]"
|
||||||
|
|
||||||
|
# Muestra indicadores de rendimiento en barra de estado
|
||||||
|
# Requiere https://github.com/thewtex/tmux-mem-cpu-load/
|
||||||
|
set -g status-interval 4
|
||||||
|
set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] | #[fg=cyan]%H:%M #[default]"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Referencias
|
||||||
|
|
||||||
|
[Tmux | Inicio](http://tmux.sourceforge.net)
|
||||||
|
|
||||||
|
[Tmux Manual](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux)
|
||||||
|
|
||||||
|
[Gentoo Wiki](http://wiki.gentoo.org/wiki/Tmux)
|
||||||
|
|
||||||
|
[Archlinux Wiki](https://wiki.archlinux.org/index.php/Tmux)
|
||||||
|
|
||||||
|
[Mostrar CPU/MEM % en barra de estado](https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux)
|
286
es-es/visualbasic-es.html.markdown
Normal file
286
es-es/visualbasic-es.html.markdown
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
---
|
||||||
|
language: Visual Basic
|
||||||
|
contributors:
|
||||||
|
- ["Brian Martin", "http://brianmartin.biz"]
|
||||||
|
translators:
|
||||||
|
- ["Adolfo Jayme Barrientos", "https://github.com/fitojb"]
|
||||||
|
author: Brian Martin
|
||||||
|
author_url: https://github.com/fitojb
|
||||||
|
filename: learnvisualbasic-es.vb
|
||||||
|
lang: es-es
|
||||||
|
---
|
||||||
|
|
||||||
|
```vb
|
||||||
|
Module Module1
|
||||||
|
|
||||||
|
Sub Main()
|
||||||
|
' Un vistazo rápido a las aplicaciones de consola de Visual Basic antes
|
||||||
|
' de que profundicemos en el tema.
|
||||||
|
' El apóstrofo inicia una línea de comentario.
|
||||||
|
' Para explorar este tutorial dentro del Compilador de Visual Basic,
|
||||||
|
' he creado un sistema de navegación.
|
||||||
|
' Dicho sistema se explicará a medida que avancemos en este
|
||||||
|
' tutorial; gradualmente entenderás lo que significa todo.
|
||||||
|
Console.Title = ("Aprende X en Y minutos")
|
||||||
|
Console.WriteLine("NAVEGACIÓN") 'Mostrar
|
||||||
|
Console.WriteLine("")
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green
|
||||||
|
Console.WriteLine("1. Salida «Hola, mundo»")
|
||||||
|
Console.WriteLine("2. Entrada «Hola, mundo»")
|
||||||
|
Console.WriteLine("3. Calcular números enteros")
|
||||||
|
Console.WriteLine("4. Calcular números decimales")
|
||||||
|
Console.WriteLine("5. Una calculadora funcional")
|
||||||
|
Console.WriteLine("6. Uso de bucles «Do While»")
|
||||||
|
Console.WriteLine("7. Uso de bucles «For While»")
|
||||||
|
Console.WriteLine("8. Declaraciones condicionales")
|
||||||
|
Console.WriteLine("9. Selecciona una bebida")
|
||||||
|
Console.WriteLine("50. Acerca de")
|
||||||
|
Console.WriteLine("Elige un número de la lista anterior")
|
||||||
|
Dim selection As String = Console.ReadLine
|
||||||
|
Select Case selection
|
||||||
|
Case "1" 'Salida «hola, mundo»
|
||||||
|
Console.Clear() 'Limpia la consola y abre la subrutina privada
|
||||||
|
SalidaHolaMundo() 'Abre la subrutina privada nombrada
|
||||||
|
Case "2" 'Entrada «hola, mundo»
|
||||||
|
Console.Clear()
|
||||||
|
EntradaHolaMundo()
|
||||||
|
Case "3" 'Calcular números enteros
|
||||||
|
Console.Clear()
|
||||||
|
CalcularNumerosEnteros()
|
||||||
|
Case "4" 'Calcular números decimales
|
||||||
|
Console.Clear()
|
||||||
|
CalcularNumerosDecimales()
|
||||||
|
Case "5" 'Una calculadora funcional
|
||||||
|
Console.Clear()
|
||||||
|
CalculadoraFuncional()
|
||||||
|
Case "6" 'Uso de bucles «Do While»
|
||||||
|
Console.Clear()
|
||||||
|
UsoBuclesDoWhile()
|
||||||
|
Case "7" 'Uso de bucles «For While»
|
||||||
|
Console.Clear()
|
||||||
|
UsoBuclesFor()
|
||||||
|
Case "8" 'Declaraciones condicionales
|
||||||
|
Console.Clear()
|
||||||
|
DeclaracionCondicional()
|
||||||
|
Case "9" 'Declaración «If/Else»
|
||||||
|
Console.Clear()
|
||||||
|
DeclaracionIfElse() 'Selecciona una bebida
|
||||||
|
Case "50" 'Cuadro de mensaje «Acerca de»
|
||||||
|
Console.Clear()
|
||||||
|
Console.Title = ("Aprende X en Y minutos :: Acerca de")
|
||||||
|
MsgBox("Tutorial escrito por Brian Martin (@BrianMartinn")
|
||||||
|
Console.Clear()
|
||||||
|
Main()
|
||||||
|
Console.ReadLine()
|
||||||
|
|
||||||
|
End Select
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'Uno - He usado números para guiarme por el sistema de navegación anterior
|
||||||
|
'cuando regrese posteriormente a implementarlo.
|
||||||
|
|
||||||
|
'Usamos subrutinas privadas para separar distintas secciones del programa.
|
||||||
|
Private Sub SalidaHolaMundo()
|
||||||
|
'Título de la aplicación de consola
|
||||||
|
Console.Title = "Salida «Hola, mundo» | Aprende X en Y minutos"
|
||||||
|
'Usa Console.Write("") o Console.WriteLine("") para mostrar salidas.
|
||||||
|
'Seguido por Console.Read(), o bien, Console.Readline()
|
||||||
|
'Console.ReadLine() muestra la salida en la consola.
|
||||||
|
Console.WriteLine("Hola, mundo")
|
||||||
|
Console.ReadLine()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'Dos
|
||||||
|
Private Sub EntradaHolaMundo()
|
||||||
|
Console.Title = "«Hola, mundo, soy...» | Aprende X en Y minutos"
|
||||||
|
' Variables
|
||||||
|
' Los datos que introduzca un usuario deben almacenarse.
|
||||||
|
' Las variables también empiezan por Dim y terminan por As VariableType.
|
||||||
|
|
||||||
|
' En este tutorial queremos conocer tu nombre y hacer que el programa
|
||||||
|
' responda a este.
|
||||||
|
Dim nombredeusuario As String
|
||||||
|
'Usamos «string» porque es una variable basada en texto.
|
||||||
|
Console.WriteLine("Hola, ¿cómo te llamas? ") 'Preguntar nombre de usuario.
|
||||||
|
nombredeusuario = Console.ReadLine() 'Almacenar nombre del usuario.
|
||||||
|
Console.WriteLine("Hola, " + nombredeusuario) 'La salida es Hola, nombre
|
||||||
|
Console.ReadLine() 'Muestra lo anterior.
|
||||||
|
'El código anterior te hará una pregunta y mostrará la respuesta.
|
||||||
|
'Entre otras variables está Integer, la cual usaremos para números enteros.
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'Tres
|
||||||
|
Private Sub CalcularNumerosEnteros()
|
||||||
|
Console.Title = "Calcular números enteros | Aprende X en Y minutos"
|
||||||
|
Console.Write("Primer número: ") 'Escribe un núm. entero, 1, 2, 104, etc
|
||||||
|
Dim a As Integer = Console.ReadLine()
|
||||||
|
Console.Write("Segundo número: ") 'Escribe otro número entero.
|
||||||
|
Dim b As Integer = Console.ReadLine()
|
||||||
|
Dim c As Integer = a + b
|
||||||
|
Console.WriteLine(c)
|
||||||
|
Console.ReadLine()
|
||||||
|
'Lo anterior es una calculadora sencilla
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'Cuatro
|
||||||
|
Private Sub CalcularNumerosDecimales()
|
||||||
|
Console.Title = "Calcular con tipo doble | Aprende X en Y minutos"
|
||||||
|
'Por supuesto, nos gustaría sumar decimales.
|
||||||
|
'Por ello podríamos cambiar del tipo Integer al Double.
|
||||||
|
|
||||||
|
'Escribe un número fraccionario, 1.2, 2.4, 50.1, 104.9 etc
|
||||||
|
Console.Write("Primer número: ")
|
||||||
|
Dim a As Double = Console.ReadLine
|
||||||
|
Console.Write("Segundo número: ") 'Escribe el segundo número.
|
||||||
|
Dim b As Double = Console.ReadLine
|
||||||
|
Dim c As Double = a + b
|
||||||
|
Console.WriteLine(c)
|
||||||
|
Console.ReadLine()
|
||||||
|
'Este programa puede sumar 1.1 y 2.2
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'Cinco
|
||||||
|
Private Sub CalculadoraFuncional()
|
||||||
|
Console.Title = "La calculadora funcional | Aprende X en Y minutos"
|
||||||
|
'Pero si quieres que la calculadora reste, divida, multiplique y
|
||||||
|
'sume.
|
||||||
|
'Copia y pega lo anterior.
|
||||||
|
Console.Write("Primer número: ")
|
||||||
|
Dim a As Double = Console.ReadLine
|
||||||
|
Console.Write("Segundo número: ")
|
||||||
|
Dim b As Integer = Console.ReadLine
|
||||||
|
Dim c As Integer = a + b
|
||||||
|
Dim d As Integer = a * b
|
||||||
|
Dim e As Integer = a - b
|
||||||
|
Dim f As Integer = a / b
|
||||||
|
|
||||||
|
'Mediante las líneas siguientes podremos restar,
|
||||||
|
'multiplicar y dividir los valores a y b
|
||||||
|
Console.Write(a.ToString() + " + " + b.ToString())
|
||||||
|
'Queremos dar un margen izquierdo de 3 espacios a los resultados.
|
||||||
|
Console.WriteLine(" = " + c.ToString.PadLeft(3))
|
||||||
|
Console.Write(a.ToString() + " * " + b.ToString())
|
||||||
|
Console.WriteLine(" = " + d.ToString.PadLeft(3))
|
||||||
|
Console.Write(a.ToString() + " - " + b.ToString())
|
||||||
|
Console.WriteLine(" = " + e.ToString.PadLeft(3))
|
||||||
|
Console.Write(a.ToString() + " / " + b.ToString())
|
||||||
|
Console.WriteLine(" = " + f.ToString.PadLeft(3))
|
||||||
|
Console.ReadLine()
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'Seis
|
||||||
|
Private Sub UsoBuclesDoWhile()
|
||||||
|
'Igual que la subrutina privada anterior
|
||||||
|
'Esta vez preguntaremos al usuario si quiere continuar (¿sí o no?)
|
||||||
|
'Usamos el bucle Do While porque no sabemos si el usuario quiere
|
||||||
|
'usar el programa más de una vez.
|
||||||
|
Console.Title = "Uso de bucles «Do While» | Aprende X en Y minutos"
|
||||||
|
Dim respuesta As String 'Usamos la variable «String» porque la resp. es texto
|
||||||
|
Do 'Comenzamos el programa con
|
||||||
|
Console.Write("Primer número: ")
|
||||||
|
Dim a As Double = Console.ReadLine
|
||||||
|
Console.Write("Segundo número: ")
|
||||||
|
Dim b As Integer = Console.ReadLine
|
||||||
|
Dim c As Integer = a + b
|
||||||
|
Dim d As Integer = a * b
|
||||||
|
Dim e As Integer = a - b
|
||||||
|
Dim f As Integer = a / b
|
||||||
|
|
||||||
|
Console.Write(a.ToString() + " + " + b.ToString())
|
||||||
|
Console.WriteLine(" = " + c.ToString.PadLeft(3))
|
||||||
|
Console.Write(a.ToString() + " * " + b.ToString())
|
||||||
|
Console.WriteLine(" = " + d.ToString.PadLeft(3))
|
||||||
|
Console.Write(a.ToString() + " - " + b.ToString())
|
||||||
|
Console.WriteLine(" = " + e.ToString.PadLeft(3))
|
||||||
|
Console.Write(a.ToString() + " / " + b.ToString())
|
||||||
|
Console.WriteLine(" = " + f.ToString.PadLeft(3))
|
||||||
|
Console.ReadLine()
|
||||||
|
'Preguntar si el usuario quiere continuar. Desafortunadamente,
|
||||||
|
'distingue entre mayúsculas y minúsculas.
|
||||||
|
Console.Write("¿Quieres continuar? (s / n)")
|
||||||
|
'El programa toma la variable, la muestra y comienza de nuevo.
|
||||||
|
respuesta = Console.ReadLine
|
||||||
|
'La orden que hará funcionar esta variable es en este caso «s»
|
||||||
|
Loop While respuesta = "s"
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'Siete
|
||||||
|
Private Sub UsoBuclesFor()
|
||||||
|
'A veces el programa debe ejecutarse solo una vez.
|
||||||
|
'En este programa contaremos a partir de 10.
|
||||||
|
|
||||||
|
Console.Title = "Uso de bucles «For» | Aprende X en Y minutos"
|
||||||
|
'Declarar Variable y desde qué número debe contar en Step -1,
|
||||||
|
'Step -2, Step -3, etc.
|
||||||
|
For i As Integer = 10 To 0 Step -1
|
||||||
|
Console.WriteLine(i.ToString) 'Muestra el valor del contador
|
||||||
|
Next i 'Calcular el valor nuevo
|
||||||
|
Console.WriteLine("Iniciar") '¡¡Comencemos el programa, nene!!
|
||||||
|
Console.ReadLine() '¡¡ZAS!! - Quizá me he emocionado bastante :)
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'Ocho
|
||||||
|
Private Sub DeclaracionCondicional()
|
||||||
|
Console.Title = "Declaraciones condicionales | Aprende X en Y minutos"
|
||||||
|
Dim nombredeUsuario As String = Console.ReadLine
|
||||||
|
Console.WriteLine("Hola, ¿cómo te llamas? ") 'Preguntar nombre de usuario.
|
||||||
|
nombredeUsuario = Console.ReadLine() 'Almacena el nombre de usuario.
|
||||||
|
If nombredeUsuario = "Adam" Then
|
||||||
|
Console.WriteLine("Hola, Adam")
|
||||||
|
Console.WriteLine("Gracias por crear este útil sitio web")
|
||||||
|
Console.ReadLine()
|
||||||
|
Else
|
||||||
|
Console.WriteLine("Hola, " + nombredeUsuario)
|
||||||
|
Console.WriteLine("¿Has visitado www.learnxinyminutes.com?")
|
||||||
|
Console.ReadLine() 'Termina y muestra la declaración anterior.
|
||||||
|
End If
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
'Nueve
|
||||||
|
Private Sub DeclaracionIfElse()
|
||||||
|
Console.Title = "Declaración «If / Else» | Aprende X en Y minutos"
|
||||||
|
'A veces es importante considerar más de dos alternativas.
|
||||||
|
'A veces, algunas de estas son mejores.
|
||||||
|
'Cuando esto sucede, necesitaríamos más de una declaración «if».
|
||||||
|
'Una declaración «if» es adecuada para máquinas expendedoras.
|
||||||
|
'En las que el usuario escribe un código (A1, A2, A3) para elegir.
|
||||||
|
'Pueden combinarse todas las elecciones en una sola declaración «if».
|
||||||
|
|
||||||
|
Dim seleccion As String = Console.ReadLine 'Valor de la selección
|
||||||
|
Console.WriteLine("A1. para 7Up")
|
||||||
|
Console.WriteLine("A2. para Fanta")
|
||||||
|
Console.WriteLine("A3. para Dr. Pepper")
|
||||||
|
Console.WriteLine("A4. para Coca-Cola")
|
||||||
|
Console.ReadLine()
|
||||||
|
If selection = "A1" Then
|
||||||
|
Console.WriteLine("7up")
|
||||||
|
Console.ReadLine()
|
||||||
|
ElseIf selection = "A2" Then
|
||||||
|
Console.WriteLine("fanta")
|
||||||
|
Console.ReadLine()
|
||||||
|
ElseIf selection = "A3" Then
|
||||||
|
Console.WriteLine("dr. pepper")
|
||||||
|
Console.ReadLine()
|
||||||
|
ElseIf selection = "A4" Then
|
||||||
|
Console.WriteLine("coca-cola")
|
||||||
|
Console.ReadLine()
|
||||||
|
Else
|
||||||
|
Console.WriteLine("Selecciona un producto")
|
||||||
|
Console.ReadLine()
|
||||||
|
End If
|
||||||
|
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
End Module
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Referencias
|
||||||
|
|
||||||
|
Aprendí Visual Basic en la aplicación de consola. Esta me permitió entender los principios de la programación para, posteriormente, aprender otros lenguajes con facilidad.
|
||||||
|
|
||||||
|
He creado un <a href="http://www.vbbootcamp.co.uk/" Title="Tutorial de Visual Basic">tutorial de Visual Basic</a> más exhaustivo para quienes quieran saber más.
|
||||||
|
|
||||||
|
Toda la sintaxis es válida. Copia el código y pégalo en el compilador de Visual Basic y ejecuta (F5) el programa.
|
@ -499,9 +499,6 @@ myNumber === myNumberObj; // = false
|
|||||||
if (0){
|
if (0){
|
||||||
// This code won't execute, because 0 is falsy.
|
// This code won't execute, because 0 is falsy.
|
||||||
}
|
}
|
||||||
if (Number(0)){
|
|
||||||
// This code *will* execute, because Number(0) is truthy.
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
441
fi-fi/go-fi.html.markdown
Normal file
441
fi-fi/go-fi.html.markdown
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
---
|
||||||
|
name: Go
|
||||||
|
category: language
|
||||||
|
language: Go
|
||||||
|
filename: learngo-fi.go
|
||||||
|
contributors:
|
||||||
|
- ["Sonia Keys", "https://github.com/soniakeys"]
|
||||||
|
- ["Christopher Bess", "https://github.com/cbess"]
|
||||||
|
- ["Jesse Johnson", "https://github.com/holocronweaver"]
|
||||||
|
- ["Quint Guvernator", "https://github.com/qguv"]
|
||||||
|
- ["Jose Donizetti", "https://github.com/josedonizetti"]
|
||||||
|
- ["Alexej Friesen", "https://github.com/heyalexej"]
|
||||||
|
- ["Clayton Walker", "https://github.com/cwalk"]
|
||||||
|
translators:
|
||||||
|
- ["Timo Virkkunen", "https://github.com/ComSecNinja"]
|
||||||
|
lang: fi-fi
|
||||||
|
---
|
||||||
|
|
||||||
|
Go luotiin työn tekemistä varten. Se ei ole tietojenkäsittelyn uusin trendi,
|
||||||
|
mutta se on uusin nopein tapa ratkaista oikean maailman ongelmia.
|
||||||
|
|
||||||
|
Sillä on staattisesti tyypitetyistä imperatiivisista kielistä tuttuja
|
||||||
|
konsepteja. Se kääntyy ja suorittuu nopeasti, lisää helposti käsitettävän
|
||||||
|
samanaikaisten komentojen suorittamisen nykyaikaisten moniytimisten
|
||||||
|
prosessoreiden hyödyntämiseksi ja antaa käyttäjälle ominaisuuksia suurten
|
||||||
|
projektien käsittelemiseksi.
|
||||||
|
|
||||||
|
Go tuo mukanaan loistavan oletuskirjaston sekä innokkaan yhteisön.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Yhden rivin kommentti
|
||||||
|
/* Useamman
|
||||||
|
rivin kommentti */
|
||||||
|
|
||||||
|
// Package -lausekkeella aloitetaan jokainen lähdekooditiedosto.
|
||||||
|
// Main on erityinen nimi joka ilmoittaa
|
||||||
|
// suoritettavan tiedoston kirjaston sijasta.
|
||||||
|
package main
|
||||||
|
|
||||||
|
// Import -lauseke ilmoittaa tässä tiedostossa käytetyt kirjastot.
|
||||||
|
import (
|
||||||
|
"fmt" // Paketti Go:n oletuskirjastosta.
|
||||||
|
"io/ioutil" // Implementoi hyödyllisiä I/O -funktioita.
|
||||||
|
m "math" // Matematiikkakirjasto jolla on paikallinen nimi m.
|
||||||
|
"net/http" // Kyllä, web-palvelin!
|
||||||
|
"strconv" // Kirjainjonojen muuntajia.
|
||||||
|
)
|
||||||
|
|
||||||
|
// Funktion määrittelijä. Main on erityinen: se on ohjelman suorittamisen
|
||||||
|
// aloittamisen alkupiste. Rakasta tai vihaa sitä, Go käyttää aaltosulkeita.
|
||||||
|
func main() {
|
||||||
|
// Println tulostaa rivin stdoutiin.
|
||||||
|
// Se tulee paketin fmt mukana, joten paketin nimi on mainittava.
|
||||||
|
fmt.Println("Hei maailma!")
|
||||||
|
|
||||||
|
// Kutsu toista funktiota tämän paketin sisällä.
|
||||||
|
beyondHello()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funktioilla voi olla parametrejä sulkeissa.
|
||||||
|
// Vaikkei parametrejä olisikaan, sulkeet ovat silti pakolliset.
|
||||||
|
func beyondHello() {
|
||||||
|
var x int // Muuttujan ilmoittaminen: ne täytyy ilmoittaa ennen käyttöä.
|
||||||
|
x = 3 // Arvon antaminen muuttujalle.
|
||||||
|
// "Lyhyet" ilmoitukset käyttävät := joka päättelee tyypin, ilmoittaa
|
||||||
|
// sekä antaa arvon muuttujalle.
|
||||||
|
y := 4
|
||||||
|
sum, prod := learnMultiple(x, y) // Funktio palauttaa kaksi arvoa.
|
||||||
|
fmt.Println("summa:", sum, "tulo:", prod) // Yksinkertainen tuloste.
|
||||||
|
learnTypes() // < y minuuttia, opi lisää!
|
||||||
|
}
|
||||||
|
|
||||||
|
/* <- usean rivin kommentti
|
||||||
|
Funktioilla voi olla parametrejä ja (useita!) palautusarvoja.
|
||||||
|
Tässä `x`, `y` ovat argumenttejä ja `sum`, `prod` ovat ne, mitä palautetaan.
|
||||||
|
Huomaa että `x` ja `sum` saavat tyyin `int`.
|
||||||
|
*/
|
||||||
|
func learnMultiple(x, y int) (sum, prod int) {
|
||||||
|
return x + y, x * y // Palauta kaksi arvoa.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sisäänrakennettuja tyyppejä ja todellisarvoja.
|
||||||
|
func learnTypes() {
|
||||||
|
// Lyhyt ilmoitus antaa yleensä haluamasi.
|
||||||
|
str := "Opi Go!" // merkkijonotyyppi.
|
||||||
|
|
||||||
|
s2 := `"raaka" todellisarvoinen merrkijono
|
||||||
|
voi sisältää rivinvaihtoja.` // Sama merkkijonotyyppi.
|
||||||
|
|
||||||
|
// Ei-ASCII todellisarvo. Go-lähdekoodi on UTF-8.
|
||||||
|
g := 'Σ' // riimutyyppi, lempinimi int32:lle, sisältää unicode-koodipisteen.
|
||||||
|
|
||||||
|
f := 3.14195 //float64, IEEE-754 64-bittinen liukuluku.
|
||||||
|
c := 3 + 4i // complex128, sisäisesti ilmaistu kahdella float64:lla.
|
||||||
|
|
||||||
|
// var -syntaksi alkuarvoilla.
|
||||||
|
var u uint = 7 // Etumerkitön, toteutus riippuvainen koosta kuten int.
|
||||||
|
var pi float32 = 22. / 7
|
||||||
|
|
||||||
|
// Muuntosyntaksi lyhyellä ilmoituksella.
|
||||||
|
n := byte('\n') // byte on leminimi uint8:lle.
|
||||||
|
|
||||||
|
// Listoilla on kiinteä koko kääntöhetkellä.
|
||||||
|
var a4 [4]int // 4 int:in lista, alkiot ovat alustettu nolliksi.
|
||||||
|
a3 := [...]int{3, 1, 5} // Listan alustaja jonka kiinteäksi kooksi tulee 3
|
||||||
|
// alkiota, jotka saavat arvot 3, 1, ja 5.
|
||||||
|
|
||||||
|
// Siivuilla on muuttuva koko. Sekä listoilla että siivuilla on puolensa,
|
||||||
|
// mutta siivut ovat yleisempiä käyttötapojensa vuoksi.
|
||||||
|
s3 := []int{4, 5, 9} // Vertaa a3: ei sananheittoa (...).
|
||||||
|
s4 := make([]int, 4) // Varaa 4 int:n siivun, alkiot alustettu nolliksi.
|
||||||
|
var d2 [][]float64 // Vain ilmoitus, muistia ei varata.
|
||||||
|
bs := []byte("a slice") // Tyypinmuuntosyntaksi.
|
||||||
|
|
||||||
|
// Koska siivut ovat dynaamisia, niitä voidaan yhdistellä sellaisinaan.
|
||||||
|
// Lisätäksesi alkioita siivuun, käytä sisäänrakennettua append()-funktiota.
|
||||||
|
// Ensimmäinen argumentti on siivu, johon alkoita lisätään.
|
||||||
|
s := []int{1, 2, 3} // Tuloksena on kolmen alkion pituinen lista.
|
||||||
|
s = append(s, 4, 5, 6) // Lisätty kolme alkiota. Siivun pituudeksi tulee 6.
|
||||||
|
fmt.Println(s) // Päivitetty siivu on nyt [1 2 3 4 5 6]
|
||||||
|
|
||||||
|
// Lisätäksesi siivun toiseen voit antaa append-funktiolle referenssin
|
||||||
|
// siivuun tai todellisarvoiseen siivuun lisäämällä sanaheiton argumentin
|
||||||
|
// perään. Tämä tapa purkaa siivun alkiot ja lisää ne siivuun s.
|
||||||
|
s = append(s, []int{7, 8, 9}...) // 2. argumentti on todellisarvoinen siivu.
|
||||||
|
fmt.Println(s) // Päivitetty siivu on nyt [1 2 3 4 5 6 7 8 9]
|
||||||
|
|
||||||
|
p, q := learnMemory() // Ilmoittaa p ja q olevan tyyppiä osoittaja int:iin.
|
||||||
|
fmt.Println(*p, *q) // * seuraa osoittajaa. Tämä tulostaa kaksi int:ä.
|
||||||
|
|
||||||
|
// Kartat ovat dynaamisesti kasvavia assosiatiivisia listoja, kuten hash tai
|
||||||
|
// dictionary toisissa kielissä.
|
||||||
|
m := map[string]int{"three": 3, "four": 4}
|
||||||
|
m["one"] = 1
|
||||||
|
|
||||||
|
// Käyttämättömät muuttujat ovat virheitä Go:ssa.
|
||||||
|
// Alaviiva antaa sinun "käyttää" muuttujan mutta hylätä sen arvon.
|
||||||
|
_, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs
|
||||||
|
// Tulostaminen tietysti lasketaan muuttujan käyttämiseksi.
|
||||||
|
fmt.Println(s, c, a4, s3, d2, m)
|
||||||
|
|
||||||
|
learnFlowControl() // Takaisin flowiin.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go:ssa on useista muista kielistä poiketen mahdollista käyttää nimettyjä
|
||||||
|
// palautusarvoja.
|
||||||
|
// Nimen antaminen palautettavan arvon tyypille funktion ilmoitusrivillä
|
||||||
|
// mahdollistaa helpon palaamisen useasta eri funktion suorituskohdasta sekä
|
||||||
|
// pelkän return-lausekkeen käytön ilman muita mainintoja.
|
||||||
|
func learnNamedReturns(x, y int) (z int) {
|
||||||
|
z = x * y
|
||||||
|
return // z on epäsuorasti tässä, koska nimesimme sen aiemmin.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go kerää kaikki roskansa. Siinä on osoittajia mutta ei niiden laskentoa.
|
||||||
|
// Voit tehdä virheen mitättömällä osoittajalla, mutta et
|
||||||
|
// kasvattamalla osoittajaa.
|
||||||
|
func learnMemory() (p, q *int) {
|
||||||
|
// Nimetyillä palautusarvoilla p ja q on tyyppi osoittaja int:iin.
|
||||||
|
p = new(int) // Sisäänrakennettu funktio new varaa muistia.
|
||||||
|
// Varattu int on alustettu nollaksi, p ei ole enää mitätön.
|
||||||
|
s := make([]int, 20) // Varaa 20 int:ä yhteen kohtaan muistissa.
|
||||||
|
s[3] = 7 // Anna yhdelle niistä arvo.
|
||||||
|
r := -2 // Ilmoita toinen paikallinen muuttuja.
|
||||||
|
return &s[3], &r // & ottaa asian osoitteen muistissa.
|
||||||
|
}
|
||||||
|
|
||||||
|
func expensiveComputation() float64 {
|
||||||
|
return m.Exp(10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func learnFlowControl() {
|
||||||
|
// If -lausekkeet vaativat aaltosulkeet mutta ei tavallisia sulkeita.
|
||||||
|
if true {
|
||||||
|
fmt.Println("mitä mä sanoin")
|
||||||
|
}
|
||||||
|
// Muotoilu on standardoitu käyttämällä komentorivin komentoa "go fmt".
|
||||||
|
if false {
|
||||||
|
// Nyrpistys.
|
||||||
|
} else {
|
||||||
|
// Nautinto.
|
||||||
|
}
|
||||||
|
// Käytä switch -lauseketta ketjutettujen if -lausekkeiden sijasta.
|
||||||
|
x := 42.0
|
||||||
|
switch x {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 42:
|
||||||
|
// Tapaukset eivät "tipu läpi".
|
||||||
|
/*
|
||||||
|
Kuitenkin meillä on erikseen `fallthrough` -avainsana. Katso:
|
||||||
|
https://github.com/golang/go/wiki/Switch#fall-through
|
||||||
|
*/
|
||||||
|
case 43:
|
||||||
|
// Saavuttamaton.
|
||||||
|
default:
|
||||||
|
// Oletustapaus (default) on valinnainen.
|
||||||
|
}
|
||||||
|
// Kuten if, for -lauseke ei myöskään käytä tavallisia sulkeita.
|
||||||
|
// for- ja if- lausekkeissa ilmoitetut muuttujat ovat paikallisia niiden
|
||||||
|
// piireissä.
|
||||||
|
for x := 0; x < 3; x++ { // ++ on lauseke. Sama kuin "x = x + 1".
|
||||||
|
fmt.Println("iteraatio", x)
|
||||||
|
}
|
||||||
|
// x == 42 tässä.
|
||||||
|
|
||||||
|
// For on kielen ainoa silmukkalauseke mutta sillä on vaihtoehtosia muotoja.
|
||||||
|
for { // Päättymätön silmukka.
|
||||||
|
break // Kunhan vitsailin.
|
||||||
|
continue // Saavuttamaton.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Voit käyttää range -lauseketta iteroidaksesi listojen, siivujen, merkki-
|
||||||
|
// jonojen, karttojen tai kanavien läpi. range palauttaa yhden (kanava) tai
|
||||||
|
// kaksi arvoa (lista, siivu, merkkijono ja kartta).
|
||||||
|
for key, value := range map[string]int{"yksi": 1, "kaksi": 2, "kolme": 3} {
|
||||||
|
// jokaista kartan paria kohden, tulosta avain ja arvo
|
||||||
|
fmt.Printf("avain=%s, arvo=%d\n", key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kuten for -lausekkeessa := if -lausekkeessa tarkoittaa ilmoittamista ja
|
||||||
|
// arvon asettamista.
|
||||||
|
// Aseta ensin y, sitten testaa onko y > x.
|
||||||
|
if y := expensiveComputation(); y > x {
|
||||||
|
x = y
|
||||||
|
}
|
||||||
|
// Todellisarvoiset funktiot ovat sulkeumia.
|
||||||
|
xBig := func() bool {
|
||||||
|
return x > 10000 // Viittaa ylempänä ilmoitettuun x:ään.
|
||||||
|
}
|
||||||
|
fmt.Println("xBig:", xBig()) // tosi (viimeisin arvo on e^10).
|
||||||
|
x = 1.3e3 // Tämä tekee x == 1300
|
||||||
|
fmt.Println("xBig:", xBig()) // epätosi nyt.
|
||||||
|
|
||||||
|
// Lisäksi todellisarvoiset funktiot voidaan samalla sekä ilmoittaa että
|
||||||
|
// kutsua, jolloin niitä voidaan käyttää funtioiden argumentteina kunhan:
|
||||||
|
// a) todellisarvoinen funktio kutsutaan välittömästi (),
|
||||||
|
// b) palautettu tyyppi vastaa odotettua argumentin tyyppiä.
|
||||||
|
fmt.Println("Lisää ja tuplaa kaksi numeroa: ",
|
||||||
|
func(a, b int) int {
|
||||||
|
return (a + b) * 2
|
||||||
|
}(10, 2)) // Kutsuttu argumenteilla 10 ja 2
|
||||||
|
// => Lisää ja tuplaa kaksi numeroa: 24
|
||||||
|
|
||||||
|
// Kun tarvitset sitä, rakastat sitä.
|
||||||
|
goto love
|
||||||
|
love:
|
||||||
|
|
||||||
|
learnFunctionFactory() // Funktioita palauttavat funktiot
|
||||||
|
learnDefer() // Nopea kiertoreitti tärkeään avainsanaan.
|
||||||
|
learnInterfaces() // Hyvää kamaa tulossa!
|
||||||
|
}
|
||||||
|
|
||||||
|
func learnFunctionFactory() {
|
||||||
|
// Seuraavat kaksi ovat vastaavia, mutta toinen on käytännöllisempi
|
||||||
|
fmt.Println(sentenceFactory("kesä")("Kaunis", "päivä!"))
|
||||||
|
|
||||||
|
d := sentenceFactory("kesä")
|
||||||
|
fmt.Println(d("Kaunis", "päivä!"))
|
||||||
|
fmt.Println(d("Laiska", "iltapäivä!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Somisteet ovat yleisiä toisissa kielissä. Sama saavutetaan Go:ssa käyttämällä
|
||||||
|
// todellisarvoisia funktioita jotka ottavat vastaan argumentteja.
|
||||||
|
func sentenceFactory(mystring string) func(before, after string) string {
|
||||||
|
return func(before, after string) string {
|
||||||
|
return fmt.Sprintf("%s %s %s", before, mystring, after) // uusi jono
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func learnDefer() (ok bool) {
|
||||||
|
// Lykätyt lausekkeet suoritetaan juuri ennen funktiosta palaamista.
|
||||||
|
defer fmt.Println("lykätyt lausekkeet suorittuvat")
|
||||||
|
defer fmt.Println("käänteisessä järjestyksessä (LIFO).")
|
||||||
|
defer fmt.Println("\nTämä rivi tulostuu ensin, koska")
|
||||||
|
// Defer -lauseketta käytetään yleisesti tiedoston sulkemiseksi, jotta
|
||||||
|
// tiedoston sulkeva funktio pysyy lähellä sen avannutta funktiota.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Määrittele Stringer rajapintatyypiksi jolla on
|
||||||
|
// yksi jäsenfunktio eli metodi, String.
|
||||||
|
type Stringer interface {
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Määrittele pair rakenteeksi jossa on kaksi kenttää, x ja y tyyppiä int.
|
||||||
|
type pair struct {
|
||||||
|
x, y int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Määrittele jäsenfunktio pair:lle. Pair tyydyttää nyt Stringer -rajapinnan.
|
||||||
|
func (p pair) String() string { // p:tä kutsutaan nimellä "receiver"
|
||||||
|
// Sprintf on toinen julkinen funktio paketissa fmt.
|
||||||
|
// Pistesyntaksilla viitataan P:n kenttiin.
|
||||||
|
return fmt.Sprintf("(%d, %d)", p.x, p.y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func learnInterfaces() {
|
||||||
|
// Aaltosuljesyntaksi on "todellisarvoinen rakenne". Se todentuu alustetuksi
|
||||||
|
// rakenteeksi. := -syntaksi ilmoittaa ja alustaa p:n täksi rakenteeksi.
|
||||||
|
p := pair{3, 4}
|
||||||
|
fmt.Println(p.String()) // Kutsu p:n (tyyppiä pair) jäsenfunktiota String.
|
||||||
|
var i Stringer // Ilmoita i Stringer-rajapintatyypiksi.
|
||||||
|
i = p // Pätevä koska pair tyydyttää rajapinnan Stringer.
|
||||||
|
// Kutsu i:n (Stringer) jäsenfunktiota String. Tuloste on sama kuin yllä.
|
||||||
|
fmt.Println(i.String())
|
||||||
|
|
||||||
|
// Funktiot fmt-paketissa kutsuvat argumenttien String-jäsenfunktiota
|
||||||
|
// selvittääkseen onko niistä saatavilla tulostettavaa vastinetta.
|
||||||
|
fmt.Println(p) // Tuloste on sama kuin yllä. Println kutsuu String-metodia.
|
||||||
|
fmt.Println(i) // Tuloste on sama kuin yllä.
|
||||||
|
|
||||||
|
learnVariadicParams("loistavaa", "oppimista", "täällä!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funktioilla voi olla muuttuva eli variteettinen
|
||||||
|
// määrä argumentteja eli parametrejä.
|
||||||
|
func learnVariadicParams(myStrings ...interface{}) {
|
||||||
|
// Iteroi jokaisen argumentin läpi.
|
||||||
|
// Tässä alaviivalla sivuutetaan argumenttilistan kunkin kohdan indeksi.
|
||||||
|
for _, param := range myStrings {
|
||||||
|
fmt.Println("param:", param)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Luovuta variteettinen arvo variteettisena parametrinä.
|
||||||
|
fmt.Println("params:", fmt.Sprintln(myStrings...))
|
||||||
|
|
||||||
|
learnErrorHandling()
|
||||||
|
}
|
||||||
|
|
||||||
|
func learnErrorHandling() {
|
||||||
|
// "; ok" -muotoa käytetään selvittääksemme toimiko jokin vai ei.
|
||||||
|
m := map[int]string{3: "kolme", 4: "neljä"}
|
||||||
|
if x, ok := m[1]; !ok { // ok on epätosi koska 1 ei ole kartassa.
|
||||||
|
fmt.Println("ei ketään täällä")
|
||||||
|
} else {
|
||||||
|
fmt.Print(x) // x olisi arvo jos se olisi kartassa.
|
||||||
|
}
|
||||||
|
// Virhearvo voi kertoa muutakin ongelmasta.
|
||||||
|
if _, err := strconv.Atoi("ei-luku"); err != nil { // _ sivuuttaa arvon
|
||||||
|
// tulostaa strconv.ParseInt: parsing "ei-luku": invalid syntax
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
// Palaamme rajapintoihin hieman myöhemmin. Sillä välin,
|
||||||
|
learnConcurrency()
|
||||||
|
}
|
||||||
|
|
||||||
|
// c on kanava, samanaikaisturvallinen viestintäolio.
|
||||||
|
func inc(i int, c chan int) {
|
||||||
|
c <- i + 1 // <- on "lähetysoperaattori" kun kanava on siitä vasemmalla.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Käytämme inc -funktiota samanaikaiseen lukujen lisäämiseen.
|
||||||
|
func learnConcurrency() {
|
||||||
|
// Sama make -funktio jota käytimme aikaisemmin siivun luomiseksi. Make
|
||||||
|
// varaa muistin ja alustaa siivut, kartat ja kanavat.
|
||||||
|
c := make(chan int)
|
||||||
|
// Aloita kolme samanaikaista gorutiinia (goroutine). Luvut kasvavat
|
||||||
|
// samanaikaisesti ja ehkäpä rinnakkain jos laite on kykenevä ja oikein
|
||||||
|
// määritelty. Kaikki kolme lähettävät samalle kanavalle.
|
||||||
|
go inc(0, c) // go -lauseke aloittaa uuden gorutiinin.
|
||||||
|
go inc(10, c)
|
||||||
|
go inc(-805, c)
|
||||||
|
// Lue kolme palautusarvoa kanavalta ja tulosta ne.
|
||||||
|
// Niiden saapumisjärjestystä ei voida taata!
|
||||||
|
// <- on "vastaanotto-operaattori" jos kanava on oikealla
|
||||||
|
fmt.Println(<-c, <-c, <-c)
|
||||||
|
|
||||||
|
cs := make(chan string) // Toinen kanava joka käsittelee merkkijonoja.
|
||||||
|
ccs := make(chan chan string) // Kanava joka käsittelee merkkijonokanavia.
|
||||||
|
go func() { c <- 84 }() // Aloita uusi gorutiini arvon lähettämiseksi.
|
||||||
|
go func() { cs <- "sanaa" }() // Uudestaan, mutta cs -kanava tällä kertaa.
|
||||||
|
// Select -lausekkeella on syntaksi kuten switch -lausekkeella mutta
|
||||||
|
// jokainen tapaus sisältää kanavaoperaation. Se valitsee satunnaisen
|
||||||
|
// tapauksen niistä kanavista, jotka ovat kommunikaatiovalmiita
|
||||||
|
select {
|
||||||
|
case i := <-c: // Vastaanotettu arvo voidaan antaa muuttujalle
|
||||||
|
fmt.Printf("se on %T", i)
|
||||||
|
case <-cs: // tai vastaanotettu arvo voidaan sivuuttaa.
|
||||||
|
fmt.Println("se on merkkijono")
|
||||||
|
case <-ccs: // Tyhjä kanava; ei valmis kommunikaatioon.
|
||||||
|
fmt.Println("ei tapahtunut.")
|
||||||
|
}
|
||||||
|
// Tässä vaiheessa arvo oli otettu joko c:ltä tai cs:ltä. Yksi kahdesta
|
||||||
|
// ylempänä aloitetusta gorutiinista on valmistunut, toinen pysyy tukossa.
|
||||||
|
|
||||||
|
learnWebProgramming() // Go tekee sitä. Sinäkin haluat tehdä sitä.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yksittäinen funktio http -paketista aloittaa web-palvelimen.
|
||||||
|
func learnWebProgramming() {
|
||||||
|
|
||||||
|
// ListenAndServe:n ensimmäinen parametri on TCP-osoite, jota kuunnellaan.
|
||||||
|
// Toinen parametri on rajapinta, http.Handler.
|
||||||
|
go func() {
|
||||||
|
err := http.ListenAndServe(":8080", pair{})
|
||||||
|
fmt.Println(err) // älä sivuuta virheitä.
|
||||||
|
}()
|
||||||
|
|
||||||
|
requestServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tee pair:sta http.Handler implementoimalla sen ainoa metodi, ServeHTTP.
|
||||||
|
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Tarjoa dataa metodilla http.ResponseWriter.
|
||||||
|
w.Write([]byte("Opit Go:n Y minuutissa!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestServer() {
|
||||||
|
resp, err := http.Get("http://localhost:8080")
|
||||||
|
fmt.Println(err)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
fmt.Printf("\nWeb-palvelin sanoo: `%s`", string(body))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Lisää luettavaa
|
||||||
|
|
||||||
|
Go-tietämyksen alku ja juuri on sen [virallinen verkkosivu]()(http://golang.org/).
|
||||||
|
Siellä voit seurata oppitunteja, askarrella vuorovaikutteisesti sekä lukea paljon.
|
||||||
|
Kierroksen lisäksi [dokumentaatio](https://golang.org/doc/) pitää sisällään tietoa
|
||||||
|
siistin Go-koodin kirjoittamisesta, pakettien ja komentojen käytöstä sekä julkaisuhistoriasta.
|
||||||
|
|
||||||
|
Kielen määritelmä itsessään on suuresti suositeltavissa. Se on helppolukuinen ja
|
||||||
|
yllättävän lyhyt (niissä määrin kuin kielimääritelmät nykypäivänä ovat.)
|
||||||
|
|
||||||
|
Voit askarrella parissa kanssa [Go playgroundissa](https://play.golang.org/p/tnWMjr16Mm).
|
||||||
|
Muuttele sitä ja aja se selaimestasi! Huomaa, että voit käyttää [https://play.golang.org](https://play.golang.org)
|
||||||
|
[REPL:na](https://en.wikipedia.org/wiki/Read-eval-print_loop) testataksesi ja koodataksesi selaimessasi, ilman Go:n asentamista.
|
||||||
|
|
||||||
|
Go:n opiskelijoiden lukulistalla on [oletuskirjaston lähdekoodi](http://golang.org/src/pkg/).
|
||||||
|
Kattavasti dokumentoituna se antaa parhaan kuvan helppolukuisesta ja ymmärrettävästä Go-koodista,
|
||||||
|
-tyylistä ja -tavoista. Voit klikata funktion nimeä [doukumentaatiossa](http://golang.org/pkg/) ja
|
||||||
|
lähdekoodi tulee esille!
|
||||||
|
|
||||||
|
Toinen loistava paikka oppia on [Go by example](https://gobyexample.com/).
|
||||||
|
|
||||||
|
Go Mobile lisää tuen mobiilialustoille (Android ja iOS). Voit kirjoittaa pelkällä Go:lla natiiveja applikaatioita tai tehdä kirjaston joka sisältää sidoksia
|
||||||
|
Go-paketista, jotka puolestaan voidaan kutsua Javasta (Android) ja Objective-C:stä (iOS). Katso [lisätietoja](https://github.com/golang/go/wiki/Mobile).
|
259
fi-fi/markdown-fi.html.markdown
Normal file
259
fi-fi/markdown-fi.html.markdown
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
---
|
||||||
|
language: markdown
|
||||||
|
filename: markdown-fi.md
|
||||||
|
contributors:
|
||||||
|
- ["Dan Turkel", "http://danturkel.com/"]
|
||||||
|
translators:
|
||||||
|
- ["Timo Virkkunen", "https://github.com/ComSecNinja"]
|
||||||
|
lang: fi-fi
|
||||||
|
---
|
||||||
|
|
||||||
|
John Gruber loi Markdownin vuona 2004. Sen tarkoitus on olla helposti luettava ja kirjoitettava syntaksi joka muuntuu helposti HTML:ksi (ja nyt myös moneksi muuksi formaatiksi).
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- Jokainen HTML-tiedosto on pätevää Markdownia. Tämä tarkoittaa että voimme
|
||||||
|
käyttää HTML-elementtejä Markdownissa, kuten kommentteja, ilman että markdown
|
||||||
|
-jäsennin vaikuttaa niihin. Tästä johtuen et voi kuitenkaan käyttää markdownia
|
||||||
|
HTML-elementtien sisällä jos luot sellaisen markdown-tiedostoon. -->
|
||||||
|
|
||||||
|
<!-- Markdownin toteutus vaihtelee jäsentimestä toiseen. Tämä opas yrittää
|
||||||
|
selventää mitkä ominaisuudet ovat yleisiä ja mitkä ovat eritysesti tiettyjen
|
||||||
|
jäsentimien ominaisuuksia. -->
|
||||||
|
|
||||||
|
<!-- Otsikot -->
|
||||||
|
<!-- Voit luoda HTML-elementtejä <h1> - <h6> helposti aloittamalla rivin
|
||||||
|
haluamallasi määrällä ristikkomerkkejä (#). -->
|
||||||
|
# Tämä on <h1>
|
||||||
|
## Tämä on <h2>
|
||||||
|
### Tämä on <h3>
|
||||||
|
#### Tämä on <h4>
|
||||||
|
##### Tämä on <h5>
|
||||||
|
###### Tämä on <h6>
|
||||||
|
|
||||||
|
<!-- Markdownissa on myös vaihtoehtoisia tapoja ilmaista h1 ja h2. -->
|
||||||
|
Tämä on h1
|
||||||
|
=============
|
||||||
|
|
||||||
|
Tämä on h2
|
||||||
|
-------------
|
||||||
|
|
||||||
|
<!-- Yksinkertaiset tekstimuotoilut -->
|
||||||
|
<!-- Tekstin voi helposti muotoilla kursiiviksi tai lihavoiduksi. -->
|
||||||
|
|
||||||
|
*Tämä teksti on kursivoitua.*
|
||||||
|
_Kuten on myös tämä teksti._
|
||||||
|
|
||||||
|
**Tämä teksti on lihavoitua.**
|
||||||
|
__Kuten on tämäkin teksti.__
|
||||||
|
|
||||||
|
***Tämä teksti on molempia.***
|
||||||
|
**_Kuten tämäkin!_**
|
||||||
|
*__Kuten tämäkin!__*
|
||||||
|
|
||||||
|
<!-- Github-tyylisessä Markdownissa, jota käytetään tiedostojen esittämiseksi
|
||||||
|
Githubissa, meillä on käytössämme myös yliviivaus: -->
|
||||||
|
|
||||||
|
~~Tämä teksti on yliviivattua.~~
|
||||||
|
|
||||||
|
<!-- Kappaleet ovat yhdellä tai useammalla peräkkäisellä tekstirivillä jotka
|
||||||
|
erotellaan yhdellä tai useammalla tyhjällä rivillä -->
|
||||||
|
|
||||||
|
Tämä on kappala. Kirjoittelen kappaleeseen, eikö tämä olekin hauskaa?
|
||||||
|
|
||||||
|
Nyt olen kappaleessa 2.
|
||||||
|
Olen edelleen toisessa kappaleessa!
|
||||||
|
|
||||||
|
|
||||||
|
Olen kolmannessa kappaleessa!
|
||||||
|
|
||||||
|
<!-- Jos haluat lisätä <br /> HTML-elementin, päätä kappale kahdella tai
|
||||||
|
useammalla välilyönnillä ja aloita sitten uusi kappale -->
|
||||||
|
|
||||||
|
Päätän tämän kahteen välilyöntiin (maalaa minut nähdäksesi ne).
|
||||||
|
|
||||||
|
There's a <br /> above me!
|
||||||
|
|
||||||
|
<!-- Lainaukset ovat helppoja ja ne tehdään >-merkillä -->
|
||||||
|
|
||||||
|
> Tämä on lainaus. Voit joko
|
||||||
|
> manuaalisesti rivittää tekstisi ja laittaa >-merkin jokaisen rivin eteen tai antaa jäsentimen rivittää pitkät tekstirivit.
|
||||||
|
> Sillä ei ole merkitystä kunhan rivit alkavat >-merkillä.
|
||||||
|
|
||||||
|
> Voit myös käyttää useampaa
|
||||||
|
>> sisennystasoa
|
||||||
|
> Kuinka hienoa se on?
|
||||||
|
|
||||||
|
<!-- Listat -->
|
||||||
|
<!-- Järjestämättömät listat tehdään asteriskilla, plussalla tai viivalla -->
|
||||||
|
|
||||||
|
* Kohta
|
||||||
|
* Kohta
|
||||||
|
* Kolmas kohta
|
||||||
|
|
||||||
|
tai
|
||||||
|
|
||||||
|
+ Kohta
|
||||||
|
+ Kohta
|
||||||
|
+ Kolmas kohta
|
||||||
|
|
||||||
|
tai
|
||||||
|
|
||||||
|
- Kohta
|
||||||
|
- Kohta
|
||||||
|
- Kolmas kohta
|
||||||
|
|
||||||
|
<!-- Järjestetyt listat tehdään järjestysluvuilla. -->
|
||||||
|
|
||||||
|
1. Kohta yksi
|
||||||
|
2. Kohta kaksi
|
||||||
|
3. Kohta kolme
|
||||||
|
|
||||||
|
<!-- Sinun ei tarvitse edes merkitä kohtia oikein ja silti markdown näyttää
|
||||||
|
oikean järjestyksen, mutta se ei välttämättä ole hyvä idea. -->
|
||||||
|
|
||||||
|
1. Kohta yksi
|
||||||
|
1. Kohta kaksi
|
||||||
|
1. Kohta kolme
|
||||||
|
<!-- (Tämä korjaantuu samanlaiseksi kuin yllä oleva esimerkki) -->
|
||||||
|
|
||||||
|
<!-- Voit myös käyttää alalistoja. -->
|
||||||
|
|
||||||
|
1. Kohta yksi
|
||||||
|
2. Kohta kaksi
|
||||||
|
3. Kohta kolme
|
||||||
|
* Alakohta
|
||||||
|
* Alakohta
|
||||||
|
4. Kohta neljä
|
||||||
|
|
||||||
|
<!-- Myös tehtävälistoja on olemassa. Tämä tekee HTML-valintaruutuja. -->
|
||||||
|
|
||||||
|
Alla olevat ruudut ilman x-merkkiä ovat merkitsemättömiä HTML-valintaruutuja.
|
||||||
|
- [ ] Ensimmäinen suoritettava tehtävä.
|
||||||
|
- [ ] Toinen tehtävä joka täytyy tehdä
|
||||||
|
Tämä alla oleva ruutu on merkitty HTML-valintaruutu.
|
||||||
|
- [x] Tämä tehtävä on suoritettu
|
||||||
|
|
||||||
|
<!-- Koodiosiot -->
|
||||||
|
<!-- Voit merkitä koodiosion (jaka käyttää <code> -elementtiä) sisentämällä
|
||||||
|
rivin neljällä välilyönnillä tai tabulaattorilla. -->
|
||||||
|
|
||||||
|
Tämä on koodia
|
||||||
|
Kuten tämäkin
|
||||||
|
|
||||||
|
<!-- Voit myös sisentää koodia samalla tavalla. -->
|
||||||
|
|
||||||
|
my_array.each do |item|
|
||||||
|
puts item
|
||||||
|
end
|
||||||
|
|
||||||
|
<!-- Muun tekstin seassa oleva koodi merkitään kahden `-merkin väliin -->
|
||||||
|
|
||||||
|
John ei tiennyt edes mitä `go_to()` -funktio teki!
|
||||||
|
|
||||||
|
<!-- Githubin Markdownissa voit käyttää erityissyntaksia koodille. -->
|
||||||
|
|
||||||
|
\`\`\`ruby <!-- paitsi että poista nuo kenoviivat, vain ```ruby ! -->
|
||||||
|
def foobar
|
||||||
|
puts "Hello world!"
|
||||||
|
end
|
||||||
|
\`\`\` <!-- tästä myös, ei kenoviivoja, vain ``` -->
|
||||||
|
|
||||||
|
<!-- Yllä oleva teksti ei vaadi sisennystä. Lisäksi Github käyttää ``` jälkeen
|
||||||
|
mainitsemasi kielen syntaksin korostusta -->
|
||||||
|
|
||||||
|
<!-- Vaakaviiva (<hr />) -->
|
||||||
|
<!-- Vaakaviivojen lisääminen käy näppärästi kolmella tai useammalla
|
||||||
|
asteriskilla taikka viivalla, välilyönneillä tai ilman -->
|
||||||
|
|
||||||
|
***
|
||||||
|
---
|
||||||
|
- - -
|
||||||
|
****************
|
||||||
|
|
||||||
|
<!-- Linkit -->
|
||||||
|
<!-- yksi markdownin parhaita ominaisuuksia on yksinkertaiset hyperlinkit. Laita
|
||||||
|
näytettävä teksti hakasulkuihin [] ja URL-osoite perään sulkeissa (). -->
|
||||||
|
|
||||||
|
[Klikkaa tästä!](http://example.com/)
|
||||||
|
|
||||||
|
<!-- Voit myös lisätä linkin otsikon heittomerkeissä osoitteen perään. -->
|
||||||
|
|
||||||
|
[Klikkaa tästä!](http://example.com/ "Linkki Example.com:iin")
|
||||||
|
|
||||||
|
<!-- Suhteelliset polut toimivat myös. -->
|
||||||
|
|
||||||
|
[Musiikkia](/musiikki/).
|
||||||
|
|
||||||
|
<!-- Markdown tukee myös viittaustyylisiä linkkejä. -->
|
||||||
|
|
||||||
|
[Klikkaa tätä linkkiä][link1] saadaksesi lisätietoja!
|
||||||
|
[Katso myös tämä linkki][foobar] jos haluat.
|
||||||
|
|
||||||
|
[link1]: http://example.com/ "Siistii!"
|
||||||
|
[foobar]: http://foobar.biz/ "Selkis!"
|
||||||
|
|
||||||
|
<!-- Otsikko voi olla myös ykittäisissä heittomerkeissä tai sulkeissa, tai
|
||||||
|
ohitettu kokonaan. Viittaukset voivat olla missä tahansa kohdassa dokumenttia ja
|
||||||
|
viittausten ID:t voivat olla mitä tahansa kunhan ne ovat uniikkeja. -->
|
||||||
|
|
||||||
|
<!-- Voit myös käyttää linkin tekstiä ID:nä näin: -->
|
||||||
|
|
||||||
|
[This][] is a link.
|
||||||
|
|
||||||
|
[this]: http://tämäonlinkki.com/
|
||||||
|
|
||||||
|
<!-- Mutta tämä tapa ei ole yleinen. -->
|
||||||
|
|
||||||
|
<!-- Kuvat -->
|
||||||
|
<!-- Kuvat tehdään samalla tavalla kuin linkitkin, mutta huutomerkki edessä! -->
|
||||||
|
|
||||||
|
![Kuvan alt-attribuutti](http://imgur.com/munkuva.jpg "Vaihtoehtoinen otsikko")
|
||||||
|
|
||||||
|
<!-- Ja viittaukset toimivat odotetusti. -->
|
||||||
|
|
||||||
|
![Tämä on se alt-attribuutti][munkuva]
|
||||||
|
|
||||||
|
[munkuva]: suhteellinen/polku/siitii/kuva.jpg "otsikko tähän tarvittaessa"
|
||||||
|
|
||||||
|
<!-- Sekalaista -->
|
||||||
|
<!-- Automaattiset linkit -->
|
||||||
|
|
||||||
|
<http://testwebsite.com/> on sama kuin
|
||||||
|
[http://testwebsite.com/](http://testwebsite.com/)
|
||||||
|
|
||||||
|
<!-- Automaattiset sähköpostilinkit -->
|
||||||
|
|
||||||
|
<foo@bar.com>
|
||||||
|
|
||||||
|
<!-- Varattujen merkkien käyttö -->
|
||||||
|
|
||||||
|
haluan kirjoittaa *tämän tekstin jonka ympärillä on asteriskit* mutta en halua
|
||||||
|
sen kursivoituvan, joten teen näin: \*tämän tekstin ympärillä on asteriskit\*.
|
||||||
|
|
||||||
|
<!-- Näppäimistön näppäimet -->
|
||||||
|
<!-- Githubin Markdownissa, voit käyttää <kbd> -tagia esittämään näppäimiä -->
|
||||||
|
|
||||||
|
Tietokoneesi kaatui? Kokeile painaa
|
||||||
|
<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
|
||||||
|
|
||||||
|
<!-- Taulukot -->
|
||||||
|
<!-- Taulukot ovat saatavilla vain Githubin markdownissa ja ne ovat melko
|
||||||
|
vaivalloisia käyttää, mutta jos todella haluat: -->
|
||||||
|
|
||||||
|
| Kolumni1 | Kolumni2 | Kolumni3 |
|
||||||
|
| :----------- | :------: | ------------: |
|
||||||
|
| Vasemmalle | Keskelle | Oikealle |
|
||||||
|
| blaa | blaa | blaa |
|
||||||
|
|
||||||
|
<!-- vaihtoehtoisesti, sama tulos -->
|
||||||
|
|
||||||
|
Kolumni 1 | Kolumni 2 | Kolumni 3
|
||||||
|
:-- | :-: | --:
|
||||||
|
Hyi tämä on ruma | saa se | loppumaan
|
||||||
|
|
||||||
|
<!-- Loppu! -->
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Lisää tietoa löydät John Gruberin [virallisesta julkaisusta](http://daringfireball.net/projects/markdown/syntax)
|
||||||
|
ja Adam Pritchardin loistavasta [lunttilapusta](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
|
@ -117,7 +117,7 @@ one-to-12 \ 0 1 2 3 4 5 6 7 8 9 10 11 12 ok
|
|||||||
: threes ( n n -- ) ?do i . 3 +loop ; \ ok
|
: threes ( n n -- ) ?do i . 3 +loop ; \ ok
|
||||||
15 0 threes \ 0 3 6 9 12 ok
|
15 0 threes \ 0 3 6 9 12 ok
|
||||||
|
|
||||||
\ Indefinite loops with `begin` <stuff to do> <flag> `unil`:
|
\ Indefinite loops with `begin` <stuff to do> <flag> `until`:
|
||||||
: death ( -- ) begin ." Are we there yet?" 0 until ; \ ok
|
: death ( -- ) begin ." Are we there yet?" 0 until ; \ ok
|
||||||
|
|
||||||
\ ---------------------------- Variables and Memory ----------------------------
|
\ ---------------------------- Variables and Memory ----------------------------
|
||||||
@ -133,7 +133,7 @@ variable age \ ok
|
|||||||
age @ . \ 21 ok
|
age @ . \ 21 ok
|
||||||
age ? \ 21 ok
|
age ? \ 21 ok
|
||||||
|
|
||||||
\ Constants are quite simiar, except we don't bother with memory addresses:
|
\ Constants are quite similar, except we don't bother with memory addresses:
|
||||||
100 constant WATER-BOILING-POINT \ ok
|
100 constant WATER-BOILING-POINT \ ok
|
||||||
WATER-BOILING-POINT . \ 100 ok
|
WATER-BOILING-POINT . \ 100 ok
|
||||||
|
|
||||||
|
115
fr-fr/HTML-fr.html.markdown
Normal file
115
fr-fr/HTML-fr.html.markdown
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
---
|
||||||
|
language: html
|
||||||
|
filename: learnhtml-fr.html
|
||||||
|
contributors:
|
||||||
|
- ["Christophe THOMAS", "https://github.com/WinChris"]
|
||||||
|
lang: fr-fr
|
||||||
|
---
|
||||||
|
HTML signifie HyperText Markup Language.
|
||||||
|
C'est un langage (format de fichiers) qui permet d'écrire des pages internet.
|
||||||
|
C’est un langage de balisage, il nous permet d'écrire des pages HTML au moyen de balises (Markup, en anglais).
|
||||||
|
Les fichiers HTML sont en réalité de simple fichier texte.
|
||||||
|
Qu'est-ce que le balisage ? C'est une façon de hiérarchiser ses données en les entourant par une balise ouvrante et une balise fermante.
|
||||||
|
Ce balisage sert à donner une signification au texte ainsi entouré.
|
||||||
|
Comme tous les autres langages, HTML a plusieurs versions. Ici, nous allons parlons de HTML5.
|
||||||
|
|
||||||
|
**NOTE :** Vous pouvez tester les différentes balises que nous allons voir au fur et à mesure du tutoriel sur des sites comme [codepen](http://codepen.io/pen/) afin de voir les résultats, comprendre, et vous familiariser avec le langage.
|
||||||
|
Cet article porte principalement sur la syntaxe et quelques astuces.
|
||||||
|
|
||||||
|
|
||||||
|
```HTML
|
||||||
|
<!-- Les commentaires sont entouré comme cette ligne! -->
|
||||||
|
|
||||||
|
<!-- #################### Les balises #################### -->
|
||||||
|
|
||||||
|
<!-- Voici un exemple de fichier HTML que nous allons analyser -->
|
||||||
|
<!-- Venez voir ce que ça donne -->
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Mon Site</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Hello, world!</h1>
|
||||||
|
<a href = "http://codepen.io/anon/pen/xwjLbZ">Venez voir ce que ça donne</a>
|
||||||
|
<p>Ceci est un paragraphe</p>
|
||||||
|
<p>Ceci est un autre paragraphe</p>
|
||||||
|
<ul>
|
||||||
|
<li>Ceci est un item d'une liste non ordonnée (liste à puces)</li>
|
||||||
|
<li>Ceci est un autre item</li>
|
||||||
|
<li>Et ceci est le dernier item de la liste</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<!-- Un fichier HTML débute toujours par indiquer au navigateur que notre page est faite en HTML -->
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<!-- Après ça on commence par ouvrir une balise <html> -->
|
||||||
|
<html>
|
||||||
|
</html>
|
||||||
|
<!-- Et puis on la referme à la fin du fichier avec </html> -->
|
||||||
|
<!-- après cette balise de fin, plus rien ne doit apparaître. -->
|
||||||
|
|
||||||
|
<!-- À l'intérieur (entre la balise ouvrant et fermante <html></html>), on trouve : -->
|
||||||
|
|
||||||
|
<!-- Un entête (<head> en anglais ; il faut le refermer avec </head>) -->
|
||||||
|
<!-- L'entête contient des descriptions et informations annexes qui ne sont pas affichées : se sont les métadonnées -->
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Mon Site</title><!-- La balise <title> permet d'indiquer au navigateur le titre à afficher dans la barre de l'onglet de la fenêtre -->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<!-- Après la balise <head>, on trouve la balise <body> -->
|
||||||
|
<!-- Pour le moment, rien n'est encore affiché dans la fenêtre du navigateur. -->
|
||||||
|
<!-- Il faut ensuite remplir le corps (balise <body>) avec du contenu -->
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Hello, world!</h1> <!-- La balise h1 permet de structurer le texte, c'est un titre -->
|
||||||
|
<!-- Il exite différents sous-titres à <h1> qui sont hiérarchisés du plus important (h2) au plus précis (h6) -->
|
||||||
|
<a href = "http://codepen.io/anon/pen/xwjLbZ">Venez voir ce que ça donne</a> <!-- Lien vers la source cible indiqué dans href="" -->
|
||||||
|
<p>Ceci est un paragraphe </p> <!-- La balise <p> permet d'inclure du texte à la page html -->
|
||||||
|
<p>Ceci est un autre paragraphe</p>
|
||||||
|
<ul> <!-- La balise <ul> permet d'introduire une liste à puces -->
|
||||||
|
<!-- Si on souhaite une liste ordonnée : <ol> liste numérotée, 1. pour le premier élément, 2. pour le second, etc -->
|
||||||
|
<li>Ceci est un item d'une liste non ordonnée (liste à puces)</li>
|
||||||
|
<li>Ceci est un autre item</li>
|
||||||
|
<li>Et ceci est le dernier item de la liste</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<!-- Voilà comment créer un fichier HTML simple -->
|
||||||
|
|
||||||
|
<!-- Mais il est possible d'ajouter encore des balises plus spécifiques -->
|
||||||
|
|
||||||
|
<!-- Pour insérer une image -->
|
||||||
|
<img src="http://i.imgur.com/XWG0O.gif"/> <!-- On indique la source de l'image dans src="" -->
|
||||||
|
<!-- La source peut-être un URL ou encore la destination d'un fichier de votre ordinateur -->
|
||||||
|
|
||||||
|
<!-- Il est possible de réaliser des tableaux également -->
|
||||||
|
|
||||||
|
<table> <!-- On ouvre la balise <table> -->
|
||||||
|
<tr> <!-- <tr> permet de créer une ligne -->
|
||||||
|
<th>First Header</th> <!-- <th> permet de créer un titre au tableau -->
|
||||||
|
<th>Second Header</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Première ligne, première cellule</td> <!-- <td> permet de créer une cellule -->
|
||||||
|
<td>Première ligne, deuxième cellule</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Deuxième ligne, première cellule</td>
|
||||||
|
<td>Deuxième ligne, deuxième cellule</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
## Utilisation
|
||||||
|
|
||||||
|
Le HTML s'écrit dans des fichiers `.html`.
|
||||||
|
|
||||||
|
## En savoir plus
|
||||||
|
|
||||||
|
* [Tutoriel HTML](http://slaout.linux62.org/html_css/html.html)
|
||||||
|
* [W3School](http://www.w3schools.com/html/html_intro.asp)
|
@ -248,7 +248,7 @@ keymap ; => {:a 1, :b 2, :c 3}
|
|||||||
|
|
||||||
; Il y a encore d'autres fonctions dans l'espace de nom clojure.sets.
|
; Il y a encore d'autres fonctions dans l'espace de nom clojure.sets.
|
||||||
|
|
||||||
; Formes utiles
|
; Formes et macros utiles
|
||||||
;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
; Les constructions logiques en Clojure sont juste des macros, et
|
; Les constructions logiques en Clojure sont juste des macros, et
|
||||||
@ -275,6 +275,33 @@ ressemblent à toutes les autres formes:
|
|||||||
(let [name "Urkel"]
|
(let [name "Urkel"]
|
||||||
(print "Saying hello to " name)
|
(print "Saying hello to " name)
|
||||||
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
|
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
|
||||||
|
|
||||||
|
; Utilisez les Threading Macros (-> et ->>) pour exprimer plus
|
||||||
|
; clairement vos transformations, en y pensant de manière multi-niveaux.
|
||||||
|
|
||||||
|
; La "flèche simple" ou "Thread-first", insère, à chaque niveau
|
||||||
|
; de la transformation, la forme courante en la seconde position
|
||||||
|
; de la forme suivante, constituant à chaque fois un nouvel étage
|
||||||
|
; de transformation. Par exemple:
|
||||||
|
(->
|
||||||
|
{:a 1 :b 2}
|
||||||
|
(assoc :c 3) ;=> Génère ici (assoc {:a 1 :b 2} :c 3)
|
||||||
|
(dissoc :b)) ;=> Génère ici (dissoc (assoc {:a 1 :b 2} :c 3) :b)
|
||||||
|
|
||||||
|
; Cette expression est ré-écrite en:
|
||||||
|
; (dissoc (assoc {:a 1 :b 2} :c 3) :b)
|
||||||
|
; et est évaluée en : {:a 1 :c 3}
|
||||||
|
|
||||||
|
; La "flèche double" ou "Thread-last" procède de la même manière
|
||||||
|
; que "->", mais insère le résultat de la réécriture de chaque
|
||||||
|
; étage en dernière position. Par exemple:
|
||||||
|
(->>
|
||||||
|
(range 10)
|
||||||
|
(map inc) ;=> Génère ici (map inc (range 10)
|
||||||
|
(filter odd?) ;=> Génère ici (filter odd? (map inc (range 10))
|
||||||
|
(into [])) ;=> Génère ici (into [] (filter odd? (map inc (range 10))), ce qui est évalué au final à;
|
||||||
|
; [1 3 5 7 9]
|
||||||
|
|
||||||
|
|
||||||
; Modules
|
; Modules
|
||||||
;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;
|
||||||
|
@ -239,7 +239,8 @@ sur une nouvelle ligne! ""Wow!"", quel style";
|
|||||||
// Opérateur ternaire
|
// Opérateur ternaire
|
||||||
// Un simple if/else peut s'écrire :
|
// Un simple if/else peut s'écrire :
|
||||||
// <condition> ? <valeur si true> : <valeur si false>
|
// <condition> ? <valeur si true> : <valeur si false>
|
||||||
string isTrue = (true) ? "True" : "False";
|
int toCompare = 17;
|
||||||
|
string isTrue = toCompare == 17 ? "True" : "False";
|
||||||
|
|
||||||
// Boucle while
|
// Boucle while
|
||||||
int fooWhile = 0;
|
int fooWhile = 0;
|
||||||
|
@ -8,7 +8,7 @@ translators:
|
|||||||
lang: fr-fr
|
lang: fr-fr
|
||||||
---
|
---
|
||||||
|
|
||||||
Au début du web, il n'y avait pas d'élements visuels, simplement du texte pure. Mais avec le dévelopement des navigateurs,
|
Au début du web, il n'y avait pas d'élements visuels, simplement du texte pur. Mais avec le dévelopement des navigateurs,
|
||||||
des pages avec du contenu visuel sont arrivées.
|
des pages avec du contenu visuel sont arrivées.
|
||||||
CSS est le langage standard qui existe et permet de garder une séparation entre
|
CSS est le langage standard qui existe et permet de garder une séparation entre
|
||||||
le contenu (HTML) et le style d'une page web.
|
le contenu (HTML) et le style d'une page web.
|
||||||
@ -16,8 +16,8 @@ le contenu (HTML) et le style d'une page web.
|
|||||||
En résumé, CSS fournit une syntaxe qui vous permet de cibler des élements présents
|
En résumé, CSS fournit une syntaxe qui vous permet de cibler des élements présents
|
||||||
sur une page HTML afin de leur donner des propriétés visuelles différentes.
|
sur une page HTML afin de leur donner des propriétés visuelles différentes.
|
||||||
|
|
||||||
Comme tous les autres langages, CSS a plusieurs versions. Ici, nous allons parlons de CSS2.0
|
Comme tous les autres langages, CSS a plusieurs versions. Ici, nous allons parler de CSS2.0
|
||||||
qui n'est pas le plus récent, mais qui reste le plus utilisé et le plus compatible avec les différents navigateur.
|
qui n'est pas le plus récent, mais qui reste le plus utilisé et le plus compatible avec les différents navigateurs.
|
||||||
|
|
||||||
**NOTE :** Vous pouvez tester les effets visuels que vous ajoutez au fur et à mesure du tutoriel sur des sites comme [dabblet](http://dabblet.com/) afin de voir les résultats, comprendre, et vous familiariser avec le langage.
|
**NOTE :** Vous pouvez tester les effets visuels que vous ajoutez au fur et à mesure du tutoriel sur des sites comme [dabblet](http://dabblet.com/) afin de voir les résultats, comprendre, et vous familiariser avec le langage.
|
||||||
Cet article porte principalement sur la syntaxe et quelques astuces.
|
Cet article porte principalement sur la syntaxe et quelques astuces.
|
||||||
@ -33,7 +33,7 @@ Cet article porte principalement sur la syntaxe et quelques astuces.
|
|||||||
/* Généralement, la première déclaration en CSS est très simple */
|
/* Généralement, la première déclaration en CSS est très simple */
|
||||||
selecteur { propriete: valeur; /* autres proprietés...*/ }
|
selecteur { propriete: valeur; /* autres proprietés...*/ }
|
||||||
|
|
||||||
/* Le sélécteur sert à cibler un élément du HTML
|
/* Le sélecteur sert à cibler un élément du HTML
|
||||||
|
|
||||||
Vous pouvez cibler tous les éléments d'une page! */
|
Vous pouvez cibler tous les éléments d'une page! */
|
||||||
* { color:red; }
|
* { color:red; }
|
||||||
|
264
fr-fr/d.html.markdown
Normal file
264
fr-fr/d.html.markdown
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
---
|
||||||
|
language: D
|
||||||
|
filename: learnd-fr.d
|
||||||
|
contributors:
|
||||||
|
- ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"]
|
||||||
|
translators:
|
||||||
|
- ["Quentin Ladeveze", "aceawan.eu"]
|
||||||
|
lang: fr-fr
|
||||||
|
---
|
||||||
|
|
||||||
|
```d
|
||||||
|
// Commençons par un classique
|
||||||
|
module hello;
|
||||||
|
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
// args n'est pas obligatoire
|
||||||
|
void main(string[] args) {
|
||||||
|
writeln("Bonjour le monde !");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Si vous êtes comme moi et que vous passez beaucoup trop de temps sur internet, il y a
|
||||||
|
de grandes chances pour que vous ayez déjà entendu parler du [D](http://dlang.org/).
|
||||||
|
D est un langage de programmation moderne, généraliste, multi-paradigmes qui contient
|
||||||
|
des fonctionnalités aussi bien de bas niveau que de haut niveau.
|
||||||
|
|
||||||
|
D est activement développé par de nombreuses personnes très intelligents, guidées par
|
||||||
|
[Walter Bright](https://fr.wikipedia.org/wiki/Walter_Bright))) et
|
||||||
|
[Andrei Alexandrescu](https://fr.wikipedia.org/wiki/Andrei_Alexandrescu).
|
||||||
|
Après cette petite introduction, jetons un coup d'oeil à quelques exemples.
|
||||||
|
|
||||||
|
```d
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
//Les conditions et les boucles sont classiques.
|
||||||
|
for(int i = 0; i < 10000; i++) {
|
||||||
|
writeln(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// On peut utiliser auto pour inférer automatiquement le
|
||||||
|
// type d'une variable.
|
||||||
|
auto n = 1;
|
||||||
|
|
||||||
|
// On peut faciliter la lecture des valeurs numériques
|
||||||
|
// en y insérant des `_`.
|
||||||
|
while(n < 10_000) {
|
||||||
|
n += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
n -= (n / 2);
|
||||||
|
} while(n > 0);
|
||||||
|
|
||||||
|
// For et while sont très utiles, mais en D, on préfère foreach.
|
||||||
|
// Les deux points : '..', créent un intervalle continue de valeurs
|
||||||
|
// incluant la première mais excluant la dernière.
|
||||||
|
foreach(i; 1..1_000_000) {
|
||||||
|
if(n % 2 == 0)
|
||||||
|
writeln(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// On peut également utiliser foreach_reverse pour itérer à l'envers.
|
||||||
|
foreach_reverse(i; 1..int.max) {
|
||||||
|
if(n % 2 == 1) {
|
||||||
|
writeln(i);
|
||||||
|
} else {
|
||||||
|
writeln("Non !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
On peut définir de nouveaux types avec les mots-clés `struct`, `class`,
|
||||||
|
`union` et `enum`. Ces types sont passés au fonction par valeur (ils sont copiés)
|
||||||
|
De plus, on peut utiliser les templates pour rendre toutes ces abstractions génériques.
|
||||||
|
|
||||||
|
```d
|
||||||
|
// Ici, 'T' est un paramètre de type. Il est similaire au <T> de C++/C#/Java.
|
||||||
|
struct LinkedList(T) {
|
||||||
|
T data = null;
|
||||||
|
|
||||||
|
// Utilisez '!' pour instancier un type paramétré.
|
||||||
|
// Encore une fois semblable à '<T>'
|
||||||
|
LinkedList!(T)* next;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BinTree(T) {
|
||||||
|
T data = null;
|
||||||
|
|
||||||
|
// Si il n'y a qu'un seul paramètre de template,
|
||||||
|
// on peut s'abstenir de mettre des parenthèses.
|
||||||
|
BinTree!T left;
|
||||||
|
BinTree!T right;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Day {
|
||||||
|
Sunday,
|
||||||
|
Monday,
|
||||||
|
Tuesday,
|
||||||
|
Wednesday,
|
||||||
|
Thursday,
|
||||||
|
Friday,
|
||||||
|
Saturday,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utilisez alias pour créer des abreviations pour les types.
|
||||||
|
alias IntList = LinkedList!int;
|
||||||
|
alias NumTree = BinTree!double;
|
||||||
|
|
||||||
|
// On peut tout aussi bien créer des templates de function !
|
||||||
|
T max(T)(T a, T b) {
|
||||||
|
if(a < b)
|
||||||
|
return b;
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On peut utiliser le mot-clé ref pour s'assurer que quelque chose est passé
|
||||||
|
// par référence, et ceci, même si a et b sont d'ordinaire passés par valeur.
|
||||||
|
// Ici ils seront toujours passés par référence à 'swap()'.
|
||||||
|
void swap(T)(ref T a, ref T b) {
|
||||||
|
auto temp = a;
|
||||||
|
|
||||||
|
a = b;
|
||||||
|
b = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avec les templates, on peut également passer des valeurs en paramètres.
|
||||||
|
class Matrix(uint m, uint n, T = int) {
|
||||||
|
T[m] rows;
|
||||||
|
T[n] columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mat = new Matrix!(3, 3); // T est 'int' par défaut
|
||||||
|
|
||||||
|
```
|
||||||
|
À propos de classes, parlons des propriétés. Une propriété est, en gros,
|
||||||
|
une méthode qui peut se comporter comme une lvalue. On peut donc utiliser
|
||||||
|
la syntaxe des structures classiques (`struct.x = 7`) comme si il
|
||||||
|
s'agissait de méthodes getter ou setter.
|
||||||
|
|
||||||
|
```d
|
||||||
|
// Considérons une classe paramétrée avec les types 'T' et 'U'
|
||||||
|
class MyClass(T, U) {
|
||||||
|
T _data;
|
||||||
|
U _other;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Et des méthodes "getter" et "setter" comme suit:
|
||||||
|
class MyClass(T, U) {
|
||||||
|
T _data;
|
||||||
|
U _other;
|
||||||
|
|
||||||
|
// Les constructeurs s'apellent toujours 'this'.
|
||||||
|
this(T t, U u) {
|
||||||
|
// Ceci va appeller les setters ci-dessous.
|
||||||
|
data = t;
|
||||||
|
other = u;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getters
|
||||||
|
@property T data() {
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property U other() {
|
||||||
|
return _other;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setters
|
||||||
|
@property void data(T t) {
|
||||||
|
_data = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property void other(U u) {
|
||||||
|
_other = u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Et on l'utilise de cette façon:
|
||||||
|
void main() {
|
||||||
|
auto mc = new MyClass!(int, string)(7, "seven");
|
||||||
|
|
||||||
|
// Importer le module 'stdio' de la bibliothèque standard permet
|
||||||
|
// d'écrire dans la console (les imports peuvent être locaux à une portée)
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
// On appelle les getters pour obtenir les valeurs.
|
||||||
|
writefln("Earlier: data = %d, str = %s", mc.data, mc.other);
|
||||||
|
|
||||||
|
// On appelle les setter pour assigner de nouvelles valeurs.
|
||||||
|
mc.data = 8;
|
||||||
|
mc.other = "eight";
|
||||||
|
|
||||||
|
// On appelle les setter pour obtenir les nouvelles valeurs.
|
||||||
|
writefln("Later: data = %d, str = %s", mc.data, mc.other);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Avec les propriétés, on peut constuire nos setters et nos getters
|
||||||
|
comme on le souhaite, tout en gardant un syntaxe très propre,
|
||||||
|
comme si on accédait directement à des membres de la classe.
|
||||||
|
|
||||||
|
Les autres fonctionnalités orientées objets à notre disposition
|
||||||
|
incluent les interfaces, les classes abstraites, et la surcharge
|
||||||
|
de méthodes. D gère l'héritage comme Java: On ne peut hériter que
|
||||||
|
d'une seule classe et implémenter autant d'interface que voulu.
|
||||||
|
|
||||||
|
Nous venons d'explorer les fonctionnalités objet du D, mais changeons
|
||||||
|
un peu de domaine. D permet la programmation fonctionelle, avec les fonctions
|
||||||
|
de premier ordre, les fonctions `pure` et les données immuables.
|
||||||
|
De plus, tout vos algorithmes fonctionelles favoris (map, reduce, filter)
|
||||||
|
sont disponibles dans le module `std.algorithm`.
|
||||||
|
|
||||||
|
```d
|
||||||
|
import std.algorithm : map, filter, reduce;
|
||||||
|
import std.range : iota; // construit un intervalle excluant la dernière valeur.
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// On veut un algorithm qui affiche la somme de la listes des carrés
|
||||||
|
// des entiers paires de 1 à 100. Un jeu d'enfant !
|
||||||
|
|
||||||
|
// On se content de passer des expressions lambda en paramètre à des templates.
|
||||||
|
// On peut fournier au template n'importe quelle fonction, mais dans notre
|
||||||
|
// cas, les lambdas sont pratiques.
|
||||||
|
auto num = iota(1, 101).filter!(x => x % 2 == 0)
|
||||||
|
.map!(y => y ^^ 2)
|
||||||
|
.reduce!((a, b) => a + b);
|
||||||
|
|
||||||
|
writeln(num);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Vous voyez comme on a calculé `num` comme on le ferait en haskell par exemple ?
|
||||||
|
C'est grâce à une innvoation de D qu'on appelle "Uniform Function Call Syntax".
|
||||||
|
Avec l'UFCS, on peut choisir d'écrire un appelle à une fonction de manière
|
||||||
|
classique, ou comme un appelle à une méthode. Walter Brighter a écrit un
|
||||||
|
article en anglais sur l'UFCS [ici.](http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394)
|
||||||
|
Pour faire court, on peut appeller une fonction dont le premier paramètre
|
||||||
|
est de type A, comme si c'était une méthode de A.
|
||||||
|
|
||||||
|
J'aime le parallélisme. Vous aimez les parallélisme ? Bien sur que vous aimez ça
|
||||||
|
Voyons comment on le fait en D !
|
||||||
|
|
||||||
|
```d
|
||||||
|
import std.stdio;
|
||||||
|
import std.parallelism : parallel;
|
||||||
|
import std.math : sqrt;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// On veut calculer la racine carré de tous les nombres
|
||||||
|
// dans notre tableau, et profiter de tous les coeurs
|
||||||
|
// à notre disposition.
|
||||||
|
auto arr = new double[1_000_000];
|
||||||
|
|
||||||
|
// On utilise un index et une référence à chaque élément du tableau.
|
||||||
|
// On appelle juste la fonction parallel sur notre tableau !
|
||||||
|
foreach(i, ref elem; parallel(arr)) {
|
||||||
|
ref = sqrt(i + 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
```
|
157
fr-fr/haml-fr.html.markdown
Normal file
157
fr-fr/haml-fr.html.markdown
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
---
|
||||||
|
language: haml
|
||||||
|
filename: learnhaml.haml
|
||||||
|
contributors:
|
||||||
|
- ["Simon Neveu", "https://github.com/sneveu"]
|
||||||
|
- ["Thibault", "https://github.com/iTech-"]
|
||||||
|
lang: fr-fr
|
||||||
|
---
|
||||||
|
|
||||||
|
Haml est un langage de balisage utilisé majoritairement avec Ruby, qui décrit de manière simple et propre le HTML de n'importe quelle page web sans l'utilisation des traditionnelles lignes de code. Le langage est une alternative très populaire au langage de templates Rails (.erb) et permet d'intégrer du code en Ruby dans votre balisage.
|
||||||
|
|
||||||
|
Son but est de réduire le nombre de répétitions dans le balisage en fermant des balises pour vous en se basant sur l'indentation de votre code. Finalement, le balisage est bien structuré, ne contient pas de répétition, est logique et facile à lire.
|
||||||
|
|
||||||
|
Vous pouvez aussi utiliser Haml sur un projet indépendant de Ruby, en installant les gems de Haml et en le convertissant en html grâce aux commandes.
|
||||||
|
|
||||||
|
$ haml fichier_entree.haml fichier_sortie.html
|
||||||
|
|
||||||
|
|
||||||
|
```haml
|
||||||
|
/ -------------------------------------------
|
||||||
|
/ Indentation
|
||||||
|
/ -------------------------------------------
|
||||||
|
|
||||||
|
/
|
||||||
|
A cause de l'importance de l'indentation sur la manière dont votre code sera
|
||||||
|
converti, l'indentation doit être constante à travers votre document. Un
|
||||||
|
simple changement d'indentation entrainera une erreur. En général, on utilise
|
||||||
|
deux espaces, mais ce genre de décision sur l'indentation vous appartient, du
|
||||||
|
moment que vous vous y tenez.
|
||||||
|
|
||||||
|
/ -------------------------------------------
|
||||||
|
/ Commentaires
|
||||||
|
/ -------------------------------------------
|
||||||
|
|
||||||
|
/ Ceci est un commentaire en Haml.
|
||||||
|
|
||||||
|
/
|
||||||
|
Pour écrire un commentaire sur plusieurs lignes, indentez votre code
|
||||||
|
commenté en le commençant par un slash
|
||||||
|
|
||||||
|
-# Ceci est un commentaire silencieux, qui n'apparaîtra pas dans le fichier
|
||||||
|
|
||||||
|
|
||||||
|
/ -------------------------------------------
|
||||||
|
/ Eléments HTML
|
||||||
|
/ -------------------------------------------
|
||||||
|
|
||||||
|
/ Pour écrire vos balises, utilisez un pourcentage suivi du nom de votre balise
|
||||||
|
%body
|
||||||
|
%header
|
||||||
|
%nav
|
||||||
|
|
||||||
|
/ Remarquez qu'il n'y a aucunes balises fermées. Le code produira alors ceci
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<nav></nav>
|
||||||
|
</header>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
/ La balise div est l'élément par défaut, vous pouvez donc l'écrire comme ceci
|
||||||
|
.balise
|
||||||
|
|
||||||
|
/ Pour ajouter du contenu à votre balise, ajoutez le texte après sa déclaration
|
||||||
|
%h1 Titre contenu
|
||||||
|
|
||||||
|
/ Pour écrire du contenu sur plusieurs lignes, imbriquez le
|
||||||
|
%p
|
||||||
|
Ce paragraphe contient beaucoup de contenu qui pourrait
|
||||||
|
probablement tenir sur deux lignes séparées.
|
||||||
|
|
||||||
|
/
|
||||||
|
Vous pouvez utiliser des caractères html spéciaux en utilisant &=. Cela va
|
||||||
|
convertir les caractères comme &, /, : en leur équivalent HTML. Par exemple
|
||||||
|
|
||||||
|
%p
|
||||||
|
&= "Oui & oui"
|
||||||
|
|
||||||
|
/ Produira 'Oui & oui'
|
||||||
|
|
||||||
|
/ Vous pouvez écrire du contenu html sans qu'il soit converti en utilisant !=
|
||||||
|
%p
|
||||||
|
!= "Voici comment écrire une balise de paragraphe <p></p>"
|
||||||
|
|
||||||
|
/ Cela produira 'Voici comment écrire une balise de paragraphe <p></p>'
|
||||||
|
|
||||||
|
/ Une classe CSS peut être ajouté à votre balise en chainant le nom de la classe
|
||||||
|
%div.truc.machin
|
||||||
|
|
||||||
|
/ ou en utilisant un hash de Ruby
|
||||||
|
%div{:class => 'truc machin'}
|
||||||
|
|
||||||
|
/ Des attributs pour n'importe quelles balises peuvent être ajoutés au hash
|
||||||
|
%a{:href => '#', :class => 'machin', :title => 'Titre machin'}
|
||||||
|
|
||||||
|
/ Pour affecter une valeur à un booléen, utilisez 'true'
|
||||||
|
%input{:selected => true}
|
||||||
|
|
||||||
|
/ Pour écrire des data-attributes, utilisez le :data avec la valeur d'un hash
|
||||||
|
%div{:data => {:attribute => 'machin'}}
|
||||||
|
|
||||||
|
|
||||||
|
/ -------------------------------------------
|
||||||
|
/ Insérer du Ruby
|
||||||
|
/ -------------------------------------------
|
||||||
|
|
||||||
|
/
|
||||||
|
Pour transférer une valeur de Ruby comme contenu d'une balise, utilisez le
|
||||||
|
signe égal suivi du code Ruby
|
||||||
|
|
||||||
|
%h1= livre.titre
|
||||||
|
|
||||||
|
%p
|
||||||
|
= livre.auteur
|
||||||
|
= livre.editeur
|
||||||
|
|
||||||
|
|
||||||
|
/ Pour lancer du code Ruby sans le convertir en HTML, utilisez un trait d'union
|
||||||
|
- livres = ['livre 1', 'livre 2', 'livre 3']
|
||||||
|
|
||||||
|
/ Ceci vous permet de faire des choses géniales comme des blocs Ruby
|
||||||
|
- livre.shuffle.each_with_index do |livre, index|
|
||||||
|
%h1= livre
|
||||||
|
|
||||||
|
if livre do
|
||||||
|
%p Ceci est un livre
|
||||||
|
|
||||||
|
/
|
||||||
|
Encore une fois il n'est pas nécessaire d'ajouter une balise fermante, même
|
||||||
|
pour Ruby.
|
||||||
|
L'indentation le fera pour vous.
|
||||||
|
|
||||||
|
|
||||||
|
/ -------------------------------------------
|
||||||
|
/ Ruby en-ligne / Interpolation en Ruby
|
||||||
|
/ -------------------------------------------
|
||||||
|
|
||||||
|
/ Inclure une variable Ruby dans une ligne en utilisant #{}
|
||||||
|
%p Votre meilleur score est #{record}
|
||||||
|
|
||||||
|
|
||||||
|
/ -------------------------------------------
|
||||||
|
/ Filtres
|
||||||
|
/ -------------------------------------------
|
||||||
|
|
||||||
|
/
|
||||||
|
Utilisez les deux points pour définir un filtre Haml, vous pouvez par exemple
|
||||||
|
utiliser un filtre :javascript pour écrire du contenu en-ligne js
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
console.log('Ceci est la balise en-ligne <script>');
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Lectures complémentaires
|
||||||
|
|
||||||
|
- [Qu'est-ce que HAML ?](http://haml.info/) - Une bonne introduction qui explique très bien les avantages d'utiliser HAML.
|
||||||
|
- [Documentation officielle](http://haml.info/docs/yardoc/file.REFERENCE.html) - Si vous souhaitez en apprendre plus et aller plus loin.
|
180
fr-fr/hy-fr.html.markdown
Normal file
180
fr-fr/hy-fr.html.markdown
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
---
|
||||||
|
language: hy
|
||||||
|
filename: learnhy-fr.hy
|
||||||
|
contributors:
|
||||||
|
- ["Abhishek L", "http://twitter.com/abhishekl"]
|
||||||
|
translators:
|
||||||
|
- ["Hughes Perreault", "https://github.com/hperreault"]
|
||||||
|
lang: fr-fr
|
||||||
|
---
|
||||||
|
|
||||||
|
Hy est un dialecte du lisp bâti par dessus python. Il fonctionne en
|
||||||
|
convertissant le code hy en un arbre de syntaxe abstraite de python (ast).
|
||||||
|
Ceci permet à hy d'appeler du code python et à python d'appeler du code hy.
|
||||||
|
|
||||||
|
Ce tutoriel fonctionne pour hy > 0.9.12
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
;; Ceci est une introduction simple à hy, pour un tutoriel rapide aller à
|
||||||
|
;; http://try-hy.appspot.com
|
||||||
|
;;
|
||||||
|
; Les commentaires se font avec des points-virgules, comme les autres LISPS
|
||||||
|
|
||||||
|
;; les s-expression de bases
|
||||||
|
; Les programmes Lisp sont fait d'expressions symboliques ou sexps qui
|
||||||
|
; ressemblent à
|
||||||
|
(some-function args)
|
||||||
|
; maintenant le quintessentiel hello world
|
||||||
|
(print "hello world")
|
||||||
|
|
||||||
|
;; les types de données simples
|
||||||
|
; Tous les types de données simples sont exactement similaires à leurs
|
||||||
|
; homologues de python
|
||||||
|
42 ; => 42
|
||||||
|
3.14 ; => 3.14
|
||||||
|
True ; => True
|
||||||
|
4+10j ; => (4+10j) un nombre complexe
|
||||||
|
|
||||||
|
; Commençons par un peu d'arithmétique très simple
|
||||||
|
(+ 4 1) ;=> 5
|
||||||
|
; l'opérateur est appliqué à tous les arguments, comme les autres lisps
|
||||||
|
(+ 4 1 2 3) ;=> 10
|
||||||
|
(- 2 1) ;=> 1
|
||||||
|
(* 4 2) ;=> 8
|
||||||
|
(/ 4 1) ;=> 4
|
||||||
|
(% 4 2) ;=> 0 l'opérateur modulo
|
||||||
|
; l'opérateur d'élévation à la puissance est représenté par ** comme en python
|
||||||
|
(** 3 2) ;=> 9
|
||||||
|
; les expressions imbriquées vont se comporter comme on s'y attend
|
||||||
|
(+ 2 (* 4 2)) ;=> 10
|
||||||
|
; aussi, les opérateurs logiques and or not et equal to etc. vont se comporter
|
||||||
|
; comme on s'y attend
|
||||||
|
(= 5 4) ;=> False
|
||||||
|
(not (= 5 4)) ;=> True
|
||||||
|
|
||||||
|
;; variables
|
||||||
|
; les variables sont déclarées en utilisant setv, les noms de variables
|
||||||
|
; peuvent utiliser l'UTF-8 à l'exception de ()[]{}",'`;#|
|
||||||
|
(setv a 42)
|
||||||
|
(setv π 3.14159)
|
||||||
|
(def *foo* 42)
|
||||||
|
;; d'autres types de conteneurs
|
||||||
|
; les chaînes, les listes, les tuples et dicts
|
||||||
|
; ce sont exactement les mêmes que les types de conteneurs de python
|
||||||
|
"hello world" ;=> "hello world"
|
||||||
|
; les opérations sur les chaînes fonctionnent comme en python
|
||||||
|
(+ "hello " "world") ;=> "hello world"
|
||||||
|
; les listes sont créés en utilisant [], l'indexation commence à 0
|
||||||
|
(setv mylist [1 2 3 4])
|
||||||
|
; les tuples sont des structures de données immuables
|
||||||
|
(setv mytuple (, 1 2))
|
||||||
|
; les dictionnaires sont des paires clé-valeur
|
||||||
|
(setv dict1 {"key1" 42 "key2" 21})
|
||||||
|
; :nom peut être utilisé pour définir des mots clés dans hy qui peuvent être
|
||||||
|
; utilisées comme clés
|
||||||
|
(setv dict2 {:key1 41 :key2 20})
|
||||||
|
; utilisez `get' pour obtenir l'élément à l'index / clé
|
||||||
|
(get mylist 1) ;=> 2
|
||||||
|
(get dict1 "key1") ;=> 42
|
||||||
|
; Alternativement, si des mots clés ont été utilisés, l'élément peut être
|
||||||
|
; obtenu directement
|
||||||
|
(:key1 dict2) ;=> 41
|
||||||
|
|
||||||
|
;; fonctions et autres constructions de programme
|
||||||
|
; les fonctions sont définies en utilisant defn, la dernière sexp est renvoyé par défaut
|
||||||
|
(defn greet [name]
|
||||||
|
"A simple greeting" ; une docstring optionnelle
|
||||||
|
(print "hello " name))
|
||||||
|
|
||||||
|
(greet "bilbo") ;=> "hello bilbo"
|
||||||
|
|
||||||
|
; les fonctions peuvent prendre des arguments optionnels ainsi que des
|
||||||
|
; arguments sous forme de mots clés
|
||||||
|
(defn foolists [arg1 &optional [arg2 2]]
|
||||||
|
[arg1 arg2])
|
||||||
|
|
||||||
|
(foolists 3) ;=> [3 2]
|
||||||
|
(foolists 10 3) ;=> [10 3]
|
||||||
|
|
||||||
|
; les fonctions anonymes sont créés en utilisant `fn' ou `lambda'
|
||||||
|
; qui sont semblable à `defn '
|
||||||
|
(map (fn [x] (* x x)) [1 2 3 4]) ;=> [1 4 9 16]
|
||||||
|
|
||||||
|
;; Opérations sur les séquences
|
||||||
|
; hy a des utilitaires natifs pour les opérations sur les séquences etc.
|
||||||
|
; récupérez le premier élément en utilisant `first' ou `car'
|
||||||
|
(setv mylist [1 2 3 4])
|
||||||
|
(setv mydict {"a" 1 "b" 2})
|
||||||
|
(first mylist) ;=> 1
|
||||||
|
|
||||||
|
; découpez les listes en utilisant slice
|
||||||
|
(slice mylist 1 3) ;=> [2 3]
|
||||||
|
|
||||||
|
; obtenez les éléments d'une liste ou dict en utilisant `get'
|
||||||
|
(get mylist 1) ;=> 2
|
||||||
|
(get mydict "b") ;=> 2
|
||||||
|
; l'indexation des listes commence à 0 comme en python
|
||||||
|
; assoc peut définir les éléments à clés/index
|
||||||
|
(assoc mylist 2 10) ; makes mylist [1 2 10 4]
|
||||||
|
(assoc mydict "c" 3) ; makes mydict {"a" 1 "b" 2 "c" 3}
|
||||||
|
; il ya tout un tas d'autres fonctions de base qui rend le travail avec
|
||||||
|
; les séquences amusant
|
||||||
|
|
||||||
|
;; les importations fonctionnent comme en pyhtonn
|
||||||
|
(import datetime)
|
||||||
|
(import [functools [partial reduce]]) ; importe fun1 et fun2 de module1
|
||||||
|
(import [matplotlib.pyplot :as plt]) ; faire une importation foo comme bar
|
||||||
|
; toutes les méthodes natives de python sont accessibles à partir de hy
|
||||||
|
; a.foo(arg) est appelé (.foo a arg)
|
||||||
|
(.split (.strip "hello world ")) ;=> ["hello" "world"]
|
||||||
|
|
||||||
|
;; Conditionelles
|
||||||
|
; (if condition (body-if-true) (body-if-false)
|
||||||
|
(if (= passcode "moria")
|
||||||
|
(print "welcome")
|
||||||
|
(print "Speak friend, and Enter!"))
|
||||||
|
|
||||||
|
; imbriquez plusieurs if else if avec le mot clé cond
|
||||||
|
(cond
|
||||||
|
[(= someval 42)
|
||||||
|
(print "Life, universe and everything else!")]
|
||||||
|
[(> someval 42)
|
||||||
|
(print "val too large")]
|
||||||
|
[(< someval 42)
|
||||||
|
(print "val too small")])
|
||||||
|
|
||||||
|
; groupez les expressions avec do, ceux-ci seront executé séquentiellemnt
|
||||||
|
; les expressions comme defn ont un do implicite
|
||||||
|
(do
|
||||||
|
(setv someval 10)
|
||||||
|
(print "someval is set to " someval)) ;=> 10
|
||||||
|
|
||||||
|
; créer une liaison lexicale avec `let', toutes les variables déclarées
|
||||||
|
; comme cela ont une portée locale
|
||||||
|
(let [[nemesis {"superman" "lex luther"
|
||||||
|
"sherlock" "moriarty"
|
||||||
|
"seinfeld" "newman"}]]
|
||||||
|
(for [(, h v) (.items nemesis)]
|
||||||
|
(print (.format "{0}'s nemesis was {1}" h v))))
|
||||||
|
|
||||||
|
;; classes
|
||||||
|
; les classes sont définies comme ceci
|
||||||
|
(defclass Wizard [object]
|
||||||
|
[[--init-- (fn [self spell]
|
||||||
|
(setv self.spell spell) ; init the spell attr
|
||||||
|
None)]
|
||||||
|
[get-spell (fn [self]
|
||||||
|
self.spell)]])
|
||||||
|
|
||||||
|
;; allez voir hylang.org
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lectures complémentaires
|
||||||
|
|
||||||
|
Ce tutoriel est juste une simple introduction à hy/lisp/python.
|
||||||
|
|
||||||
|
La documentation de HY: [http://hy.readthedocs.org](http://hy.readthedocs.org)
|
||||||
|
|
||||||
|
Le repo GitHub de HY: [http://github.com/hylang/hy](http://github.com/hylang/hy)
|
||||||
|
|
||||||
|
Sur freenode irc #hy, twitter hashtag #hylang
|
@ -6,23 +6,26 @@ contributors:
|
|||||||
filename: javascript-fr.js
|
filename: javascript-fr.js
|
||||||
translators:
|
translators:
|
||||||
- ['@nbrugneaux', 'https://nicolasbrugneaux.me']
|
- ['@nbrugneaux', 'https://nicolasbrugneaux.me']
|
||||||
|
- ['Michel Antoine', 'https://github.com/antoin-m']
|
||||||
lang: fr-fr
|
lang: fr-fr
|
||||||
---
|
---
|
||||||
|
|
||||||
JavaScript a été créé par Brendan Eich, travaillant alors a Netscape, en 1995.
|
JavaScript a été créé par Brendan Eich, travaillant alors a Netscape, en 1995.
|
||||||
Le langage avait à l'origine pour but d'être un langage de scripting simple
|
Le langage avait à l'origine pour but d'être un langage de scripting simple
|
||||||
pour les sites web, complétant le Java (à ne pas confondre avec JavaScript)
|
pour les sites web, complétant le Java (à ne pas confondre avec JavaScript)
|
||||||
pour des applications web complexes. Mais son intégration très proche et
|
pour des applications web complexes. Mais son intégration très proche et
|
||||||
simple des pages web, ainsi que le support natif des navigateurs a rendu
|
simple des pages web, ainsi que le support natif des navigateurs a rendu
|
||||||
le JavaScript incontournable aujourd'hui tant bien dans le front-end que
|
le JavaScript incontournable aujourd'hui tant bien dans le front-end que
|
||||||
dans le back-end.
|
dans le back-end.
|
||||||
|
|
||||||
En effet, le JavaScript n'est plus uniquement limité aux navigateurs, grâce à
|
En effet, le JavaScript n'est plus uniquement limité aux navigateurs, grâce à
|
||||||
Node.JS, un projet qui offre un environnement indépendant dans lequel un
|
Node.JS, un projet qui offre un environnement indépendant dans lequel un
|
||||||
interpréteur Javascript, basé sur le célèbre moteur V8 de Google Chrome,
|
interpréteur Javascript, basé sur le célèbre moteur V8 de Google Chrome,
|
||||||
peut être utilisé directement côté serveur pour exécuter des programmes écrits
|
peut être utilisé directement côté serveur pour exécuter des programmes écrits
|
||||||
en JavaScript.
|
en JavaScript.
|
||||||
|
|
||||||
|
ECMAScript (la norme du langage Javascript) entre en version 6. Cette version introduit de nombreuses mises à jour tout en restant rétrocompatible. L'implémentation de ces nouvelles fonctionnalités est en cours et celles-ci ne sont donc pas forcément compatibles avec tous les navigateurs.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Les commentaires sont comme en C. Les commentaires mono-ligne commencent par 2 slashs,
|
// Les commentaires sont comme en C. Les commentaires mono-ligne commencent par 2 slashs,
|
||||||
/* et les commentaires sur plusieurs lignes commencent avec slash-étoile
|
/* et les commentaires sur plusieurs lignes commencent avec slash-étoile
|
||||||
@ -31,7 +34,7 @@ en JavaScript.
|
|||||||
// Toutes les expressions peuvent finir par ;
|
// Toutes les expressions peuvent finir par ;
|
||||||
doStuff();
|
doStuff();
|
||||||
|
|
||||||
// ... mais n'en n'ont pas forcément besoin, les point-virgules sont ajoutés
|
// ... mais n'en n'ont pas forcément besoin, les point-virgules sont ajoutés
|
||||||
// lors de l’interprétation aux sauts de ligne, sauf exceptions
|
// lors de l’interprétation aux sauts de ligne, sauf exceptions
|
||||||
doStuff()
|
doStuff()
|
||||||
|
|
||||||
@ -79,6 +82,12 @@ false; // faux
|
|||||||
"abc";
|
"abc";
|
||||||
'Hello, world';
|
'Hello, world';
|
||||||
|
|
||||||
|
// *ES6:* Les chaines de caractères peuvent être crées en utilisant un modèle
|
||||||
|
// entouré des quotes inverses (`) à la place des quotes classiques (' ou ").
|
||||||
|
// Les variables sont interprétées avec ${var}
|
||||||
|
let banta = "Harry", santa = "Hermione";
|
||||||
|
`${banta}, your santa is ${santa}.` // = "Harry, your santa is Hermione."
|
||||||
|
|
||||||
// La négation utilise le symbole !
|
// La négation utilise le symbole !
|
||||||
!true; // = false
|
!true; // = false
|
||||||
!false; // = true
|
!false; // = true
|
||||||
@ -117,26 +126,34 @@ false; // faux
|
|||||||
|
|
||||||
// Il y a également null et undefined
|
// Il y a également null et undefined
|
||||||
null; // utilisé pour une non-valeur
|
null; // utilisé pour une non-valeur
|
||||||
undefined; // utilisé pour une valeur actuellement non présente (cependant,
|
undefined; // utilisé pour une valeur actuellement non présente (cependant,
|
||||||
// undefined est aussi une valeur valide)
|
// undefined est aussi une valeur valide)
|
||||||
|
|
||||||
// false, null, undefined, NaN, 0 and '' sont 'presque-faux' (falsy), tout le reste
|
// false, null, undefined, NaN, 0 and '' sont 'presque-faux' (falsy), tout le reste
|
||||||
// est 'presque-vrai' (truthy)
|
// est 'presque-vrai' (truthy)
|
||||||
// Notez que 0 est falsy mais '0' est truthy, alors même que 0 == '0' (mais 0 !== '0')
|
// Notez que 0 est falsy mais '0' est truthy, alors même que 0 == '0' (mais 0 !== '0')
|
||||||
|
|
||||||
|
// *ES6:* Introduction d'un nouveau type primitif : Symbol
|
||||||
|
var symbol_one = Symbol();
|
||||||
|
var symbol_two = Symbol('This is optional description, for debugging');
|
||||||
|
typeof symbol_one === 'symbol' // = true
|
||||||
|
|
||||||
|
// *ES6:* Un Symbol est immutable et unique
|
||||||
|
Symbol() === Symbol() // = false
|
||||||
|
Symbol('learnx') === Symbol('learnx') // = false
|
||||||
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
// 2. Variables, Tableaux et Objets
|
// 2. Variables, Tableaux, Objets, Maps et Sets
|
||||||
|
|
||||||
// Les variables sont déclarées avec le mot clé var. Le typage en JavaScript est
|
// Les variables sont déclarées avec le mot clé var. Le typage en JavaScript est
|
||||||
// dynamique, donc pas besoin de spécifier le type. L'assignement utilise un seul =.
|
// dynamique, donc pas besoin de spécifier le type. L'assignement utilise un seul =.
|
||||||
var someVar = 5;
|
var someVar = 5;
|
||||||
|
|
||||||
// si vous oubliez le mot clé var, vous n'aurez pas d'erreur (sauf en mode strict)
|
// si vous oubliez le mot clé var, vous n'aurez pas d'erreur (sauf en mode strict)
|
||||||
someOtherVar = 10;
|
someOtherVar = 10;
|
||||||
|
|
||||||
// ... mais la variable aura une portée globale (plus communément trouvé en tant
|
// ... mais la variable aura une portée globale (plus communément trouvé en tant
|
||||||
// que "global scope" en anglais), et non pas une portée limitée à la fonction
|
// que "global scope" en anglais), et non pas une portée limitée à la fonction
|
||||||
// dans laquelle vous l'aviez définie.
|
// dans laquelle vous l'aviez définie.
|
||||||
|
|
||||||
// Les variables déclarées et non assignées sont undefined par défaut
|
// Les variables déclarées et non assignées sont undefined par défaut
|
||||||
@ -145,6 +162,32 @@ var someThirdVar = undefined;
|
|||||||
|
|
||||||
// ... sont deux déclarations identiques.
|
// ... sont deux déclarations identiques.
|
||||||
|
|
||||||
|
// Il est possible de déclarer plusieurs variables en séparant leur déclaration
|
||||||
|
// avec l'opérateur virgule
|
||||||
|
var someFourthVar = 2, someFifthVar = 4;
|
||||||
|
|
||||||
|
// *ES6:* Les variables peuvent maintenant être déclarées avec les mots-clés
|
||||||
|
// `let` et `const`
|
||||||
|
let someSixthVar = 6;
|
||||||
|
const someSeventhVar = 7;
|
||||||
|
|
||||||
|
// *ES6:* Le mot-clé `let` attache la variable au block de code et non à la fonction
|
||||||
|
// à l'inverse de `var`
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
x += 10;
|
||||||
|
}
|
||||||
|
i; // = raises ReferenceError
|
||||||
|
|
||||||
|
// *ES6:* Les variables "const" doivent être assignées lors de l'initialisation
|
||||||
|
const someEighthVar = 7;
|
||||||
|
const someNinthVar; // raises SyntaxError
|
||||||
|
|
||||||
|
// *ES6:* Modifier une variable constante ne lève par d'erreur mais échoue
|
||||||
|
// silencieusement
|
||||||
|
const someNinthVar = 9;
|
||||||
|
someNinthVar = 10;
|
||||||
|
someNinthVar; // = 9
|
||||||
|
|
||||||
// Il y a des raccourcis pour les opérations mathématiques:
|
// Il y a des raccourcis pour les opérations mathématiques:
|
||||||
someVar += 5; // équivalent pour someVar = someVar + 5;
|
someVar += 5; // équivalent pour someVar = someVar + 5;
|
||||||
someVar *= 10; // de même, someVar = someVar * 100;
|
someVar *= 10; // de même, someVar = someVar * 100;
|
||||||
@ -165,6 +208,22 @@ myArray.length; // = 4
|
|||||||
// Ajout/Modification à un index spécifique
|
// Ajout/Modification à un index spécifique
|
||||||
myArray[3] = 'Hello';
|
myArray[3] = 'Hello';
|
||||||
|
|
||||||
|
// *ES6:* Les Arrays peuvent maintenant être déstructurés en utilisant le pattern matching
|
||||||
|
var [a, b] = [1, 2];
|
||||||
|
var [a, , b] = [1, -2, 2]
|
||||||
|
|
||||||
|
a; // = 1
|
||||||
|
b; // = 2
|
||||||
|
|
||||||
|
// *ES6:* La déstructuration peut échouer silencieusement.
|
||||||
|
// Il est aussi possible d'utiliser des valeurs par défaut
|
||||||
|
var [a] = [];
|
||||||
|
a; // = undefined;
|
||||||
|
var [a = 1] = [];
|
||||||
|
a; // = 1;
|
||||||
|
var [a = 1] = [2];
|
||||||
|
a; // = 2;
|
||||||
|
|
||||||
// Les objets JavaScript sont appelés 'dictionnaires' ou 'maps' dans certains autres
|
// Les objets JavaScript sont appelés 'dictionnaires' ou 'maps' dans certains autres
|
||||||
// langages : ils sont une liste non-ordonnée de paires clé-valeur.
|
// langages : ils sont une liste non-ordonnée de paires clé-valeur.
|
||||||
var myObj = {key1: 'Hello', key2: 'World'};
|
var myObj = {key1: 'Hello', key2: 'World'};
|
||||||
@ -179,12 +238,55 @@ myObj['my other key']; // = 4
|
|||||||
// .. ou avec un point si la clé est un identifiant valide.
|
// .. ou avec un point si la clé est un identifiant valide.
|
||||||
myObj.myKey; // = 'myValue'
|
myObj.myKey; // = 'myValue'
|
||||||
|
|
||||||
|
// *ES6:* Un Symbol peut être utilisé en tant que clé. Puisque ceux-ci sont uniques,
|
||||||
|
// le seul moyen d'accéder à la propriété est d'avoir une référence sur ce Symbol.
|
||||||
|
myObj["key"] = "public value";
|
||||||
|
myObj[Symbol("key")] = "secret value";
|
||||||
|
myObj[Symbol("key")]; // = undefined
|
||||||
|
|
||||||
// Les objets sont eux aussi modifiables.
|
// Les objets sont eux aussi modifiables.
|
||||||
myObj.myThirdKey = true;
|
myObj.myThirdKey = true;
|
||||||
|
|
||||||
// Si vous essayez d'accéder à une valeur non-définie, vous obtiendrez undefined
|
// Si vous essayez d'accéder à une valeur non-définie, vous obtiendrez undefined
|
||||||
myObj.myFourthKey; // = undefined
|
myObj.myFourthKey; // = undefined
|
||||||
|
|
||||||
|
// *ES6:* Comme les Arrays, les Objects peuvent être déstructurés en utilisant le pattern matching
|
||||||
|
var {foo} = {foo: "bar"};
|
||||||
|
foo // = "bar"
|
||||||
|
|
||||||
|
// *ES6:* Les Objects déstructurés peuvent utiliser des noms de variables différents
|
||||||
|
// de ceux d'origine grâce au pattern matching
|
||||||
|
var {foo, moo: baz} = {foo: "bar", moo: "car"};
|
||||||
|
foo // = "bar"
|
||||||
|
baz // = "car"
|
||||||
|
|
||||||
|
// *ES6:* Il est possible d'utiliser des valeurs par défaut lor de la déstructuration d'un Object
|
||||||
|
var {foo="bar"} = {moo: "car"};
|
||||||
|
foo // = "bar"
|
||||||
|
|
||||||
|
// *ES6:* Une erreur lors de la déstructuration restera silencieuse
|
||||||
|
var {foo} = {};
|
||||||
|
foo // = undefined
|
||||||
|
|
||||||
|
// *ES6:* Les Maps sont des objets itérables de type clé-valeur.
|
||||||
|
// Il est possible de créer une nouvelle map en utilisant `new Map()`
|
||||||
|
var myMap = new Map();
|
||||||
|
|
||||||
|
// *ES6:* Il est possible d'ajouter un couple clé-valeur avec la méthode `.set()`,
|
||||||
|
// de récupérer une valeur avec `.get()`,
|
||||||
|
// de vérifier qu'une clé existe avec `.has()`
|
||||||
|
// et enfin de supprimer un couple clé-valeur avec `.delete()`
|
||||||
|
|
||||||
|
myMap.set("name", "Douglas");
|
||||||
|
myMap.get("name"); // = "Douglas"
|
||||||
|
myMap.has("name"); // = true
|
||||||
|
myMap.delete("name");
|
||||||
|
|
||||||
|
// *ES6:* Les Sets sont des ensembles de valeurs uniques.
|
||||||
|
// Il est possible de créer un set avec `new Set()`.
|
||||||
|
// Toute valeur non unique est ignorée.
|
||||||
|
var mySet = new Set([1,2,2]);
|
||||||
|
console.log([...mySet]); // = [1,2]
|
||||||
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
// 3. Logique et structures de contrôle
|
// 3. Logique et structures de contrôle
|
||||||
@ -198,7 +300,7 @@ else if (count === 4) {
|
|||||||
// uniquement quand count est 4
|
// uniquement quand count est 4
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// le reste du temps, si ni 3, ni 4.
|
// le reste du temps, si ni 3, ni 4.
|
||||||
}
|
}
|
||||||
|
|
||||||
// De même pour while.
|
// De même pour while.
|
||||||
@ -218,6 +320,22 @@ for (var i = 0; i < 5; i++){
|
|||||||
// sera exécutée 5 fois
|
// sera exécutée 5 fois
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// La boucle for...in permet d'itérer sur les noms des propriétés d'un objet
|
||||||
|
var description = "";
|
||||||
|
var person = {fname:"Paul", lname:"Ken", age:18};
|
||||||
|
for (var x in person){
|
||||||
|
description += person[x] + " ";
|
||||||
|
}
|
||||||
|
description; // = "Paul Ken 18 "
|
||||||
|
|
||||||
|
// *ES6:* La boucle for...of permet d'itérer sur les propriétés d'un objet
|
||||||
|
var description = "";
|
||||||
|
var person = {fname:"Paul", lname:"Ken", age:18};
|
||||||
|
for (var x of person){
|
||||||
|
description += x + " ";
|
||||||
|
}
|
||||||
|
description; // = "Paul Ken 18 "
|
||||||
|
|
||||||
// && est le "et" logique, || est le "ou" logique
|
// && est le "et" logique, || est le "ou" logique
|
||||||
if (house.size === 'big' && house.colour === 'blue'){
|
if (house.size === 'big' && house.colour === 'blue'){
|
||||||
house.contains = 'bear';
|
house.contains = 'bear';
|
||||||
@ -264,7 +382,21 @@ function myFunction(thing){
|
|||||||
}
|
}
|
||||||
myFunction('foo'); // = 'FOO'
|
myFunction('foo'); // = 'FOO'
|
||||||
|
|
||||||
// Les fonctions JavaScript sont des objets de première classe, donc peuvent
|
// Attention, la valeur à retourner doit se trouver sur la même ligne que
|
||||||
|
// le mot-clé `return` sinon la fonction retournera systématiquement `undefined`
|
||||||
|
function myFunction(){
|
||||||
|
return // <- semicolon automatically inserted here
|
||||||
|
{thisIsAn: 'object literal'}
|
||||||
|
}
|
||||||
|
myFunction(); // = undefined
|
||||||
|
|
||||||
|
// *ES6:* Les paramètres des fonctions peuvent désormais avoir des valeurs par défaut
|
||||||
|
function default(x, y = 2) {
|
||||||
|
return x + y;
|
||||||
|
}
|
||||||
|
default(10); // == 12
|
||||||
|
|
||||||
|
// Les fonctions JavaScript sont des objets de première classe, donc peuvent
|
||||||
// être réassignées à d'autres variables et passées en tant que paramètres pour
|
// être réassignées à d'autres variables et passées en tant que paramètres pour
|
||||||
// d'autres fonctions
|
// d'autres fonctions
|
||||||
function myFunction(){
|
function myFunction(){
|
||||||
@ -274,13 +406,17 @@ setTimeout(myFunction, 5000);
|
|||||||
// Note: setTimeout ne fait pas parti du langage, mais les navigateurs ainsi
|
// Note: setTimeout ne fait pas parti du langage, mais les navigateurs ainsi
|
||||||
// que Node.js le rendent disponible
|
// que Node.js le rendent disponible
|
||||||
|
|
||||||
// Les fonctions n'ont pas nécessairement besoin d'un nom, elles peuvent être
|
// Les fonctions n'ont pas nécessairement besoin d'un nom, elles peuvent être
|
||||||
// anonymes
|
// anonymes
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
// ce code s'exécutera dans 5 secondes
|
// ce code s'exécutera dans 5 secondes
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
// Le Javascript crée uniquement un scope, une portée d'action limitée, pour
|
// *ES6:* Introduction d'un sucre syntaxique permettant de créer
|
||||||
|
// une fonction anonyme de la forme : `param => returnValue`.
|
||||||
|
setTimeout(() => console.log('5 seconds, are up.'), 5000);
|
||||||
|
|
||||||
|
// Le Javascript crée uniquement un scope, une portée d'action limitée, pour
|
||||||
// les fonctions, et pas dans les autres blocs.
|
// les fonctions, et pas dans les autres blocs.
|
||||||
if (true){
|
if (true){
|
||||||
var i = 5;
|
var i = 5;
|
||||||
@ -293,7 +429,7 @@ i; // = 5 - et non undefined comme vous pourriez vous y attendre
|
|||||||
var temporary = 5;
|
var temporary = 5;
|
||||||
// Nous pouvons accéder au scope global en assignant à l'objet global,
|
// Nous pouvons accéder au scope global en assignant à l'objet global,
|
||||||
// qui dans les navigateurs est "window". Il est différent dans Node.js,
|
// qui dans les navigateurs est "window". Il est différent dans Node.js,
|
||||||
// le scope global sera en fait local au module dans lequel vous
|
// le scope global sera en fait local au module dans lequel vous
|
||||||
// vous trouvez. http://nodejs.org/api/globals.html
|
// vous trouvez. http://nodejs.org/api/globals.html
|
||||||
window.permanent = 10;
|
window.permanent = 10;
|
||||||
})();
|
})();
|
||||||
@ -302,8 +438,8 @@ i; // = 5 - et non undefined comme vous pourriez vous y attendre
|
|||||||
temporary; // raises ReferenceError
|
temporary; // raises ReferenceError
|
||||||
permanent; // = 10
|
permanent; // = 10
|
||||||
|
|
||||||
// Une des fonctionnalités les plus puissantes de Javascript est le système de
|
// Une des fonctionnalités les plus puissantes de Javascript est le système de
|
||||||
// closures. Si une fonction est définie dans une autre fonction, alors la
|
// closures. Si une fonction est définie dans une autre fonction, alors la
|
||||||
// fonction interne aura accès aux variables de la fonction parente, même si
|
// fonction interne aura accès aux variables de la fonction parente, même si
|
||||||
// celle-ci a déjà finie son exécution.
|
// celle-ci a déjà finie son exécution.
|
||||||
function sayHelloInFiveSeconds(name){
|
function sayHelloInFiveSeconds(name){
|
||||||
@ -318,6 +454,18 @@ function sayHelloInFiveSeconds(name){
|
|||||||
}
|
}
|
||||||
sayHelloInFiveSeconds('Adam'); // ouvre un popup avec 'Hello, Adam!' dans 5sec
|
sayHelloInFiveSeconds('Adam'); // ouvre un popup avec 'Hello, Adam!' dans 5sec
|
||||||
|
|
||||||
|
// *ES6:* Les paramètres des fonctions appelées avec un tableau en entré
|
||||||
|
// préfixé par `...` vont se peupler avec les éléments du tableau
|
||||||
|
function spread(x, y, z) {
|
||||||
|
return x + y + z;
|
||||||
|
}
|
||||||
|
spread(...[1,2,3]); // == 6
|
||||||
|
|
||||||
|
// *ES6:* Les fonctions peuvent recevoir les paramètres dans un tableau en utilisant l'opérateur `...`
|
||||||
|
function spread(x, y, z) {
|
||||||
|
return x + y + z;
|
||||||
|
}
|
||||||
|
spread(...[1,2,3]); // == 6
|
||||||
|
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
// 5. Encore plus à propos des Objets; Constructeurs and Prototypes
|
// 5. Encore plus à propos des Objets; Constructeurs and Prototypes
|
||||||
@ -340,7 +488,7 @@ myObj = {
|
|||||||
};
|
};
|
||||||
myObj.myFunc(); // = 'Hello world!'
|
myObj.myFunc(); // = 'Hello world!'
|
||||||
|
|
||||||
// La valeur de "this" change de par l'endroit où la fonction est appelée, et
|
// La valeur de "this" change de par l'endroit où la fonction est appelée, et
|
||||||
// non de l'endroit où elle est définie. Donc elle ne fonctionnera pas si elle
|
// non de l'endroit où elle est définie. Donc elle ne fonctionnera pas si elle
|
||||||
// est appelée hors du contexte l'objet.
|
// est appelée hors du contexte l'objet.
|
||||||
var myFunc = myObj.myFunc;
|
var myFunc = myObj.myFunc;
|
||||||
@ -356,7 +504,7 @@ myObj.myOtherFunc = myOtherFunc;
|
|||||||
myObj.myOtherFunc(); // = 'HELLO WORLD!'
|
myObj.myOtherFunc(); // = 'HELLO WORLD!'
|
||||||
|
|
||||||
// Le contexte correspond à la valeur de "this".
|
// Le contexte correspond à la valeur de "this".
|
||||||
// Nous pouvons aussi spécifier un contexte, forcer la valeur de "this,
|
// Nous pouvons aussi spécifier un contexte, forcer la valeur de "this,
|
||||||
// pour une fonction quand elle est appelée grâce à "call" ou "apply".
|
// pour une fonction quand elle est appelée grâce à "call" ou "apply".
|
||||||
var anotherFunc = function(s){
|
var anotherFunc = function(s){
|
||||||
return this.myString + s;
|
return this.myString + s;
|
||||||
@ -371,19 +519,19 @@ Math.min(42, 6, 27); // = 6
|
|||||||
Math.min([42, 6, 27]); // = NaN (uh-oh!)
|
Math.min([42, 6, 27]); // = NaN (uh-oh!)
|
||||||
Math.min.apply(Math, [42, 6, 27]); // = 6
|
Math.min.apply(Math, [42, 6, 27]); // = 6
|
||||||
|
|
||||||
// Mais, "call" and "apply" fonctionnenent uniquement au moment de l'appel de la
|
// Mais, "call" and "apply" fonctionnenent uniquement au moment de l'appel de la
|
||||||
// fonction. Pour lier le contexte de façon permanente, nous pouvons utiliser
|
// fonction. Pour lier le contexte de façon permanente, nous pouvons utiliser
|
||||||
// "bind" pour garder une référence à la fonction avec ce "this".
|
// "bind" pour garder une référence à la fonction avec ce "this".
|
||||||
var boundFunc = anotherFunc.bind(myObj);
|
var boundFunc = anotherFunc.bind(myObj);
|
||||||
boundFunc(' And Hello Saturn!'); // = 'Hello World! And Hello Saturn!'
|
boundFunc(' And Hello Saturn!'); // = 'Hello World! And Hello Saturn!'
|
||||||
|
|
||||||
// "bind" peut aussi être utilisé pour créer une application partielle de la
|
// "bind" peut aussi être utilisé pour créer une application partielle de la
|
||||||
// fonction (curry)
|
// fonction (curry)
|
||||||
var product = function(a, b){ return a * b; }
|
var product = function(a, b){ return a * b; }
|
||||||
var doubler = product.bind(this, 2);
|
var doubler = product.bind(this, 2);
|
||||||
doubler(8); // = 16
|
doubler(8); // = 16
|
||||||
|
|
||||||
// Lorsque vous appelez une fonction avec le mot clé "new", un nouvel objet est
|
// Lorsque vous appelez une fonction avec le mot clé "new", un nouvel objet est
|
||||||
// crée et mis à disposition de la fonction via "this". Ces fonctions sont
|
// crée et mis à disposition de la fonction via "this". Ces fonctions sont
|
||||||
// communément appelées constructeurs.
|
// communément appelées constructeurs.
|
||||||
var MyConstructor = function(){
|
var MyConstructor = function(){
|
||||||
@ -395,8 +543,8 @@ myNewObj.myNumber; // = 5
|
|||||||
// Chaque objet en Javascript a un "prototype". Quand vous essayez d'accéder à
|
// Chaque objet en Javascript a un "prototype". Quand vous essayez d'accéder à
|
||||||
// une propriété que l'objet n'a pas, l'interpréteur va regarder son prototype.
|
// une propriété que l'objet n'a pas, l'interpréteur va regarder son prototype.
|
||||||
|
|
||||||
// Quelques implémentations de JS vous laissent accéder au prototype avec la
|
// Quelques implémentations de JS vous laissent accéder au prototype avec la
|
||||||
// propriété "magique" __proto__. Ceci peut être utile, mais n'est pas standard
|
// propriété "magique" __proto__. Ceci peut être utile, mais n'est pas standard
|
||||||
// et ne fonctionne pas dans certains des navigateurs actuels.
|
// et ne fonctionne pas dans certains des navigateurs actuels.
|
||||||
var myObj = {
|
var myObj = {
|
||||||
myString: 'Hello world!'
|
myString: 'Hello world!'
|
||||||
@ -469,9 +617,6 @@ myNumber === myNumberObj; // = false
|
|||||||
if (0){
|
if (0){
|
||||||
// 0 est falsy, le code ne fonctionnera pas.
|
// 0 est falsy, le code ne fonctionnera pas.
|
||||||
}
|
}
|
||||||
if (Number(0)){
|
|
||||||
// Parce que Number(0) est truthy, le code fonctionnera
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cependant, vous pouvez ajouter des fonctionnalités aux types de bases grâce à
|
// Cependant, vous pouvez ajouter des fonctionnalités aux types de bases grâce à
|
||||||
// cette particularité.
|
// cette particularité.
|
||||||
@ -481,7 +626,7 @@ String.prototype.firstCharacter = function(){
|
|||||||
'abc'.firstCharacter(); // = 'a'
|
'abc'.firstCharacter(); // = 'a'
|
||||||
|
|
||||||
// C'est très souvent utilisé pour le "polyfilling", qui implémente des nouvelles
|
// C'est très souvent utilisé pour le "polyfilling", qui implémente des nouvelles
|
||||||
// fonctionnalités de JavaScript dans de plus anciens environnements, tels que
|
// fonctionnalités de JavaScript dans de plus anciens environnements, tels que
|
||||||
// les vieux navigateurs.
|
// les vieux navigateurs.
|
||||||
|
|
||||||
//Par exemple, Object.create est assez récent, mais peut être implémenté grâce à
|
//Par exemple, Object.create est assez récent, mais peut être implémenté grâce à
|
||||||
@ -495,31 +640,83 @@ if (Object.create === undefined){ // pour ne pas reécrire si la fonction existe
|
|||||||
return new Constructor();
|
return new Constructor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// *ES6:* Les objets peuvent être équipés de proxies qui permettent d'intercepter
|
||||||
|
// les actions sur leurs propriétés. Voici comment créer un proxy sur un objet :
|
||||||
|
var proxyObject = new Proxy(object, handler);
|
||||||
|
|
||||||
|
// *ES6:* Les méthodes d'un objet handler sont appelées lors de l'interception d'une action.
|
||||||
|
// La méthode `.get()` est appelée à chaque lecture d'une propriété
|
||||||
|
// tandis que la méthode `.set()` est appelée à chaque écriture.
|
||||||
|
var handler = {
|
||||||
|
get (target, key) {
|
||||||
|
console.info('Get on property' + key);
|
||||||
|
return target[key];
|
||||||
|
},
|
||||||
|
set (target, key, value) {
|
||||||
|
console.info('Set on property' + key);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *ES6:* Les classes peuvent désormais être définies en utilisant le mot-clé `class`.
|
||||||
|
// Le constructeur s'appelle `constructor` et les méthodes statiques utilisent le mot-clé `static`
|
||||||
|
class Foo {
|
||||||
|
constructor() {console.log("constructing Foo");}
|
||||||
|
bar() {return "bar";}
|
||||||
|
static baz() {return "baz";}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *ES6:* Les objets issus des classes sont initialisés avec le mot-clé `new`.
|
||||||
|
// Il est possible d'hériter d'une classe avec le mot-clé `extends`
|
||||||
|
var FooObject = new Foo(); // = "constructing Foo"
|
||||||
|
class Zoo extends Foo {}
|
||||||
|
|
||||||
|
// *ES6:* Les méthodes statiques doivent être appelées par la classe, les autres méthodes par l'objet
|
||||||
|
Foo.baz() // = "baz"
|
||||||
|
FooObject.bar() // = "bar"
|
||||||
|
|
||||||
|
// *ES6:* Il est désormais possible d'exporter des valeurs en tant que module.
|
||||||
|
// Les exports peuvent être n'importe quel objet, valeur ou fonction.
|
||||||
|
var api = {
|
||||||
|
foo: "bar",
|
||||||
|
baz: "ponyfoo"
|
||||||
|
};
|
||||||
|
export default api;
|
||||||
|
|
||||||
|
// *ES6:* La syntaxe `export default` permet d'exporter l'objet sans en changer le nom.
|
||||||
|
// Il y a plusieurs façons de l'importer:
|
||||||
|
import coolapi from "api"; // = importe le module dans la variable `coolapi`
|
||||||
|
import {foo, baz} from "api"; // = importe les attributs `foo` et `baz` du module
|
||||||
|
import {foo as moo, baz} from "api"; // = importe les attributs `foo` (en le renommant `moo`) et `baz` du module
|
||||||
|
import _, {map} from "api"; // = importe les exports par défaut ET `map`
|
||||||
|
import * as coolapi from "api"; // = importe le namespace global du module
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Pour aller plus loin (en anglais)
|
## Pour aller plus loin (en anglais)
|
||||||
|
|
||||||
The [Mozilla Developer
|
The [Mozilla Developer
|
||||||
Network](https://developer.mozilla.org/fr-FR/docs/Web/JavaScript) expose une
|
Network](https://developer.mozilla.org/fr-FR/docs/Web/JavaScript) expose une
|
||||||
excellente documentation pour le Javascript dans les navigateurs. Et contient
|
excellente documentation pour le Javascript dans les navigateurs. Et contient
|
||||||
également un wiki pour s'entraider.
|
également un wiki pour s'entraider.
|
||||||
|
|
||||||
MDN's [A re-introduction to
|
MDN's [A re-introduction to
|
||||||
JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
||||||
recouvre les principaux sujets vus ici. Le guide est délibérément uniquement
|
recouvre les principaux sujets vus ici. Le guide est délibérément uniquement
|
||||||
à propos du JavaScript, et ne parle pas des navigateurs; pour cela, dirigez vous
|
à propos du JavaScript, et ne parle pas des navigateurs; pour cela, dirigez vous
|
||||||
plutôt ici :
|
plutôt ici :
|
||||||
[Document Object
|
[Document Object
|
||||||
Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)
|
Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)
|
||||||
|
|
||||||
[Learn Javascript by Example and with Challenges](http://www.learneroo.com/modules/64/nodes/350) quelques challenges.
|
[Learn Javascript by Example and with Challenges](http://www.learneroo.com/modules/64/nodes/350) quelques challenges.
|
||||||
|
|
||||||
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) is an in-depth
|
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) is an in-depth
|
||||||
un guide pour vous éviter les faux-amis dans le JavaScript.
|
un guide pour vous éviter les faux-amis dans le JavaScript.
|
||||||
|
|
||||||
[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) un classique. A lire.
|
[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) un classique. A lire.
|
||||||
|
|
||||||
En addition aux contributeurs de cet article, du contenu provient du
|
En addition aux contributeurs de cet article, du contenu provient du
|
||||||
"Python tutorial" de Louie Dinh, et de [JS
|
"Python tutorial" de Louie Dinh, et de [JS
|
||||||
Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
||||||
sur le réseau Mozilla.
|
sur le réseau Mozilla.
|
||||||
|
@ -4,7 +4,7 @@ filename: learnLivescript-fr.ls
|
|||||||
contributors:
|
contributors:
|
||||||
- ["Christina Whyte", "http://github.com/kurisuwhyte/"]
|
- ["Christina Whyte", "http://github.com/kurisuwhyte/"]
|
||||||
translators:
|
translators:
|
||||||
- ["Morgan Bohn", "https://github.com/morganbohn"]
|
- ["Morgan Bohn", "https://github.com/dotmobo"]
|
||||||
lang: fr-fr
|
lang: fr-fr
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
language: markdown
|
language: markdown
|
||||||
contributors:
|
contributors:
|
||||||
- ["Andrei Curelaru", "http://www.infinidad.fr"]
|
- ["Andrei Curelaru", "http://www.infinidad.fr"]
|
||||||
filename: markdown.md
|
filename: markdown-fr.md
|
||||||
lang: fr-fr
|
lang: fr-fr
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ lang: fr-fr
|
|||||||
|
|
||||||
L'Objective-C est un langage de programmation orienté objet réflexif principalement utilisé par Apple pour les systèmes d'exploitations Mac OS X et iOS et leurs frameworks respectifs, Cocoa et Cocoa Touch.
|
L'Objective-C est un langage de programmation orienté objet réflexif principalement utilisé par Apple pour les systèmes d'exploitations Mac OS X et iOS et leurs frameworks respectifs, Cocoa et Cocoa Touch.
|
||||||
|
|
||||||
```objective_c
|
```objective-c
|
||||||
// Les commentaires sur une seule ligne commencent par //
|
// Les commentaires sur une seule ligne commencent par //
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
174
fr-fr/perl-fr.html.markdown
Normal file
174
fr-fr/perl-fr.html.markdown
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
---
|
||||||
|
name: perl
|
||||||
|
category: language
|
||||||
|
language: perl
|
||||||
|
filename: learnperl-fr.pl
|
||||||
|
contributors:
|
||||||
|
- ["Korjavin Ivan", "http://github.com/korjavin"]
|
||||||
|
- ["Matteo Taroli", "http://www.matteotaroli.be"]
|
||||||
|
translators:
|
||||||
|
- ["Matteo Taroli", "http://www.matteotaroli.be"]
|
||||||
|
lang: fr-fr
|
||||||
|
---
|
||||||
|
Perl 5 est un langage de programmation riche en fonctionnalité, avec plus de 25 ans de développement.
|
||||||
|
|
||||||
|
Perl 5 fonctionne sur plus de 100 plateformes, allant des pc portables aux mainframes et
|
||||||
|
est autant adapté à un prototypage rapide qu'à des projets de grande envergure.
|
||||||
|
|
||||||
|
```perl
|
||||||
|
# Les commentaires en une ligne commencent par un dièse
|
||||||
|
|
||||||
|
|
||||||
|
#### Types de variables de Perl
|
||||||
|
|
||||||
|
# Les variables comment par un symbole précisant le type.
|
||||||
|
# Un nom de variable valide commence par une lettre ou un underscore,
|
||||||
|
# suivi d'un nombre quelconque de lettres, chiffres ou underscores.
|
||||||
|
|
||||||
|
### Perl a trois types principaux de variables: $scalaire, @tableau and %hash
|
||||||
|
|
||||||
|
## Scalaires
|
||||||
|
# Un scalaire représente une valeur unique :
|
||||||
|
my $animal = "chameau";
|
||||||
|
my $reponse = 42;
|
||||||
|
|
||||||
|
# Les valeurs scalaires peuvent être des strings, des entiers ou des nombres à virgule flottante
|
||||||
|
# et Perl les convertira automatiquement entre elles quand nécessaire.
|
||||||
|
|
||||||
|
## Tableaux
|
||||||
|
# Un tableau représente une liste de valeurs :
|
||||||
|
my @animaux = ("chameau", "lama", "chouette");
|
||||||
|
my @nombres = (23, 42, 69);
|
||||||
|
my @melange = ("chameau", 42, 1.23);
|
||||||
|
|
||||||
|
## Hashes
|
||||||
|
# Un hash représente un ensemble de paires de clé/valeur :
|
||||||
|
my %fruit_couleur = ("pomme", "rouge", "banane", "jaune");
|
||||||
|
|
||||||
|
# Vous pouvez utiliser des espaces et l'opérateur "=>" pour les disposer plus joliment :
|
||||||
|
|
||||||
|
my %fruit_couleur = (
|
||||||
|
pomme => "rouge",
|
||||||
|
banane => "jaune"
|
||||||
|
);
|
||||||
|
|
||||||
|
# Les scalaires, tableaux et hashes sont plus amplement documentés dans le perldata
|
||||||
|
# (perldoc perldata)
|
||||||
|
|
||||||
|
# Des types de données plus complexes peuvent être construits en utilisant des références,
|
||||||
|
# vous permettant de construire des listes et des hashes à l'intérieur d'autres listes et hashes.
|
||||||
|
|
||||||
|
#### Conditions et boucles
|
||||||
|
|
||||||
|
# Perl possède la plupart des conditions et boucles habituelles.
|
||||||
|
|
||||||
|
if ($var) {
|
||||||
|
...
|
||||||
|
} elsif ($var eq 'bar') {
|
||||||
|
...
|
||||||
|
} else {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
unless (condition) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
# Ceci est fourni en tant que version plus lisible de "if (!condition)"
|
||||||
|
|
||||||
|
# la postcondition à la sauce Perl
|
||||||
|
|
||||||
|
print "Yow!" if $zippy;
|
||||||
|
print "Nous n'avons pas de banane." unless $bananes;
|
||||||
|
|
||||||
|
# while
|
||||||
|
while (condition) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
# boucle for et iteration
|
||||||
|
for (my $i = 0; $i < $max; $i++) {
|
||||||
|
print "l'index est $i";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (my $i = 0; $i < @elements; $i++) {
|
||||||
|
print "L'élément courant est " . $elements[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $element (@elements) {
|
||||||
|
print $element;
|
||||||
|
}
|
||||||
|
|
||||||
|
# implicitement
|
||||||
|
|
||||||
|
# La variable de contexte scalaire $_ est utilisée par défaut dans différentes
|
||||||
|
# situations, comme par exemple dans la boucle foreach ou en argument par défaut
|
||||||
|
# de la plupart des fonctions pour en simplifier l'écriture.
|
||||||
|
|
||||||
|
# Dans l'exemple suivant, $_ prends successivement la valeur de
|
||||||
|
# chaque élément de la liste.
|
||||||
|
|
||||||
|
for (@elements) {
|
||||||
|
print; # affiche le contenu de $_
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#### Expressions régulières
|
||||||
|
|
||||||
|
# Le support des expressions régulières par Perl est aussi large que profond
|
||||||
|
# et est sujet à une longue documentation sur perlrequick, perlretut et ailleurs.
|
||||||
|
# Cependant, pour faire court :
|
||||||
|
|
||||||
|
# Simple correspondance
|
||||||
|
if (/foo/) { ... } # vrai si $_ contient "foo"
|
||||||
|
if ($a =~ /foo/) { ... } # vrai si $a contient "foo"
|
||||||
|
|
||||||
|
# Simple substitution
|
||||||
|
|
||||||
|
$a =~ s/foo/bar/; # remplace le premier foo par bar dans $a
|
||||||
|
$a =~ s/foo/bar/g; # remplace TOUTES LES INSTANCES de foo par bar dans $a
|
||||||
|
|
||||||
|
|
||||||
|
#### Fichiers et E/S
|
||||||
|
|
||||||
|
# Vous pouvez ouvrir un fichier pour y écrire ou pour le lire avec la fonction "open()".
|
||||||
|
|
||||||
|
open(my $in, "<", "input.txt") or die "Impossible d'ouvrir input.txt: $!";
|
||||||
|
open(my $out, ">", "output.txt") or die "Impossible d'ouvrir output.txt: $!";
|
||||||
|
open(my $log, ">>", "my.log") or die "Impossible d'ouvrir my.log: $!";
|
||||||
|
|
||||||
|
# Vous pouvez lire depuis un descripteur de fichier grâce à l'opérateur "<>".
|
||||||
|
# Dans un contexte scalaire, il lit une seule ligne depuis le descripteur de fichier
|
||||||
|
# et dans un contexte de liste, il lit le fichier complet, assignant chaque ligne à un
|
||||||
|
# élément de la liste :
|
||||||
|
|
||||||
|
my $ligne = <$in>
|
||||||
|
my $lignes = <$in>
|
||||||
|
|
||||||
|
#### Ecrire des fonctions
|
||||||
|
|
||||||
|
# Ecrire des fonctions est facile :
|
||||||
|
|
||||||
|
sub logger {
|
||||||
|
my $logmessage = shift;
|
||||||
|
|
||||||
|
open my $logfile, ">>", "my.log" or die "Impossible d'ouvrir my.log: $!";
|
||||||
|
|
||||||
|
print $logfile $logmessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Maintenant, nous pouvons utiliser cette fonction comme n'importe quelle fonction intégrée :
|
||||||
|
|
||||||
|
logger("On a une fonction de logging!!");
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Utiliser des modules Perl
|
||||||
|
|
||||||
|
Les modules Perl fournissent une palette de fonctionnalités vous évitant de réinventer la roue et peuvent être téléchargés depuis CPAN (http://www.cpan.org/). Un certain nombre de modules populaires sont inclus dans la distribution même de Perl.
|
||||||
|
|
||||||
|
Perlfaq contiens des questions et réponses liées aux tâches habituelles et propose souvent des suggestions quant aux bons modules à utiliser.
|
||||||
|
|
||||||
|
#### Pour en savoir plus
|
||||||
|
- [perl-tutorial](http://perl-tutorial.org/)
|
||||||
|
- [Learn at www.perl.com](http://www.perl.org/learn.html)
|
||||||
|
- [perldoc](http://perldoc.perl.org/)
|
||||||
|
- and perl built-in : `perldoc perlintro`
|
696
fr-fr/php.html.markdown
Normal file
696
fr-fr/php.html.markdown
Normal file
@ -0,0 +1,696 @@
|
|||||||
|
---
|
||||||
|
language: PHP
|
||||||
|
contributors:
|
||||||
|
- ["Malcolm Fell", "http://emarref.net/"]
|
||||||
|
- ["Trismegiste", "https://github.com/Trismegiste"]
|
||||||
|
translators:
|
||||||
|
- ["Pascal Boutin", "http://pboutin.net/"]
|
||||||
|
lang: fr-fr
|
||||||
|
---
|
||||||
|
|
||||||
|
This document describes PHP 5+.
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Le code PHP doit être placé à l'intérieur de balises '<?php'
|
||||||
|
|
||||||
|
// Si votre fichier php ne contient que du code PHP, il est
|
||||||
|
// généralement recommandé de ne pas fermer la balise '?>'
|
||||||
|
|
||||||
|
// Deux barres obliques amorcent un commentaire simple.
|
||||||
|
|
||||||
|
# Le dièse aussi, bien que les barres obliques soient plus courantes
|
||||||
|
|
||||||
|
/*
|
||||||
|
Les barres obliques et les astérisques peuvent être utilisés
|
||||||
|
pour faire un commentaire multi-lignes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Utilisez "echo" ou "print" afficher une sortie
|
||||||
|
print('Hello '); // Affiche "Hello " sans retour à la ligne
|
||||||
|
|
||||||
|
// Les parenthèses sont facultatives pour print et echo
|
||||||
|
echo "World\n"; // Affiche "World" avec un retour à la ligne
|
||||||
|
|
||||||
|
// toutes les instructions doivent se terminer par un point-virgule
|
||||||
|
|
||||||
|
// Tout ce qui se trouve en dehors des <?php ?> est automatiquement
|
||||||
|
// affiché en sortie
|
||||||
|
Hello World Again!
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
* Types & Variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Les noms de variables débutent par le symbole $
|
||||||
|
// Un nom de variable valide commence par une lettre ou un souligné,
|
||||||
|
// suivi de n'importe quelle lettre, nombre ou de soulignés.
|
||||||
|
|
||||||
|
// Les valeurs booléenes ne sont pas sensibles à la casse
|
||||||
|
$boolean = true; // ou TRUE ou True
|
||||||
|
$boolean = false; // ou FALSE ou False
|
||||||
|
|
||||||
|
// Entiers (integers)
|
||||||
|
$int1 = 12; // => 12
|
||||||
|
$int2 = -12; // => -12
|
||||||
|
$int3 = 012; // => 10 (un 0 devant la valeur désigne une valeur octale)
|
||||||
|
$int4 = 0x0F; // => 15 (un 0x devant la valeur désigne une valeur hexadécimale)
|
||||||
|
|
||||||
|
// Réels (floats, doubles)
|
||||||
|
$float = 1.234;
|
||||||
|
$float = 1.2e3;
|
||||||
|
$float = 7E-10;
|
||||||
|
|
||||||
|
// Suppression d'une variable
|
||||||
|
unset($int1);
|
||||||
|
|
||||||
|
// Arithmétique
|
||||||
|
$sum = 1 + 1; // 2 (addition)
|
||||||
|
$difference = 2 - 1; // 1 (soustraction)
|
||||||
|
$product = 2 * 2; // 4 (produit)
|
||||||
|
$quotient = 2 / 1; // 2 (division)
|
||||||
|
|
||||||
|
// Arithmétique (raccourcis)
|
||||||
|
$number = 0;
|
||||||
|
$number += 2; // Incrémente $number de 2
|
||||||
|
echo $number++; // Affiche 2 (incrémente après l'évaluation)
|
||||||
|
echo ++$number; // Affiche 4 (incrémente avant l'évaluation)
|
||||||
|
$number /= $float; // Divise et assigne le quotient à $number
|
||||||
|
|
||||||
|
// Les chaînes de caractères (strings) doivent être à
|
||||||
|
// l'intérieur d'une paire d'apostrophes
|
||||||
|
$sgl_quotes = '$String'; // => '$String'
|
||||||
|
|
||||||
|
// Évitez les guillemets sauf pour inclure le contenu d'une autre variable
|
||||||
|
$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'
|
||||||
|
|
||||||
|
// Les caractères spéciaux sont seulement échappés avec des guillemets
|
||||||
|
$escaped = "This contains a \t tab character.";
|
||||||
|
$unescaped = 'This just contains a slash and a t: \t';
|
||||||
|
|
||||||
|
// En cas de besoin, placez la variable dans des accolades
|
||||||
|
$money = "I have $${number} in the bank.";
|
||||||
|
|
||||||
|
// Depuis PHP 5.3, Nowdoc peut être utilisé pour faire des chaînes
|
||||||
|
// multi-lignes non-interprétées
|
||||||
|
$nowdoc = <<<'END'
|
||||||
|
Multi line
|
||||||
|
string
|
||||||
|
END;
|
||||||
|
|
||||||
|
// Heredoc peut être utilisé pour faire des chaînes multi-lignes interprétées
|
||||||
|
$heredoc = <<<END
|
||||||
|
Multi line
|
||||||
|
$sgl_quotes
|
||||||
|
END;
|
||||||
|
|
||||||
|
// La concaténation de chaînes se fait avec un .
|
||||||
|
echo 'This string ' . 'is concatenated';
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Constantes
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Une constante est déclarée avec define()
|
||||||
|
// et ne peut jamais être changée durant l'exécution
|
||||||
|
|
||||||
|
// un nom valide de constante commence par une lettre ou un souligné,
|
||||||
|
// suivi de n'importe quelle lettre, nombre ou soulignés.
|
||||||
|
define("FOO", "something");
|
||||||
|
|
||||||
|
// on peut accéder à une constante en utilisant directement son nom
|
||||||
|
echo 'This outputs '.FOO;
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Tableaux (array)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Tous les tableaux en PHP sont associatifs (hashmaps),
|
||||||
|
|
||||||
|
// Fonctionne dans toutes les versions de PHP
|
||||||
|
$associative = array('One' => 1, 'Two' => 2, 'Three' => 3);
|
||||||
|
|
||||||
|
// PHP 5.4 a introduit une nouvelle syntaxe
|
||||||
|
$associative = ['One' => 1, 'Two' => 2, 'Three' => 3];
|
||||||
|
|
||||||
|
echo $associative['One']; // affiche 1
|
||||||
|
|
||||||
|
// Dans une liste simple, l'index est automatiquement attribué en tant que clé
|
||||||
|
$array = ['One', 'Two', 'Three'];
|
||||||
|
echo $array[0]; // => "One"
|
||||||
|
|
||||||
|
// Ajoute un élément à la fin du tableau
|
||||||
|
$array[] = 'Four';
|
||||||
|
|
||||||
|
// Retrait d'un élément du tableau
|
||||||
|
unset($array[3]);
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Affichage
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo('Hello World!');
|
||||||
|
// Affiche Hello World! dans stdout.
|
||||||
|
// Stdout est la page web si on exécute depuis un navigateur.
|
||||||
|
|
||||||
|
print('Hello World!'); // Pareil à "écho"
|
||||||
|
|
||||||
|
// Pour écho, vous n'avez pas besoin des parenthèses
|
||||||
|
echo 'Hello World!';
|
||||||
|
print 'Hello World!'; // Pour print non plus
|
||||||
|
|
||||||
|
$paragraph = 'paragraph';
|
||||||
|
|
||||||
|
echo 100; // Affichez un scalaire directement
|
||||||
|
echo $paragraph; // ou des variables
|
||||||
|
|
||||||
|
// Si le raccourci de sortie est configuré, ou si votre version de PHP est
|
||||||
|
// 5.4.0+, vous pouvez utiliser ceci:
|
||||||
|
?>
|
||||||
|
<p><?= $paragraph ?></p>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$x = 1;
|
||||||
|
$y = 2;
|
||||||
|
$x = $y; // $x contient maintenant la même valeur que $y
|
||||||
|
$z = &$y;
|
||||||
|
// $z contient une référence vers $y. Changer la valeur de
|
||||||
|
// $z changerait également la valeur de $y, et vice-versa.
|
||||||
|
// $x resterait inchangé comme la valeur initiale de $y
|
||||||
|
|
||||||
|
echo $x; // => 2
|
||||||
|
echo $z; // => 2
|
||||||
|
$y = 0;
|
||||||
|
echo $x; // => 2
|
||||||
|
echo $z; // => 0
|
||||||
|
|
||||||
|
// Affiche le type et la valeur de la variable dans stdout
|
||||||
|
var_dump($z); // prints int(0)
|
||||||
|
|
||||||
|
// Affiche la variable dans stdout dans un format plus convivial
|
||||||
|
print_r($array); // prints: Array ( [0] => One [1] => Two [2] => Three )
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Logique
|
||||||
|
*/
|
||||||
|
$a = 0;
|
||||||
|
$b = '0';
|
||||||
|
$c = '1';
|
||||||
|
$d = '1';
|
||||||
|
|
||||||
|
// assert affiche un avertissement dans son argument n'est pas vrai
|
||||||
|
|
||||||
|
// Ces comparaisons vont toujours être vraies, même si leurs
|
||||||
|
// types ne sont pas les mêmes.
|
||||||
|
assert($a == $b); // égalité
|
||||||
|
assert($c != $a); // inégalité
|
||||||
|
assert($c <> $a); // inégalité (moins courant)
|
||||||
|
assert($a < $c);
|
||||||
|
assert($c > $b);
|
||||||
|
assert($a <= $b);
|
||||||
|
assert($c >= $d);
|
||||||
|
|
||||||
|
// Ces comparaisons vont seulement être vraies si les types concordent.
|
||||||
|
assert($c === $d);
|
||||||
|
assert($a !== $d);
|
||||||
|
assert(1 === '1');
|
||||||
|
assert(1 !== '1');
|
||||||
|
|
||||||
|
// Opérateur 'spaceship' depuis PHP 7
|
||||||
|
$a = 100;
|
||||||
|
$b = 1000;
|
||||||
|
|
||||||
|
echo $a <=> $a; // 0 car ils sont égaux
|
||||||
|
echo $a <=> $b; // -1 car $a < $b
|
||||||
|
echo $b <=> $a; // 1 car $b > $a
|
||||||
|
|
||||||
|
// Les variables peuvent être transtypées dépendamment de leur usage.
|
||||||
|
|
||||||
|
$integer = 1;
|
||||||
|
echo $integer + $integer; // => 2
|
||||||
|
|
||||||
|
$string = '1';
|
||||||
|
echo $string + $string; // => 2
|
||||||
|
|
||||||
|
$string = 'one';
|
||||||
|
echo $string + $string; // => 0
|
||||||
|
// Donne 0 car l'opérateur + ne peut pas transtyper la chaîne 'one' en un nombre
|
||||||
|
|
||||||
|
// On peut également transtyper manuellement pour utiliser
|
||||||
|
// une variable dans un autre type
|
||||||
|
|
||||||
|
$boolean = (boolean) 1; // => true
|
||||||
|
|
||||||
|
$zero = 0;
|
||||||
|
$boolean = (boolean) $zero; // => false
|
||||||
|
|
||||||
|
// Il y a également des fonctions dédiées pour transtyper
|
||||||
|
$integer = 5;
|
||||||
|
$string = strval($integer);
|
||||||
|
|
||||||
|
$var = null; // Valeur nulle
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Structures de contrôle
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
print 'Je suis affiché';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
print 'Je ne le suis pas';
|
||||||
|
} else {
|
||||||
|
print 'Je suis affiché';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
print 'Je ne suis pas affiché';
|
||||||
|
} elseif (true) {
|
||||||
|
print 'Je le suis';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opérateur ternaire
|
||||||
|
print (false ? 'N\'est pas affiché' : 'L\'est');
|
||||||
|
|
||||||
|
// Opérateur ternaire depuis PHP 5.3
|
||||||
|
// équivalent de $x ? $x : 'Does'
|
||||||
|
$x = false;
|
||||||
|
print($x ?: 'Does');
|
||||||
|
|
||||||
|
// depuis PHP 7, on peut facilement vérifier si une valeur est nulle
|
||||||
|
$a = null;
|
||||||
|
$b = 'Hello World';
|
||||||
|
echo $a ?? 'a is not set'; // Affiche 'a is not set'
|
||||||
|
echo $b ?? 'b is not set'; // Affiche 'Hello World'
|
||||||
|
|
||||||
|
|
||||||
|
$x = 0;
|
||||||
|
if ($x === '0') {
|
||||||
|
print 'Pas affiché';
|
||||||
|
} elseif($x == '1') {
|
||||||
|
print 'Pas affiché';
|
||||||
|
} else {
|
||||||
|
print 'Affiché';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Cette syntaxe alternative est particulièrement utile avec du HTML:
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if ($x): ?>
|
||||||
|
<p>Ceci est affiché si $x est vrai</p>
|
||||||
|
<?php else: ?>
|
||||||
|
<p>Ceci est affiché si $x est faux</p>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// On peut également utiliser une condition multiple (switch case)
|
||||||
|
switch ($x) {
|
||||||
|
case '0':
|
||||||
|
print 'Les switch font du transtypage implicite';
|
||||||
|
break; // Il est important de déclaré un 'break', sinon les cas
|
||||||
|
// 'two' et 'three' seront évalués
|
||||||
|
case 'two':
|
||||||
|
case 'three':
|
||||||
|
// Si $x == 'two' || $x == 'three'
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Si aucun cas n'a été vrai
|
||||||
|
}
|
||||||
|
|
||||||
|
// Structures itératives (for, while, do while)
|
||||||
|
$i = 0;
|
||||||
|
while ($i < 5) {
|
||||||
|
echo $i++;
|
||||||
|
}; // Affiche "01234"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
do {
|
||||||
|
echo $i++;
|
||||||
|
} while ($i < 5); // Affiche "01234"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
for ($x = 0; $x < 10; $x++) {
|
||||||
|
echo $x;
|
||||||
|
} // Affiche "0123456789"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
$wheels = ['bicycle' => 2, 'car' => 4];
|
||||||
|
|
||||||
|
// Les boucles 'foreach' sont utiles pour parcourir les tableaux
|
||||||
|
foreach ($wheels as $wheel_count) {
|
||||||
|
echo $wheel_count;
|
||||||
|
} // Affiche "24"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
// Il est également possible d'accéder aux clés du tableau
|
||||||
|
foreach ($wheels as $vehicle => $wheel_count) {
|
||||||
|
echo "The $vehicle have $wheel_count wheels";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
while ($i < 5) {
|
||||||
|
if ($i === 3) {
|
||||||
|
break; // Permet d'arrêter la boucle
|
||||||
|
}
|
||||||
|
echo $i++;
|
||||||
|
} // Affiche "012"
|
||||||
|
|
||||||
|
for ($i = 0; $i < 5; $i++) {
|
||||||
|
if ($i === 3) {
|
||||||
|
continue; // Permet de passer immédiatement à l'itération suivante
|
||||||
|
}
|
||||||
|
echo $i;
|
||||||
|
} // Affiche "0124"
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Fonctions
|
||||||
|
*/
|
||||||
|
|
||||||
|
// On peut déclarer une fonction avec le mot clé 'function'
|
||||||
|
function my_function () {
|
||||||
|
return 'Hello';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo my_function(); // => "Hello"
|
||||||
|
|
||||||
|
|
||||||
|
// Les noms de fonction débutent par le symbole $
|
||||||
|
// Un nom de variable valide commence par une lettre ou un souligné,
|
||||||
|
// suivi de n'importe quelle lettre, nombre ou de soulignés.
|
||||||
|
|
||||||
|
function add ($x, $y = 1) { // $y est facultatif et sa valeur par défaut est 1
|
||||||
|
$result = $x + $y;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo add(4); // => 5
|
||||||
|
echo add(4, 2); // => 6
|
||||||
|
|
||||||
|
// $result n'est pas accessible en dehors de la fonction
|
||||||
|
// print $result; // Retourne un avertissement
|
||||||
|
|
||||||
|
// Depuis PHP 5.3 on peut déclarer des fonctions anonymes
|
||||||
|
$inc = function ($x) {
|
||||||
|
return $x + 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
echo $inc(2); // => 3
|
||||||
|
|
||||||
|
function foo ($x, $y, $z) {
|
||||||
|
echo "$x - $y - $z";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Une fonction peut retourner une fonction
|
||||||
|
function bar ($x, $y) {
|
||||||
|
// On peut utiliser 'use' pour passer des variables externes
|
||||||
|
return function ($z) use ($x, $y) {
|
||||||
|
foo($x, $y, $z);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$bar = bar('A', 'B');
|
||||||
|
$bar('C'); // Affiche "A - B - C"
|
||||||
|
|
||||||
|
// On peut exécuter une fonction par son nom en chaîne de caractères
|
||||||
|
$function_name = 'add';
|
||||||
|
echo $function_name(1, 2); // => 3
|
||||||
|
// Utile pour déterminer par programmation quelle fonction exécuter.
|
||||||
|
|
||||||
|
// On peut également utiliser
|
||||||
|
call_user_func(callable $callback [, $parameter [, ... ]]);
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Insertions
|
||||||
|
*/
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Le PHP se trouvant dans un fichier inclus doit
|
||||||
|
// également commencer par une balise PHP.
|
||||||
|
|
||||||
|
include 'my-file.php';
|
||||||
|
// Le code se trouvant dans my-file.php est maintenant disponible dans
|
||||||
|
// le contexte courant. Si le fichier ne peut pas être inclus
|
||||||
|
// (ex. non trouvé), un avertissement sera émit.
|
||||||
|
|
||||||
|
include_once 'my-file.php';
|
||||||
|
// Si le code dans my-file.php a déjà été inclus ailleur, il ne va pas
|
||||||
|
// être inclus de nouveau.
|
||||||
|
|
||||||
|
require 'my-file.php';
|
||||||
|
require_once 'my-file.php';
|
||||||
|
// Même comportement que include() mais déclenche une érreur fatale si le fichier ne peux pas être inclus.
|
||||||
|
|
||||||
|
// Contenu de my-include.php:
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return 'Anything you like.';
|
||||||
|
// Fin de my-include.php
|
||||||
|
|
||||||
|
// include() et require() peuvent également retourner une valeur
|
||||||
|
$value = include('my-include.php');
|
||||||
|
|
||||||
|
// Les fichiers sont inclus depuis le chemin donné ou, si aucun chemin n'est donné,
|
||||||
|
// la configuration 'include_path'. Si le fichier n'est pas trouvé dans le 'include_path',
|
||||||
|
// include va finalement vérifier dans le répertoire courant avant d'échouer.
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Classes
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Les classes sont définies avec le mot clé 'class'
|
||||||
|
|
||||||
|
class MyClass
|
||||||
|
{
|
||||||
|
const MY_CONST = 'value'; // Une constante
|
||||||
|
|
||||||
|
static $staticVar = 'static';
|
||||||
|
|
||||||
|
// Variables statiques et leur visibilité
|
||||||
|
public static $publicStaticVar = 'publicStatic';
|
||||||
|
// Accessible à l'intérieur de la classe seulement
|
||||||
|
private static $privateStaticVar = 'privateStatic';
|
||||||
|
// Accessible à l'intérieur de la classe et des classes enfants
|
||||||
|
protected static $protectedStaticVar = 'protectedStatic';
|
||||||
|
|
||||||
|
// Les attributs doivent définir leur visibilité
|
||||||
|
public $property = 'public';
|
||||||
|
public $instanceProp;
|
||||||
|
protected $prot = 'protected';
|
||||||
|
private $priv = 'private';
|
||||||
|
|
||||||
|
// Déclaration d'un constructeur avec __construct
|
||||||
|
public function __construct($instanceProp) {
|
||||||
|
// Access instance variables with $this
|
||||||
|
$this->instanceProp = $instanceProp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Les méthodes sont déclarés par des fonctions au sein de la classe
|
||||||
|
public function myMethod()
|
||||||
|
{
|
||||||
|
print 'MyClass';
|
||||||
|
}
|
||||||
|
|
||||||
|
// le mot clé 'final' rend la function impossible à surcharger
|
||||||
|
final function youCannotOverrideMe()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Les attributs et méthodes statiques peuvent être accédés sans devoir
|
||||||
|
* instancier la classe. Les attributs statiques ne sont pas accessibles depuis
|
||||||
|
* une instance, même si les méthodes statiques le sont.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static function myStaticMethod()
|
||||||
|
{
|
||||||
|
print 'I am static';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Les constantes d'une classe peuvent toujours être utilisé de façon statique
|
||||||
|
echo MyClass::MY_CONST; // Outputs 'value';
|
||||||
|
|
||||||
|
echo MyClass::$staticVar; // Retourne 'static';
|
||||||
|
MyClass::myStaticMethod(); // Retourne 'I am static';
|
||||||
|
|
||||||
|
// On peut instancier une classe en utilisant le mot clé 'new'
|
||||||
|
$my_class = new MyClass('An instance property');
|
||||||
|
|
||||||
|
// On peut accéder aux attributs/méthodes d'une instance avec ->
|
||||||
|
echo $my_class->property; // => "public"
|
||||||
|
echo $my_class->instanceProp; // => "An instance property"
|
||||||
|
$my_class->myMethod(); // => "MyClass"
|
||||||
|
|
||||||
|
|
||||||
|
// On peut hériter d'une classe en utilisant 'extends'
|
||||||
|
class MyOtherClass extends MyClass
|
||||||
|
{
|
||||||
|
function printProtectedProperty()
|
||||||
|
{
|
||||||
|
echo $this->prot;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Surcharge d'une méthode
|
||||||
|
function myMethod()
|
||||||
|
{
|
||||||
|
parent::myMethod();
|
||||||
|
print ' > MyOtherClass';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$my_other_class = new MyOtherClass('Instance prop');
|
||||||
|
$my_other_class->printProtectedProperty(); // => Retourne "protected"
|
||||||
|
$my_other_class->myMethod(); // Retourne "MyClass > MyOtherClass"
|
||||||
|
|
||||||
|
// On peut empêcher qu'une classe soit héritée
|
||||||
|
final class YouCannotExtendMe
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// On peut utiliser des "méthodes magiques" pour se faire des accesseurs
|
||||||
|
class MyMapClass
|
||||||
|
{
|
||||||
|
private $property;
|
||||||
|
|
||||||
|
public function __get($key)
|
||||||
|
{
|
||||||
|
return $this->$key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($key, $value)
|
||||||
|
{
|
||||||
|
$this->$key = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = new MyMapClass();
|
||||||
|
echo $x->property; // Va utiliser la méthode __get()
|
||||||
|
$x->property = 'Something'; // Va utiliser la méthode __set()
|
||||||
|
|
||||||
|
// Les classes peuvent être abstraites (en utilisant le mot clé 'abstract'), ou
|
||||||
|
// elle peuvent implémenter une interface (en utilisant le mot clé 'implement').
|
||||||
|
|
||||||
|
// Une interface peut être déclarée avec le mot clé 'interface'
|
||||||
|
|
||||||
|
interface InterfaceOne
|
||||||
|
{
|
||||||
|
public function doSomething();
|
||||||
|
}
|
||||||
|
|
||||||
|
interface InterfaceTwo
|
||||||
|
{
|
||||||
|
public function doSomethingElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Les interfaces peuvent hériter d'autres interfaces
|
||||||
|
interface InterfaceThree extends InterfaceTwo
|
||||||
|
{
|
||||||
|
public function doAnotherContract();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class MyAbstractClass implements InterfaceOne
|
||||||
|
{
|
||||||
|
public $x = 'doSomething';
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyConcreteClass extends MyAbstractClass implements InterfaceTwo
|
||||||
|
{
|
||||||
|
public function doSomething()
|
||||||
|
{
|
||||||
|
echo $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function doSomethingElse()
|
||||||
|
{
|
||||||
|
echo 'doSomethingElse';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Les classes peuvent implémenter plusieurs interfaces à la fois
|
||||||
|
class SomeOtherClass implements InterfaceOne, InterfaceTwo
|
||||||
|
{
|
||||||
|
public function doSomething()
|
||||||
|
{
|
||||||
|
echo 'doSomething';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function doSomethingElse()
|
||||||
|
{
|
||||||
|
echo 'doSomethingElse';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Espaces de noms (namespaces)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Cette section est séparée, car une déclaration d'espace de nom doit être
|
||||||
|
// la première chose que l'on retrouve dans un fichier PHP,
|
||||||
|
// imaginons que c'est le cas
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Par défaut, les classes existent dans l'espace de nom global et peuvent
|
||||||
|
// être appelé explicitement avec un antislash.
|
||||||
|
|
||||||
|
$cls = new \MyClass();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// On peut spécifier l'espace de nom d'un fichier comme cela
|
||||||
|
namespace My\Namespace;
|
||||||
|
|
||||||
|
class MyClass
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// (depuis un autre fichier...)
|
||||||
|
$cls = new My\Namespace\MyClass;
|
||||||
|
|
||||||
|
// Ou depuis un autre espace de nom
|
||||||
|
namespace My\Other\Namespace;
|
||||||
|
|
||||||
|
use My\Namespace\MyClass;
|
||||||
|
|
||||||
|
$cls = new MyClass();
|
||||||
|
|
||||||
|
// On peut également utiliser un alias sur un espace de nom
|
||||||
|
|
||||||
|
namespace My\Other\Namespace;
|
||||||
|
|
||||||
|
use My\Namespace as SomeOtherNamespace;
|
||||||
|
|
||||||
|
$cls = new SomeOtherNamespace\MyClass();
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pour plus d'informations
|
||||||
|
|
||||||
|
Visitez la [documentation officielle](http://www.php.net/manual/fr).
|
||||||
|
|
||||||
|
Si vous êtes intéressé par les bonnes pratiques, visitez
|
||||||
|
[PHP The Right Way](http://www.phptherightway.com/) (anglais seulement).
|
||||||
|
|
||||||
|
Si vous êtes habitué à utiliser de bons gestionaires de dépendances, regardez
|
||||||
|
[Composer](http://getcomposer.org/).
|
||||||
|
|
||||||
|
Pour consulter les standards, visitez "the PHP Framework Interoperability Groups"
|
||||||
|
[PSR standards](https://github.com/php-fig/fig-standards).
|
@ -14,12 +14,11 @@ Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiqu
|
|||||||
|
|
||||||
Vos retours sont grandement appréciés. Vous pouvez me contacter sur Twitter [@louiedinh](http://twitter.com/louiedinh) ou par e-mail: louiedinh [at] [google's email service]
|
Vos retours sont grandement appréciés. Vous pouvez me contacter sur Twitter [@louiedinh](http://twitter.com/louiedinh) ou par e-mail: louiedinh [at] [google's email service]
|
||||||
|
|
||||||
NB: Cet artice s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x
|
N.B. : Cet article s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x. Python 2.7 est en fin de vie et ne sera plus maintenu à partir de 2020, il est donc recommandé d'apprendre Python avec Python 3. Pour Python 3.x, il existe un autre [tutoriel pour Python 3](http://learnxinyminutes.com/docs/fr-fr/python3-fr/).
|
||||||
Vous pourrez bientôt trouver un article pour Python 3!
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Une ligne simple de commentaire commence par un dièse
|
# Une ligne simple de commentaire commence par un dièse
|
||||||
""" Les lignes de commenatires multipes peuvent être écrites
|
""" Les lignes de commentaires multipes peuvent être écrites
|
||||||
en utilisant 3 guillemets ("), et sont souvent utilisées
|
en utilisant 3 guillemets ("), et sont souvent utilisées
|
||||||
pour les commentaires
|
pour les commentaires
|
||||||
"""
|
"""
|
||||||
|
723
fr-fr/python3-fr.html.markdown
Normal file
723
fr-fr/python3-fr.html.markdown
Normal file
@ -0,0 +1,723 @@
|
|||||||
|
---
|
||||||
|
language: python3
|
||||||
|
contributors:
|
||||||
|
- ["Louie Dinh", "http://pythonpracticeprojects.com"]
|
||||||
|
- ["Steven Basart", "http://github.com/xksteven"]
|
||||||
|
- ["Andre Polykanine", "https://github.com/Oire"]
|
||||||
|
- ["Zachary Ferguson", "http://github.com/zfergus2"]
|
||||||
|
translators:
|
||||||
|
- ["Gnomino", "https://github.com/Gnomino"]
|
||||||
|
filename: learnpython3-fr.py
|
||||||
|
lang: fr-fr
|
||||||
|
---
|
||||||
|
|
||||||
|
Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des
|
||||||
|
langages les populaires. Je suis tombé amoureux de Python pour la clarté de sa syntaxe.
|
||||||
|
C'est tout simplement du pseudo-code exécutable.
|
||||||
|
|
||||||
|
L'auteur original apprécierait les retours (en anglais): vous pouvez le contacter sur Twitter à [@louiedinh](http://twitter.com/louiedinh) ou par mail à l'adresse louiedinh [at] [google's email service]
|
||||||
|
|
||||||
|
Note : Cet article s'applique spécifiquement à Python 3. Jettez un coup d'oeil [ici](http://learnxinyminutes.com/docs/fr-fr/python-fr/) pour apprendre le vieux Python 2.7
|
||||||
|
|
||||||
|
```python
|
||||||
|
|
||||||
|
# Un commentaire d'une ligne commence par un dièse
|
||||||
|
|
||||||
|
""" Les chaînes de caractères peuvent être écrites
|
||||||
|
avec 3 guillemets doubles ("), et sont souvent
|
||||||
|
utilisées comme des commentaires.
|
||||||
|
"""
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 1. Types de données primaires et opérateurs
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# On a des nombres
|
||||||
|
3 # => 3
|
||||||
|
|
||||||
|
# Les calculs sont ce à quoi on s'attend
|
||||||
|
1 + 1 # => 2
|
||||||
|
8 - 1 # => 7
|
||||||
|
10 * 2 # => 20
|
||||||
|
|
||||||
|
# Sauf pour la division qui retourne un float (nombre à virgule flottante)
|
||||||
|
35 / 5 # => 7.0
|
||||||
|
|
||||||
|
# Résultats de divisions entières tronqués pour les nombres positifs et négatifs
|
||||||
|
5 // 3 # => 1
|
||||||
|
5.0 // 3.0 # => 1.0 # works on floats too
|
||||||
|
-5 // 3 # => -2
|
||||||
|
-5.0 // 3.0 # => -2.0
|
||||||
|
|
||||||
|
# Quand on utilise un float, le résultat est un float
|
||||||
|
3 * 2.0 # => 6.0
|
||||||
|
|
||||||
|
# Modulo (reste de la division)
|
||||||
|
7 % 3 # => 1
|
||||||
|
|
||||||
|
# Exponentiation (x**y, x élevé à la puissance y)
|
||||||
|
2**4 # => 16
|
||||||
|
|
||||||
|
# Forcer la priorité de calcul avec des parenthèses
|
||||||
|
(1 + 3) * 2 # => 8
|
||||||
|
|
||||||
|
# Les valeurs booléennes sont primitives
|
||||||
|
True
|
||||||
|
False
|
||||||
|
|
||||||
|
# Négation avec not
|
||||||
|
not True # => False
|
||||||
|
not False # => True
|
||||||
|
|
||||||
|
# Opérateurs booléens
|
||||||
|
# On note que "and" et "or" sont sensibles à la casse
|
||||||
|
True and False #=> False
|
||||||
|
False or True #=> True
|
||||||
|
|
||||||
|
# Utilisation des opérations booléennes avec des entiers :
|
||||||
|
0 and 2 #=> 0
|
||||||
|
-5 or 0 #=> -5
|
||||||
|
0 == False #=> True
|
||||||
|
2 == True #=> False
|
||||||
|
1 == True #=> True
|
||||||
|
|
||||||
|
# On vérifie une égalité avec ==
|
||||||
|
1 == 1 # => True
|
||||||
|
2 == 1 # => False
|
||||||
|
|
||||||
|
# On vérifie une inégalité avec !=
|
||||||
|
1 != 1 # => False
|
||||||
|
2 != 1 # => True
|
||||||
|
|
||||||
|
# Autres opérateurs de comparaison
|
||||||
|
1 < 10 # => True
|
||||||
|
1 > 10 # => False
|
||||||
|
2 <= 2 # => True
|
||||||
|
2 >= 2 # => True
|
||||||
|
|
||||||
|
# On peut enchaîner les comparaisons
|
||||||
|
1 < 2 < 3 # => True
|
||||||
|
2 < 3 < 2 # => False
|
||||||
|
|
||||||
|
# (is vs. ==) is vérifie si deux variables pointent sur le même objet, mais == vérifie
|
||||||
|
# si les objets ont la même valeur.
|
||||||
|
a = [1, 2, 3, 4] # a pointe sur une nouvelle liste, [1, 2, 3, 4]
|
||||||
|
b = a # b pointe sur a
|
||||||
|
b is a # => True, a et b pointent sur le même objet
|
||||||
|
b == a # => True, les objets a et b sont égaux
|
||||||
|
b = [1, 2, 3, 4] # b pointe sur une nouvelle liste, [1, 2, 3, 4]
|
||||||
|
b is a # => False, a et b ne pointent pas sur le même objet
|
||||||
|
b == a # => True, les objets a et b ne pointent pas sur le même objet
|
||||||
|
|
||||||
|
# Les chaînes (ou strings) sont créées avec " ou '
|
||||||
|
"Ceci est une chaine"
|
||||||
|
'Ceci est une chaine aussi.'
|
||||||
|
|
||||||
|
# On peut additionner des chaînes aussi ! Mais essayez d'éviter de le faire.
|
||||||
|
"Hello " + "world!" # => "Hello world!"
|
||||||
|
# On peut aussi le faire sans utiliser '+'
|
||||||
|
"Hello " "world!" # => "Hello world!"
|
||||||
|
|
||||||
|
# On peut traîter une chaîne comme une liste de caractères
|
||||||
|
"This is a string"[0] # => 'T'
|
||||||
|
|
||||||
|
# .format peut être utilisé pour formatter des chaînes, comme ceci:
|
||||||
|
"{} peuvent etre {}".format("Les chaînes", "interpolées")
|
||||||
|
|
||||||
|
# On peut aussi réutiliser le même argument pour gagner du temps.
|
||||||
|
"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick")
|
||||||
|
#=> "Jack be nimble, Jack be quick, Jack jump over the candle stick"
|
||||||
|
|
||||||
|
# On peut aussi utiliser des mots clés pour éviter de devoir compter.
|
||||||
|
"{name} wants to eat {food}".format(name="Bob", food="lasagna") #=> "Bob wants to eat lasagna"
|
||||||
|
|
||||||
|
# Si votre code doit aussi être compatible avec Python 2.5 et moins,
|
||||||
|
# vous pouvez encore utiliser l'ancienne syntaxe :
|
||||||
|
"Les %s peuvent être %s avec la %s méthode" % ("chaînes", "interpolées", "vieille")
|
||||||
|
|
||||||
|
|
||||||
|
# None est un objet
|
||||||
|
None # => None
|
||||||
|
|
||||||
|
# N'utilisez pas "==" pour comparer des objets à None
|
||||||
|
# Utilisez plutôt "is". Cela permet de vérifier l'égalité de l'identité des objets.
|
||||||
|
"etc" is None # => False
|
||||||
|
None is None # => True
|
||||||
|
|
||||||
|
# None, 0, and les strings/lists/dicts (chaînes/listes/dictionnaires) valent False lorsqu'ils sont convertis en booléens.
|
||||||
|
# Toutes les autres valeurs valent True
|
||||||
|
bool(0) # => False
|
||||||
|
bool("") # => False
|
||||||
|
bool([]) #=> False
|
||||||
|
bool({}) #=> False
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 2. Variables et Collections
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# Python a une fonction print pour afficher du texte
|
||||||
|
print("I'm Python. Nice to meet you!")
|
||||||
|
|
||||||
|
# Par défaut, la fonction print affiche aussi une nouvelle ligne à la fin.
|
||||||
|
# Utilisez l'argument optionnel end pour changer ce caractère de fin.
|
||||||
|
print("Hello, World", end="!") # => Hello, World!
|
||||||
|
|
||||||
|
# Pas besoin de déclarer des variables avant de les définir.
|
||||||
|
# La convention est de nommer ses variables avec des minuscules_et_underscores
|
||||||
|
some_var = 5
|
||||||
|
some_var # => 5
|
||||||
|
|
||||||
|
# Tenter d'accéder à une variable non définie lève une exception.
|
||||||
|
# Voir Structures de contrôle pour en apprendre plus sur le traitement des exceptions.
|
||||||
|
une_variable_inconnue # Lève une NameError
|
||||||
|
|
||||||
|
# Les listes permettent de stocker des séquences
|
||||||
|
li = []
|
||||||
|
# On peut initialiser une liste pré-remplie
|
||||||
|
other_li = [4, 5, 6]
|
||||||
|
|
||||||
|
# On ajoute des objets à la fin d'une liste avec .append
|
||||||
|
li.append(1) # li vaut maintenant [1]
|
||||||
|
li.append(2) # li vaut maintenant [1, 2]
|
||||||
|
li.append(4) # li vaut maintenant [1, 2, 4]
|
||||||
|
li.append(3) # li vaut maintenant [1, 2, 4, 3]
|
||||||
|
# On enlève le dernier élément avec .pop
|
||||||
|
li.pop() # => 3 et li vaut maintenant [1, 2, 4]
|
||||||
|
# Et on le remet
|
||||||
|
li.append(3) # li vaut de nouveau [1, 2, 4, 3]
|
||||||
|
|
||||||
|
# Accès à un élément d'une liste :
|
||||||
|
li[0] # => 1
|
||||||
|
# Accès au dernier élément :
|
||||||
|
li[-1] # => 3
|
||||||
|
|
||||||
|
# Accéder à un élément en dehors des limites lève une IndexError
|
||||||
|
li[4] # Lève une IndexError
|
||||||
|
|
||||||
|
# On peut accéder à une intervalle avec la syntaxe "slice"
|
||||||
|
# (c'est un rang du type "fermé/ouvert")
|
||||||
|
li[1:3] # => [2, 4]
|
||||||
|
# Omettre les deux premiers éléments
|
||||||
|
li[2:] # => [4, 3]
|
||||||
|
# Prendre les trois premiers
|
||||||
|
li[:3] # => [1, 2, 4]
|
||||||
|
# Sélectionner un élément sur deux
|
||||||
|
li[::2] # =>[1, 4]
|
||||||
|
# Avoir une copie de la liste à l'envers
|
||||||
|
li[::-1] # => [3, 4, 2, 1]
|
||||||
|
# Pour des "slices" plus élaborées :
|
||||||
|
# li[debut:fin:pas]
|
||||||
|
|
||||||
|
# Faire une copie d'une profondeur de un avec les "slices"
|
||||||
|
li2 = li[:] # => li2 = [1, 2, 4, 3] mais (li2 is li) vaut False.
|
||||||
|
|
||||||
|
# Enlever des éléments arbitrairement d'une liste
|
||||||
|
del li[2] # li is now [1, 2, 3]
|
||||||
|
|
||||||
|
# On peut additionner des listes
|
||||||
|
# Note: les valeurs de li et other_li ne sont pas modifiées.
|
||||||
|
li + other_li # => [1, 2, 3, 4, 5, 6]
|
||||||
|
|
||||||
|
# Concaténer des listes avec "extend()"
|
||||||
|
li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
|
||||||
|
|
||||||
|
# Vérifier la présence d'un objet dans une liste avec "in"
|
||||||
|
1 in li # => True
|
||||||
|
|
||||||
|
# Examiner la longueur avec "len()"
|
||||||
|
len(li) # => 6
|
||||||
|
|
||||||
|
|
||||||
|
# Les tuples sont comme des listes mais sont immuables.
|
||||||
|
tup = (1, 2, 3)
|
||||||
|
tup[0] # => 1
|
||||||
|
tup[0] = 3 # Lève une TypeError
|
||||||
|
|
||||||
|
# Note : un tuple de taille un doit avoir une virgule après le dernier élément,
|
||||||
|
# mais ce n'est pas le cas des tuples d'autres tailles, même zéro.
|
||||||
|
type((1)) # => <class 'int'>
|
||||||
|
type((1,)) # => <class 'tuple'>
|
||||||
|
type(()) # => <class 'tuple'>
|
||||||
|
|
||||||
|
# On peut utiliser la plupart des opérations des listes sur des tuples.
|
||||||
|
len(tup) # => 3
|
||||||
|
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
|
||||||
|
tup[:2] # => (1, 2)
|
||||||
|
2 in tup # => True
|
||||||
|
|
||||||
|
# Vous pouvez décomposer des tuples (ou des listes) dans des variables
|
||||||
|
a, b, c = (1, 2, 3) # a vaut 1, b vaut 2 et c vaut 3
|
||||||
|
# Les tuples sont créés par défaut sans parenthèses
|
||||||
|
d, e, f = 4, 5, 6
|
||||||
|
# Voyez comme il est facile d'intervertir deux valeurs :
|
||||||
|
e, d = d, e # d vaut maintenant 5 et e vaut maintenant 4
|
||||||
|
|
||||||
|
|
||||||
|
# Créer un dictionnaire :
|
||||||
|
empty_dict = {}
|
||||||
|
# Un dictionnaire pré-rempli :
|
||||||
|
filled_dict = {"one": 1, "two": 2, "three": 3}
|
||||||
|
|
||||||
|
# Note : les clés des dictionnaires doivent être de types immuables.
|
||||||
|
# Elles doivent être convertibles en une valeur constante pour une recherche rapide.
|
||||||
|
# Les types immuables incluent les ints, floats, strings et tuples.
|
||||||
|
invalid_dict = {[1,2,3]: "123"} # => Lève une TypeError: unhashable type: 'list'
|
||||||
|
valid_dict = {(1,2,3):[1,2,3]} # Par contre, les valeurs peuvent être de tout type.
|
||||||
|
|
||||||
|
# On trouve une valeur avec []
|
||||||
|
filled_dict["one"] # => 1
|
||||||
|
|
||||||
|
# On obtient toutes les clés sous forme d'un itérable avec "keys()" Il faut l'entourer
|
||||||
|
# de list() pour avoir une liste Note: l'ordre n'est pas garanti.
|
||||||
|
list(filled_dict.keys()) # => ["three", "two", "one"]
|
||||||
|
|
||||||
|
|
||||||
|
# On obtient toutes les valeurs sous forme d'un itérable avec "values()".
|
||||||
|
# Là aussi, il faut utiliser list() pour avoir une liste.
|
||||||
|
# Note : l'ordre n'est toujours pas garanti.
|
||||||
|
list(filled_dict.values()) # => [3, 2, 1]
|
||||||
|
|
||||||
|
|
||||||
|
# On vérifie la présence d'une clé dans un dictionnaire avec "in"
|
||||||
|
"one" in filled_dict # => True
|
||||||
|
1 in filled_dict # => False
|
||||||
|
|
||||||
|
# L'accès à une clé non-existente lève une KeyError
|
||||||
|
filled_dict["four"] # KeyError
|
||||||
|
|
||||||
|
# On utilise "get()" pour éviter la KeyError
|
||||||
|
filled_dict.get("one") # => 1
|
||||||
|
filled_dict.get("four") # => None
|
||||||
|
# La méthode get accepte une valeur de retour par défaut en cas de valeur non-existante.
|
||||||
|
filled_dict.get("one", 4) # => 1
|
||||||
|
filled_dict.get("four", 4) # => 4
|
||||||
|
|
||||||
|
# "setdefault()" insère une valeur dans un dictionnaire si la clé n'est pas présente.
|
||||||
|
filled_dict.setdefault("five", 5) # filled_dict["five"] devient 5
|
||||||
|
filled_dict.setdefault("five", 6) # filled_dict["five"] est toujours 5
|
||||||
|
|
||||||
|
# Ajouter à un dictionnaire
|
||||||
|
filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
|
||||||
|
#filled_dict["four"] = 4 # une autre méthode
|
||||||
|
|
||||||
|
# Enlever des clés d'un dictionnaire avec del
|
||||||
|
del filled_dict["one"] # Enlever la clé "one" de filled_dict.
|
||||||
|
|
||||||
|
|
||||||
|
# Les sets stockent des ensembles
|
||||||
|
empty_set = set()
|
||||||
|
# Initialiser un set avec des valeurs. Oui, ça ressemble aux dictionnaires, désolé.
|
||||||
|
some_set = {1, 1, 2, 2, 3, 4} # some_set est maintenant {1, 2, 3, 4}
|
||||||
|
|
||||||
|
# Comme les clés d'un dictionnaire, les éléments d'un set doivent être immuables.
|
||||||
|
invalid_set = {[1], 1} # => Lève une TypeError: unhashable type: 'list'
|
||||||
|
valid_set = {(1,), 1}
|
||||||
|
|
||||||
|
# On peut changer un set :
|
||||||
|
filled_set = some_set
|
||||||
|
|
||||||
|
# Ajouter un objet au set :
|
||||||
|
filled_set.add(5) # filled_set vaut maintenant {1, 2, 3, 4, 5}
|
||||||
|
|
||||||
|
# Chercher les intersections de deux sets avec &
|
||||||
|
other_set = {3, 4, 5, 6}
|
||||||
|
filled_set & other_set # => {3, 4, 5}
|
||||||
|
|
||||||
|
# On fait l'union de sets avec |
|
||||||
|
filled_set | other_set # => {1, 2, 3, 4, 5, 6}
|
||||||
|
|
||||||
|
# On fait la différence de deux sets avec -
|
||||||
|
{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
|
||||||
|
|
||||||
|
# On vérifie la présence d'un objet dans un set avec in
|
||||||
|
2 in filled_set # => True
|
||||||
|
10 in filled_set # => False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 3. Structures de contrôle et Itérables
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# On crée juste une variable
|
||||||
|
some_var = 5
|
||||||
|
|
||||||
|
# Voici une condition "si". L'indentation est significative en Python!
|
||||||
|
# Affiche: "some_var is smaller than 10"
|
||||||
|
if some_var > 10:
|
||||||
|
print("some_var is totally bigger than 10.")
|
||||||
|
elif some_var < 10: # La clause elif ("sinon si") est optionelle
|
||||||
|
print("some_var is smaller than 10.")
|
||||||
|
else: # La clause else ("sinon") l'est aussi.
|
||||||
|
print("some_var is indeed 10.")
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Les boucles "for" itèrent sur une liste
|
||||||
|
Affiche:
|
||||||
|
chien est un mammifère
|
||||||
|
chat est un mammifère
|
||||||
|
souris est un mammifère
|
||||||
|
"""
|
||||||
|
for animal in ["chien", "chat", "souris"]:
|
||||||
|
# On peut utiliser format() pour interpoler des chaînes formattées
|
||||||
|
print("{} est un mammifère".format(animal))
|
||||||
|
|
||||||
|
"""
|
||||||
|
"range(nombre)" retourne un itérable de nombres
|
||||||
|
de zéro au nombre donné
|
||||||
|
Affiche:
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
"""
|
||||||
|
for i in range(4):
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
"""
|
||||||
|
"range(debut, fin)" retourne un itérable de nombre
|
||||||
|
de debut à fin.
|
||||||
|
Affiche:
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
"""
|
||||||
|
for i in range(4, 8):
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
"""
|
||||||
|
"range(debut, fin, pas)" retourne un itérable de nombres
|
||||||
|
de début à fin en incrémentant de pas.
|
||||||
|
Si le pas n'est pas indiqué, la valeur par défaut est 1.
|
||||||
|
Affiche:
|
||||||
|
4
|
||||||
|
6
|
||||||
|
8
|
||||||
|
"""
|
||||||
|
for i in range(4, 8, 2):
|
||||||
|
print(i)
|
||||||
|
"""
|
||||||
|
|
||||||
|
Les boucles "while" bouclent jusqu'à ce que la condition devienne fausse.
|
||||||
|
Affiche:
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
"""
|
||||||
|
x = 0
|
||||||
|
while x < 4:
|
||||||
|
print(x)
|
||||||
|
x += 1 # Raccourci pour x = x + 1
|
||||||
|
|
||||||
|
# On gère les exceptions avec un bloc try/except
|
||||||
|
try:
|
||||||
|
# On utilise "raise" pour lever une erreur
|
||||||
|
raise IndexError("Ceci est une erreur d'index")
|
||||||
|
except IndexError as e:
|
||||||
|
pass # Pass signifie simplement "ne rien faire". Généralement, on gère l'erreur ici.
|
||||||
|
except (TypeError, NameError):
|
||||||
|
pass # Si besoin, on peut aussi gérer plusieurs erreurs en même temps.
|
||||||
|
else: # Clause optionelle des blocs try/except. Doit être après tous les except.
|
||||||
|
print("Tout va bien!") # Uniquement si aucune exception n'est levée.
|
||||||
|
finally: # Éxécuté dans toutes les circonstances.
|
||||||
|
print("On nettoie les ressources ici")
|
||||||
|
|
||||||
|
# Au lieu de try/finally pour nettoyer les ressources, on peut utiliser with
|
||||||
|
with open("myfile.txt") as f:
|
||||||
|
for line in f:
|
||||||
|
print(line)
|
||||||
|
|
||||||
|
# Python offre une abstraction fondamentale : l'Iterable.
|
||||||
|
# Un itérable est un objet pouvant être traîté comme une séquence.
|
||||||
|
# L'objet retourné par la fonction range() est un itérable.
|
||||||
|
|
||||||
|
filled_dict = {"one": 1, "two": 2, "three": 3}
|
||||||
|
our_iterable = filled_dict.keys()
|
||||||
|
print(our_iterable) #=> range(1,10). C'est un objet qui implémente l'interface Iterable
|
||||||
|
|
||||||
|
# On peut boucler dessus
|
||||||
|
for i in our_iterable:
|
||||||
|
print(i) # Affiche one, two, three
|
||||||
|
|
||||||
|
# Cependant, on ne peut pas accéder aux éléments par leur adresse.
|
||||||
|
our_iterable[1] # Lève une TypeError
|
||||||
|
|
||||||
|
# Un itérable est un objet qui sait créer un itérateur.
|
||||||
|
our_iterator = iter(our_iterable)
|
||||||
|
|
||||||
|
# Notre itérateur est un objet qui se rappelle de notre position quand on le traverse.
|
||||||
|
# On passe à l'élément suivant avec "next()".
|
||||||
|
next(our_iterator) #=> "one"
|
||||||
|
|
||||||
|
# Il garde son état quand on itère.
|
||||||
|
next(our_iterator) #=> "two"
|
||||||
|
next(our_iterator) #=> "three"
|
||||||
|
|
||||||
|
# Après que l'itérateur a retourné toutes ses données, il lève une exception StopIterator
|
||||||
|
next(our_iterator) # Lève une StopIteration
|
||||||
|
|
||||||
|
# On peut mettre tous les éléments d'un itérateur dans une liste avec list()
|
||||||
|
list(filled_dict.keys()) #=> Returns ["one", "two", "three"]
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 4. Fonctions
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# On utilise "def" pour créer des fonctions
|
||||||
|
def add(x, y):
|
||||||
|
print("x est {} et y est {}".format(x, y))
|
||||||
|
return x + y # On retourne une valeur avec return
|
||||||
|
|
||||||
|
# Appel d'une fonction avec des paramètres :
|
||||||
|
add(5, 6) # => affiche "x est 5 et y est 6" et retourne 11
|
||||||
|
|
||||||
|
# Une autre manière d'appeller une fonction : avec des arguments
|
||||||
|
add(y=6, x=5) # Les arguments peuvent être dans n'importe quel ordre.
|
||||||
|
|
||||||
|
# Définir une fonction qui prend un nombre variable d'arguments
|
||||||
|
def varargs(*args):
|
||||||
|
return args
|
||||||
|
|
||||||
|
varargs(1, 2, 3) # => (1, 2, 3)
|
||||||
|
|
||||||
|
# On peut aussi définir une fonction qui prend un nombre variable de paramètres.
|
||||||
|
def keyword_args(**kwargs):
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
# Appelons la pour voir ce qu'il se passe :
|
||||||
|
keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
|
||||||
|
|
||||||
|
|
||||||
|
# On peut aussi faire les deux à la fois :
|
||||||
|
def all_the_args(*args, **kwargs):
|
||||||
|
print(args)
|
||||||
|
print(kwargs)
|
||||||
|
"""
|
||||||
|
all_the_args(1, 2, a=3, b=4) affiche:
|
||||||
|
(1, 2)
|
||||||
|
{"a": 3, "b": 4}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# En appelant des fonctions, on peut aussi faire l'inverse :
|
||||||
|
# utiliser * pour étendre un tuple de paramètres
|
||||||
|
# et ** pour étendre un dictionnaire d'arguments.
|
||||||
|
args = (1, 2, 3, 4)
|
||||||
|
kwargs = {"a": 3, "b": 4}
|
||||||
|
all_the_args(*args) # équivalent à foo(1, 2, 3, 4)
|
||||||
|
all_the_args(**kwargs) # équivalent à foo(a=3, b=4)
|
||||||
|
all_the_args(*args, **kwargs) # équivalent à foo(1, 2, 3, 4, a=3, b=4)
|
||||||
|
|
||||||
|
# Retourne plusieurs valeurs (avec un tuple)
|
||||||
|
def swap(x, y):
|
||||||
|
return y, x # Retourne plusieurs valeurs avec un tuple sans parenthèses.
|
||||||
|
# (Note: on peut aussi utiliser des parenthèses)
|
||||||
|
|
||||||
|
x = 1
|
||||||
|
y = 2
|
||||||
|
x, y = swap(x, y) # => x = 2, y = 1
|
||||||
|
# (x, y) = swap(x,y) # Là aussi, rien ne nous empêche d'ajouter des parenthèses
|
||||||
|
|
||||||
|
# Portée des fonctions :
|
||||||
|
x = 5
|
||||||
|
|
||||||
|
def setX(num):
|
||||||
|
# La variable locale x n'est pas la même que la variable globale x
|
||||||
|
x = num # => 43
|
||||||
|
print (x) # => 43
|
||||||
|
|
||||||
|
def setGlobalX(num):
|
||||||
|
global x
|
||||||
|
print (x) # => 5
|
||||||
|
x = num # la variable globale x est maintenant 6
|
||||||
|
print (x) # => 6
|
||||||
|
|
||||||
|
setX(43)
|
||||||
|
setGlobalX(6)
|
||||||
|
|
||||||
|
|
||||||
|
# Python a des fonctions de première classe
|
||||||
|
def create_adder(x):
|
||||||
|
def adder(y):
|
||||||
|
return x + y
|
||||||
|
return adder
|
||||||
|
|
||||||
|
add_10 = create_adder(10)
|
||||||
|
add_10(3) # => 13
|
||||||
|
|
||||||
|
# Mais aussi des fonctions anonymes
|
||||||
|
(lambda x: x > 2)(3) # => True
|
||||||
|
(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
|
||||||
|
|
||||||
|
# TODO - Fix for iterables
|
||||||
|
# Il y a aussi des fonctions de base
|
||||||
|
map(add_10, [1, 2, 3]) # => [11, 12, 13]
|
||||||
|
map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3]
|
||||||
|
|
||||||
|
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
|
||||||
|
|
||||||
|
# On peut utiliser les compréhensions de listes pour de jolies maps et filtres.
|
||||||
|
# Une compréhension de liste stocke la sortie comme une liste qui peut elle même être une liste imbriquée.
|
||||||
|
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
|
||||||
|
[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 5. Classes
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
|
||||||
|
# On utilise l'opérateur "classe" pour définir une classe
|
||||||
|
class Human:
|
||||||
|
|
||||||
|
# Un attribut de la classe. Il est partagé par toutes les instances de la classe.
|
||||||
|
species = "H. sapiens"
|
||||||
|
|
||||||
|
# L'initialiseur de base. Il est appelé quand la classe est instanciée.
|
||||||
|
# Note : les doubles underscores au début et à la fin sont utilisés pour
|
||||||
|
# les fonctions et attributs utilisés par Python mais contrôlés par l'utilisateur.
|
||||||
|
# Les méthodes (ou objets ou attributs) comme: __init__, __str__,
|
||||||
|
# __repr__ etc. sont appelés méthodes magiques.
|
||||||
|
# Vous ne devriez pas inventer de noms de ce style.
|
||||||
|
def __init__(self, name):
|
||||||
|
# Assigner l'argument à l'attribut de l'instance
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
# Une méthode de l'instance. Toutes prennent "self" comme premier argument.
|
||||||
|
def say(self, msg):
|
||||||
|
return "{name}: {message}".format(name=self.name, message=msg)
|
||||||
|
|
||||||
|
# Une méthode de classe est partagée avec entre les instances
|
||||||
|
# Ils sont appelés avec la classe comme premier argument
|
||||||
|
@classmethod
|
||||||
|
def get_species(cls):
|
||||||
|
return cls.species
|
||||||
|
|
||||||
|
# Une méthode statique est appelée sans référence à une instance ni à une classe.
|
||||||
|
@staticmethod
|
||||||
|
def grunt():
|
||||||
|
return "*grunt*"
|
||||||
|
|
||||||
|
|
||||||
|
# Instantier une classe
|
||||||
|
i = Human(name="Ian")
|
||||||
|
print(i.say("hi")) # affiche "Ian: hi"
|
||||||
|
|
||||||
|
j = Human("Joel")
|
||||||
|
print(j.say("hello")) # affiche "Joel: hello"
|
||||||
|
|
||||||
|
# Appeller notre méthode de classe
|
||||||
|
i.get_species() # => "H. sapiens"
|
||||||
|
|
||||||
|
# Changer les attributs partagés
|
||||||
|
Human.species = "H. neanderthalensis"
|
||||||
|
i.get_species() # => "H. neanderthalensis"
|
||||||
|
j.get_species() # => "H. neanderthalensis"
|
||||||
|
|
||||||
|
# Appeller la méthode statique
|
||||||
|
Human.grunt() # => "*grunt*"
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 6. Modules
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# On peut importer des modules
|
||||||
|
import math
|
||||||
|
print(math.sqrt(16)) # => 4.0
|
||||||
|
|
||||||
|
# On peut importer des fonctions spécifiques d'un module
|
||||||
|
from math import ceil, floor
|
||||||
|
print(ceil(3.7)) # => 4.0
|
||||||
|
print(floor(3.7)) # => 3.0
|
||||||
|
|
||||||
|
# On peut importer toutes les fonctions d'un module
|
||||||
|
# Attention: ce n'est pas recommandé.
|
||||||
|
from math import *
|
||||||
|
|
||||||
|
# On peut raccourcir un nom de module
|
||||||
|
import math as m
|
||||||
|
math.sqrt(16) == m.sqrt(16) # => True
|
||||||
|
|
||||||
|
# Les modules Python sont juste des fichiers Python.
|
||||||
|
# Vous pouvez écrire les vôtres et les importer. Le nom du module
|
||||||
|
# est le nom du fichier.
|
||||||
|
|
||||||
|
# On peut voir quels fonctions et objets un module définit
|
||||||
|
import math
|
||||||
|
dir(math)
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 7. Avancé
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# Les générateurs aident à faire du code paresseux (lazy)
|
||||||
|
def double_numbers(iterable):
|
||||||
|
for i in iterable:
|
||||||
|
yield i + i
|
||||||
|
|
||||||
|
# Un générateur crée des valeurs à la volée.
|
||||||
|
# Au lieu de générer et retourner toutes les valeurs en une fois, il en crée une à chaque
|
||||||
|
# itération. Cela signifie que les valeurs supérieures à 15 ne seront pas traîtées par
|
||||||
|
# double_numbers.
|
||||||
|
# Note : range est un générateur aussi.
|
||||||
|
# Créer une liste 1-900000000 prendrait beaucoup de temps
|
||||||
|
# On met un underscore à la fin d'un nom de variable normalement réservé par Python.
|
||||||
|
range_ = range(1, 900000000)
|
||||||
|
# Double tous les nombres jusqu'à ce qu'un nombre >=30 soit trouvé
|
||||||
|
for i in double_numbers(range_):
|
||||||
|
print(i)
|
||||||
|
if i >= 30:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
# Decorateurs
|
||||||
|
# Dans cet exemple, beg enveloppe say
|
||||||
|
# Beg appellera say. Si say_please vaut True le message retourné sera changé
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
def beg(target_function):
|
||||||
|
@wraps(target_function)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
msg, say_please = target_function(*args, **kwargs)
|
||||||
|
if say_please:
|
||||||
|
return "{} {}".format(msg, "Please! I am poor :(")
|
||||||
|
return msg
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@beg
|
||||||
|
def say(say_please=False):
|
||||||
|
msg = "Can you buy me a beer?"
|
||||||
|
return msg, say_please
|
||||||
|
|
||||||
|
|
||||||
|
print(say()) # affiche Can you buy me a beer?
|
||||||
|
print(say(say_please=True)) # affiche Can you buy me a beer? Please! I am poor :(
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prêt pour encore plus ?
|
||||||
|
|
||||||
|
### En ligne et gratuit (en anglais)
|
||||||
|
|
||||||
|
* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
|
||||||
|
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
|
||||||
|
* [Dive Into Python](http://www.diveintopython.net/)
|
||||||
|
* [Ideas for Python Projects](http://pythonpracticeprojects.com)
|
||||||
|
* [The Official Docs](http://docs.python.org/3/)
|
||||||
|
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
|
||||||
|
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
|
||||||
|
* [Python Course](http://www.python-course.eu/index.php)
|
||||||
|
* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
|
||||||
|
|
||||||
|
### Livres (en anglais)
|
||||||
|
|
||||||
|
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
|
||||||
|
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
|
||||||
|
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
|
@ -208,6 +208,7 @@ sSquared.reduce (_+_)
|
|||||||
// La fonction filter prend un prédicat (une fonction de type A -> Booléen) et
|
// La fonction filter prend un prédicat (une fonction de type A -> Booléen) et
|
||||||
// sélectionne tous les éléments qui satisfont ce prédicat
|
// sélectionne tous les éléments qui satisfont ce prédicat
|
||||||
List(1, 2, 3) filter (_ > 2) // List(3)
|
List(1, 2, 3) filter (_ > 2) // List(3)
|
||||||
|
case class Person(name: String, age: Int)
|
||||||
List(
|
List(
|
||||||
Person(name = "Dom", age = 23),
|
Person(name = "Dom", age = 23),
|
||||||
Person(name = "Bob", age = 30)
|
Person(name = "Bob", age = 30)
|
||||||
@ -217,6 +218,7 @@ List(
|
|||||||
|
|
||||||
// Scala a une méthode foreach définie pour certaines collections
|
// Scala a une méthode foreach définie pour certaines collections
|
||||||
// qui prend en argument une fonction renvoyant Unit (une méthode void)
|
// qui prend en argument une fonction renvoyant Unit (une méthode void)
|
||||||
|
val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
|
||||||
aListOfNumbers foreach (x => println(x))
|
aListOfNumbers foreach (x => println(x))
|
||||||
aListOfNumbers foreach println
|
aListOfNumbers foreach println
|
||||||
|
|
||||||
@ -271,11 +273,12 @@ i // Montre la valeur de i. Notez que while est une boucle au sens classique.
|
|||||||
// mais utiliser des combinateurs et des compréhensions comme ci-dessus est plus
|
// mais utiliser des combinateurs et des compréhensions comme ci-dessus est plus
|
||||||
// facile pour comprendre et pour faire la parallélisation
|
// facile pour comprendre et pour faire la parallélisation
|
||||||
|
|
||||||
|
i = 0
|
||||||
// La boucle do while
|
// La boucle do while
|
||||||
do {
|
do {
|
||||||
println("x is still less then 10");
|
println("x is still less then 10");
|
||||||
x += 1
|
i += 1
|
||||||
} while (x < 10)
|
} while (i < 10)
|
||||||
|
|
||||||
|
|
||||||
// La récursivité est un moyen idiomatique de faire une chose répétitive en Scala.
|
// La récursivité est un moyen idiomatique de faire une chose répétitive en Scala.
|
||||||
@ -370,7 +373,7 @@ val email(user, domain) = "henry@zkpr.com"
|
|||||||
|
|
||||||
"Les chaînes de caractères Scala sont entourées de doubles guillements"
|
"Les chaînes de caractères Scala sont entourées de doubles guillements"
|
||||||
'a' // Un caractère de Scala
|
'a' // Un caractère de Scala
|
||||||
'Les simples guillemets n'existent pas en Scala // Erreur
|
// 'Les simples guillemets n'existent pas en Scala' // Erreur
|
||||||
"Les chaînes de caractères possèdent les méthodes usuelles de Java".length
|
"Les chaînes de caractères possèdent les méthodes usuelles de Java".length
|
||||||
"Il y a aussi quelques méthodes extra de Scala.".reverse
|
"Il y a aussi quelques méthodes extra de Scala.".reverse
|
||||||
|
|
||||||
|
@ -87,22 +87,22 @@ mySearch = function(src: string, sub: string) {
|
|||||||
|
|
||||||
// Les membres des classes sont publiques par défaut.
|
// Les membres des classes sont publiques par défaut.
|
||||||
class Point {
|
class Point {
|
||||||
// Propriétés
|
// Propriétés
|
||||||
x: number;
|
x: number;
|
||||||
|
|
||||||
// Constructeur - Les mots clés "public" et "private" dans ce contexte
|
// Constructeur - Les mots clés "public" et "private" dans ce contexte
|
||||||
// génèrent le code de la propriété et son initialisation dans le
|
// génèrent le code de la propriété et son initialisation dans le
|
||||||
// constructeur. Ici, "y" sera défini de la même façon que "x",
|
// constructeur. Ici, "y" sera défini de la même façon que "x",
|
||||||
// mais avec moins de code. Les valeurs par défaut sont supportées.
|
// mais avec moins de code. Les valeurs par défaut sont supportées.
|
||||||
constructor(x: number, public y: number = 0) {
|
constructor(x: number, public y: number = 0) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fonctions
|
// Fonctions
|
||||||
dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
|
dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
|
||||||
|
|
||||||
// Membres statiques
|
// Membres statiques
|
||||||
static origin = new Point(0, 0);
|
static origin = new Point(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var p1 = new Point(10 ,20);
|
var p1 = new Point(10 ,20);
|
||||||
@ -110,17 +110,17 @@ var p2 = new Point(25); // y sera 0
|
|||||||
|
|
||||||
// Héritage
|
// Héritage
|
||||||
class Point3D extends Point {
|
class Point3D extends Point {
|
||||||
constructor(x: number, y: number, public z: number = 0) {
|
constructor(x: number, y: number, public z: number = 0) {
|
||||||
// Un appel explicite au constructeur de la super classe
|
// Un appel explicite au constructeur de la super classe
|
||||||
// est obligatoire.
|
// est obligatoire.
|
||||||
super(x, y);
|
super(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redéfinition
|
// Redéfinition
|
||||||
dist() {
|
dist() {
|
||||||
var d = super.dist();
|
var d = super.dist();
|
||||||
return Math.sqrt(d * d + this.z * this.z);
|
return Math.sqrt(d * d + this.z * this.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modules, "." peut être utilisé comme un séparateur de sous modules.
|
// Modules, "." peut être utilisé comme un séparateur de sous modules.
|
||||||
@ -144,19 +144,19 @@ var s2 = new G.Square(10);
|
|||||||
// Génériques
|
// Génériques
|
||||||
// Classes
|
// Classes
|
||||||
class Tuple<T1, T2> {
|
class Tuple<T1, T2> {
|
||||||
constructor(public item1: T1, public item2: T2) {
|
constructor(public item1: T1, public item2: T2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interfaces
|
// Interfaces
|
||||||
interface Pair<T> {
|
interface Pair<T> {
|
||||||
item1: T;
|
item1: T;
|
||||||
item2: T;
|
item2: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Et fonctions
|
// Et fonctions
|
||||||
var pairToTuple = function<T>(p: Pair<T>) {
|
var pairToTuple = function<T>(p: Pair<T>) {
|
||||||
return new Tuple(p.item1, p.item2);
|
return new Tuple(p.item1, p.item2);
|
||||||
};
|
};
|
||||||
|
|
||||||
var tuple = pairToTuple({ item1:"hello", item2:"world"});
|
var tuple = pairToTuple({ item1:"hello", item2:"world"});
|
||||||
|
@ -8,113 +8,117 @@ lang: fr-fr
|
|||||||
|
|
||||||
Proposé à l'origine par Clark Evans en Mai 2001, YAML est un un format de
|
Proposé à l'origine par Clark Evans en Mai 2001, YAML est un un format de
|
||||||
représentation de données par sérialisation, conçu pour être aisément
|
représentation de données par sérialisation, conçu pour être aisément
|
||||||
éditable et lisible par nous même, les humains.
|
modifiable et lisible par nous-mêmes, les humains.
|
||||||
|
|
||||||
YAML est plus concis que le XML auquel il est parfois comparé par ceux qui le découvre, plus lisible et clair que le CSV, et emprunte beaucoup au JSON dont il est un parent naturel. Toutefois, YAML emprunte également des idées et concepts de chez Python, et s'intègre bien avec bon nombre de langages.
|
YAML est plus concis que le XML auquel il est parfois comparé par ceux qui le
|
||||||
|
découvre, plus lisible et clair que le CSV, et emprunte beaucoup au JSON dont
|
||||||
|
il est un parent naturel. Toutefois, YAML emprunte également des idées et
|
||||||
|
concepts de Python, et s'intègre bien avec bon nombre de langages.
|
||||||
|
Contrairement à ce dernier, YAML interdit l'utilisation des tabulations.
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# les Commentaires sont précédés d'un signe "#", comme cette ligne.
|
# Les commentaires sont précédés d'un signe "#", comme cette ligne.
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# SCALAIRES #
|
# SCALAIRES #
|
||||||
#############
|
#############
|
||||||
|
|
||||||
# Les scalaires sont l'ensemble des types YAML qui ne sont pas des collections
|
# Les scalaires sont l'ensemble des types YAML qui ne sont pas des collections
|
||||||
# ( listes ou tableaux associatifs ).
|
# (listes ou tableaux associatifs).
|
||||||
|
|
||||||
# Notre objet root ( racine ), sera une map ( carte ) et englobera
|
# Notre objet root (racine), sera une map (carte) et englobera
|
||||||
# l'intégralité du document. Cette map est l'équivalent d'un dictionnaire,
|
# l'intégralité du document. Cette map est l'équivalent d'un dictionnaire,
|
||||||
# hash ou objet dans d'autres langages.
|
# hash ou objet dans d'autres langages.
|
||||||
clé: valeur
|
clé: valeur
|
||||||
aurtre_clé: une autre valeur
|
autre_clé: une autre valeur
|
||||||
valeur_numérique: 100
|
valeur_numérique: 100
|
||||||
notation_scientifique: 1e+12
|
notation_scientifique: 1e+12
|
||||||
boolean: true
|
booléen: true
|
||||||
valeur_null: null
|
valeur_null: null
|
||||||
clé avec espaces: valeur
|
clé avec espaces: valeur
|
||||||
# Bien qu'il ne soit pas nécessaire d'enfermer les chaînes de caractères
|
# Bien qu'il ne soit pas nécessaire de mettre les chaînes de caractères
|
||||||
# entre guillemets, cela reste possible, et parfois utile.
|
# entre guillemets, cela reste possible, et parfois utile.
|
||||||
toutefois: "Une chaîne, peut être contenue entre guillemets."
|
toutefois: "Une chaîne, peut être contenue entre guillemets."
|
||||||
"Une clé entre guillemets.": "Utile si on veut utiliser ':' dans la clé."
|
"Une clé entre guillemets.": "Utile si l'on veut utiliser ':' dans la clé."
|
||||||
|
|
||||||
# Les chaînes couvrant plusieurs lignes, peuvent être écrites au choix,
|
# Les chaînes couvrant plusieurs lignes, peuvent être écrites au choix,
|
||||||
# comme un 'bloc littéral' ( avec | ) ou bien 'bloc replié' avec ( > ).
|
# comme un "bloc littéral" (avec '|') ou bien un "bloc replié" (avec '>').
|
||||||
bloc_littéral: |
|
bloc_littéral: |
|
||||||
Tout ce bloc de texte sera la valeur de la clé 'bloc_littéral',
|
Tout ce bloc de texte sera la valeur de la clé "bloc_littéral",
|
||||||
avec préservation des retours à la ligne. ( chaque ligne vide à
|
avec préservation des retours à la ligne.
|
||||||
l'intérieur du même bloc, sera remplacée par "\n\n" )
|
|
||||||
|
|
||||||
Le littéral continue jusqu'à ce que l'indentation soit annulée.
|
Le littéral continue jusqu'à ce que l'indentation soit annulée.
|
||||||
|
|
||||||
Toutes lignes qui serait "d'avantage indentées" conservent leur
|
Toutes lignes qui seraient "davantage indentées" conservent leur
|
||||||
indentation, constituée de 4 espaces.
|
indentation, constituée de 4 espaces.
|
||||||
bloc_replié: >
|
bloc_replié: >
|
||||||
Tout ce bloc de texte sera la valeur de la clé 'bloc_replié', mais
|
Tout ce bloc de texte sera la valeur de la clé "bloc_replié", mais
|
||||||
cette fois ci, toutes les nouvelles lignes deviendront un simple espace.
|
cette fois-ci, toutes les nouvelles lignes deviendront un simple espace.
|
||||||
|
|
||||||
Les lignes vides, comme ci-dessus, seront converties en caractère "\n".
|
Les lignes vides, comme ci-dessus, seront converties en caractère de
|
||||||
|
nouvelle ligne.
|
||||||
|
|
||||||
Les lignes 'plus-indentées' gardent leurs retours à la ligne -
|
Les lignes "plus-indentées" gardent leurs retours à la ligne -
|
||||||
ce texte apparaîtra sur deux lignes.
|
ce texte apparaîtra sur deux lignes.
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# COLLECTIONS #
|
# COLLECTIONS #
|
||||||
###############
|
###############
|
||||||
|
|
||||||
# l'Imbrication est créée par indentation.
|
# L'imbrication est créée par indentation.
|
||||||
une_map_imbriquée:
|
une_map_imbriquée:
|
||||||
clé: valeur
|
clé: valeur
|
||||||
autre_clé: autre valeur
|
autre_clé: autre valeur
|
||||||
autre_map_imbriquée:
|
autre_map_imbriquée:
|
||||||
bonjour: bonjour
|
bonjour: bonjour
|
||||||
|
|
||||||
# les Clés des Maps ne sont pas nécessairement des chaînes de caractères.
|
# Les clés des maps ne sont pas nécessairement des chaînes de caractères.
|
||||||
0.25: une clé de type float
|
0.25: une clé de type flottant
|
||||||
|
|
||||||
# les Clés peuvent également être des objets s'étendant sur plusieurs lignes,
|
# Les clés peuvent également être des objets s'étendant sur plusieurs lignes,
|
||||||
# en utilisant le signe "?" pour indiquer le début de la clé.
|
# en utilisant le signe "?" pour indiquer le début de la clé.
|
||||||
? |
|
? |
|
||||||
ceci est une Clé
|
ceci est une clé
|
||||||
sur de multiples lignes
|
sur de multiples lignes
|
||||||
: et ceci est sa Valeur
|
: et ceci est sa valeur
|
||||||
|
|
||||||
# YAML autorise aussi l'usage des collections à l'intérieur des clés,
|
# YAML autorise aussi l'usage des collections à l'intérieur des clés,
|
||||||
# mais certains langages de programmation ne le tolère pas si bien.
|
# mais certains langages de programmation ne le tolère pas si bien.
|
||||||
|
|
||||||
# les Séquences (équivalent des listes ou tableaux) ressemblent à cela:
|
# Les séquences (équivalent des listes ou tableaux) ressemblent à cela :
|
||||||
une_séquence:
|
une_séquence:
|
||||||
- Item 1
|
- Objet 1
|
||||||
- Item 2
|
- Objet 2
|
||||||
- 0.5 # les séquences peuvent contenir des types variés.
|
- 0.5 # les séquences peuvent contenir des types variés.
|
||||||
- Item 4
|
- Objet 4
|
||||||
- clé: valeur
|
- clé: valeur
|
||||||
autre_clé: autre_valeur
|
autre_clé: autre_valeur
|
||||||
-
|
-
|
||||||
- Ceci est une séquence
|
- Ceci est une séquence
|
||||||
- dans une autre séquence
|
- dans une autre séquence
|
||||||
|
|
||||||
# YAML étant un proche parent de JSON, vous pouvez écrire directement
|
# YAML étant un proche parent de JSON, vous pouvez écrire directement
|
||||||
# des maps et séquences façon JSON
|
# des maps et séquences façon JSON
|
||||||
json_map: {"clé": "valeur"}
|
json_map: {"clé": "valeur"}
|
||||||
json_seq: [1, 2, 3, "soleil"]
|
json_seq: [1, 2, 3, "soleil"]
|
||||||
|
|
||||||
#################################
|
################################
|
||||||
# AUTRES FONCTIONNALITÉES YAML #
|
# AUTRES FONCTIONNALITÉES YAML #
|
||||||
#################################
|
################################
|
||||||
|
|
||||||
# YAML possède une fonctionnalité fort utile nommée 'ancres'. Celle-ci
|
# YAML possède une fonctionnalité fort utile nommée "ancres". Celle-ci
|
||||||
# vous permet de dupliquer aisément du contenu au sein de votre document.
|
# vous permet de dupliquer aisément du contenu au sein de votre document.
|
||||||
|
|
||||||
# Les deux clés suivantes auront la même valeur:
|
# Les deux clés suivantes auront la même valeur :
|
||||||
contenu_ancré: &nom_ancre Cette chaîne sera la valeur des deux clés.
|
contenu_ancré: &nom_ancre Cette chaîne sera la valeur des deux clés.
|
||||||
autre_ancre: *nom_ancre
|
autre_ancre: *nom_ancre
|
||||||
|
|
||||||
# Avec les Tags YAML, vous pouvez explicitement déclarer des types de données.
|
# Avec les tags YAML, vous pouvez explicitement déclarer des types de données.
|
||||||
chaine_explicite: !!str 0.5
|
chaine_explicite: !!str 0.5
|
||||||
|
|
||||||
# Certains parsers implémentent des tags spécifiques à d'autres langages,
|
# Certains analyseurs syntaxiques (parsers) implémentent des tags spécifiques à
|
||||||
# comme par exemple le "complex number" de Python.
|
# d'autres langages, comme par exemple celui des nombres complexes de Python.
|
||||||
python_complex_number: !!python/complex 1+2j
|
python_complex_number: !!python/complex 1+2j
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
@ -122,7 +126,7 @@ python_complex_number: !!python/complex 1+2j
|
|||||||
#####################
|
#####################
|
||||||
|
|
||||||
# YAML interprète également les données formatées ISO de type date et datetime,
|
# YAML interprète également les données formatées ISO de type date et datetime,
|
||||||
# pas seulement les chaînes et nombres.
|
# pas seulement les chaînes et nombres.
|
||||||
datetime: 2001-12-15T02:59:43.1Z
|
datetime: 2001-12-15T02:59:43.1Z
|
||||||
datetime_avec_espaces: 2001-12-14 21:59:43.10 -5
|
datetime_avec_espaces: 2001-12-14 21:59:43.10 -5
|
||||||
date: 2002-12-14
|
date: 2002-12-14
|
||||||
@ -135,14 +139,14 @@ fichier_gif: !!binary |
|
|||||||
+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
|
+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
|
||||||
AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
|
AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
|
||||||
|
|
||||||
# YAML a de même un type "set", qui ressemble à cela:
|
# YAML a de même un type "set", semblable à ceci :
|
||||||
set:
|
set:
|
||||||
? item1
|
? item1
|
||||||
? item2
|
? item2
|
||||||
? item3
|
? item3
|
||||||
|
|
||||||
# Comme dans Python, les sets ne sont que des maps contenant des valeurs null ;
|
# Comme dans Python, les sets ne sont que des maps contenant des valeurs null ;
|
||||||
# le set précédent est l'équivalent du suivant:
|
# le set précédent est l'équivalent du suivant :
|
||||||
set2:
|
set2:
|
||||||
item1: null
|
item1: null
|
||||||
item2: null
|
item2: null
|
||||||
@ -152,6 +156,6 @@ set2:
|
|||||||
|
|
||||||
Quelques références et outils :
|
Quelques références et outils :
|
||||||
|
|
||||||
- Doc officielle [YAML 1.2](http://www.yaml.org/spec/1.2/spec.html) *anglais*,
|
- Documentation officielle [YAML 1.2](http://www.yaml.org/spec/1.2/spec.html) *anglais*,
|
||||||
- Une [Introduction à YAML](http://sweetohm.net/html/introduction-yaml.html) très bien construite et claire,
|
- Une [Introduction à YAML](http://sweetohm.net/html/introduction-yaml.html) très bien construite et claire,
|
||||||
- Un outil pour tester [live](http://yaml-online-parser.appspot.com/) la syntaxe YAML, avec des exemples.
|
- Un outil pour tester [en ligne](http://yaml-online-parser.appspot.com/) la syntaxe YAML, avec des exemples.
|
||||||
|
@ -5,7 +5,7 @@ contributors:
|
|||||||
filename: learnfsharp.fs
|
filename: learnfsharp.fs
|
||||||
---
|
---
|
||||||
|
|
||||||
F# is a general purpose functional/OO programming language. It's free and open source, and runs on Linux, Mac, Windows and more.
|
F# is a general purpose functional/OO programming language. It's free and open source, and runs on Linux, Mac, Windows and more.
|
||||||
|
|
||||||
It has a powerful type system that traps many errors at compile time, but it uses type inference so that it reads more like a dynamic language.
|
It has a powerful type system that traps many errors at compile time, but it uses type inference so that it reads more like a dynamic language.
|
||||||
|
|
||||||
@ -31,14 +31,14 @@ If you want to try out the code below, you can go to [tryfsharp.org](http://www.
|
|||||||
// The "let" keyword defines an (immutable) value
|
// The "let" keyword defines an (immutable) value
|
||||||
let myInt = 5
|
let myInt = 5
|
||||||
let myFloat = 3.14
|
let myFloat = 3.14
|
||||||
let myString = "hello" //note that no types needed
|
let myString = "hello" // note that no types needed
|
||||||
|
|
||||||
// ------ Lists ------
|
// ------ Lists ------
|
||||||
let twoToFive = [2;3;4;5] // Square brackets create a list with
|
let twoToFive = [2; 3; 4; 5] // Square brackets create a list with
|
||||||
// semicolon delimiters.
|
// semicolon delimiters.
|
||||||
let oneToFive = 1 :: twoToFive // :: creates list with new 1st element
|
let oneToFive = 1 :: twoToFive // :: creates list with new 1st element
|
||||||
// The result is [1;2;3;4;5]
|
// The result is [1; 2; 3; 4; 5]
|
||||||
let zeroToFive = [0;1] @ twoToFive // @ concats two lists
|
let zeroToFive = [0; 1] @ twoToFive // @ concats two lists
|
||||||
|
|
||||||
// IMPORTANT: commas are never used as delimiters, only semicolons!
|
// IMPORTANT: commas are never used as delimiters, only semicolons!
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ add 2 3 // Now run the function.
|
|||||||
|
|
||||||
// to define a multiline function, just use indents. No semicolons needed.
|
// to define a multiline function, just use indents. No semicolons needed.
|
||||||
let evens list =
|
let evens list =
|
||||||
let isEven x = x%2 = 0 // Define "isEven" as a sub function
|
let isEven x = x % 2 = 0 // Define "isEven" as a sub function
|
||||||
List.filter isEven list // List.filter is a library function
|
List.filter isEven list // List.filter is a library function
|
||||||
// with two parameters: a boolean function
|
// with two parameters: a boolean function
|
||||||
// and a list to work on
|
// and a list to work on
|
||||||
@ -75,7 +75,7 @@ let sumOfSquaresTo100piped =
|
|||||||
|
|
||||||
// you can define lambdas (anonymous functions) using the "fun" keyword
|
// you can define lambdas (anonymous functions) using the "fun" keyword
|
||||||
let sumOfSquaresTo100withFun =
|
let sumOfSquaresTo100withFun =
|
||||||
[1..100] |> List.map (fun x -> x*x) |> List.sum
|
[1..100] |> List.map (fun x -> x * x) |> List.sum
|
||||||
|
|
||||||
// In F# there is no "return" keyword. A function always
|
// In F# there is no "return" keyword. A function always
|
||||||
// returns the value of the last expression used.
|
// returns the value of the last expression used.
|
||||||
@ -90,7 +90,7 @@ let simplePatternMatch =
|
|||||||
| _ -> printfn "x is something else" // underscore matches anything
|
| _ -> printfn "x is something else" // underscore matches anything
|
||||||
|
|
||||||
// F# doesn't allow nulls by default -- you must use an Option type
|
// F# doesn't allow nulls by default -- you must use an Option type
|
||||||
// and then pattern match.
|
// and then pattern match.
|
||||||
// Some(..) and None are roughly analogous to Nullable wrappers
|
// Some(..) and None are roughly analogous to Nullable wrappers
|
||||||
let validValue = Some(99)
|
let validValue = Some(99)
|
||||||
let invalidValue = None
|
let invalidValue = None
|
||||||
@ -109,103 +109,103 @@ optionPatternMatch invalidValue
|
|||||||
// The printf/printfn functions are similar to the
|
// The printf/printfn functions are similar to the
|
||||||
// Console.Write/WriteLine functions in C#.
|
// Console.Write/WriteLine functions in C#.
|
||||||
printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true
|
printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true
|
||||||
printfn "A string %s, and something generic %A" "hello" [1;2;3;4]
|
printfn "A string %s, and something generic %A" "hello" [1; 2; 3; 4]
|
||||||
|
|
||||||
// There are also sprintf/sprintfn functions for formatting data
|
// There are also sprintf/sprintfn functions for formatting data
|
||||||
// into a string, similar to String.Format in C#.
|
// into a string, similar to String.Format in C#.
|
||||||
|
|
||||||
// ================================================
|
// ================================================
|
||||||
// More on functions
|
// More on functions
|
||||||
// ================================================
|
// ================================================
|
||||||
|
|
||||||
// F# is a true functional language -- functions are first
|
// F# is a true functional language -- functions are first
|
||||||
// class entities and can be combined easy to make powerful
|
// class entities and can be combined easily to make powerful
|
||||||
// constructs
|
// constructs
|
||||||
|
|
||||||
// Modules are used to group functions together
|
// Modules are used to group functions together
|
||||||
// Indentation is needed for each nested module.
|
// Indentation is needed for each nested module.
|
||||||
module FunctionExamples =
|
module FunctionExamples =
|
||||||
|
|
||||||
// define a simple adding function
|
// define a simple adding function
|
||||||
let add x y = x + y
|
let add x y = x + y
|
||||||
|
|
||||||
// basic usage of a function
|
// basic usage of a function
|
||||||
let a = add 1 2
|
let a = add 1 2
|
||||||
printfn "1+2 = %i" a
|
printfn "1 + 2 = %i" a
|
||||||
|
|
||||||
// partial application to "bake in" parameters
|
// partial application to "bake in" parameters
|
||||||
let add42 = add 42
|
let add42 = add 42
|
||||||
let b = add42 1
|
let b = add42 1
|
||||||
printfn "42+1 = %i" b
|
printfn "42 + 1 = %i" b
|
||||||
|
|
||||||
// composition to combine functions
|
// composition to combine functions
|
||||||
let add1 = add 1
|
let add1 = add 1
|
||||||
let add2 = add 2
|
let add2 = add 2
|
||||||
let add3 = add1 >> add2
|
let add3 = add1 >> add2
|
||||||
let c = add3 7
|
let c = add3 7
|
||||||
printfn "3+7 = %i" c
|
printfn "3 + 7 = %i" c
|
||||||
|
|
||||||
// higher order functions
|
// higher order functions
|
||||||
[1..10] |> List.map add3 |> printfn "new list is %A"
|
[1..10] |> List.map add3 |> printfn "new list is %A"
|
||||||
|
|
||||||
// lists of functions, and more
|
// lists of functions, and more
|
||||||
let add6 = [add1; add2; add3] |> List.reduce (>>)
|
let add6 = [add1; add2; add3] |> List.reduce (>>)
|
||||||
let d = add6 7
|
let d = add6 7
|
||||||
printfn "1+2+3+7 = %i" d
|
printfn "1 + 2 + 3 + 7 = %i" d
|
||||||
|
|
||||||
// ================================================
|
// ================================================
|
||||||
// Lists and collection
|
// Lists and collection
|
||||||
// ================================================
|
// ================================================
|
||||||
|
|
||||||
// There are three types of ordered collection:
|
// There are three types of ordered collection:
|
||||||
// * Lists are most basic immutable collection.
|
// * Lists are most basic immutable collection.
|
||||||
// * Arrays are mutable and more efficient when needed.
|
// * Arrays are mutable and more efficient when needed.
|
||||||
// * Sequences are lazy and infinite (e.g. an enumerator).
|
// * Sequences are lazy and infinite (e.g. an enumerator).
|
||||||
//
|
//
|
||||||
// Other collections include immutable maps and sets
|
// Other collections include immutable maps and sets
|
||||||
// plus all the standard .NET collections
|
// plus all the standard .NET collections
|
||||||
|
|
||||||
module ListExamples =
|
module ListExamples =
|
||||||
|
|
||||||
// lists use square brackets
|
// lists use square brackets
|
||||||
let list1 = ["a";"b"]
|
let list1 = ["a"; "b"]
|
||||||
let list2 = "c" :: list1 // :: is prepending
|
let list2 = "c" :: list1 // :: is prepending
|
||||||
let list3 = list1 @ list2 // @ is concat
|
let list3 = list1 @ list2 // @ is concat
|
||||||
|
|
||||||
// list comprehensions (aka generators)
|
// list comprehensions (aka generators)
|
||||||
let squares = [for i in 1..10 do yield i*i]
|
let squares = [for i in 1..10 do yield i * i]
|
||||||
|
|
||||||
// prime number generator
|
// prime number generator
|
||||||
let rec sieve = function
|
let rec sieve = function
|
||||||
| (p::xs) -> p :: sieve [ for x in xs do if x % p > 0 then yield x ]
|
| (p::xs) -> p :: sieve [ for x in xs do if x % p > 0 then yield x ]
|
||||||
| [] -> []
|
| [] -> []
|
||||||
let primes = sieve [2..50]
|
let primes = sieve [2..50]
|
||||||
printfn "%A" primes
|
printfn "%A" primes
|
||||||
|
|
||||||
// pattern matching for lists
|
|
||||||
let listMatcher aList =
|
|
||||||
match aList with
|
|
||||||
| [] -> printfn "the list is empty"
|
|
||||||
| [first] -> printfn "the list has one element %A " first
|
|
||||||
| [first; second] -> printfn "list is %A and %A" first second
|
|
||||||
| _ -> printfn "the list has more than two elements"
|
|
||||||
|
|
||||||
listMatcher [1;2;3;4]
|
// pattern matching for lists
|
||||||
listMatcher [1;2]
|
let listMatcher aList =
|
||||||
|
match aList with
|
||||||
|
| [] -> printfn "the list is empty"
|
||||||
|
| [first] -> printfn "the list has one element %A " first
|
||||||
|
| [first; second] -> printfn "list is %A and %A" first second
|
||||||
|
| _ -> printfn "the list has more than two elements"
|
||||||
|
|
||||||
|
listMatcher [1; 2; 3; 4]
|
||||||
|
listMatcher [1; 2]
|
||||||
listMatcher [1]
|
listMatcher [1]
|
||||||
listMatcher []
|
listMatcher []
|
||||||
|
|
||||||
// recursion using lists
|
// recursion using lists
|
||||||
let rec sum aList =
|
let rec sum aList =
|
||||||
match aList with
|
match aList with
|
||||||
| [] -> 0
|
| [] -> 0
|
||||||
| x::xs -> x + sum xs
|
| x::xs -> x + sum xs
|
||||||
sum [1..10]
|
sum [1..10]
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
// Standard library functions
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
// Standard library functions
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
// map
|
// map
|
||||||
let add3 x = x + 3
|
let add3 x = x + 3
|
||||||
[1..10] |> List.map add3
|
[1..10] |> List.map add3
|
||||||
@ -213,102 +213,102 @@ module ListExamples =
|
|||||||
// filter
|
// filter
|
||||||
let even x = x % 2 = 0
|
let even x = x % 2 = 0
|
||||||
[1..10] |> List.filter even
|
[1..10] |> List.filter even
|
||||||
|
|
||||||
// many more -- see documentation
|
// many more -- see documentation
|
||||||
|
|
||||||
module ArrayExamples =
|
module ArrayExamples =
|
||||||
|
|
||||||
// arrays use square brackets with bar
|
// arrays use square brackets with bar
|
||||||
let array1 = [| "a";"b" |]
|
let array1 = [| "a"; "b" |]
|
||||||
let first = array1.[0] // indexed access using dot
|
let first = array1.[0] // indexed access using dot
|
||||||
|
|
||||||
// pattern matching for arrays is same as for lists
|
|
||||||
let arrayMatcher aList =
|
|
||||||
match aList with
|
|
||||||
| [| |] -> printfn "the array is empty"
|
|
||||||
| [| first |] -> printfn "the array has one element %A " first
|
|
||||||
| [| first; second |] -> printfn "array is %A and %A" first second
|
|
||||||
| _ -> printfn "the array has more than two elements"
|
|
||||||
|
|
||||||
arrayMatcher [| 1;2;3;4 |]
|
// pattern matching for arrays is same as for lists
|
||||||
|
let arrayMatcher aList =
|
||||||
|
match aList with
|
||||||
|
| [| |] -> printfn "the array is empty"
|
||||||
|
| [| first |] -> printfn "the array has one element %A " first
|
||||||
|
| [| first; second |] -> printfn "array is %A and %A" first second
|
||||||
|
| _ -> printfn "the array has more than two elements"
|
||||||
|
|
||||||
|
arrayMatcher [| 1; 2; 3; 4 |]
|
||||||
|
|
||||||
// Standard library functions just as for List
|
// Standard library functions just as for List
|
||||||
|
|
||||||
[| 1..10 |]
|
[| 1..10 |]
|
||||||
|> Array.map (fun i -> i+3)
|
|> Array.map (fun i -> i + 3)
|
||||||
|> Array.filter (fun i -> i%2 = 0)
|
|> Array.filter (fun i -> i % 2 = 0)
|
||||||
|> Array.iter (printfn "value is %i. ")
|
|> Array.iter (printfn "value is %i. ")
|
||||||
|
|
||||||
|
|
||||||
module SequenceExamples =
|
module SequenceExamples =
|
||||||
|
|
||||||
// sequences use curly braces
|
// sequences use curly braces
|
||||||
let seq1 = seq { yield "a"; yield "b" }
|
let seq1 = seq { yield "a"; yield "b" }
|
||||||
|
|
||||||
// sequences can use yield and
|
// sequences can use yield and
|
||||||
// can contain subsequences
|
// can contain subsequences
|
||||||
let strange = seq {
|
let strange = seq {
|
||||||
// "yield! adds one element
|
// "yield" adds one element
|
||||||
yield 1; yield 2;
|
yield 1; yield 2;
|
||||||
|
|
||||||
// "yield!" adds a whole subsequence
|
// "yield!" adds a whole subsequence
|
||||||
yield! [5..10]
|
yield! [5..10]
|
||||||
yield! seq {
|
yield! seq {
|
||||||
for i in 1..10 do
|
for i in 1..10 do
|
||||||
if i%2 = 0 then yield i }}
|
if i % 2 = 0 then yield i }}
|
||||||
// test
|
// test
|
||||||
strange |> Seq.toList
|
strange |> Seq.toList
|
||||||
|
|
||||||
|
|
||||||
// Sequences can be created using "unfold"
|
// Sequences can be created using "unfold"
|
||||||
// Here's the fibonacci series
|
// Here's the fibonacci series
|
||||||
let fib = Seq.unfold (fun (fst,snd) ->
|
let fib = Seq.unfold (fun (fst,snd) ->
|
||||||
Some(fst + snd, (snd, fst + snd))) (0,1)
|
Some(fst + snd, (snd, fst + snd))) (0,1)
|
||||||
|
|
||||||
// test
|
// test
|
||||||
let fib10 = fib |> Seq.take 10 |> Seq.toList
|
let fib10 = fib |> Seq.take 10 |> Seq.toList
|
||||||
printf "first 10 fibs are %A" fib10
|
printf "first 10 fibs are %A" fib10
|
||||||
|
|
||||||
|
|
||||||
// ================================================
|
// ================================================
|
||||||
// Data Types
|
// Data Types
|
||||||
// ================================================
|
// ================================================
|
||||||
|
|
||||||
module DataTypeExamples =
|
module DataTypeExamples =
|
||||||
|
|
||||||
// All data is immutable by default
|
// All data is immutable by default
|
||||||
|
|
||||||
// Tuples are quick 'n easy anonymous types
|
// Tuples are quick 'n easy anonymous types
|
||||||
// -- Use a comma to create a tuple
|
// -- Use a comma to create a tuple
|
||||||
let twoTuple = 1,2
|
let twoTuple = 1, 2
|
||||||
let threeTuple = "a",2,true
|
let threeTuple = "a", 2, true
|
||||||
|
|
||||||
// Pattern match to unpack
|
|
||||||
let x,y = twoTuple //sets x=1 y=2
|
|
||||||
|
|
||||||
// ------------------------------------
|
// Pattern match to unpack
|
||||||
// Record types have named fields
|
let x, y = twoTuple // sets x = 1, y = 2
|
||||||
// ------------------------------------
|
|
||||||
|
// ------------------------------------
|
||||||
|
// Record types have named fields
|
||||||
|
// ------------------------------------
|
||||||
|
|
||||||
// Use "type" with curly braces to define a record type
|
// Use "type" with curly braces to define a record type
|
||||||
type Person = {First:string; Last:string}
|
type Person = {First:string; Last:string}
|
||||||
|
|
||||||
// Use "let" with curly braces to create a record
|
// Use "let" with curly braces to create a record
|
||||||
let person1 = {First="John"; Last="Doe"}
|
let person1 = {First="John"; Last="Doe"}
|
||||||
|
|
||||||
// Pattern match to unpack
|
// Pattern match to unpack
|
||||||
let {First=first} = person1 //sets first="john"
|
let {First = first} = person1 // sets first="John"
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
// Union types (aka variants) have a set of choices
|
// Union types (aka variants) have a set of choices
|
||||||
// Only case can be valid at a time.
|
// Only case can be valid at a time.
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
||||||
// Use "type" with bar/pipe to define a union type
|
// Use "type" with bar/pipe to define a union type
|
||||||
type Temp =
|
type Temp =
|
||||||
| DegreesC of float
|
| DegreesC of float
|
||||||
| DegreesF of float
|
| DegreesF of float
|
||||||
|
|
||||||
// Use one of the cases to create one
|
// Use one of the cases to create one
|
||||||
let temp1 = DegreesF 98.6
|
let temp1 = DegreesF 98.6
|
||||||
let temp2 = DegreesC 37.0
|
let temp2 = DegreesC 37.0
|
||||||
@ -317,29 +317,29 @@ module DataTypeExamples =
|
|||||||
let printTemp = function
|
let printTemp = function
|
||||||
| DegreesC t -> printfn "%f degC" t
|
| DegreesC t -> printfn "%f degC" t
|
||||||
| DegreesF t -> printfn "%f degF" t
|
| DegreesF t -> printfn "%f degF" t
|
||||||
|
|
||||||
printTemp temp1
|
printTemp temp1
|
||||||
printTemp temp2
|
printTemp temp2
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
// Recursive types
|
// Recursive types
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
||||||
// Types can be combined recursively in complex ways
|
// Types can be combined recursively in complex ways
|
||||||
// without having to create subclasses
|
// without having to create subclasses
|
||||||
type Employee =
|
type Employee =
|
||||||
| Worker of Person
|
| Worker of Person
|
||||||
| Manager of Employee list
|
| Manager of Employee list
|
||||||
|
|
||||||
let jdoe = {First="John";Last="Doe"}
|
let jdoe = {First="John"; Last="Doe"}
|
||||||
let worker = Worker jdoe
|
let worker = Worker jdoe
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
// Modelling with types
|
// Modeling with types
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
||||||
// Union types are great for modelling state without using flags
|
// Union types are great for modeling state without using flags
|
||||||
type EmailAddress =
|
type EmailAddress =
|
||||||
| ValidEmailAddress of string
|
| ValidEmailAddress of string
|
||||||
| InvalidEmailAddress of string
|
| InvalidEmailAddress of string
|
||||||
|
|
||||||
@ -350,68 +350,68 @@ module DataTypeExamples =
|
|||||||
|
|
||||||
// The combination of union types and record types together
|
// The combination of union types and record types together
|
||||||
// provide a great foundation for domain driven design.
|
// provide a great foundation for domain driven design.
|
||||||
// You can create hundreds of little types that accurately
|
// You can create hundreds of little types that accurately
|
||||||
// reflect the domain.
|
// reflect the domain.
|
||||||
|
|
||||||
type CartItem = { ProductCode: string; Qty: int }
|
type CartItem = { ProductCode: string; Qty: int }
|
||||||
type Payment = Payment of float
|
type Payment = Payment of float
|
||||||
type ActiveCartData = { UnpaidItems: CartItem list }
|
type ActiveCartData = { UnpaidItems: CartItem list }
|
||||||
type PaidCartData = { PaidItems: CartItem list; Payment: Payment}
|
type PaidCartData = { PaidItems: CartItem list; Payment: Payment}
|
||||||
|
|
||||||
type ShoppingCart =
|
type ShoppingCart =
|
||||||
| EmptyCart // no data
|
| EmptyCart // no data
|
||||||
| ActiveCart of ActiveCartData
|
| ActiveCart of ActiveCartData
|
||||||
| PaidCart of PaidCartData
|
| PaidCart of PaidCartData
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
// Built in behavior for types
|
// Built in behavior for types
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
||||||
// Core types have useful "out-of-the-box" behavior, no coding needed.
|
// Core types have useful "out-of-the-box" behavior, no coding needed.
|
||||||
// * Immutability
|
// * Immutability
|
||||||
// * Pretty printing when debugging
|
// * Pretty printing when debugging
|
||||||
// * Equality and comparison
|
// * Equality and comparison
|
||||||
// * Serialization
|
// * Serialization
|
||||||
|
|
||||||
// Pretty printing using %A
|
// Pretty printing using %A
|
||||||
printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A"
|
printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A"
|
||||||
twoTuple person1 temp1 worker
|
twoTuple person1 temp1 worker
|
||||||
|
|
||||||
// Equality and comparison built in.
|
// Equality and comparison built in.
|
||||||
// Here's an example with cards.
|
// Here's an example with cards.
|
||||||
type Suit = Club | Diamond | Spade | Heart
|
type Suit = Club | Diamond | Spade | Heart
|
||||||
type Rank = Two | Three | Four | Five | Six | Seven | Eight
|
type Rank = Two | Three | Four | Five | Six | Seven | Eight
|
||||||
| Nine | Ten | Jack | Queen | King | Ace
|
| Nine | Ten | Jack | Queen | King | Ace
|
||||||
|
|
||||||
let hand = [ Club,Ace; Heart,Three; Heart,Ace;
|
let hand = [ Club, Ace; Heart, Three; Heart, Ace;
|
||||||
Spade,Jack; Diamond,Two; Diamond,Ace ]
|
Spade, Jack; Diamond, Two; Diamond, Ace ]
|
||||||
|
|
||||||
// sorting
|
// sorting
|
||||||
List.sort hand |> printfn "sorted hand is (low to high) %A"
|
List.sort hand |> printfn "sorted hand is (low to high) %A"
|
||||||
List.max hand |> printfn "high card is %A"
|
List.max hand |> printfn "high card is %A"
|
||||||
List.min hand |> printfn "low card is %A"
|
List.min hand |> printfn "low card is %A"
|
||||||
|
|
||||||
|
|
||||||
// ================================================
|
// ================================================
|
||||||
// Active patterns
|
// Active patterns
|
||||||
// ================================================
|
// ================================================
|
||||||
|
|
||||||
module ActivePatternExamples =
|
module ActivePatternExamples =
|
||||||
|
|
||||||
// F# has a special type of pattern matching called "active patterns"
|
// F# has a special type of pattern matching called "active patterns"
|
||||||
// where the pattern can be parsed or detected dynamically.
|
// where the pattern can be parsed or detected dynamically.
|
||||||
|
|
||||||
// "banana clips" are the syntax for active patterns
|
// "banana clips" are the syntax for active patterns
|
||||||
|
|
||||||
// for example, define an "active" pattern to match character types...
|
// for example, define an "active" pattern to match character types...
|
||||||
let (|Digit|Letter|Whitespace|Other|) ch =
|
let (|Digit|Letter|Whitespace|Other|) ch =
|
||||||
if System.Char.IsDigit(ch) then Digit
|
if System.Char.IsDigit(ch) then Digit
|
||||||
else if System.Char.IsLetter(ch) then Letter
|
else if System.Char.IsLetter(ch) then Letter
|
||||||
else if System.Char.IsWhiteSpace(ch) then Whitespace
|
else if System.Char.IsWhiteSpace(ch) then Whitespace
|
||||||
else Other
|
else Other
|
||||||
|
|
||||||
// ... and then use it to make parsing logic much clearer
|
// ... and then use it to make parsing logic much clearer
|
||||||
let printChar ch =
|
let printChar ch =
|
||||||
match ch with
|
match ch with
|
||||||
| Digit -> printfn "%c is a Digit" ch
|
| Digit -> printfn "%c is a Digit" ch
|
||||||
| Letter -> printfn "%c is a Letter" ch
|
| Letter -> printfn "%c is a Letter" ch
|
||||||
@ -419,57 +419,57 @@ module ActivePatternExamples =
|
|||||||
| _ -> printfn "%c is something else" ch
|
| _ -> printfn "%c is something else" ch
|
||||||
|
|
||||||
// print a list
|
// print a list
|
||||||
['a';'b';'1';' ';'-';'c'] |> List.iter printChar
|
['a'; 'b'; '1'; ' '; '-'; 'c'] |> List.iter printChar
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// FizzBuzz using active patterns
|
// FizzBuzz using active patterns
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
||||||
// You can create partial matching patterns as well
|
// You can create partial matching patterns as well
|
||||||
// Just use undercore in the defintion, and return Some if matched.
|
// Just use underscore in the defintion, and return Some if matched.
|
||||||
let (|MultOf3|_|) i = if i % 3 = 0 then Some MultOf3 else None
|
let (|MultOf3|_|) i = if i % 3 = 0 then Some MultOf3 else None
|
||||||
let (|MultOf5|_|) i = if i % 5 = 0 then Some MultOf5 else None
|
let (|MultOf5|_|) i = if i % 5 = 0 then Some MultOf5 else None
|
||||||
|
|
||||||
// the main function
|
// the main function
|
||||||
let fizzBuzz i =
|
let fizzBuzz i =
|
||||||
match i with
|
match i with
|
||||||
| MultOf3 & MultOf5 -> printf "FizzBuzz, "
|
| MultOf3 & MultOf5 -> printf "FizzBuzz, "
|
||||||
| MultOf3 -> printf "Fizz, "
|
| MultOf3 -> printf "Fizz, "
|
||||||
| MultOf5 -> printf "Buzz, "
|
| MultOf5 -> printf "Buzz, "
|
||||||
| _ -> printf "%i, " i
|
| _ -> printf "%i, " i
|
||||||
|
|
||||||
// test
|
// test
|
||||||
[1..20] |> List.iter fizzBuzz
|
[1..20] |> List.iter fizzBuzz
|
||||||
|
|
||||||
// ================================================
|
// ================================================
|
||||||
// Conciseness
|
// Conciseness
|
||||||
// ================================================
|
// ================================================
|
||||||
|
|
||||||
module AlgorithmExamples =
|
module AlgorithmExamples =
|
||||||
|
|
||||||
// F# has a high signal/noise ratio, so code reads
|
// F# has a high signal/noise ratio, so code reads
|
||||||
// almost like the actual algorithm
|
// almost like the actual algorithm
|
||||||
|
|
||||||
// ------ Example: define sumOfSquares function ------
|
// ------ Example: define sumOfSquares function ------
|
||||||
let sumOfSquares n =
|
let sumOfSquares n =
|
||||||
[1..n] // 1) take all the numbers from 1 to n
|
[1..n] // 1) take all the numbers from 1 to n
|
||||||
|> List.map square // 2) square each one
|
|> List.map square // 2) square each one
|
||||||
|> List.sum // 3) sum the results
|
|> List.sum // 3) sum the results
|
||||||
|
|
||||||
// test
|
// test
|
||||||
sumOfSquares 100 |> printfn "Sum of squares = %A"
|
sumOfSquares 100 |> printfn "Sum of squares = %A"
|
||||||
|
|
||||||
// ------ Example: define a sort function ------
|
// ------ Example: define a sort function ------
|
||||||
let rec sort list =
|
let rec sort list =
|
||||||
match list with
|
match list with
|
||||||
// If the list is empty
|
// If the list is empty
|
||||||
| [] ->
|
| [] ->
|
||||||
[] // return an empty list
|
[] // return an empty list
|
||||||
// If the list is not empty
|
// If the list is not empty
|
||||||
| firstElem::otherElements -> // take the first element
|
| firstElem::otherElements -> // take the first element
|
||||||
let smallerElements = // extract the smaller elements
|
let smallerElements = // extract the smaller elements
|
||||||
otherElements // from the remaining ones
|
otherElements // from the remaining ones
|
||||||
|> List.filter (fun e -> e < firstElem)
|
|> List.filter (fun e -> e < firstElem)
|
||||||
|> sort // and sort them
|
|> sort // and sort them
|
||||||
let largerElements = // extract the larger ones
|
let largerElements = // extract the larger ones
|
||||||
otherElements // from the remaining ones
|
otherElements // from the remaining ones
|
||||||
@ -479,13 +479,13 @@ module AlgorithmExamples =
|
|||||||
List.concat [smallerElements; [firstElem]; largerElements]
|
List.concat [smallerElements; [firstElem]; largerElements]
|
||||||
|
|
||||||
// test
|
// test
|
||||||
sort [1;5;23;18;9;1;3] |> printfn "Sorted = %A"
|
sort [1; 5; 23; 18; 9; 1; 3] |> printfn "Sorted = %A"
|
||||||
|
|
||||||
// ================================================
|
// ================================================
|
||||||
// Asynchronous Code
|
// Asynchronous Code
|
||||||
// ================================================
|
// ================================================
|
||||||
|
|
||||||
module AsyncExample =
|
module AsyncExample =
|
||||||
|
|
||||||
// F# has built-in features to help with async code
|
// F# has built-in features to help with async code
|
||||||
// without encountering the "pyramid of doom"
|
// without encountering the "pyramid of doom"
|
||||||
@ -495,23 +495,23 @@ module AsyncExample =
|
|||||||
open System.Net
|
open System.Net
|
||||||
open System
|
open System
|
||||||
open System.IO
|
open System.IO
|
||||||
open Microsoft.FSharp.Control.CommonExtensions
|
open Microsoft.FSharp.Control.CommonExtensions
|
||||||
|
|
||||||
// Fetch the contents of a URL asynchronously
|
// Fetch the contents of a URL asynchronously
|
||||||
let fetchUrlAsync url =
|
let fetchUrlAsync url =
|
||||||
async { // "async" keyword and curly braces
|
async { // "async" keyword and curly braces
|
||||||
// creates an "async" object
|
// creates an "async" object
|
||||||
let req = WebRequest.Create(Uri(url))
|
let req = WebRequest.Create(Uri(url))
|
||||||
use! resp = req.AsyncGetResponse()
|
use! resp = req.AsyncGetResponse()
|
||||||
// use! is async assignment
|
// use! is async assignment
|
||||||
use stream = resp.GetResponseStream()
|
use stream = resp.GetResponseStream()
|
||||||
// "use" triggers automatic close()
|
// "use" triggers automatic close()
|
||||||
// on resource at end of scope
|
// on resource at end of scope
|
||||||
use reader = new IO.StreamReader(stream)
|
use reader = new IO.StreamReader(stream)
|
||||||
let html = reader.ReadToEnd()
|
let html = reader.ReadToEnd()
|
||||||
printfn "finished downloading %s" url
|
printfn "finished downloading %s" url
|
||||||
}
|
}
|
||||||
|
|
||||||
// a list of sites to fetch
|
// a list of sites to fetch
|
||||||
let sites = ["http://www.bing.com";
|
let sites = ["http://www.bing.com";
|
||||||
"http://www.google.com";
|
"http://www.google.com";
|
||||||
@ -520,90 +520,90 @@ module AsyncExample =
|
|||||||
"http://www.yahoo.com"]
|
"http://www.yahoo.com"]
|
||||||
|
|
||||||
// do it
|
// do it
|
||||||
sites
|
sites
|
||||||
|> List.map fetchUrlAsync // make a list of async tasks
|
|> List.map fetchUrlAsync // make a list of async tasks
|
||||||
|> Async.Parallel // set up the tasks to run in parallel
|
|> Async.Parallel // set up the tasks to run in parallel
|
||||||
|> Async.RunSynchronously // start them off
|
|> Async.RunSynchronously // start them off
|
||||||
|
|
||||||
// ================================================
|
// ================================================
|
||||||
// .NET compatability
|
// .NET compatibility
|
||||||
// ================================================
|
// ================================================
|
||||||
|
|
||||||
module NetCompatibilityExamples =
|
module NetCompatibilityExamples =
|
||||||
|
|
||||||
// F# can do almost everything C# can do, and it integrates
|
// F# can do almost everything C# can do, and it integrates
|
||||||
// seamlessly with .NET or Mono libraries.
|
// seamlessly with .NET or Mono libraries.
|
||||||
|
|
||||||
// ------- work with existing library functions -------
|
// ------- work with existing library functions -------
|
||||||
|
|
||||||
let (i1success,i1) = System.Int32.TryParse("123");
|
let (i1success, i1) = System.Int32.TryParse("123");
|
||||||
if i1success then printfn "parsed as %i" i1 else printfn "parse failed"
|
if i1success then printfn "parsed as %i" i1 else printfn "parse failed"
|
||||||
|
|
||||||
// ------- Implement interfaces on the fly! -------
|
// ------- Implement interfaces on the fly! -------
|
||||||
|
|
||||||
// create a new object that implements IDisposable
|
// create a new object that implements IDisposable
|
||||||
let makeResource name =
|
let makeResource name =
|
||||||
{ new System.IDisposable
|
{ new System.IDisposable
|
||||||
with member this.Dispose() = printfn "%s disposed" name }
|
with member this.Dispose() = printfn "%s disposed" name }
|
||||||
|
|
||||||
let useAndDisposeResources =
|
let useAndDisposeResources =
|
||||||
use r1 = makeResource "first resource"
|
use r1 = makeResource "first resource"
|
||||||
printfn "using first resource"
|
printfn "using first resource"
|
||||||
for i in [1..3] do
|
for i in [1..3] do
|
||||||
let resourceName = sprintf "\tinner resource %d" i
|
let resourceName = sprintf "\tinner resource %d" i
|
||||||
use temp = makeResource resourceName
|
use temp = makeResource resourceName
|
||||||
printfn "\tdo something with %s" resourceName
|
printfn "\tdo something with %s" resourceName
|
||||||
use r2 = makeResource "second resource"
|
use r2 = makeResource "second resource"
|
||||||
printfn "using second resource"
|
printfn "using second resource"
|
||||||
printfn "done."
|
printfn "done."
|
||||||
|
|
||||||
// ------- Object oriented code -------
|
// ------- Object oriented code -------
|
||||||
|
|
||||||
// F# is also a fully fledged OO language.
|
// F# is also a fully fledged OO language.
|
||||||
// It supports classes, inheritance, virtual methods, etc.
|
// It supports classes, inheritance, virtual methods, etc.
|
||||||
|
|
||||||
// interface with generic type
|
// interface with generic type
|
||||||
type IEnumerator<'a> =
|
type IEnumerator<'a> =
|
||||||
abstract member Current : 'a
|
abstract member Current : 'a
|
||||||
abstract MoveNext : unit -> bool
|
abstract MoveNext : unit -> bool
|
||||||
|
|
||||||
// abstract base class with virtual methods
|
// abstract base class with virtual methods
|
||||||
[<AbstractClass>]
|
[<AbstractClass>]
|
||||||
type Shape() =
|
type Shape() =
|
||||||
//readonly properties
|
// readonly properties
|
||||||
abstract member Width : int with get
|
abstract member Width : int with get
|
||||||
abstract member Height : int with get
|
abstract member Height : int with get
|
||||||
//non-virtual method
|
// non-virtual method
|
||||||
member this.BoundingArea = this.Height * this.Width
|
member this.BoundingArea = this.Height * this.Width
|
||||||
//virtual method with base implementation
|
// virtual method with base implementation
|
||||||
abstract member Print : unit -> unit
|
abstract member Print : unit -> unit
|
||||||
default this.Print () = printfn "I'm a shape"
|
default this.Print () = printfn "I'm a shape"
|
||||||
|
|
||||||
// concrete class that inherits from base class and overrides
|
// concrete class that inherits from base class and overrides
|
||||||
type Rectangle(x:int, y:int) =
|
type Rectangle(x:int, y:int) =
|
||||||
inherit Shape()
|
inherit Shape()
|
||||||
override this.Width = x
|
override this.Width = x
|
||||||
override this.Height = y
|
override this.Height = y
|
||||||
override this.Print () = printfn "I'm a Rectangle"
|
override this.Print () = printfn "I'm a Rectangle"
|
||||||
|
|
||||||
//test
|
// test
|
||||||
let r = Rectangle(2,3)
|
let r = Rectangle(2, 3)
|
||||||
printfn "The width is %i" r.Width
|
printfn "The width is %i" r.Width
|
||||||
printfn "The area is %i" r.BoundingArea
|
printfn "The area is %i" r.BoundingArea
|
||||||
r.Print()
|
r.Print()
|
||||||
|
|
||||||
// ------- extension methods -------
|
// ------- extension methods -------
|
||||||
|
|
||||||
//Just as in C#, F# can extend existing classes with extension methods.
|
// Just as in C#, F# can extend existing classes with extension methods.
|
||||||
type System.String with
|
type System.String with
|
||||||
member this.StartsWithA = this.StartsWith "A"
|
member this.StartsWithA = this.StartsWith "A"
|
||||||
|
|
||||||
//test
|
// test
|
||||||
let s = "Alice"
|
let s = "Alice"
|
||||||
printfn "'%s' starts with an 'A' = %A" s s.StartsWithA
|
printfn "'%s' starts with an 'A' = %A" s s.StartsWithA
|
||||||
|
|
||||||
// ------- events -------
|
// ------- events -------
|
||||||
|
|
||||||
type MyButton() =
|
type MyButton() =
|
||||||
let clickEvent = new Event<_>()
|
let clickEvent = new Event<_>()
|
||||||
|
|
||||||
@ -615,11 +615,11 @@ module NetCompatibilityExamples =
|
|||||||
|
|
||||||
// test
|
// test
|
||||||
let myButton = new MyButton()
|
let myButton = new MyButton()
|
||||||
myButton.OnClick.Add(fun (sender, arg) ->
|
myButton.OnClick.Add(fun (sender, arg) ->
|
||||||
printfn "Click event with arg=%O" arg)
|
printfn "Click event with arg=%O" arg)
|
||||||
|
|
||||||
myButton.TestEvent("Hello World!")
|
myButton.TestEvent("Hello World!")
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## More Information
|
## More Information
|
||||||
|
@ -5,20 +5,22 @@ contributors:
|
|||||||
- ["Jake Prather", "http://github.com/JakeHP"]
|
- ["Jake Prather", "http://github.com/JakeHP"]
|
||||||
- ["Leo Rudberg" , "http://github.com/LOZORD"]
|
- ["Leo Rudberg" , "http://github.com/LOZORD"]
|
||||||
- ["Betsy Lorton" , "http://github.com/schbetsy"]
|
- ["Betsy Lorton" , "http://github.com/schbetsy"]
|
||||||
|
- ["Bruno Volcov", "http://github.com/volcov"]
|
||||||
|
- ["Andrew Taylor", "http://github.com/andrewjt71"]
|
||||||
filename: LearnGit.txt
|
filename: LearnGit.txt
|
||||||
---
|
---
|
||||||
|
|
||||||
Git is a distributed version control and source code management system.
|
Git is a distributed version control and source code management system.
|
||||||
|
|
||||||
It does this through a series of snapshots of your project, and it works
|
It does this through a series of snapshots of your project, and it works
|
||||||
with those snapshots to provide you with functionality to version and
|
with those snapshots to provide you with functionality to version and
|
||||||
manage your source code.
|
manage your source code.
|
||||||
|
|
||||||
## Versioning Concepts
|
## Versioning Concepts
|
||||||
|
|
||||||
### What is version control?
|
### What is version control?
|
||||||
|
|
||||||
Version control is a system that records changes to a file, or set of files, over time.
|
Version control is a system that records changes to a file(s), over time.
|
||||||
|
|
||||||
### Centralized Versioning VS Distributed Versioning
|
### Centralized Versioning VS Distributed Versioning
|
||||||
|
|
||||||
@ -42,8 +44,9 @@ Version control is a system that records changes to a file, or set of files, ove
|
|||||||
|
|
||||||
### Repository
|
### Repository
|
||||||
|
|
||||||
A set of files, directories, historical records, commits, and heads. Imagine it as a source code data structure,
|
A set of files, directories, historical records, commits, and heads. Imagine it
|
||||||
with the attribute that each source code "element" gives you access to its revision history, among other things.
|
as a source code data structure, with the attribute that each source code
|
||||||
|
"element" gives you access to its revision history, among other things.
|
||||||
|
|
||||||
A git repository is comprised of the .git directory & working tree.
|
A git repository is comprised of the .git directory & working tree.
|
||||||
|
|
||||||
@ -54,32 +57,38 @@ The .git directory contains all the configurations, logs, branches, HEAD, and mo
|
|||||||
|
|
||||||
### Working Tree (component of repository)
|
### Working Tree (component of repository)
|
||||||
|
|
||||||
This is basically the directories and files in your repository. It is often referred to
|
This is basically the directories and files in your repository. It is often
|
||||||
as your working directory.
|
referred to as your working directory.
|
||||||
|
|
||||||
### Index (component of .git dir)
|
### Index (component of .git dir)
|
||||||
|
|
||||||
The Index is the staging area in git. It's basically a layer that separates your working tree
|
The Index is the staging area in git. It's basically a layer that separates your working tree
|
||||||
from the Git repository. This gives developers more power over what gets sent to the Git
|
from the Git repository. This gives developers more power over what gets sent
|
||||||
repository.
|
to the Git repository.
|
||||||
|
|
||||||
### Commit
|
### Commit
|
||||||
|
|
||||||
A git commit is a snapshot of a set of changes, or manipulations to your Working Tree.
|
A git commit is a snapshot of a set of changes, or manipulations to your Working
|
||||||
For example, if you added 5 files, and removed 2 others, these changes will be contained
|
Tree. For example, if you added 5 files, and removed 2 others, these changes
|
||||||
in a commit (or snapshot). This commit can then be pushed to other repositories, or not!
|
will be contained in a commit (or snapshot). This commit can then be pushed to
|
||||||
|
other repositories, or not!
|
||||||
|
|
||||||
### Branch
|
### Branch
|
||||||
|
|
||||||
A branch is essentially a pointer that points to the last commit you made. As you commit,
|
A branch is essentially a pointer to the last commit you made. As you go on
|
||||||
this pointer will automatically update and point to the latest commit.
|
committing, this pointer will automatically update to point the latest commit.
|
||||||
|
|
||||||
|
### Tag
|
||||||
|
|
||||||
|
A tag is a mark on specific point in history. Typically people use this
|
||||||
|
functionality to mark release points (v1.0, and so on)
|
||||||
|
|
||||||
### HEAD and head (component of .git dir)
|
### HEAD and head (component of .git dir)
|
||||||
|
|
||||||
HEAD is a pointer that points to the current branch. A repository only has 1 *active* HEAD.
|
HEAD is a pointer that points to the current branch. A repository only has 1 *active* HEAD.
|
||||||
head is a pointer that points to any commit. A repository can have any number of heads.
|
head is a pointer that points to any commit. A repository can have any number of heads.
|
||||||
|
|
||||||
###Stages of Git
|
### Stages of Git
|
||||||
* Modified - Changes have been made to a file but file has not been committed to Git Database yet
|
* Modified - Changes have been made to a file but file has not been committed to Git Database yet
|
||||||
* Staged - Marks a modified file to go into your next commit snapshot
|
* Staged - Marks a modified file to go into your next commit snapshot
|
||||||
* Committed - Files have been committed to the Git Database
|
* Committed - Files have been committed to the Git Database
|
||||||
@ -95,7 +104,7 @@ head is a pointer that points to any commit. A repository can have any number of
|
|||||||
|
|
||||||
### init
|
### init
|
||||||
|
|
||||||
Create an empty Git repository. The Git repository's settings, stored information,
|
Create an empty Git repository. The Git repository's settings, stored information,
|
||||||
and more is stored in a directory (a folder) named ".git".
|
and more is stored in a directory (a folder) named ".git".
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -104,15 +113,12 @@ $ git init
|
|||||||
|
|
||||||
### config
|
### config
|
||||||
|
|
||||||
To configure settings. Whether it be for the repository, the system itself, or global
|
To configure settings. Whether it be for the repository, the system itself,
|
||||||
configurations.
|
or global configurations ( global config file is `~/.gitconfig` ).
|
||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Print & Set Some Basic Config Variables (Global)
|
# Print & Set Some Basic Config Variables (Global)
|
||||||
$ git config --global user.email
|
|
||||||
$ 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"
|
||||||
```
|
```
|
||||||
@ -142,10 +148,20 @@ $ git commit --help
|
|||||||
$ git init --help
|
$ git init --help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### ignore files
|
||||||
|
|
||||||
|
To intentionally untrack file(s) & folder(s) from git. Typically meant for
|
||||||
|
private & temp files which would otherwise be shared in the repository.
|
||||||
|
```bash
|
||||||
|
$ echo "temp/" >> .gitignore
|
||||||
|
$ echo "private_key" >> .gitignore
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### status
|
### status
|
||||||
|
|
||||||
To show differences between the index file (basically your working copy/repo) and the current
|
To show differences between the index file (basically your working copy/repo)
|
||||||
HEAD commit.
|
and the current HEAD commit.
|
||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -172,7 +188,8 @@ $ git add /path/to/file/HelloWorld.c
|
|||||||
$ git add ./*.java
|
$ git add ./*.java
|
||||||
```
|
```
|
||||||
|
|
||||||
This only adds a file to the staging area/index, it doesn't commit it to the working directory/repo.
|
This only adds a file to the staging area/index, it doesn't commit it to the
|
||||||
|
working directory/repo.
|
||||||
|
|
||||||
### branch
|
### branch
|
||||||
|
|
||||||
@ -196,6 +213,28 @@ $ git branch -m myBranchName myNewBranchName
|
|||||||
$ git branch myBranchName --edit-description
|
$ git branch myBranchName --edit-description
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### tag
|
||||||
|
|
||||||
|
Manage your tags
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List tags
|
||||||
|
$ git tag
|
||||||
|
# Create a annotated tag
|
||||||
|
# The -m specifies a tagging message,which is stored with the tag.
|
||||||
|
# If you don’t specify a message for an annotated tag,
|
||||||
|
# Git launches your editor so you can type it in.
|
||||||
|
$ git tag -a v2.0 -m 'my version 2.0'
|
||||||
|
# Show info about tag
|
||||||
|
# That shows the tagger information, the date the commit was tagged,
|
||||||
|
# and the annotation message before showing the commit information.
|
||||||
|
$ git show v2.0
|
||||||
|
# Push a single tag to remote
|
||||||
|
$ git push origin v2.0
|
||||||
|
# Push a lot of tags to remote
|
||||||
|
$ git push origin --tags
|
||||||
|
```
|
||||||
|
|
||||||
### checkout
|
### checkout
|
||||||
|
|
||||||
Updates all files in the working tree to match the version in the index, or specified tree.
|
Updates all files in the working tree to match the version in the index, or specified tree.
|
||||||
@ -205,7 +244,8 @@ Updates all files in the working tree to match the version in the index, or spec
|
|||||||
$ git checkout
|
$ git checkout
|
||||||
# Checkout a specified branch
|
# Checkout a specified branch
|
||||||
$ git checkout branchName
|
$ git checkout branchName
|
||||||
# Create a new branch & switch to it, like: "git branch <name>; git checkout <name>"
|
# Create a new branch & switch to it
|
||||||
|
# equivalent to "git branch <name>; git checkout <name>"
|
||||||
$ git checkout -b newBranch
|
$ git checkout -b newBranch
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -218,6 +258,10 @@ to a remote branch.
|
|||||||
```bash
|
```bash
|
||||||
# Clone learnxinyminutes-docs
|
# Clone learnxinyminutes-docs
|
||||||
$ git clone https://github.com/adambard/learnxinyminutes-docs.git
|
$ git clone https://github.com/adambard/learnxinyminutes-docs.git
|
||||||
|
# shallow clone - faster cloning that pulls only latest snapshot
|
||||||
|
$ git clone --depth 1 https://github.com/adambard/learnxinyminutes-docs.git
|
||||||
|
# clone only a specific branch
|
||||||
|
$ git clone -b master-cn https://github.com/adambard/learnxinyminutes-docs.git --single-branch
|
||||||
```
|
```
|
||||||
|
|
||||||
### commit
|
### commit
|
||||||
@ -231,6 +275,9 @@ $ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
|
|||||||
|
|
||||||
# automatically stage modified or deleted files, except new files, and then commit
|
# automatically stage modified or deleted files, except new files, and then commit
|
||||||
$ git commit -a -m "Modified foo.php and removed bar.php"
|
$ git commit -a -m "Modified foo.php and removed bar.php"
|
||||||
|
|
||||||
|
# change last commit (this deletes previous commit with a fresh commit)
|
||||||
|
$ git commit --amend -m "Correct message"
|
||||||
```
|
```
|
||||||
|
|
||||||
### diff
|
### diff
|
||||||
@ -268,7 +315,7 @@ $ git config --global alias.g "grep --break --heading --line-number"
|
|||||||
$ git grep 'variableName' -- '*.java'
|
$ git grep 'variableName' -- '*.java'
|
||||||
|
|
||||||
# Search for a line that contains "arrayListName" and, "add" or "remove"
|
# Search for a line that contains "arrayListName" and, "add" or "remove"
|
||||||
$ git grep -e 'arrayListName' --and \( -e add -e remove \)
|
$ git grep -e 'arrayListName' --and \( -e add -e remove \)
|
||||||
```
|
```
|
||||||
|
|
||||||
Google is your friend; for more examples
|
Google is your friend; for more examples
|
||||||
@ -282,11 +329,14 @@ Display commits to the repository.
|
|||||||
# Show all commits
|
# Show all commits
|
||||||
$ git log
|
$ git log
|
||||||
|
|
||||||
# Show X number of commits
|
# Show only commit message & ref
|
||||||
$ git log -n 10
|
$ git log --oneline
|
||||||
|
|
||||||
# Show merge commits only
|
# Show merge commits only
|
||||||
$ git log --merges
|
$ git log --merges
|
||||||
|
|
||||||
|
# Show all commits represented by an ASCII graph
|
||||||
|
$ git log --graph
|
||||||
```
|
```
|
||||||
|
|
||||||
### merge
|
### merge
|
||||||
@ -303,7 +353,7 @@ $ git merge --no-ff branchName
|
|||||||
|
|
||||||
### mv
|
### mv
|
||||||
|
|
||||||
Rename or move a file
|
Rename or move a file
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Renaming a file
|
# Renaming a file
|
||||||
@ -325,9 +375,12 @@ Pulls from a repository and merges it with another branch.
|
|||||||
# Update your local repo, by merging in new changes
|
# Update your local repo, by merging in new changes
|
||||||
# from the remote "origin" and "master" branch.
|
# from the remote "origin" and "master" branch.
|
||||||
# git pull <remote> <branch>
|
# git pull <remote> <branch>
|
||||||
# git pull => implicitly defaults to => git pull origin master
|
|
||||||
$ git pull origin master
|
$ git pull origin master
|
||||||
|
|
||||||
|
# By default, git pull will update your current branch
|
||||||
|
# by merging in new changes from its remote-tracking branch
|
||||||
|
$ git pull
|
||||||
|
|
||||||
# Merge in changes from remote branch and rebase
|
# Merge in changes from remote branch and rebase
|
||||||
# branch commits onto your local repo, like: "git pull <remote> <branch>, git rebase <branch>"
|
# branch commits onto your local repo, like: "git pull <remote> <branch>, git rebase <branch>"
|
||||||
$ git pull origin master --rebase
|
$ git pull origin master --rebase
|
||||||
@ -338,32 +391,37 @@ $ git pull origin master --rebase
|
|||||||
Push and merge changes from a branch to a remote & branch.
|
Push and merge changes from a branch to a remote & branch.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Push and merge changes from a local repo to a
|
# Push and merge changes from a local repo to a
|
||||||
# remote named "origin" and "master" branch.
|
# remote named "origin" and "master" branch.
|
||||||
# git push <remote> <branch>
|
# git push <remote> <branch>
|
||||||
# git push => implicitly defaults to => git push origin master
|
|
||||||
$ git push origin master
|
$ git push origin master
|
||||||
|
|
||||||
|
# By default, git push will push and merge changes from
|
||||||
|
# the current branch to its remote-tracking branch
|
||||||
|
$ git push
|
||||||
|
|
||||||
# To link up current local branch with a remote branch, add -u flag:
|
# To link up current local branch with a remote branch, add -u flag:
|
||||||
$ git push -u origin master
|
$ git push -u origin master
|
||||||
# Now, anytime you want to push from that same local branch, use shortcut:
|
# Now, anytime you want to push from that same local branch, use shortcut:
|
||||||
$ git push
|
$ git push
|
||||||
```
|
```
|
||||||
|
|
||||||
### stash
|
### stash
|
||||||
|
|
||||||
Stashing takes the dirty state of your working directory and saves it on a stack of unfinished changes that you can reapply at any time.
|
Stashing takes the dirty state of your working directory and saves it on a stack
|
||||||
|
of unfinished changes that you can reapply at any time.
|
||||||
|
|
||||||
Let's say you've been doing some work in your git repo, but you want to pull from the remote.
|
Let's say you've been doing some work in your git repo, but you want to pull
|
||||||
Since you have dirty (uncommited) changes to some files, you are not able to run `git pull`.
|
from the remote. Since you have dirty (uncommited) changes to some files, you
|
||||||
Instead, you can run `git stash` to save your changes onto a stack!
|
are not able to run `git pull`. Instead, you can run `git stash` to save your
|
||||||
|
changes onto a stack!
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git stash
|
$ git stash
|
||||||
Saved working directory and index state \
|
Saved working directory and index state \
|
||||||
"WIP on master: 049d078 added the index file"
|
"WIP on master: 049d078 added the index file"
|
||||||
HEAD is now at 049d078 added the index file
|
HEAD is now at 049d078 added the index file
|
||||||
(To restore them type "git stash apply")
|
(To restore them type "git stash apply")
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you can pull!
|
Now you can pull!
|
||||||
@ -410,7 +468,7 @@ Now you're ready to get back to work on your stuff!
|
|||||||
|
|
||||||
[Additional Reading.](http://git-scm.com/book/en/v1/Git-Tools-Stashing)
|
[Additional Reading.](http://git-scm.com/book/en/v1/Git-Tools-Stashing)
|
||||||
|
|
||||||
### rebase (caution)
|
### rebase (caution)
|
||||||
|
|
||||||
Take all changes that were committed on one branch, and replay them onto another branch.
|
Take all changes that were committed on one branch, and replay them onto another branch.
|
||||||
*Do not rebase commits that you have pushed to a public repo*.
|
*Do not rebase commits that you have pushed to a public repo*.
|
||||||
@ -445,6 +503,16 @@ $ git reset 31f2bb1
|
|||||||
# after the specified commit).
|
# after the specified commit).
|
||||||
$ git reset --hard 31f2bb1
|
$ git reset --hard 31f2bb1
|
||||||
```
|
```
|
||||||
|
### revert
|
||||||
|
|
||||||
|
Revert can be used to undo a commit. It should not be confused with reset which restores
|
||||||
|
the state of a project to a previous point. Revert will add a new commit which is the
|
||||||
|
inverse of the specified commit, thus reverting it.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Revert a specified commit
|
||||||
|
$ git revert <commit>
|
||||||
|
```
|
||||||
|
|
||||||
### rm
|
### rm
|
||||||
|
|
||||||
@ -464,6 +532,8 @@ $ git rm /pather/to/the/file/HelloWorld.c
|
|||||||
|
|
||||||
* [Udemy Git Tutorial: A Comprehensive Guide](https://blog.udemy.com/git-tutorial-a-comprehensive-guide/)
|
* [Udemy Git Tutorial: A Comprehensive Guide](https://blog.udemy.com/git-tutorial-a-comprehensive-guide/)
|
||||||
|
|
||||||
|
* [Git Immersion - A Guided tour that walks through the fundamentals of git](http://gitimmersion.com/)
|
||||||
|
|
||||||
* [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)
|
||||||
@ -477,3 +547,6 @@ $ git rm /pather/to/the/file/HelloWorld.c
|
|||||||
* [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html)
|
* [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html)
|
||||||
|
|
||||||
* [Pro Git](http://www.git-scm.com/book/en/v2)
|
* [Pro Git](http://www.git-scm.com/book/en/v2)
|
||||||
|
|
||||||
|
* [An introduction to Git and GitHub for Beginners (Tutorial)](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners)
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ contributors:
|
|||||||
- ["Quint Guvernator", "https://github.com/qguv"]
|
- ["Quint Guvernator", "https://github.com/qguv"]
|
||||||
- ["Jose Donizetti", "https://github.com/josedonizetti"]
|
- ["Jose Donizetti", "https://github.com/josedonizetti"]
|
||||||
- ["Alexej Friesen", "https://github.com/heyalexej"]
|
- ["Alexej Friesen", "https://github.com/heyalexej"]
|
||||||
|
- ["Clayton Walker", "https://github.com/cwalk"]
|
||||||
---
|
---
|
||||||
|
|
||||||
Go was created out of the need to get work done. It's not the latest trend
|
Go was created out of the need to get work done. It's not the latest trend
|
||||||
@ -107,15 +108,16 @@ can include line breaks.` // Same string type.
|
|||||||
bs := []byte("a slice") // Type conversion syntax.
|
bs := []byte("a slice") // Type conversion syntax.
|
||||||
|
|
||||||
// Because they are dynamic, slices can be appended to on-demand.
|
// Because they are dynamic, slices can be appended to on-demand.
|
||||||
// To append elements to a slice, built-in append() function is used.
|
// To append elements to a slice, the built-in append() function is used.
|
||||||
// First argument is a slice to which we are appending. Commonly,
|
// First argument is a slice to which we are appending. Commonly,
|
||||||
// the array variable is updated in place, as in example below.
|
// the array variable is updated in place, as in example below.
|
||||||
s := []int{1, 2, 3} // Result is a slice of length 3.
|
s := []int{1, 2, 3} // Result is a slice of length 3.
|
||||||
s = append(s, 4, 5, 6) // Added 3 elements. Slice now has length of 6.
|
s = append(s, 4, 5, 6) // Added 3 elements. Slice now has length of 6.
|
||||||
fmt.Println(s) // Updated slice is now [1 2 3 4 5 6]
|
fmt.Println(s) // Updated slice is now [1 2 3 4 5 6]
|
||||||
|
|
||||||
// To append another slice, instead of list of atomic elements we can
|
// To append another slice, instead of list of atomic elements we can
|
||||||
// pass a reference to a slice or a slice literal like this, with a
|
// pass a reference to a slice or a slice literal like this, with a
|
||||||
// trailing elipsis, meaning take a slice and unpack its elements,
|
// trailing ellipsis, meaning take a slice and unpack its elements,
|
||||||
// appending them to slice s.
|
// appending them to slice s.
|
||||||
s = append(s, []int{7, 8, 9}...) // Second argument is a slice literal.
|
s = append(s, []int{7, 8, 9}...) // Second argument is a slice literal.
|
||||||
fmt.Println(s) // Updated slice is now [1 2 3 4 5 6 7 8 9]
|
fmt.Println(s) // Updated slice is now [1 2 3 4 5 6 7 8 9]
|
||||||
@ -129,7 +131,7 @@ can include line breaks.` // Same string type.
|
|||||||
m["one"] = 1
|
m["one"] = 1
|
||||||
|
|
||||||
// Unused variables are an error in Go.
|
// Unused variables are an error in Go.
|
||||||
// The underbar lets you "use" a variable but discard its value.
|
// The underscore lets you "use" a variable but discard its value.
|
||||||
_, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs
|
_, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs
|
||||||
// Output of course counts as using a variable.
|
// Output of course counts as using a variable.
|
||||||
fmt.Println(s, c, a4, s3, d2, m)
|
fmt.Println(s, c, a4, s3, d2, m)
|
||||||
@ -164,7 +166,7 @@ func expensiveComputation() float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func learnFlowControl() {
|
func learnFlowControl() {
|
||||||
// If statements require brace brackets, and do not require parens.
|
// If statements require brace brackets, and do not require parentheses.
|
||||||
if true {
|
if true {
|
||||||
fmt.Println("told ya")
|
fmt.Println("told ya")
|
||||||
}
|
}
|
||||||
@ -407,6 +409,8 @@ func requestServer() {
|
|||||||
|
|
||||||
The root of all things Go is the [official Go web site](http://golang.org/).
|
The root of all things Go is the [official Go web site](http://golang.org/).
|
||||||
There you can follow the tutorial, play interactively, and read lots.
|
There you can follow the tutorial, play interactively, and read lots.
|
||||||
|
Aside from a tour, [the docs](https://golang.org/doc/) contain information on
|
||||||
|
how to write clean and effective Go code, package and command docs, and release history.
|
||||||
|
|
||||||
The language definition itself is highly recommended. It's easy to read
|
The language definition itself is highly recommended. It's easy to read
|
||||||
and amazingly short (as language definitions go these days.)
|
and amazingly short (as language definitions go these days.)
|
||||||
@ -420,3 +424,5 @@ idioms. Or you can click on a function name in [the
|
|||||||
documentation](http://golang.org/pkg/) and the source code comes up!
|
documentation](http://golang.org/pkg/) and the source code comes up!
|
||||||
|
|
||||||
Another great resource to learn Go is [Go by example](https://gobyexample.com/).
|
Another great resource to learn Go is [Go by example](https://gobyexample.com/).
|
||||||
|
|
||||||
|
Go Mobile adds support for mobile platforms (Android and iOS). You can write all-Go native mobile apps or write a library that contains bindings from a Go package, which can be invoked via Java (Android) and Objective-C (iOS). Check out the [Go Mobile page](https://github.com/golang/go/wiki/Mobile) for more information.
|
||||||
|
@ -99,7 +99,7 @@ technologies.sort()
|
|||||||
// To sort without mutating original, you can do:
|
// To sort without mutating original, you can do:
|
||||||
sortedTechnologies = technologies.sort( false )
|
sortedTechnologies = technologies.sort( false )
|
||||||
|
|
||||||
/*** Manipulating Lists ***/
|
/*** Manipulating Lists ***/e
|
||||||
|
|
||||||
//Replace all elements in the list
|
//Replace all elements in the list
|
||||||
Collections.replaceAll(technologies, 'Gradle', 'gradle')
|
Collections.replaceAll(technologies, 'Gradle', 'gradle')
|
||||||
@ -200,6 +200,14 @@ def y = 10
|
|||||||
def x = (y > 1) ? "worked" : "failed"
|
def x = (y > 1) ? "worked" : "failed"
|
||||||
assert x == "worked"
|
assert x == "worked"
|
||||||
|
|
||||||
|
//Groovy supports 'The Elvis Operator' too!
|
||||||
|
//Instead of using the ternary operator:
|
||||||
|
|
||||||
|
displayName = user.name ? user.name : 'Anonymous'
|
||||||
|
|
||||||
|
//We can write it:
|
||||||
|
displayName = user.name ?: 'Anonymous'
|
||||||
|
|
||||||
//For loop
|
//For loop
|
||||||
//Iterate over a range
|
//Iterate over a range
|
||||||
def x = 0
|
def x = 0
|
||||||
@ -422,6 +430,3 @@ Join a [Groovy user group](http://www.groovy-lang.org/usergroups.html)
|
|||||||
[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/
|
[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/
|
||||||
[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize
|
[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize
|
||||||
[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html
|
[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
language: Hack
|
language: Hack
|
||||||
contributors:
|
contributors:
|
||||||
- ["Stephen Holdaway", "https://github.com/stecman"]
|
- ["Stephen Holdaway", "https://github.com/stecman"]
|
||||||
|
- ["David Lima", "https://github.com/davelima"]
|
||||||
filename: learnhack.hh
|
filename: learnhack.hh
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ function identity(?string $stringOrNull) : ?string
|
|||||||
class TypeHintedProperties
|
class TypeHintedProperties
|
||||||
{
|
{
|
||||||
public ?string $name;
|
public ?string $name;
|
||||||
|
|
||||||
protected int $id;
|
protected int $id;
|
||||||
|
|
||||||
private float $score = 100.0;
|
private float $score = 100.0;
|
||||||
@ -90,7 +91,7 @@ function openBox(Box<int> $box) : int
|
|||||||
|
|
||||||
|
|
||||||
// Shapes
|
// Shapes
|
||||||
//
|
//
|
||||||
// Hack adds the concept of shapes for defining struct-like arrays with a
|
// Hack adds the concept of shapes for defining struct-like arrays with a
|
||||||
// guaranteed, type-checked set of keys
|
// guaranteed, type-checked set of keys
|
||||||
type Point2D = shape('x' => int, 'y' => int);
|
type Point2D = shape('x' => int, 'y' => int);
|
||||||
@ -107,7 +108,7 @@ distance(
|
|||||||
|
|
||||||
|
|
||||||
// Type aliasing
|
// Type aliasing
|
||||||
//
|
//
|
||||||
// Hack adds a bunch of type aliasing features for making complex types readable
|
// Hack adds a bunch of type aliasing features for making complex types readable
|
||||||
newtype VectorArray = array<int, Vector<int>>;
|
newtype VectorArray = array<int, Vector<int>>;
|
||||||
|
|
||||||
@ -141,7 +142,7 @@ function getRoadType() : RoadType
|
|||||||
|
|
||||||
|
|
||||||
// Constructor argument promotion
|
// Constructor argument promotion
|
||||||
//
|
//
|
||||||
// To avoid boilerplate property and constructor definitions that only set
|
// To avoid boilerplate property and constructor definitions that only set
|
||||||
// properties, Hack adds a concise syntax for defining properties and a
|
// properties, Hack adds a concise syntax for defining properties and a
|
||||||
// constructor at the same time.
|
// constructor at the same time.
|
||||||
@ -152,7 +153,7 @@ class ArgumentPromotion
|
|||||||
private bool $isAwesome) {}
|
private bool $isAwesome) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WithoutArugmentPromotion
|
class WithoutArgumentPromotion
|
||||||
{
|
{
|
||||||
public string $name;
|
public string $name;
|
||||||
|
|
||||||
@ -169,13 +170,13 @@ class WithoutArugmentPromotion
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Co-oprerative multi-tasking
|
// Co-operative multi-tasking
|
||||||
//
|
//
|
||||||
// Two new keywords "async" and "await" can be used to perform mutli-tasking
|
// Two new keywords "async" and "await" can be used to perform multi-tasking
|
||||||
// Note that this does not involve threads - it just allows transfer of control
|
// Note that this does not involve threads - it just allows transfer of control
|
||||||
async function cooperativePrint(int $start, int $end) : Awaitable<void>
|
async function cooperativePrint(int $start, int $end) : Awaitable<void>
|
||||||
{
|
{
|
||||||
for ($i = $start; $i <= $end; $i++) {
|
for ($i = $start; $i <= $end; $i++) {
|
||||||
echo "$i ";
|
echo "$i ";
|
||||||
|
|
||||||
// Give other tasks a chance to do something
|
// Give other tasks a chance to do something
|
||||||
@ -192,9 +193,9 @@ AwaitAllWaitHandle::fromArray([
|
|||||||
|
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
//
|
//
|
||||||
// Attributes are a form of metadata for functions. Hack provides some
|
// Attributes are a form of metadata for functions. Hack provides some
|
||||||
// special built-in attributes that introduce useful behaviour.
|
// special built-in attributes that introduce useful behaviour.
|
||||||
|
|
||||||
// The __Memoize special attribute causes the result of a function to be cached
|
// The __Memoize special attribute causes the result of a function to be cached
|
||||||
<<__Memoize>>
|
<<__Memoize>>
|
||||||
@ -247,7 +248,7 @@ class ConsistentBar extends ConsistentFoo
|
|||||||
class InvalidFooSubclass extends ConsistentFoo
|
class InvalidFooSubclass extends ConsistentFoo
|
||||||
{
|
{
|
||||||
// Not matching the parent constructor will cause a type checker error:
|
// Not matching the parent constructor will cause a type checker error:
|
||||||
//
|
//
|
||||||
// "This object is of type ConsistentBaz. It is incompatible with this object
|
// "This object is of type ConsistentBaz. It is incompatible with this object
|
||||||
// of type ConsistentFoo because some of their methods are incompatible"
|
// of type ConsistentFoo because some of their methods are incompatible"
|
||||||
//
|
//
|
||||||
@ -258,7 +259,7 @@ class InvalidFooSubclass extends ConsistentFoo
|
|||||||
|
|
||||||
// Using the __Override annotation on a non-overriden method will cause a
|
// Using the __Override annotation on a non-overriden method will cause a
|
||||||
// type checker error:
|
// type checker error:
|
||||||
//
|
//
|
||||||
// "InvalidFooSubclass::otherMethod() is marked as override; no non-private
|
// "InvalidFooSubclass::otherMethod() is marked as override; no non-private
|
||||||
// parent definition found or overridden parent is defined in non-<?hh code"
|
// parent definition found or overridden parent is defined in non-<?hh code"
|
||||||
//
|
//
|
||||||
|
@ -62,11 +62,11 @@ $ haml input_file.haml output_file.html
|
|||||||
%h1 Headline copy
|
%h1 Headline copy
|
||||||
|
|
||||||
/ To write multiline content, nest it instead
|
/ To write multiline content, nest it instead
|
||||||
%p
|
%p
|
||||||
This is a lot of content that we could probably split onto two
|
This is a lot of content that we could probably split onto two
|
||||||
separate lines.
|
separate lines.
|
||||||
|
|
||||||
/
|
/
|
||||||
You can escape html by using the ampersand and equals sign ( &= ). This
|
You can escape html by using the ampersand and equals sign ( &= ). This
|
||||||
converts html-sensitive characters (&, /, :) into their html encoded
|
converts html-sensitive characters (&, /, :) into their html encoded
|
||||||
equivalents. For example
|
equivalents. For example
|
||||||
@ -102,7 +102,7 @@ $ haml input_file.haml output_file.html
|
|||||||
/ Inserting Ruby
|
/ Inserting Ruby
|
||||||
/ -------------------------------------------
|
/ -------------------------------------------
|
||||||
|
|
||||||
/
|
/
|
||||||
To output a Ruby value as the contents of a tag, use an equals sign followed
|
To output a Ruby value as the contents of a tag, use an equals sign followed
|
||||||
by the Ruby code
|
by the Ruby code
|
||||||
|
|
||||||
@ -122,11 +122,36 @@ $ haml input_file.haml output_file.html
|
|||||||
|
|
||||||
if book do
|
if book do
|
||||||
%p This is a book
|
%p This is a book
|
||||||
|
|
||||||
|
/ Adding ordered / unordered list
|
||||||
|
%ul
|
||||||
|
%li
|
||||||
|
=item1
|
||||||
|
=item2
|
||||||
|
|
||||||
/
|
/
|
||||||
Again, no need to add the closing tags to the block, even for the Ruby.
|
Again, no need to add the closing tags to the block, even for the Ruby.
|
||||||
Indentation will take care of that for you.
|
Indentation will take care of that for you.
|
||||||
|
|
||||||
|
/ -------------------------------------------
|
||||||
|
/ Inserting Table with bootstrap classes
|
||||||
|
/ -------------------------------------------
|
||||||
|
|
||||||
|
%table.table.table-hover
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th Header 1
|
||||||
|
%th Header 2
|
||||||
|
|
||||||
|
%tr
|
||||||
|
%td Value1
|
||||||
|
%td value2
|
||||||
|
|
||||||
|
%tfoot
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
Foot value
|
||||||
|
|
||||||
|
|
||||||
/ -------------------------------------------
|
/ -------------------------------------------
|
||||||
/ Inline Ruby / Ruby interpolation
|
/ Inline Ruby / Ruby interpolation
|
||||||
@ -141,7 +166,7 @@ $ haml input_file.haml output_file.html
|
|||||||
/ -------------------------------------------
|
/ -------------------------------------------
|
||||||
|
|
||||||
/
|
/
|
||||||
Use the colon to define Haml filters, one example of a filter you can
|
Use the colon to define Haml filters, one example of a filter you can
|
||||||
use is :javascript, which can be used for writing inline js
|
use is :javascript, which can be used for writing inline js
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
|
@ -81,7 +81,7 @@ not False -- True
|
|||||||
[5,4..1] -- [5, 4, 3, 2, 1]
|
[5,4..1] -- [5, 4, 3, 2, 1]
|
||||||
|
|
||||||
-- indexing into a list
|
-- indexing into a list
|
||||||
[0..] !! 5 -- 5
|
[1..10] !! 3 -- 4
|
||||||
|
|
||||||
-- You can also have infinite lists in Haskell!
|
-- You can also have infinite lists in Haskell!
|
||||||
[1..] -- a list of all the natural numbers
|
[1..] -- a list of all the natural numbers
|
||||||
@ -195,11 +195,11 @@ foo 5 -- 15
|
|||||||
-- function composition
|
-- function composition
|
||||||
-- the (.) function chains functions together.
|
-- the (.) function chains functions together.
|
||||||
-- For example, here foo is a function that takes a value. It adds 10 to it,
|
-- For example, here foo is a function that takes a value. It adds 10 to it,
|
||||||
-- multiplies the result of that by 5, and then returns the final value.
|
-- multiplies the result of that by 4, and then returns the final value.
|
||||||
foo = (*5) . (+10)
|
foo = (*4) . (+10)
|
||||||
|
|
||||||
-- (5 + 10) * 5 = 75
|
-- (5 + 10) * 4 = 60
|
||||||
foo 5 -- 75
|
foo 5 -- 60
|
||||||
|
|
||||||
-- fixing precedence
|
-- fixing precedence
|
||||||
-- Haskell has another operator called `$`. This operator applies a function
|
-- Haskell has another operator called `$`. This operator applies a function
|
||||||
@ -426,7 +426,7 @@ qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
|
|||||||
greater = filter (>= p) xs
|
greater = filter (>= p) xs
|
||||||
```
|
```
|
||||||
|
|
||||||
Haskell is easy to install. Get it [here](http://www.haskell.org/platform/).
|
There are two popular ways to install Haskell: The traditional [Cabal-based installation](http://www.haskell.org/platform/), and the newer [Stack-based process](https://www.stackage.org/install).
|
||||||
|
|
||||||
You can find a much gentler introduction from the excellent
|
You can find a much gentler introduction from the excellent
|
||||||
[Learn you a Haskell](http://learnyouahaskell.com/) or
|
[Learn you a Haskell](http://learnyouahaskell.com/) or
|
||||||
|
107
hu-hu/coffeescript-hu.html.markdown
Normal file
107
hu-hu/coffeescript-hu.html.markdown
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
---
|
||||||
|
language: coffeescript
|
||||||
|
contributors:
|
||||||
|
- ["Tenor Biel", "http://github.com/L8D"]
|
||||||
|
- ["Xavier Yao", "http://github.com/xavieryao"]
|
||||||
|
translators:
|
||||||
|
- ["Tamás Diószegi", "http://github.com/ditam"]
|
||||||
|
lang: hu-hu
|
||||||
|
filename: coffeescript-hu.coffee
|
||||||
|
---
|
||||||
|
|
||||||
|
A CoffeeScript egy apró nyelv ami egy-az-egyben egyenértékű Javascript kódra fordul, és így futásidőben már nem szükséges interpretálni.
|
||||||
|
Mint a JavaScript egyik követője, a CoffeeScript mindent megtesz azért, hogy olvasható, jól formázott és jól futó JavaScript kódot állítson elő, ami minden JavaScript futtatókörnyezetben jól működik.
|
||||||
|
|
||||||
|
Rézletekért lásd még a [CoffeeScript weboldalát](http://coffeescript.org/), ahol egy teljes CoffeScript tutorial is található.
|
||||||
|
|
||||||
|
```coffeescript
|
||||||
|
# A CoffeeScript egy hipszter nyelv.
|
||||||
|
# Követi több modern nyelv trendjeit.
|
||||||
|
# Így a kommentek, mint Ruby-ban és Python-ban, a szám szimbólummal kezdődnek.
|
||||||
|
|
||||||
|
###
|
||||||
|
A komment blokkok ilyenek, és közvetlenül '/ *' és '* /' jelekre fordítódnak
|
||||||
|
az eredményül kapott JavaScript kódban.
|
||||||
|
|
||||||
|
Mielőtt tovább olvasol, jobb, ha a JavaScript alapvető szemantikájával
|
||||||
|
tisztában vagy.
|
||||||
|
|
||||||
|
(A kód példák alatt kommentként látható a fordítás után kapott JavaScript kód.)
|
||||||
|
###
|
||||||
|
|
||||||
|
# Értékadás:
|
||||||
|
number = 42 #=> var number = 42;
|
||||||
|
opposite = true #=> var opposite = true;
|
||||||
|
|
||||||
|
# Feltételes utasítások:
|
||||||
|
number = -42 if opposite #=> if(opposite) { number = -42; }
|
||||||
|
|
||||||
|
# Függvények:
|
||||||
|
square = (x) -> x * x #=> var square = function(x) { return x * x; }
|
||||||
|
|
||||||
|
fill = (container, liquid = "coffee") ->
|
||||||
|
"Filling the #{container} with #{liquid}..."
|
||||||
|
#=>var fill;
|
||||||
|
#
|
||||||
|
#fill = function(container, liquid) {
|
||||||
|
# if (liquid == null) {
|
||||||
|
# liquid = "coffee";
|
||||||
|
# }
|
||||||
|
# return "Filling the " + container + " with " + liquid + "...";
|
||||||
|
#};
|
||||||
|
|
||||||
|
# Szám tartományok:
|
||||||
|
list = [1..5] #=> var list = [1, 2, 3, 4, 5];
|
||||||
|
|
||||||
|
# Objektumok:
|
||||||
|
math =
|
||||||
|
root: Math.sqrt
|
||||||
|
square: square
|
||||||
|
cube: (x) -> x * square x
|
||||||
|
#=> var math = {
|
||||||
|
# "root": Math.sqrt,
|
||||||
|
# "square": square,
|
||||||
|
# "cube": function(x) { return x * square(x); }
|
||||||
|
# };
|
||||||
|
|
||||||
|
# "Splat" jellegű függvény-paraméterek:
|
||||||
|
race = (winner, runners...) ->
|
||||||
|
print winner, runners
|
||||||
|
#=>race = function() {
|
||||||
|
# var runners, winner;
|
||||||
|
# winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
||||||
|
# return print(winner, runners);
|
||||||
|
# };
|
||||||
|
|
||||||
|
# Létezés-vizsgálat:
|
||||||
|
alert "I knew it!" if elvis?
|
||||||
|
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
|
||||||
|
|
||||||
|
# Tömb értelmezések: (array comprehensions)
|
||||||
|
cubes = (math.cube num for num in list)
|
||||||
|
#=>cubes = (function() {
|
||||||
|
# var _i, _len, _results;
|
||||||
|
# _results = [];
|
||||||
|
# for (_i = 0, _len = list.length; _i < _len; _i++) {
|
||||||
|
# num = list[_i];
|
||||||
|
# _results.push(math.cube(num));
|
||||||
|
# }
|
||||||
|
# return _results;
|
||||||
|
# })();
|
||||||
|
|
||||||
|
foods = ['broccoli', 'spinach', 'chocolate']
|
||||||
|
eat food for food in foods when food isnt 'chocolate'
|
||||||
|
#=>foods = ['broccoli', 'spinach', 'chocolate'];
|
||||||
|
#
|
||||||
|
#for (_k = 0, _len2 = foods.length; _k < _len2; _k++) {
|
||||||
|
# food = foods[_k];
|
||||||
|
# if (food !== 'chocolate') {
|
||||||
|
# eat(food);
|
||||||
|
# }
|
||||||
|
#}
|
||||||
|
```
|
||||||
|
|
||||||
|
## További források
|
||||||
|
|
||||||
|
- [Smooth CoffeeScript](http://autotelicum.github.io/Smooth-CoffeeScript/)
|
||||||
|
- [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read)
|
555
hu-hu/ruby-hu.html.markdown
Normal file
555
hu-hu/ruby-hu.html.markdown
Normal file
@ -0,0 +1,555 @@
|
|||||||
|
---
|
||||||
|
language: ruby
|
||||||
|
lang: hu-hu
|
||||||
|
filenev: learnruby.rb
|
||||||
|
contributors:
|
||||||
|
- ["David Underwood", "http://theflyingdeveloper.com"]
|
||||||
|
- ["Joel Walden", "http://joelwalden.net"]
|
||||||
|
- ["Luke Holder", "http://twitter.com/lukeholder"]
|
||||||
|
- ["Tristan Hume", "http://thume.ca/"]
|
||||||
|
- ["Nick LaMuro", "https://github.com/NickLaMuro"]
|
||||||
|
- ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
|
||||||
|
- ["Ariel Krakowski", "http://www.learneroo.com"]
|
||||||
|
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
|
||||||
|
- ["Levi Bostian", "https://github.com/levibostian"]
|
||||||
|
- ["Rahil Momin", "https://github.com/iamrahil"]
|
||||||
|
translators:
|
||||||
|
- ["Zsolt Prontvai", "https://github.com/prozsolt"]
|
||||||
|
---
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# Ez egy komment
|
||||||
|
|
||||||
|
=begin
|
||||||
|
Ez egy többsoros komment
|
||||||
|
Senki sem használja
|
||||||
|
Neked sem kellene
|
||||||
|
=end
|
||||||
|
|
||||||
|
# Először is: Minden objektum
|
||||||
|
|
||||||
|
# A számok objektumok
|
||||||
|
|
||||||
|
3.class #=> Fixnum
|
||||||
|
|
||||||
|
3.to_s #=> "3"
|
||||||
|
|
||||||
|
|
||||||
|
# Néhány alapvető számtani művelet
|
||||||
|
1 + 1 #=> 2
|
||||||
|
8 - 1 #=> 7
|
||||||
|
10 * 2 #=> 20
|
||||||
|
35 / 5 #=> 7
|
||||||
|
2**5 #=> 32
|
||||||
|
|
||||||
|
# A számtani művelet csak szintaktikus cukor
|
||||||
|
# az objektumon történő függvény hívásra
|
||||||
|
1.+(3) #=> 4
|
||||||
|
10.* 5 #=> 50
|
||||||
|
|
||||||
|
# A speciális értékek objektumok
|
||||||
|
nil # Nincs itt semmi látnivaló
|
||||||
|
true # igaz
|
||||||
|
false # hamis
|
||||||
|
|
||||||
|
nil.class #=> NilClass
|
||||||
|
true.class #=> TrueClass
|
||||||
|
false.class #=> FalseClass
|
||||||
|
|
||||||
|
# Egyenlőség
|
||||||
|
1 == 1 #=> true
|
||||||
|
2 == 1 #=> false
|
||||||
|
|
||||||
|
# Egyenlőtlenség
|
||||||
|
1 != 1 #=> false
|
||||||
|
2 != 1 #=> true
|
||||||
|
|
||||||
|
# A false-on kívül, nil az egyetlen hamis érték
|
||||||
|
|
||||||
|
!nil #=> true
|
||||||
|
!false #=> true
|
||||||
|
!0 #=> false
|
||||||
|
|
||||||
|
# Még több összehasonlítás
|
||||||
|
1 < 10 #=> true
|
||||||
|
1 > 10 #=> false
|
||||||
|
2 <= 2 #=> true
|
||||||
|
2 >= 2 #=> true
|
||||||
|
|
||||||
|
# Logikai operátorok
|
||||||
|
true && false #=> false
|
||||||
|
true || false #=> true
|
||||||
|
!true #=> false
|
||||||
|
|
||||||
|
# A logikai operátoroknak alternatív verziójuk is van sokkal kisebb
|
||||||
|
# precedenciával. Ezeket arra szánták, hogy több állítást összeláncoljanak
|
||||||
|
# amíg egyikük igaz vagy hamis értékkel nem tér vissza.
|
||||||
|
|
||||||
|
# `csinalj_valami_mast` csak akkor fut le, ha `csinalj_valamit` igaz értékkel
|
||||||
|
# tért vissza.
|
||||||
|
csinalj_valamit() and csinalj_valami_mast()
|
||||||
|
# `log_error` csak akkor fut le, ha `csinalj_valamit` hamis értékkel
|
||||||
|
# tért vissza.
|
||||||
|
csinalj_valamit() or log_error()
|
||||||
|
|
||||||
|
|
||||||
|
# A sztringek objektumok
|
||||||
|
|
||||||
|
'Én egy sztring vagyok'.class #=> String
|
||||||
|
"Én is egy sztring vagyok".class #=> String
|
||||||
|
|
||||||
|
helykitolto = 'interpolációt használhatok'
|
||||||
|
"Sztring #{helykitolto}, ha dupla időzőjelben van a sztringem"
|
||||||
|
#=> "Sztring interpolációt használhatok, ha dupla időzőjelben van a sztringem"
|
||||||
|
|
||||||
|
# A szimpla idézőjelet preferáljuk, ahol csak lehet,
|
||||||
|
# mert a dupla idézőjel extra számításokat végez.
|
||||||
|
|
||||||
|
# Kombinálhatunk sztringeket, de nem számokkal
|
||||||
|
'hello ' + 'world' #=> "hello world"
|
||||||
|
'hello ' + 3 #=> TypeError: can't convert Fixnum into String
|
||||||
|
'hello ' + 3.to_s #=> "hello 3"
|
||||||
|
|
||||||
|
# kiírás a kimenetre
|
||||||
|
puts "Írok"
|
||||||
|
|
||||||
|
# Változók
|
||||||
|
x = 25 #=> 25
|
||||||
|
x #=> 25
|
||||||
|
|
||||||
|
# Értékadás az adott értékkel tér vissza
|
||||||
|
# Ez azt jelenti, hogy használhatunk többszörös értékadást:
|
||||||
|
|
||||||
|
x = y = 10 #=> 10
|
||||||
|
x #=> 10
|
||||||
|
y #=> 10
|
||||||
|
|
||||||
|
# Konvencióból, snake_case változó neveket használj
|
||||||
|
snake_case = true
|
||||||
|
|
||||||
|
# Leíró változó neveket használj
|
||||||
|
ut_a_projekt_gyokerehez = '/jo/nev/'
|
||||||
|
ut = '/rossz/nev/'
|
||||||
|
|
||||||
|
# A szimbólumok (objektumok)
|
||||||
|
# A szimbólumok megváltoztathatatlan, újra felhasználható konstans,
|
||||||
|
# mely belsőleg egész számként reprezentált. Sokszor sztring helyett használják,
|
||||||
|
# hogy effektíven közvetítsünk konkrét, értelmes értékeket
|
||||||
|
|
||||||
|
:fuggoben.class #=> Symbol
|
||||||
|
|
||||||
|
statusz = :fuggoben
|
||||||
|
|
||||||
|
statusz == :fuggoben #=> true
|
||||||
|
|
||||||
|
statusz == 'fuggoben' #=> false
|
||||||
|
|
||||||
|
statusz == :jovahagyott #=> false
|
||||||
|
|
||||||
|
# Tömbök
|
||||||
|
|
||||||
|
# Ez egy tömb
|
||||||
|
tomb = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
|
||||||
|
|
||||||
|
# A tömmbök különböző tipusú dolgokat tartalmazhat
|
||||||
|
|
||||||
|
[1, 'hello', false] #=> [1, "hello", false]
|
||||||
|
|
||||||
|
# Tömbök indexelhetőek
|
||||||
|
# Az elejéről
|
||||||
|
tomb[0] #=> 1
|
||||||
|
tomb[12] #=> nil
|
||||||
|
|
||||||
|
# Akárcsak a számtani műveletek [var] hozzáférés
|
||||||
|
# is csak szintaktikus cukor
|
||||||
|
# a [] függvény hívására az objektumon
|
||||||
|
tomb.[] 0 #=> 1
|
||||||
|
tomb.[] 12 #=> nil
|
||||||
|
|
||||||
|
# A végéről
|
||||||
|
tomb[-1] #=> 5
|
||||||
|
|
||||||
|
# Kezdőértékkel és hosszal
|
||||||
|
tomb[2, 3] #=> [3, 4, 5]
|
||||||
|
|
||||||
|
# Tömb megfordítása
|
||||||
|
a=[1,2,3]
|
||||||
|
a.reverse! #=> [3,2,1]
|
||||||
|
|
||||||
|
# Vagy tartománnyal
|
||||||
|
tomb[1..3] #=> [2, 3, 4]
|
||||||
|
|
||||||
|
# Így adhatunk a tömbhöz
|
||||||
|
tomb << 6 #=> [1, 2, 3, 4, 5, 6]
|
||||||
|
# Vagy így
|
||||||
|
tomb.push(6) #=> [1, 2, 3, 4, 5, 6]
|
||||||
|
|
||||||
|
# Ellenőrízük, hogy a tömb tartalmaz egy elemet
|
||||||
|
tomb.include?(1) #=> true
|
||||||
|
|
||||||
|
# Hash-ek a ruby elsődleges szótárjai kulcs/érték párokkal
|
||||||
|
# Hash-eket kapcsos zárójellel jelöljük
|
||||||
|
hash = { 'szin' => 'zold', 'szam' => 5 }
|
||||||
|
|
||||||
|
hash.keys #=> ['szin', 'szam']
|
||||||
|
|
||||||
|
# Hash-ekben könnyen kreshetünk a kulcs segítségével:
|
||||||
|
hash['szin'] #=> 'zold'
|
||||||
|
hash['szam'] #=> 5
|
||||||
|
|
||||||
|
# Nem létező kulcsra keresve nil-t kapunk:
|
||||||
|
hash['nincs itt semmi'] #=> nil
|
||||||
|
|
||||||
|
# Ruby 1.9-től, egy külnleges szintaxist is használhatunk a szimbólumot
|
||||||
|
# használunk kulcsnak
|
||||||
|
|
||||||
|
uj_hash = { defcon: 3, action: true }
|
||||||
|
|
||||||
|
uj_hash.keys #=> [:defcon, :action]
|
||||||
|
|
||||||
|
# Ellenőrizzük, hogy az adott kulcs és érték bene-e van a hash-ben
|
||||||
|
uj_hash.has_key?(:defcon) #=> true
|
||||||
|
uj_hash.has_value?(3) #=> true
|
||||||
|
|
||||||
|
# Tip: A tömbök és hash-ek is felsorolhatóak
|
||||||
|
# Sok közös függvényük van, akár az each, map, count, és több
|
||||||
|
|
||||||
|
# Kontroll Struktúrák
|
||||||
|
|
||||||
|
if true
|
||||||
|
'ha állítás'
|
||||||
|
elsif false
|
||||||
|
'különben ha, opcionális'
|
||||||
|
else
|
||||||
|
'különben, szintén opcionális'
|
||||||
|
end
|
||||||
|
|
||||||
|
for szamlalo in 1..5
|
||||||
|
puts "iteracio #{szamlalo}"
|
||||||
|
end
|
||||||
|
#=> iteracio 1
|
||||||
|
#=> iteracio 2
|
||||||
|
#=> iteracio 3
|
||||||
|
#=> iteracio 4
|
||||||
|
#=> iteracio 5
|
||||||
|
|
||||||
|
# HOWEVER, No-one uses for loops.
|
||||||
|
# Instead you should use the "each" method and pass it a block.
|
||||||
|
# A block is a bunch of code that you can pass to a method like "each".
|
||||||
|
# It is analogous to lambdas, anonymous functions or closures in other
|
||||||
|
# programming languages.
|
||||||
|
#
|
||||||
|
# The "each" method of a range runs the block once for each element of the range.
|
||||||
|
# The block is passed a counter as a parameter.
|
||||||
|
# Calling the "each" method with a block looks like this:
|
||||||
|
|
||||||
|
(1..5).each do |counter|
|
||||||
|
puts "iteration #{counter}"
|
||||||
|
end
|
||||||
|
#=> iteration 1
|
||||||
|
#=> iteration 2
|
||||||
|
#=> iteration 3
|
||||||
|
#=> iteration 4
|
||||||
|
#=> iteration 5
|
||||||
|
|
||||||
|
# You can also surround blocks in curly brackets:
|
||||||
|
(1..5).each { |counter| puts "iteration #{counter}" }
|
||||||
|
|
||||||
|
# The contents of data structures can also be iterated using each.
|
||||||
|
array.each do |element|
|
||||||
|
puts "#{element} is part of the array"
|
||||||
|
end
|
||||||
|
hash.each do |key, value|
|
||||||
|
puts "#{key} is #{value}"
|
||||||
|
end
|
||||||
|
|
||||||
|
counter = 1
|
||||||
|
while counter <= 5 do
|
||||||
|
puts "iteration #{counter}"
|
||||||
|
counter += 1
|
||||||
|
end
|
||||||
|
#=> iteration 1
|
||||||
|
#=> iteration 2
|
||||||
|
#=> iteration 3
|
||||||
|
#=> iteration 4
|
||||||
|
#=> iteration 5
|
||||||
|
|
||||||
|
jegy = '4'
|
||||||
|
|
||||||
|
case jegy
|
||||||
|
when '5'
|
||||||
|
puts 'Kitünő'
|
||||||
|
when '4'
|
||||||
|
puts 'Jó'
|
||||||
|
when '3'
|
||||||
|
puts 'Közepes'
|
||||||
|
when '2'
|
||||||
|
puts 'Elégsége'
|
||||||
|
when '1'
|
||||||
|
puts 'Elégtelen'
|
||||||
|
else
|
||||||
|
puts 'Alternatív értékelés, hm?'
|
||||||
|
end
|
||||||
|
#=> "Jó"
|
||||||
|
|
||||||
|
# case-ek tartományokat is használhatnak
|
||||||
|
jegy = 82
|
||||||
|
case jegy
|
||||||
|
when 90..100
|
||||||
|
puts 'Hurrá!'
|
||||||
|
when 80...90
|
||||||
|
puts 'Jó munka'
|
||||||
|
else
|
||||||
|
puts 'Megbuktál!'
|
||||||
|
end
|
||||||
|
#=> "Jó munka"
|
||||||
|
|
||||||
|
# kivétel kezelés:
|
||||||
|
begin
|
||||||
|
# kód ami kivételt dobhat
|
||||||
|
raise NoMemoryError, 'Megtelt a memória'
|
||||||
|
rescue NoMemoryError => kivetel_valtozo
|
||||||
|
puts 'NoMemoryError-t dobott', kivetel_valtozo
|
||||||
|
rescue RuntimeError => mas_kivetel_valtozo
|
||||||
|
puts 'RuntimeError dobott most'
|
||||||
|
else
|
||||||
|
puts 'Ez akkor fut ha nem dob kivételt'
|
||||||
|
ensure
|
||||||
|
puts 'Ez a kód mindenképpen lefut'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Függvények
|
||||||
|
|
||||||
|
def ketszeres(x)
|
||||||
|
x * 2
|
||||||
|
end
|
||||||
|
|
||||||
|
# Függvények (és egyébb blokkok) implicit viszatértnek az utolsó értékkel
|
||||||
|
ketszeres(2) #=> 4
|
||||||
|
|
||||||
|
# Zárójelezés opcionális, ha az eredmény félreérthetetlen
|
||||||
|
ketszeres 3 #=> 6
|
||||||
|
|
||||||
|
ketszeres ketszeres 3 #=> 12
|
||||||
|
|
||||||
|
def osszeg(x, y)
|
||||||
|
x + y
|
||||||
|
end
|
||||||
|
|
||||||
|
# Függvény argumentumait vesszővel választjuk el.
|
||||||
|
osszeg 3, 4 #=> 7
|
||||||
|
|
||||||
|
osszeg osszeg(3, 4), 5 #=> 12
|
||||||
|
|
||||||
|
# yield
|
||||||
|
# Minden függvénynek van egy implicit, opcionális block paramétere
|
||||||
|
# 'yield' kulcsszóval hívhatjuk
|
||||||
|
|
||||||
|
def korulvesz
|
||||||
|
puts '{'
|
||||||
|
yield
|
||||||
|
puts '}'
|
||||||
|
end
|
||||||
|
|
||||||
|
korulvesz { puts 'hello world' }
|
||||||
|
|
||||||
|
# {
|
||||||
|
# hello world
|
||||||
|
# }
|
||||||
|
|
||||||
|
|
||||||
|
# Fuggvénynek átadhatunk blokkot
|
||||||
|
# "&" jelöli az átadott blokk referenciáját
|
||||||
|
def vendegek(&block)
|
||||||
|
block.call 'valami_argumentum'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Argumentum lisát is átadhatunk, ami tömbé lesz konvertálva
|
||||||
|
# Erre való a splat operátor ("*")
|
||||||
|
def vendegek(*array)
|
||||||
|
array.each { |vendeg| puts vendeg }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Osztályt a class kulcsszóval definiálhatunk
|
||||||
|
class Ember
|
||||||
|
|
||||||
|
# Az osztály változó. Az osztály minden példánnyával megvan osztva
|
||||||
|
@@faj = 'H. sapiens'
|
||||||
|
|
||||||
|
# Alap inicializáló
|
||||||
|
def initialize(nev, kor = 0)
|
||||||
|
# Hozzárendeli az argumentumot a "nev" példány változóhoz
|
||||||
|
@nev = nev
|
||||||
|
# Ha nem adtunk meg kort akkor az alapértemezet értéket fogja használni
|
||||||
|
@kor = kor
|
||||||
|
end
|
||||||
|
|
||||||
|
# Alap setter függvény
|
||||||
|
def nev=(nev)
|
||||||
|
@nev = nev
|
||||||
|
end
|
||||||
|
|
||||||
|
# Alap getter függvény
|
||||||
|
def nev
|
||||||
|
@nev
|
||||||
|
end
|
||||||
|
|
||||||
|
# A fönti funkcionalítást az attr_accessor függvénnyel is elérhetjük
|
||||||
|
attr_accessor :nev
|
||||||
|
|
||||||
|
# Getter/setter függvények egyenként is kreálhatóak
|
||||||
|
attr_reader :nev
|
||||||
|
attr_writer :nev
|
||||||
|
|
||||||
|
# Az osztály függvények "self"-et hasznalnak, hogy megkülönböztessék magukat a
|
||||||
|
# példány függvényektől
|
||||||
|
# Az osztályn hívhatóak, nem a példányon
|
||||||
|
def self.mond(uzenet)
|
||||||
|
puts uzenet
|
||||||
|
end
|
||||||
|
|
||||||
|
def faj
|
||||||
|
@@faj
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Példányosítsuk az osztályt
|
||||||
|
jim = Ember.new('Jim Halpert')
|
||||||
|
|
||||||
|
dwight = Ember.new('Dwight K. Schrute')
|
||||||
|
|
||||||
|
# Hívjunk meg pár függvényt
|
||||||
|
jim.faj #=> "H. sapiens"
|
||||||
|
jim.nev #=> "Jim Halpert"
|
||||||
|
jim.nev = "Jim Halpert II" #=> "Jim Halpert II"
|
||||||
|
jim.nev #=> "Jim Halpert II"
|
||||||
|
dwight.faj #=> "H. sapiens"
|
||||||
|
dwight.nev #=> "Dwight K. Schrute"
|
||||||
|
|
||||||
|
# Hívjuk meg az osztály függvényt
|
||||||
|
Ember.mond('Hi') #=> "Hi"
|
||||||
|
|
||||||
|
# Változók szókjait az elnevezésük definiálja
|
||||||
|
# $ kezdetű változók globálisak
|
||||||
|
$var = "Én egy globális változó vagyok"
|
||||||
|
defined? $var #=> "global-variable"
|
||||||
|
|
||||||
|
# Változók amik @-al kezdődnek példány szkópjuk van
|
||||||
|
@var = "Én egy példány változó vagyok"
|
||||||
|
defined? @var #=> "instance-variable"
|
||||||
|
|
||||||
|
# Változók amik @@-al kezdődnek példány szkópjuk van
|
||||||
|
@@var = "Én egy osztály változó vagyok"
|
||||||
|
defined? @@var #=> "class variable"
|
||||||
|
|
||||||
|
# Változók amik nagy betűvel kezdődnek a konstansok
|
||||||
|
Var = "Konstans vagyok"
|
||||||
|
defined? Var #=> "constant"
|
||||||
|
|
||||||
|
# Az osztály is objetum. Tehát az osztálynak lehet példány változója
|
||||||
|
# Az osztályváltozón osztozik minden pédány és leszármazott
|
||||||
|
|
||||||
|
# Ős osztály
|
||||||
|
class Ember
|
||||||
|
@@foo = 0
|
||||||
|
|
||||||
|
def self.foo
|
||||||
|
@@foo
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.foo=(ertek)
|
||||||
|
@@foo = ertek
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Leszarmazott osztály
|
||||||
|
class Dolgozo < Ember
|
||||||
|
end
|
||||||
|
|
||||||
|
Ember.foo # 0
|
||||||
|
Dolgozo.foo # 0
|
||||||
|
|
||||||
|
Ember.foo = 2 # 2
|
||||||
|
Dolgozo.foo # 2
|
||||||
|
|
||||||
|
# Az osztálynak példány változóját nem látja az osztály leszármazottja.
|
||||||
|
|
||||||
|
class Ember
|
||||||
|
@bar = 0
|
||||||
|
|
||||||
|
def self.bar
|
||||||
|
@bar
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.bar=(ertek)
|
||||||
|
@bar = ertek
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Doctor < Ember
|
||||||
|
end
|
||||||
|
|
||||||
|
Ember.bar # 0
|
||||||
|
Doctor.bar # nil
|
||||||
|
|
||||||
|
module ModulePelda
|
||||||
|
def foo
|
||||||
|
'foo'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Modulok include-olása a fügvényeiket az osztály példányaihoz köti.
|
||||||
|
# Modulok extend-elésa a fügvényeiket magához az osztályhoz köti.
|
||||||
|
|
||||||
|
class Szemely
|
||||||
|
include ModulePelda
|
||||||
|
end
|
||||||
|
|
||||||
|
class Konyv
|
||||||
|
extend ModulePelda
|
||||||
|
end
|
||||||
|
|
||||||
|
Szemely.foo # => NoMethodError: undefined method `foo' for Szemely:Class
|
||||||
|
Szemely.new.foo # => 'foo'
|
||||||
|
Konyv.foo # => 'foo'
|
||||||
|
Konyv.new.foo # => NoMethodError: undefined method `foo'
|
||||||
|
|
||||||
|
# Callback-ek végrehajtódnak amikor include-olunk és extend-elünk egy modult
|
||||||
|
|
||||||
|
module ConcernPelda
|
||||||
|
def self.included(base)
|
||||||
|
base.extend(ClassMethods)
|
||||||
|
base.send(:include, InstanceMethods)
|
||||||
|
end
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
def bar
|
||||||
|
'bar'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module InstanceMethods
|
||||||
|
def qux
|
||||||
|
'qux'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Valami
|
||||||
|
include ConcernPelda
|
||||||
|
end
|
||||||
|
|
||||||
|
Valami.bar # => 'bar'
|
||||||
|
Valami.qux # => NoMethodError: undefined method `qux'
|
||||||
|
Valami.new.bar # => NoMethodError: undefined method `bar'
|
||||||
|
Valami.new.qux # => 'qux'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Egyéb források
|
||||||
|
|
||||||
|
- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338)
|
||||||
|
- [Official Documentation](http://www.ruby-doc.org/core-2.1.1/)
|
||||||
|
- [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/)
|
||||||
|
- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - A régebbi [ingyenes változat](http://ruby-doc.com/docs/ProgrammingRuby/) elérhető online.
|
||||||
|
- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide)
|
@ -1,10 +1,11 @@
|
|||||||
---
|
---
|
||||||
language: xml
|
language: xml
|
||||||
filename: learnxml.xml
|
filename: learnxml-id.xml
|
||||||
contributors:
|
contributors:
|
||||||
- ["João Farias", "https://github.com/JoaoGFarias"]
|
- ["João Farias", "https://github.com/JoaoGFarias"]
|
||||||
translators:
|
translators:
|
||||||
- ["Rizky Luthfianto", "https://github.com/rilut"]
|
- ["Rizky Luthfianto", "https://github.com/rilut"]
|
||||||
|
lang: id-id
|
||||||
---
|
---
|
||||||
|
|
||||||
XML adalah bahasa markup yang dirancang untuk menyimpan dan mengirim data.
|
XML adalah bahasa markup yang dirancang untuk menyimpan dan mengirim data.
|
||||||
|
@ -13,13 +13,14 @@ contributors:
|
|||||||
filename: LearnBash.sh
|
filename: LearnBash.sh
|
||||||
translators:
|
translators:
|
||||||
- ["Robert Margelli", "http://github.com/sinkswim/"]
|
- ["Robert Margelli", "http://github.com/sinkswim/"]
|
||||||
|
- ["Tommaso Pifferi", "http://github.com/neslinesli93/"]
|
||||||
lang: it-it
|
lang: it-it
|
||||||
---
|
---
|
||||||
|
|
||||||
Bash è il nome della shell di unix, la quale è stata distribuita anche come shell del sistema oprativo GNU e la shell di default su Linux e Mac OS X.
|
Bash è il nome della shell di unix, la quale è stata distribuita anche come shell del sistema oprativo GNU e la shell di default su Linux e Mac OS X.
|
||||||
Quasi tutti gli esempi sottostanti possono fare parte di uno shell script o eseguiti direttamente nella shell.
|
Quasi tutti gli esempi sottostanti possono fare parte di uno shell script o eseguiti direttamente nella shell.
|
||||||
|
|
||||||
[Per saperne di piu'.](http://www.gnu.org/software/bash/manual/bashref.html)
|
[Per saperne di più.](http://www.gnu.org/software/bash/manual/bashref.html)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
@ -34,32 +35,34 @@ echo Ciao mondo!
|
|||||||
echo 'Questa è la prima riga'; echo 'Questa è la seconda riga'
|
echo 'Questa è la prima riga'; echo 'Questa è la seconda riga'
|
||||||
|
|
||||||
# Per dichiarare una variabile:
|
# Per dichiarare una variabile:
|
||||||
VARIABILE="Una stringa"
|
Variabile="Una stringa"
|
||||||
|
|
||||||
# Ma non così:
|
# Ma non così:
|
||||||
VARIABILE = "Una stringa"
|
Variabile = "Una stringa"
|
||||||
# Bash stabilirà che VARIABILE è un comando da eseguire e darà un errore
|
# Bash stabilirà che Variabile è un comando da eseguire e darà un errore
|
||||||
# perchè non esiste.
|
# perchè non esiste.
|
||||||
|
|
||||||
# Usare la variabile:
|
# Usare la variabile:
|
||||||
echo $VARIABILE
|
echo $Variabile
|
||||||
echo "$VARIABILE"
|
echo "$Variabile"
|
||||||
echo '$VARIABILE'
|
echo '$Variabile'
|
||||||
# Quando usi la variabile stessa - assegnala, esportala, oppure — scrivi
|
# Quando usi la variabile stessa - assegnala, esportala, oppure — scrivi
|
||||||
# il suo nome senza $. Se vuoi usare il valore della variabile, devi usare $.
|
# il suo nome senza $. Se vuoi usare il valore della variabile, devi usare $.
|
||||||
# Nota che ' (singolo apice) non espande le variabili!
|
# Nota che ' (singolo apice) non espande le variabili!
|
||||||
|
|
||||||
# Sostituzione di stringhe nelle variabili
|
# Sostituzione di stringhe nelle variabili
|
||||||
echo ${VARIABILE/Una/A}
|
echo ${Variabile/Una/A}
|
||||||
# Questo sostituirà la prima occorrenza di "Una" con "La"
|
# Questo sostituirà la prima occorrenza di "Una" con "La"
|
||||||
|
|
||||||
# Sottostringa di una variabile
|
# Sottostringa di una variabile
|
||||||
echo ${VARIABILE:0:7}
|
Lunghezza=7
|
||||||
|
echo ${Variabile:0:Lunghezza}
|
||||||
# Questo ritornerà solamente i primi 7 caratteri
|
# Questo ritornerà solamente i primi 7 caratteri
|
||||||
|
|
||||||
# Valore di default per la variabile
|
# Valore di default per la variabile
|
||||||
echo ${FOO:-"ValoreDiDefaultSeFOOMancaOÈ Vuoto"}
|
echo ${Foo:-"ValoreDiDefaultSeFooMancaOppureÈVuoto"}
|
||||||
# Questo funziona per null (FOO=), stringa vuota (FOO=""), zero (FOO=0) ritorna 0
|
# Questo funziona per null (Foo=), stringa vuota (Foo=""), zero (Foo=0) ritorna 0
|
||||||
|
# Nota: viene ritornato il valore di default, il contenuto della variabile pero' non cambia.
|
||||||
|
|
||||||
# Variabili builtin:
|
# Variabili builtin:
|
||||||
# Ci sono delle variabili builtin molto utili, come
|
# Ci sono delle variabili builtin molto utili, come
|
||||||
@ -71,31 +74,40 @@ echo "Argomenti dello script separati in variabili distinte: $1 $2..."
|
|||||||
|
|
||||||
# Leggere un valore di input:
|
# Leggere un valore di input:
|
||||||
echo "Come ti chiami?"
|
echo "Come ti chiami?"
|
||||||
read NOME # Nota che non abbiamo dovuto dichiarare una nuova variabile
|
read Nome # Nota che non abbiamo dovuto dichiarare una nuova variabile
|
||||||
echo Ciao, $NOME!
|
echo Ciao, $Nome!
|
||||||
|
|
||||||
# Classica struttura if:
|
# Classica struttura if:
|
||||||
# usa 'man test' per maggiori informazioni sulle condizionali
|
# usa 'man test' per maggiori informazioni sulle condizionali
|
||||||
if [ $NOME -ne $USER ]
|
if [ $Nome -ne $USER ]
|
||||||
then
|
then
|
||||||
echo "Il tuo nome non è lo username"
|
echo "Il tuo nome non è lo username"
|
||||||
else
|
else
|
||||||
echo "Il tuo nome è lo username"
|
echo "Il tuo nome è lo username"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Nota: se $Name è vuoto, la condizione precedente viene interpretata come:
|
||||||
|
if [ -ne $USER ]
|
||||||
|
# che genera un errore di sintassi. Quindi il metodo sicuro per usare
|
||||||
|
# variabili che possono contenere stringhe vuote è il seguente:
|
||||||
|
if [ "$Name" -ne $USER ] ...
|
||||||
|
# che viene interpretato come:
|
||||||
|
if [ "" -ne $USER ] ...
|
||||||
|
# e dunque funziona correttamente.
|
||||||
|
|
||||||
# C'è anche l'esecuzione condizionale
|
# C'è anche l'esecuzione condizionale
|
||||||
echo "Sempre eseguito" || echo "Eseguito solo se la prima condizione fallisce"
|
echo "Sempre eseguito" || echo "Eseguito solo se la prima condizione fallisce"
|
||||||
echo "Sempre eseguito" && echo "Eseguito solo se la prima condizione NON fallisce"
|
echo "Sempre eseguito" && echo "Eseguito solo se la prima condizione NON fallisce"
|
||||||
|
|
||||||
# Per usare && e || con l'if, c'è bisogno di piu' paia di parentesi quadre:
|
# Per usare && e || con l'if, c'è bisogno di piu' paia di parentesi quadre:
|
||||||
if [ $NOME == "Steve" ] && [ $ETA -eq 15 ]
|
if [ "$Nome" == "Steve" ] && [ "$Eta" -eq 15 ]
|
||||||
then
|
then
|
||||||
echo "Questo verrà eseguito se $NOME è Steve E $ETA è 15."
|
echo "Questo verrà eseguito se $Nome è Steve E $Eta è 15."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $NOME == "Daniya" ] || [ $NOME == "Zach" ]
|
if [ "$Nome" == "Daniya" ] || [ "$Nome" == "Zach" ]
|
||||||
then
|
then
|
||||||
echo "Questo verrà eseguito se $NAME è Daniya O Zach."
|
echo "Questo verrà eseguito se $Nome è Daniya O Zach."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Le espressioni sono nel seguente formato:
|
# Le espressioni sono nel seguente formato:
|
||||||
@ -137,7 +149,7 @@ python hello.py > /dev/null 2>&1
|
|||||||
# se invece vuoi appendere usa ">>":
|
# se invece vuoi appendere usa ">>":
|
||||||
python hello.py >> "output.out" 2>> "error.err"
|
python hello.py >> "output.out" 2>> "error.err"
|
||||||
|
|
||||||
# Sovrascrivi output.txt, appendi a error.err, e conta le righe:
|
# Sovrascrivi output.out, appendi a error.err, e conta le righe:
|
||||||
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
|
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
|
||||||
wc -l output.out error.err
|
wc -l output.out error.err
|
||||||
|
|
||||||
@ -145,7 +157,7 @@ wc -l output.out error.err
|
|||||||
# vedi: man fd
|
# vedi: man fd
|
||||||
echo <(echo "#ciaomondo")
|
echo <(echo "#ciaomondo")
|
||||||
|
|
||||||
# Sovrascrivi output.txt con "#helloworld":
|
# Sovrascrivi output.out con "#helloworld":
|
||||||
cat > output.out <(echo "#helloworld")
|
cat > output.out <(echo "#helloworld")
|
||||||
echo "#helloworld" > output.out
|
echo "#helloworld" > output.out
|
||||||
echo "#helloworld" | cat > output.out
|
echo "#helloworld" | cat > output.out
|
||||||
@ -164,7 +176,7 @@ echo "Ci sono $(ls | wc -l) oggetti qui."
|
|||||||
echo "Ci sono `ls | wc -l` oggetti qui."
|
echo "Ci sono `ls | wc -l` oggetti qui."
|
||||||
|
|
||||||
# Bash utilizza uno statemente case che funziona in maniera simile allo switch in Java e C++:
|
# Bash utilizza uno statemente case che funziona in maniera simile allo switch in Java e C++:
|
||||||
case "$VARIABILE" in
|
case "$Variabile" in
|
||||||
#Lista di pattern per le condizioni che vuoi soddisfare
|
#Lista di pattern per le condizioni che vuoi soddisfare
|
||||||
0) echo "C'è uno zero.";;
|
0) echo "C'è uno zero.";;
|
||||||
1) echo "C'è un uno.";;
|
1) echo "C'è un uno.";;
|
||||||
@ -172,10 +184,10 @@ case "$VARIABILE" in
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
# I cicli for iterano per ogni argomento fornito:
|
# I cicli for iterano per ogni argomento fornito:
|
||||||
# I contenuti di $VARIABILE sono stampati tre volte.
|
# I contenuti di $Variabile sono stampati tre volte.
|
||||||
for VARIABILE in {1..3}
|
for Variabile in {1..3}
|
||||||
do
|
do
|
||||||
echo "$VARIABILE"
|
echo "$Variabile"
|
||||||
done
|
done
|
||||||
|
|
||||||
# O scrivilo con il "ciclo for tradizionale":
|
# O scrivilo con il "ciclo for tradizionale":
|
||||||
@ -186,16 +198,16 @@ done
|
|||||||
|
|
||||||
# Possono essere usati anche per agire su file..
|
# Possono essere usati anche per agire su file..
|
||||||
# Questo eseguirà il comando 'cat' su file1 e file2
|
# Questo eseguirà il comando 'cat' su file1 e file2
|
||||||
for VARIABILE in file1 file2
|
for Variabile in file1 file2
|
||||||
do
|
do
|
||||||
cat "$VARIABILE"
|
cat "$Variabile"
|
||||||
done
|
done
|
||||||
|
|
||||||
# ..o dall'output di un comando
|
# ..o dall'output di un comando
|
||||||
# Questo eseguirà cat sull'output di ls.
|
# Questo eseguirà cat sull'output di ls.
|
||||||
for OUTPUT in $(ls)
|
for Output in $(ls)
|
||||||
do
|
do
|
||||||
cat "$OUTPUT"
|
cat "$Output"
|
||||||
done
|
done
|
||||||
|
|
||||||
# while loop:
|
# while loop:
|
||||||
@ -223,7 +235,7 @@ bar ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Per chiamare la funzione
|
# Per chiamare la funzione
|
||||||
foo "Il mio nome è" $NOME
|
foo "Il mio nome è" $Nome
|
||||||
|
|
||||||
# Ci sono un sacco di comandi utili che dovresti imparare:
|
# Ci sono un sacco di comandi utili che dovresti imparare:
|
||||||
# stampa le ultime 10 righe di file.txt
|
# stampa le ultime 10 righe di file.txt
|
||||||
@ -245,7 +257,7 @@ grep "^foo.*bar$" file.txt
|
|||||||
grep -c "^foo.*bar$" file.txt
|
grep -c "^foo.*bar$" file.txt
|
||||||
# se vuoi letteralmente cercare la stringa,
|
# se vuoi letteralmente cercare la stringa,
|
||||||
# e non la regex, usa fgrep (o grep -F)
|
# e non la regex, usa fgrep (o grep -F)
|
||||||
fgrep "^foo.*bar$" file.txt
|
fgrep "^foo.*bar$" file.txt
|
||||||
|
|
||||||
|
|
||||||
# Leggi la documentazione dei builtin di bash con il builtin 'help' di bash:
|
# Leggi la documentazione dei builtin di bash con il builtin 'help' di bash:
|
||||||
|
@ -1,75 +1,72 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
language: brainfuck
|
language: brainfuck
|
||||||
contributors:
|
contributors:
|
||||||
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
|
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
|
||||||
- ["Mathias Bynens", "http://mathiasbynens.be/"]
|
- ["Mathias Bynens", "http://mathiasbynens.be/"]
|
||||||
translators:
|
translators:
|
||||||
- ["Ivan Sala", "http://slavni96.github.io/"]
|
- ["Ivan Sala", "http://slavni96.github.io/"]
|
||||||
|
- ["Christian Grasso", "http://chris54721.net"]
|
||||||
lang: it-it
|
lang: it-it
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Brainfuck è un linguaggio di programmazione estremamente minimale,
|
Brainfuck è un linguaggio di programmazione
|
||||||
ma è ingrado di rappresentare completamente una macchina di turnig,
|
[Turing equivalente](https://it.wikipedia.org/wiki/Turing_equivalenza)
|
||||||
e sfrutta solo 8 caratteri.
|
estremamente minimale, composto da solo 8 comandi.
|
||||||
[Per saperne di più](http://it.wikipedia.org/wiki/Brainfuck)
|
|
||||||
|
Puoi provarlo nel tuo browser utilizzando
|
||||||
|
[brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/).
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Qualsiasi carattere che non sia "><+-.,[]" (escludendo gli apici)
|
Qualsiasi carattere diverso da "><+-.,[]" (escludendo gli apici)
|
||||||
viene ignorato.
|
viene ignorato.
|
||||||
Branfuck è caratterizzato da un array (vettore) di 30,000 celle
|
Branfuck è caratterizzato da un array di 30,000 celle inizializzate a zero
|
||||||
inizializzare a zero, e un puntatore che punta alla cella corrente.
|
e da un puntatore che punta alla cella corrente.
|
||||||
|
|
||||||
Vi sono solo otto comando:
|
Vi sono otto comandi:
|
||||||
+ : Incrementa il valore della cella attuale di uno.
|
+ : Incrementa il valore della cella attuale di uno.
|
||||||
- : Decrementa il valore della cella attuale di uno.
|
- : Decrementa il valore della cella attuale di uno.
|
||||||
> : Sposta il puntatore sulla cella seguente (prossima a destra).
|
> : Sposta il puntatore sulla cella seguente (sulla destra).
|
||||||
< : Sposta il puntatore sulla cella precendete (precedente a sinistra).
|
< : Sposta il puntatore sulla cella precendete (sulla sinistra).
|
||||||
. : Stampa il valore in ASCII della cella corrente. (es: 65 = 'A')
|
. : Stampa il valore ASCII della cella corrente. (es. 65 = 'A')
|
||||||
, : Legge un singolo carattere come input per la cella corrente.
|
, : Legge un singolo carattere come input e lo salva nella cella corrente.
|
||||||
[ : Se il valore della cella corrente è zero, conclude il ciclo
|
[ : Se il valore della cella corrente è zero, prosegue fino alla ] corrispondente.
|
||||||
andando alla sua corrispondente ].
|
|
||||||
Altrimenti, passa alla prossima istruzione.
|
Altrimenti, passa alla prossima istruzione.
|
||||||
] : Se il valore della cella corrente è zero, passa alla prossima istruzione.
|
] : Se il valore della cella corrente è zero, passa alla prossima istruzione.
|
||||||
Altrimenti torna indetro fino alla [ corrispondente.
|
Altrimenti, torna indietro fino alla [ corrispondente.
|
||||||
|
|
||||||
[ e ] creano un loop (while). Ovviamente dovranno essere bilanciati.
|
[ e ] formano un ciclo while. Ovviamente dovranno essere bilanciati.
|
||||||
Per ogni [ dovrà corrispondere una ]
|
(Ad ogni [ dovrà corrispondere una ])
|
||||||
|
|
||||||
Alcuni semplici esempi di programmi scritti in Brainfuck:
|
Ecco alcuni semplici esempi di programmi scritti in Brainfuck:
|
||||||
|
|
||||||
++++++ [ > ++++++++++ < - ] > +++++ .
|
++++++ [ > ++++++++++ < - ] > +++++ .
|
||||||
|
|
||||||
Questo programma stampa in output la lettera 'A'. Priam incrementa
|
Questo programma stampa in output la lettera 'A'. Prima di tutto, incrementa
|
||||||
la cella #1 fino a 6, Quindi la cella #1 viene usata per crare un ciclo.
|
la cella #1 fino al valore 6. La cella #1 verrà utilizzata per il ciclo.
|
||||||
Poi, entra in un loop ([) e si sposta alla cella #2.
|
Poi, entra nel ciclo ([) e si sposta alla cella #2. Incrementa la cella #2 10
|
||||||
Incrementa la cella #2 10 volte, e torna alla cella #1, e la decrementa.
|
volte, torna alla cella #1, e decrementa quest'ultima.
|
||||||
Questo avviene 6 volte (servono che la cella #1 venga decrementata 6 volte
|
Il ciclo si ripete 6 volte (la cella #1 viene decrementata 6 volte prima di
|
||||||
per raggiungere lo 0. Quindi passa alla corrispondente ] e prosegue).
|
raggiungere lo 0, quindi prosegue oltre la corrispondente ]).
|
||||||
|
|
||||||
A questo punto, siamo sulla cella #1, che ha valore 0,
|
A questo punto, siamo sulla cella #1, che ha valore 0, mentre la cella #2 ha
|
||||||
la cella #2 ha valore 60 (6*10). Ci spostiamo sulla cella #2, incrementiamo
|
valore 60. Ci spostiamo sulla cella #2, la incrementiamo per 5 volte, ottenendo
|
||||||
per 5 volte, e otteniamo il valore 65, quindi stampaimo il valore della cella
|
il valore 65, quindi stampiamo il valore della cella #2.
|
||||||
#2 (.).
|
Il valore 65 equivale ad 'A' in ASCII, per cui viene stampato 'A' nel terminale.
|
||||||
65 è 'A' in ASCII, quindi alla fine viene stampata 'A'.
|
|
||||||
|
|
||||||
|
|
||||||
, [ > + < - ] > .
|
, [ > + < - ] > .
|
||||||
|
|
||||||
Questo programma legge un carattere come input dall'utente,
|
Questo programma legge un carattere come input dall'utente, quindi salva il
|
||||||
quindi salva il carattere dentro la cella #1.
|
carattere nella cella #1. Dopodichè entra in un ciclo. Si sposta alla cella #2,
|
||||||
In seguito, incominca a ciclare.
|
incrementa quest'ultima, torna alla cella #1, e decrementa quest'ultima.
|
||||||
Si sposta alla cella #², e increementa il valore della cella (#2).
|
Il ciclo continua fino a quando la cella #1 diventa 0, e quindi la cella #2
|
||||||
Quindi torna alla cella #1, e decrementa il valore della cella (#1).
|
avrà il valore iniziale della cella #1. Infine, visto che ci troviamo sulla
|
||||||
Questo continua fino a quando la cella #²1 diventa 0, e quindi la cella #2
|
cella #1 alla fine del ciclo, si sposta sulla cella #2 e stampa il valore in
|
||||||
avrà il valore iniziale della cella #1.
|
ASCII.
|
||||||
Infine, visto che ci troviamo sulla cella #1 alla fine del ciclo, si sposta
|
|
||||||
sulla cella #2 e stampa il valore in ASCII.
|
|
||||||
|
|
||||||
Gli spazi nel codice sovrastante, sono presenti solo a scopo di ottenere
|
Gli spazi nel codice sovrastante sono presenti solo a scopo di ottenere
|
||||||
una maggiore leggibilità, si poteva anche scrivere senza:
|
una maggiore leggibilità. Lo stesso programma poteva essere scritto senza spazi:
|
||||||
|
|
||||||
,[>+<-]>.
|
,[>+<-]>.
|
||||||
|
|
||||||
@ -77,25 +74,19 @@ Proviamo, adesso, a capire cosa fa invece questo programma:
|
|||||||
|
|
||||||
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
|
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
|
||||||
|
|
||||||
Prende due numeri in input e quindi li moltiplica.
|
Il programma legge 2 numeri come input dall'utente, e li moltiplica.
|
||||||
|
|
||||||
Prima prende in input i due numeri (,>,<), quindi inizia un cilclo
|
Innanzitutto, legge in input i due numeri. Poi entra nel ciclo più esterno
|
||||||
basandosi sulla cella #1.
|
basandosi sulla cella #1. Quindi si sposta sulla cella #2, e inizia il ciclo
|
||||||
Quindi si sposta sulla cella #2, e inizia un altro ciclo condizionato
|
più interno basandosi sul valore della cella #2, incrementando la cella #3.
|
||||||
dal valore della cella #2, incrementando la cella #3.
|
|
||||||
Arrivati a questo punto abbiamo un problema: alla fine del ciclo interno
|
Arrivati a questo punto abbiamo un problema: alla fine del ciclo interno
|
||||||
la cella #2 ha valore 0. In questo caso, quando il ciclo esterno rifarà
|
la cella #2 avrà valore 0. Ciò impedirà di eseguire nuovamente il ciclo interno.
|
||||||
partire il ciclo interno, non funzionerà più perchè la cella #2 ha valore 0.
|
Per ovviare a questo problema, incrementiamo anche la cella #4, e copiamo il
|
||||||
Per ovviare a questo problema, oltre alla cella 3, incrementiamo anche la cella
|
valore di quest'ultima nella cella #2.
|
||||||
#4, e alla fine di ogni ciclo interno copiala il valore della cella #4
|
Il risultato sarà infine contenuto nella cella #3.
|
||||||
nella cella #2, in modo che il ciclo interno
|
|
||||||
possa essere eseguito una altra volta.
|
|
||||||
Alla fine la cella #3 contiene il risultato.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
E questo è brainfuck...Non è difficele, vero?
|
E questo è brainfuck. Non è così difficile, eh? Se vuoi, ora puoi scrivere per
|
||||||
Per divertimento adesso puoi scrivere i tuoi programmi in brainfuck,
|
divertimento altri programmi in brainfuck, oppure scrivere un interprete
|
||||||
oppure puoi scrivere un interprete brainfuck in un altro linguaggio.
|
brainfuck in un altro linguaggio. L'interprete è abbastanza semplice da
|
||||||
L'interprete è abbastanza semplice da implementare, ma se sei veramente
|
implementare, ma se sei veramente masochista, prova ad implementare un interprete brainfuck... in brainfuck.
|
||||||
masochista prova ad implementare un interprete brainfuck in...
|
|
||||||
brainfuck.
|
|
||||||
|
@ -4,6 +4,8 @@ filename: learncpp-it.cpp
|
|||||||
contributors:
|
contributors:
|
||||||
- ["Steven Basart", "http://github.com/xksteven"]
|
- ["Steven Basart", "http://github.com/xksteven"]
|
||||||
- ["Matt Kline", "https://github.com/mrkline"]
|
- ["Matt Kline", "https://github.com/mrkline"]
|
||||||
|
- ["Geoff Liu", "http://geoffliu.me"]
|
||||||
|
- ["Connor Waters", "http://github.com/connorwaters"]
|
||||||
translators:
|
translators:
|
||||||
- ["Robert Margelli", "http://github.com/sinkswim/"]
|
- ["Robert Margelli", "http://github.com/sinkswim/"]
|
||||||
lang: it-it
|
lang: it-it
|
||||||
@ -54,11 +56,11 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
// Tuttavia, il C++ varia nei seguenti modi:
|
// Tuttavia, il C++ varia nei seguenti modi:
|
||||||
|
|
||||||
// In C++, i caratteri come letterali sono da un byte.
|
// In C++, i caratteri come letterali sono dei char.
|
||||||
sizeof('c') == 1
|
sizeof('c') == sizeof(char) == 1
|
||||||
|
|
||||||
// In C, i caratteri come letterali sono della stessa dimensione degli interi.
|
// In C, i caratteri come letterali sono degli interi.
|
||||||
sizeof('c') == sizeof(10)
|
sizeof('c') == sizeof(int)
|
||||||
|
|
||||||
|
|
||||||
// C++ ha prototipizzazione rigida
|
// C++ ha prototipizzazione rigida
|
||||||
@ -160,11 +162,14 @@ void foo()
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// Assume che tutto venga dal namespace "Secondo"
|
// Include tutti i simboli del namespace Secondo nello scope attuale.
|
||||||
// a meno che non venga dichiarato altrimenti.
|
// Osserva che chiamare semplicemente foo() non va più bene perché è ambiguo:
|
||||||
|
// bisogna specificare se vogliamo chiamare foo definita nel namespace Secondo
|
||||||
|
// o foo definita nel livello principale del programma.
|
||||||
|
|
||||||
using namespace Secondo;
|
using namespace Secondo;
|
||||||
|
|
||||||
foo(); // stampa "Questa è Secondo::foo"
|
Secondo::foo(); // stampa "Questa è Secondo::foo"
|
||||||
Primo::Annidato::foo(); // stampa "Questa è Primo::Annidato::foo"
|
Primo::Annidato::foo(); // stampa "Questa è Primo::Annidato::foo"
|
||||||
::foo(); // stampa "Questa è foo globale"
|
::foo(); // stampa "Questa è foo globale"
|
||||||
}
|
}
|
||||||
@ -244,12 +249,137 @@ cout << fooRef; // Stampa "Io sono foo. Ciao!"
|
|||||||
// Non riassegna "fooRef". Questo è come scrivere "foo = bar", e
|
// Non riassegna "fooRef". Questo è come scrivere "foo = bar", e
|
||||||
// foo == "Io sono bar"
|
// foo == "Io sono bar"
|
||||||
// dopo questa riga.
|
// dopo questa riga.
|
||||||
|
cout << &fooRef << endl; // Stampa l'indirizzo di foo
|
||||||
fooRef = bar;
|
fooRef = bar;
|
||||||
|
cout << &fooRef << endl; // Stampa lo stesso l'indirizzo di foo
|
||||||
|
cout << fooRef; // Stampa "Io sono bar"
|
||||||
|
|
||||||
|
// L'indirizzo di fooRef rimane lo stesso, ovvero si riferisce ancora a foo.
|
||||||
|
|
||||||
|
|
||||||
const string& barRef = bar; // Crea un riferimento const a bar.
|
const string& barRef = bar; // Crea un riferimento const a bar.
|
||||||
// Come in C, i valori const (i puntatori e i riferimenti) non possono essere modificati.
|
// Come in C, i valori const (i puntatori e i riferimenti) non possono essere modificati.
|
||||||
barRef += ". Ciao!"; // Errore, i riferimenti const non possono essere modificati.
|
barRef += ". Ciao!"; // Errore, i riferimenti const non possono essere modificati.
|
||||||
|
|
||||||
|
// Facciamo un piccolo excursus: prima di approfondire ancora i riferimenti, è necessario
|
||||||
|
// introdurre il concetto di oggetto temporaneo. Supponiamo di avere il seguente codice:
|
||||||
|
string tempObjectFun() { ... }
|
||||||
|
string retVal = tempObjectFun();
|
||||||
|
|
||||||
|
// Nella seconda riga si ha che:
|
||||||
|
// - un oggetto di tipo stringa viene ritornato da tempObjectFun
|
||||||
|
// - viene costruita una nuova stringa, utilizzando l'oggetto ritornato come
|
||||||
|
// argomento per il costruttore
|
||||||
|
// - l'oggetto ritornato da tempObjectFun viene distrutto
|
||||||
|
// L'oggetto ritornato da tempObjectFun viene detto oggetto temporaneo.
|
||||||
|
// Un oggetto temporaneo viene creato quando una funzione ritorna un oggetto, e viene
|
||||||
|
// distrutto quando l'espressione che lo racchiude termina la sua esecuzione - questo
|
||||||
|
// comportamento viene definito dallo standard, ma i compilatori possono modificarlo
|
||||||
|
// a piacere. Cerca su google "return value optimization" se vuoi approfondire.
|
||||||
|
// Dunque nel seguente codice:
|
||||||
|
foo(bar(tempObjectFun()))
|
||||||
|
|
||||||
|
// dando per scontato che foo e bar esistano, l'oggetto ritornato da tempObjectFun
|
||||||
|
// è passato a bar ed è distrutto prima dell'invocazione di foo.
|
||||||
|
|
||||||
|
// Tornando ai riferimenti, c'è un'eccezione a quanto appena detto.
|
||||||
|
// Infatti un oggetto temporaneo "viene distrutto quando l'espressione
|
||||||
|
// che lo racchiude termina la sua esecuzione", tranne quando è legato ad un
|
||||||
|
// riferimento di tipo const. In tal caso la sua vita viene estesa per tutto
|
||||||
|
// lo scope attuale:
|
||||||
|
|
||||||
|
void constReferenceTempObjectFun() {
|
||||||
|
// constRef riceve l'oggetto temporaneo, che non viene distrutto fino
|
||||||
|
// alla fine di questa funzione.
|
||||||
|
const string& constRef = tempObjectFun();
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Un altro tipo di riferimento introdotto nel C++11 è specifico per gli
|
||||||
|
// oggetti temporanei. Non puoi dichiarare una variabile di quel tipo, ma
|
||||||
|
// ha la precedenza nella risoluzione degli overload:
|
||||||
|
|
||||||
|
void someFun(string& s) { ... } // Riferimento normale
|
||||||
|
void someFun(string&& s) { ... } // Riferimento ad un oggetto temporaneo
|
||||||
|
|
||||||
|
string foo;
|
||||||
|
someFun(foo); // Chiama la versione con il riferimento normale
|
||||||
|
someFun(tempObjectFun()); // Chiama la versione con il riferimento temporaneo
|
||||||
|
|
||||||
|
// Ad esempio potrai vedere questi due costruttori per std::basic_string:
|
||||||
|
basic_string(const basic_string& other);
|
||||||
|
basic_string(basic_string&& other);
|
||||||
|
|
||||||
|
// L'idea è che se noi costruiamo una nuova stringa a partire da un oggetto temporaneo
|
||||||
|
// (che in ogni caso verrà distrutto), possiamo avere un costruttore più efficiente
|
||||||
|
// che in un certo senso "recupera" parti di quella stringa temporanea.
|
||||||
|
// Ci si riferisce a questo concetto come "move semantics".
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// Enum
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
// Gli enum sono un modo per assegnare un valore ad una costante, e sono
|
||||||
|
// principalmente usati per rendere il codice più leggibile.
|
||||||
|
enum ETipiMacchine
|
||||||
|
{
|
||||||
|
AlfaRomeo,
|
||||||
|
Ferrari,
|
||||||
|
SUV,
|
||||||
|
Panda
|
||||||
|
};
|
||||||
|
|
||||||
|
ETipiMacchine GetPreferredCarType()
|
||||||
|
{
|
||||||
|
return ETipiMacchine::Ferrari;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dal C++11 in poi c'è un modo molto semplice per assegnare un tipo ad un enum,
|
||||||
|
// che può essere utile per la serializzazione dei dati o per convertire gli enum
|
||||||
|
// tra il tipo desiderato e le rispettive costanti.
|
||||||
|
enum ETipiMacchine : uint8_t
|
||||||
|
{
|
||||||
|
AlfaRomeo, // 0
|
||||||
|
Ferrari, // 1
|
||||||
|
SUV = 254, // 254
|
||||||
|
Ibrida // 255
|
||||||
|
};
|
||||||
|
|
||||||
|
void WriteByteToFile(uint8_t InputValue)
|
||||||
|
{
|
||||||
|
// Serializza InputValue in un file
|
||||||
|
}
|
||||||
|
|
||||||
|
void WritePreferredCarTypeToFile(ETipiMacchine InputCarType)
|
||||||
|
{
|
||||||
|
// L'enum viene implicitamente convertito ad un uint8_t poiché
|
||||||
|
// è stato dichiarato come tale
|
||||||
|
WriteByteToFile(InputCarType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// D'altro canto potresti voler evitare che un enum venga accidentalmente convertito
|
||||||
|
// in un intero o in un altro tipo, quindi è possibile create una classe enum che
|
||||||
|
// impedisce la conversione implicita.
|
||||||
|
enum class ETipiMacchine : uint8_t
|
||||||
|
{
|
||||||
|
AlfaRomeo, // 0
|
||||||
|
Ferrari, // 1
|
||||||
|
SUV = 254, // 254
|
||||||
|
Ibrida // 255
|
||||||
|
};
|
||||||
|
|
||||||
|
void WriteByteToFile(uint8_t InputValue)
|
||||||
|
{
|
||||||
|
// Serializza InputValue in un file
|
||||||
|
}
|
||||||
|
|
||||||
|
void WritePreferredCarTypeToFile(ETipiMacchine InputCarType)
|
||||||
|
{
|
||||||
|
// Il compilatore darà errore anche se ETipiMacchine è un uint8_t: questo
|
||||||
|
// perchè abbiamo dichiarato l'enum come "enum class"!
|
||||||
|
WriteByteToFile(InputCarType);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
// Classi e programmazione orientata agli oggetti
|
// Classi e programmazione orientata agli oggetti
|
||||||
/////////////////////////////////////////////////
|
/////////////////////////////////////////////////
|
||||||
@ -296,13 +426,16 @@ public:
|
|||||||
// Questi sono chiamati quando un oggetto è rimosso o esce dalla visibilità.
|
// Questi sono chiamati quando un oggetto è rimosso o esce dalla visibilità.
|
||||||
// Questo permette paradigmi potenti come il RAII
|
// Questo permette paradigmi potenti come il RAII
|
||||||
// (vedi sotto)
|
// (vedi sotto)
|
||||||
// I distruttori devono essere virtual per permettere a classi di essere derivate da questa.
|
// I distruttori devono essere virtual per permettere a classi di essere
|
||||||
|
// derivate da questa; altrimenti, il distruttore della classe derivata
|
||||||
|
// non viene chiamato se l'oggetto viene distrutto tramite un riferimento alla
|
||||||
|
// classe da cui ha ereditato o tramite un puntatore.
|
||||||
virtual ~Dog();
|
virtual ~Dog();
|
||||||
|
|
||||||
}; // Un punto e virgola deve seguire la definizione della funzione
|
}; // Un punto e virgola deve seguire la definizione della funzione
|
||||||
|
|
||||||
// Le funzioni membro di una classe sono generalmente implementate in files .cpp .
|
// Le funzioni membro di una classe sono generalmente implementate in files .cpp .
|
||||||
void Cane::Cane()
|
Cane::Cane()
|
||||||
{
|
{
|
||||||
std::cout << "Un cane è stato costruito\n";
|
std::cout << "Un cane è stato costruito\n";
|
||||||
}
|
}
|
||||||
@ -325,7 +458,7 @@ void Cane::print() const
|
|||||||
std::cout << "Il cane è " << nome << " e pesa " << peso << "kg\n";
|
std::cout << "Il cane è " << nome << " e pesa " << peso << "kg\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cane::~Cane()
|
Cane::~Cane()
|
||||||
{
|
{
|
||||||
cout << "Ciao ciao " << nome << "\n";
|
cout << "Ciao ciao " << nome << "\n";
|
||||||
}
|
}
|
||||||
@ -340,10 +473,12 @@ int main() {
|
|||||||
|
|
||||||
// Ereditarietà:
|
// Ereditarietà:
|
||||||
|
|
||||||
// Questa classe eredita tutto ciò che è public e protected dalla classe Cane
|
// Questa classe eredita tutto ciò che è public e protected dalla classe Cane,
|
||||||
|
// ma anche ciò che privato: tuttavia non potrà accedere direttamente a membri/metodi
|
||||||
|
// privati se non c'è un metodo pubblico o privato che permetta di farlo.
|
||||||
class MioCane : public Cane {
|
class MioCane : public Cane {
|
||||||
|
|
||||||
void impostaProprietario(const std::string& proprietarioCane)
|
void impostaProprietario(const std::string& proprietarioCane);
|
||||||
|
|
||||||
// Sovrascrivi il comportamento della funzione print per tutti i MioCane. Vedi
|
// Sovrascrivi il comportamento della funzione print per tutti i MioCane. Vedi
|
||||||
// http://it.wikipedia.org/wiki/Polimorfismo_%28informatica%29
|
// http://it.wikipedia.org/wiki/Polimorfismo_%28informatica%29
|
||||||
@ -447,6 +582,7 @@ int main () {
|
|||||||
// definire una classe o una funzione che prende un parametro di un dato tipo:
|
// definire una classe o una funzione che prende un parametro di un dato tipo:
|
||||||
template<class T>
|
template<class T>
|
||||||
class Box {
|
class Box {
|
||||||
|
public:
|
||||||
// In questa classe, T può essere usato come qualsiasi tipo.
|
// In questa classe, T può essere usato come qualsiasi tipo.
|
||||||
void inserisci(const T&) { ... }
|
void inserisci(const T&) { ... }
|
||||||
};
|
};
|
||||||
@ -519,19 +655,23 @@ printMessage<10>(); // Stampa "Impara il C++ più velocemente in soli 10 minuti
|
|||||||
// (vedi http://en.cppreference.com/w/cpp/error/exception)
|
// (vedi http://en.cppreference.com/w/cpp/error/exception)
|
||||||
// ma ogni tipo può essere lanciato come eccezione
|
// ma ogni tipo può essere lanciato come eccezione
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
// Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi
|
// Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi
|
||||||
// handlers _catch_.
|
// handlers _catch_.
|
||||||
try {
|
try {
|
||||||
// Non allocare eccezioni nello heap usando _new_.
|
// Non allocare eccezioni nello heap usando _new_.
|
||||||
throw std::exception("È avvenuto un problema");
|
throw std::runtime_error("C'è stato un problema.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cattura le eccezioni come riferimenti const se sono oggetti
|
// Cattura le eccezioni come riferimenti const se sono oggetti
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
{
|
{
|
||||||
std::cout << ex.what();
|
std::cout << ex.what();
|
||||||
|
}
|
||||||
|
|
||||||
// Cattura ogni eccezioni non catturata dal blocco _catch_ precedente
|
// Cattura ogni eccezioni non catturata dal blocco _catch_ precedente
|
||||||
} catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
std::cout << "Catturata un'eccezione sconosciuta";
|
std::cout << "Catturata un'eccezione sconosciuta";
|
||||||
throw; // Rilancia l'eccezione
|
throw; // Rilancia l'eccezione
|
||||||
@ -541,7 +681,7 @@ catch (const std::exception& ex)
|
|||||||
// RAII
|
// RAII
|
||||||
///////
|
///////
|
||||||
|
|
||||||
// RAII sta per Resource Allocation Is Initialization.
|
// RAII sta per "Resource Allocation Is Initialization".
|
||||||
// Spesso viene considerato come il più potente paradigma in C++.
|
// Spesso viene considerato come il più potente paradigma in C++.
|
||||||
// È un concetto semplice: un costruttore di un oggetto
|
// È un concetto semplice: un costruttore di un oggetto
|
||||||
// acquisisce le risorse di tale oggetto ed il distruttore le rilascia.
|
// acquisisce le risorse di tale oggetto ed il distruttore le rilascia.
|
||||||
@ -563,9 +703,9 @@ void faiQualcosaConUnFile(const char* nomefile)
|
|||||||
// Sfortunatamente, le cose vengono complicate dalla gestione degli errori.
|
// Sfortunatamente, le cose vengono complicate dalla gestione degli errori.
|
||||||
// Supponiamo che fopen fallisca, e che faiQualcosaConUnFile e
|
// Supponiamo che fopen fallisca, e che faiQualcosaConUnFile e
|
||||||
// faiQualcosAltroConEsso ritornano codici d'errore se falliscono.
|
// faiQualcosAltroConEsso ritornano codici d'errore se falliscono.
|
||||||
// (Le eccezioni sono la maniera preferita per gestire i fallimenti,
|
// (Le eccezioni sono la maniera preferita per gestire i fallimenti,
|
||||||
// ma alcuni programmatori, specialmente quelli con un passato in C,
|
// ma alcuni programmatori, specialmente quelli con un passato in C,
|
||||||
// non sono d'accordo con l'utilità delle eccezioni).
|
// non sono d'accordo con l'utilità delle eccezioni).
|
||||||
// Adesso dobbiamo verificare che ogni chiamata per eventuali fallimenti e chiudere il gestore di file
|
// Adesso dobbiamo verificare che ogni chiamata per eventuali fallimenti e chiudere il gestore di file
|
||||||
// se un problema è avvenuto.
|
// se un problema è avvenuto.
|
||||||
bool faiQualcosaConUnFile(const char* nomefile)
|
bool faiQualcosaConUnFile(const char* nomefile)
|
||||||
@ -615,7 +755,7 @@ void faiQualcosaConUnFile(const char* nomefile)
|
|||||||
{
|
{
|
||||||
FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura
|
FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura
|
||||||
if (fh == nullptr)
|
if (fh == nullptr)
|
||||||
throw std::exception("Non è stato possibile aprire il file.").
|
throw std::runtime_error("Errore nell'apertura del file.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
faiQualcosaConIlFile(fh);
|
faiQualcosaConIlFile(fh);
|
||||||
@ -678,26 +818,29 @@ class Foo {
|
|||||||
virtual void bar();
|
virtual void bar();
|
||||||
};
|
};
|
||||||
class FooSub : public Foo {
|
class FooSub : public Foo {
|
||||||
virtual void bar(); // sovrascrive Foo::bar!
|
virtual void bar(); // Sovrascrive Foo::bar!
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 0 == false == NULL (la maggior parte delle volte)!
|
// 0 == false == NULL (la maggior parte delle volte)!
|
||||||
bool* pt = new bool;
|
bool* pt = new bool;
|
||||||
*pt = 0; // Setta il valore puntato da 'pt' come falso.
|
*pt = 0; // Setta il valore puntato da 'pt' come falso.
|
||||||
pt = 0; // Setta 'pt' al puntatore null. Entrambe le righe vengono compilate senza warnings.
|
pt = 0; // Setta 'pt' al puntatore null. Entrambe le righe vengono compilate senza warnings.
|
||||||
|
|
||||||
// nullptr dovrebbe risolvere alcune di quei problemi:
|
// nullptr dovrebbe risolvere alcune di quei problemi:
|
||||||
int* pt2 = new int;
|
int* pt2 = new int;
|
||||||
*pt2 = nullptr; // Non compila
|
*pt2 = nullptr; // Non compila
|
||||||
pt2 = nullptr; // Setta pt2 a null.
|
pt2 = nullptr; // Setta pt2 a null.
|
||||||
|
|
||||||
// Ma in qualche modo il tipo 'bool' è una eccezione (questo è per rendere compilabile `if (ptr)`.
|
// C'è un'eccezione per i bool.
|
||||||
*pt = nullptr; // Questo compila, anche se '*pt' è un bool!
|
// Questo permette di testare un puntatore a null con if(!ptr), ma
|
||||||
|
// come conseguenza non puoi assegnare nullptr a un bool direttamente!
|
||||||
|
*pt = nullptr; // Questo compila, anche se '*pt' è un bool!
|
||||||
|
|
||||||
|
|
||||||
// '=' != '=' != '='!
|
// '=' != '=' != '='!
|
||||||
// Chiama Foo::Foo(const Foo&) o qualche variante del costruttore di copia.
|
// Chiama Foo::Foo(const Foo&) o qualche variante (vedi "move semantics")
|
||||||
|
// del costruttore di copia.
|
||||||
Foo f2;
|
Foo f2;
|
||||||
Foo f1 = f2;
|
Foo f1 = f2;
|
||||||
|
|
||||||
@ -711,6 +854,22 @@ Foo f1 = fooSub;
|
|||||||
Foo f1;
|
Foo f1;
|
||||||
f1 = f2;
|
f1 = f2;
|
||||||
|
|
||||||
|
|
||||||
|
// Come deallocare realmente le risorse all'interno di un vettore:
|
||||||
|
class Foo { ... };
|
||||||
|
vector<Foo> v;
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
v.push_back(Foo());
|
||||||
|
|
||||||
|
// La riga seguente riduce la dimensione di v a 0, ma il distruttore non
|
||||||
|
// viene chiamato e dunque le risorse non sono deallocate!
|
||||||
|
v.empty();
|
||||||
|
v.push_back(Foo()); // Il nuovo valore viene copiato nel primo Foo che abbiamo inserito
|
||||||
|
|
||||||
|
// Distrugge realmente tutti i valori dentro v. Vedi la sezione riguardante gli
|
||||||
|
// oggetti temporanei per capire come mai funziona così.
|
||||||
|
v.swap(vector<Foo>());
|
||||||
|
|
||||||
```
|
```
|
||||||
Letture consigliate:
|
Letture consigliate:
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ contributors:
|
|||||||
- ["Luca 'Kino' Maroni", "http://github.com/kino90"]
|
- ["Luca 'Kino' Maroni", "http://github.com/kino90"]
|
||||||
- ["Tenor Biel", "http://github.com/L8D"]
|
- ["Tenor Biel", "http://github.com/L8D"]
|
||||||
- ["Xavier Yao", "http://github.com/xavieryao"]
|
- ["Xavier Yao", "http://github.com/xavieryao"]
|
||||||
|
translators:
|
||||||
|
- ["Tommaso Pifferi","http://github.com/neslinesli93"]
|
||||||
filename: coffeescript-it.coffee
|
filename: coffeescript-it.coffee
|
||||||
lang: it-it
|
lang: it-it
|
||||||
---
|
---
|
||||||
@ -59,34 +61,34 @@ matematica =
|
|||||||
quadrato: quadrato
|
quadrato: quadrato
|
||||||
cubo: (x) -> x * quadrato x
|
cubo: (x) -> x * quadrato x
|
||||||
#=> var matematica = {
|
#=> var matematica = {
|
||||||
# "radice": Math.sqrt,
|
# "radice": Math.sqrt,
|
||||||
# "quadrato": quadrato,
|
# "quadrato": quadrato,
|
||||||
# "cubo": function(x) { return x * quadrato(x); }
|
# "cubo": function(x) { return x * quadrato(x); }
|
||||||
#}
|
# }
|
||||||
|
|
||||||
# Splats:
|
# Splats:
|
||||||
gara = (vincitore, partecipanti...) ->
|
gara = (vincitore, partecipanti...) ->
|
||||||
print vincitore, partecipanti
|
print vincitore, partecipanti
|
||||||
#=>gara = function() {
|
#=>gara = function() {
|
||||||
# var partecipanti, vincitore;
|
# var partecipanti, vincitore;
|
||||||
# vincitore = arguments[0], partecipanti = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
# vincitore = arguments[0], partecipanti = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
||||||
# return print(vincitore, partecipanti);
|
# return print(vincitore, partecipanti);
|
||||||
#};
|
# };
|
||||||
|
|
||||||
# Esistenza:
|
# Esistenza:
|
||||||
alert "Lo sapevo!" if elvis?
|
alert "Lo sapevo!" if elvis?
|
||||||
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("Lo sapevo!"); }
|
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("Lo sapevo!"); }
|
||||||
|
|
||||||
# Comprensione degli Array:
|
# Comprensione degli Array:
|
||||||
cubi = (matematica.cubo num for num in lista)
|
cubi = (matematica.cubo num for num in lista)
|
||||||
#=>cubi = (function() {
|
#=>cubi = (function() {
|
||||||
# var _i, _len, _results;
|
# var _i, _len, _results;
|
||||||
# _results = [];
|
# _results = [];
|
||||||
# for (_i = 0, _len = lista.length; _i < _len; _i++) {
|
# for (_i = 0, _len = lista.length; _i < _len; _i++) {
|
||||||
# num = lista[_i];
|
# num = lista[_i];
|
||||||
# _results.push(matematica.cubo(num));
|
# _results.push(matematica.cubo(num));
|
||||||
# }
|
# }
|
||||||
# return _results;
|
# return _results;
|
||||||
# })();
|
# })();
|
||||||
|
|
||||||
cibi = ['broccoli', 'spinaci', 'cioccolato']
|
cibi = ['broccoli', 'spinaci', 'cioccolato']
|
||||||
|
@ -4,6 +4,8 @@ contributors:
|
|||||||
- ["Luca 'Kino' Maroni", "https://github.com/kino90"]
|
- ["Luca 'Kino' Maroni", "https://github.com/kino90"]
|
||||||
- ["Joao Marques", "http://github.com/mrshankly"]
|
- ["Joao Marques", "http://github.com/mrshankly"]
|
||||||
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
|
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
|
||||||
|
translators:
|
||||||
|
- ["Tommaso Pifferi","http://github.com/neslinesli93"]
|
||||||
filename: learnelixir-it.ex
|
filename: learnelixir-it.ex
|
||||||
lang: it-it
|
lang: it-it
|
||||||
---
|
---
|
||||||
@ -379,6 +381,12 @@ spawn(f) #=> #PID<0.40.0>
|
|||||||
# Per passare messaggi si usa l'operatore `send`.
|
# Per passare messaggi si usa l'operatore `send`.
|
||||||
# Perché tutto questo sia utile dobbiamo essere capaci di ricevere messaggi,
|
# Perché tutto questo sia utile dobbiamo essere capaci di ricevere messaggi,
|
||||||
# oltre ad inviarli. Questo è realizzabile con `receive`:
|
# oltre ad inviarli. Questo è realizzabile con `receive`:
|
||||||
|
|
||||||
|
# Il blocco `receive do` viene usato per mettersi in ascolto di messaggi
|
||||||
|
# ed elaborarli quando vengono ricevuti. Un blocco `receive do` elabora
|
||||||
|
# un solo messaggio ricevuto: per fare elaborazione multipla di messaggi,
|
||||||
|
# una funzione con un blocco `receive do` al suo intero dovrà chiamare
|
||||||
|
# ricorsivamente sé stessa per entrare di nuovo nel blocco `receive do`.
|
||||||
defmodule Geometria do
|
defmodule Geometria do
|
||||||
def calcolo_area do
|
def calcolo_area do
|
||||||
receive do
|
receive do
|
||||||
@ -394,6 +402,8 @@ end
|
|||||||
|
|
||||||
# Compila il modulo e crea un processo che esegue `calcolo_area` nella shell
|
# Compila il modulo e crea un processo che esegue `calcolo_area` nella shell
|
||||||
pid = spawn(fn -> Geometria.calcolo_area() end) #=> #PID<0.40.0>
|
pid = spawn(fn -> Geometria.calcolo_area() end) #=> #PID<0.40.0>
|
||||||
|
# Alternativamente
|
||||||
|
pid = spawn(Geometria, :calcolo_area, [])
|
||||||
|
|
||||||
# Invia un messaggio a `pid` che farà match su un pattern nel blocco in receive
|
# Invia un messaggio a `pid` che farà match su un pattern nel blocco in receive
|
||||||
send pid, {:rettangolo, 2, 3}
|
send pid, {:rettangolo, 2, 3}
|
||||||
|
@ -6,6 +6,7 @@ contributors:
|
|||||||
- ["Madison Dickson", "http://github.com/mix3d"]
|
- ["Madison Dickson", "http://github.com/mix3d"]
|
||||||
translators:
|
translators:
|
||||||
- ["Ivan Sala","http://github.com/slavni96"]
|
- ["Ivan Sala","http://github.com/slavni96"]
|
||||||
|
- ["Tommaso Pifferi","http://github.com/neslinesli93"]
|
||||||
lang: it-it
|
lang: it-it
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -31,9 +32,9 @@ import java.security.*;
|
|||||||
// Ogni file .java contiene una classe pubblica, con lo stesso nome del file
|
// Ogni file .java contiene una classe pubblica, con lo stesso nome del file
|
||||||
public class LearnJava {
|
public class LearnJava {
|
||||||
|
|
||||||
// Un programma deve avere un metodo main come punto di partenza
|
// Un programma deve avere un metodo main come punto di partenza.
|
||||||
// Ma si possono creare anche file senza main, che però per essere usati
|
// Tuttavia si possono creare anche file senza main, che però
|
||||||
// devono essere richiamati da altri file.
|
// per essere usati devono essere richiamati da altri file.
|
||||||
public static void main (String[] args) {
|
public static void main (String[] args) {
|
||||||
|
|
||||||
// Per stampare a schermo si usa System.out.println
|
// Per stampare a schermo si usa System.out.println
|
||||||
@ -47,88 +48,157 @@ public class LearnJava {
|
|||||||
System.out.print("Ciao ");
|
System.out.print("Ciao ");
|
||||||
System.out.print("Mondo ");
|
System.out.print("Mondo ");
|
||||||
|
|
||||||
|
// Per stampare del testo formattato, si puo' usare System.out.printf
|
||||||
|
System.out.printf("pi greco = %.5f", Math.PI); // => pi greco = 3.14159
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Tipi e Variabili
|
// Variabili
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Si dichiara una variabile usando <tipo> <nome>
|
|
||||||
// Byte - variabile intera da 8 bit con segno
|
/*
|
||||||
|
* Dichiarazione delle Variabili
|
||||||
|
*/
|
||||||
|
// Per dichiarare una variabile basta fare <tipoDato> <nomeVariabile>
|
||||||
|
int fooInt;
|
||||||
|
// Per dichiarare piu' di una variabile dello lo stesso tipo si usa:
|
||||||
|
// <tipoDato> <nomeVariabile1>, <nomeVariabile2>, <nomeVariabile3>
|
||||||
|
int fooInt1, fooInt2, fooInt3;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inizializzazione delle Variabili
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Per inizializzare una variabile si usa
|
||||||
|
// <tipoDato> <nomeVariabile> = <valore>
|
||||||
|
int fooInt = 1;
|
||||||
|
// Per inizializzare piu' di una variabile dello lo stesso tipo
|
||||||
|
// si usa <tipoDato> <nomeVariabile1>, <nomeVariabile2>, <nomeVariabile3> = <valore>
|
||||||
|
int fooInt1, fooInt2, fooInt3;
|
||||||
|
fooInt1 = fooInt2 = fooInt3 = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tipi di Variabili
|
||||||
|
*/
|
||||||
|
// Byte - intero con segno a 8 bit (in complemento a 2)
|
||||||
// (-128 <= byte <= 127)
|
// (-128 <= byte <= 127)
|
||||||
byte fooByte = 100;
|
byte fooByte = 100;
|
||||||
|
|
||||||
// Short - variabile intera da 18 bit con segno
|
// Short - intero con segno a 16 bit (in complemento a 2)
|
||||||
// (-32,768 <= short <= 32,767)
|
// (-32,768 <= short <= 32,767)
|
||||||
short fooShort = 10000;
|
short fooShort = 10000;
|
||||||
|
|
||||||
// Integer - variabile intera da 32 bit con segno
|
// Integer - intero con segno a 32 bit (in complemento a 2)
|
||||||
// (-2,147,483,648 <= int <= 2,147,483,647)
|
// (-2,147,483,648 <= int <= 2,147,483,647)
|
||||||
int fooInt = 1;
|
int fooInt = 1;
|
||||||
|
|
||||||
// Long - variabile da 64 bit intera con segno
|
// Long - intero con segno a 64 bit (in complemento a 2)
|
||||||
// (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
|
// (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
|
||||||
long fooLong = 100000L;
|
long fooLong = 100000L;
|
||||||
// L viene usato per specificare che il valore dalla variabile
|
// L viene usato per indicare che il valore e' di tipo Long;
|
||||||
// e' di tipo "Long", qualsiasi variabile che non viene contrassegnata
|
// altrimenti il valore viene considerato come intero.
|
||||||
// e' trattata di base come un intero.
|
|
||||||
|
|
||||||
// Nota: Java non dispone di variabili senza segno
|
// Nota: Java non dispone di interi senza segno.
|
||||||
|
|
||||||
// Float - variabile piu' precisa, con virgola [numeri reali]
|
// Float - Numero in virgola mobile a 32 bit con precisione singola (IEEE 754)
|
||||||
// di grandezza 32 bit
|
// 2^-149 <= float <= (2-2^-23) * 2^127
|
||||||
float fooFloat = 234.5f;
|
float fooFloat = 234.5f;
|
||||||
// f e' usato per specificare che la variabile e'' di tipo "float"
|
// f o F indicano the la variabile e' di tipo float;
|
||||||
// altrimenti di default viene trattata come un "dobule"
|
// altrimenti il valore viene considerato come double.
|
||||||
|
|
||||||
// Double - ancora piu' precisione la si puo' ottenere con una variabile
|
// Double - Numero in virgola mobile a 64 bit con precisione doppia (IEEE 754)
|
||||||
// Double, con granzezza di 64 bit.
|
// 2^-1074 <= x <= (2-2^-52) * 2^1023
|
||||||
double fooDouble = 123.4;
|
double fooDouble = 123.4;
|
||||||
|
|
||||||
// Boolean - vero & falso
|
// Boolean - Puo' assumere il valore vero (true) o falso (false)
|
||||||
boolean fooBoolean = true;
|
boolean fooBoolean = true;
|
||||||
boolean barBoolean = false;
|
boolean barBoolean = false;
|
||||||
|
|
||||||
// Char - un singolo carattere con grandezza 16 bit
|
// Char - Un singolo carattere Unicode a 16-bit
|
||||||
char fooChar = 'A';
|
char fooChar = 'A';
|
||||||
|
|
||||||
// final - Costanti, non possono essere riassegnate ad un altro oggetto
|
// Le variabili precedute da final possono essere inizializzate una volta sola,
|
||||||
final int ORE_LAVORATIVE_DI_UNA_SETTIMANA = 9001;
|
final int HOURS_I_WORK_PER_WEEK = 9001;
|
||||||
|
// pero' e' possibile dichiararle e poi inizializzarle in un secondo momento.
|
||||||
|
final double E;
|
||||||
|
E = 2.71828;
|
||||||
|
|
||||||
// String - Stringhe, array di caratteri
|
|
||||||
String fooString = "Ecco una stringa!";
|
|
||||||
|
|
||||||
// \n e' un carattere speciale che permette di andare a capo.
|
// BigInteger - Interi a precisione arbitraria
|
||||||
String barString = "Andare a capo?\nNessun problema!";
|
//
|
||||||
// \t e' un carattere speciale che permette di aggiungere un 'Tab'
|
// BigInteger e' un tipo di dato che permette ai programmatori di
|
||||||
String bazString = "Vuoi inserire tab?\tNessun problema";
|
// gestire interi piu' grandi di 64 bit. Internamente, le variabili
|
||||||
|
// di tipo BigInteger vengono memorizzate come un vettore di byte e
|
||||||
|
// vengono manipolate usando funzioni dentro la classe BigInteger.
|
||||||
|
//
|
||||||
|
// Una variabile di tipo BigInteger puo' essere inizializzata usando
|
||||||
|
// un array di byte oppure una stringa.
|
||||||
|
|
||||||
|
BigInteger fooBigInteger = new BigDecimal(fooByteArray);
|
||||||
|
|
||||||
|
// BigDecimal - Numero con segno, immutabile, a precisione arbitraria
|
||||||
|
//
|
||||||
|
// Una variabile di tipo BigDecimal e' composta da due parti: un intero
|
||||||
|
// a precisione arbitraria detto 'non scalato', e un intero a 32 bit
|
||||||
|
// che rappresenta la 'scala', ovvero la potenza di 10 con cui
|
||||||
|
// moltiplicare l'intero non scalato.
|
||||||
|
//
|
||||||
|
// I BigDecimal permettono un controllo completo sull'arrotondamento
|
||||||
|
// dei numeri. Essi sono molto usati in ambito finanziario, nella
|
||||||
|
// gestione delle valute, e in ogni altro posto in cui serve
|
||||||
|
// precisione esatta.
|
||||||
|
//
|
||||||
|
// Le variabili di tipo BigDecimal possono essere inizializzate con un
|
||||||
|
// int, long, double o String, oppure con un intero non scalato
|
||||||
|
// (di tipo BigInteger) e una scala (int).
|
||||||
|
|
||||||
|
BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Stringhe
|
||||||
|
String fooString = "Questa e' la mia stringa!";
|
||||||
|
|
||||||
|
// \n e' un carattere di escape che rappresenta l'andare a capo
|
||||||
|
String barString = "Stampare su una nuova riga?\nNessun problema!";
|
||||||
|
// \t e' un carattere di escape che aggiunge un tab
|
||||||
|
String bazString = "Vuoi aggiungere un tab?\tNessun problema!";
|
||||||
System.out.println(fooString);
|
System.out.println(fooString);
|
||||||
System.out.println(barString);
|
System.out.println(barString);
|
||||||
System.out.println(bazString);
|
System.out.println(bazString);
|
||||||
|
|
||||||
// Vettori [array]
|
// Vettori
|
||||||
//La lunghezza del vettore deve essere decisa quando viene istanziato
|
// La dimensione di un array deve essere decisa in fase di
|
||||||
//Si puo' dichiarare come segue:
|
// istanziazione. Per dichiarare un array si puo' fare in due modi:
|
||||||
//<tipodato> [] <nomevariabile> = new <tipodato>[<grandezza vettore>];
|
// <tipoDato>[] <nomeVariabile> = new <tipoDato>[<dimensioneArray>];
|
||||||
//<tipodato> <nomevariabile>[] = new <tipodato>[<grandezza vettore>];
|
// <tipoDato> <nomeVariabile>[] = new <tipoDato>[<dimensioneArray>];
|
||||||
int [] intArray = new int[10];
|
int[] intArray = new int[10];
|
||||||
String [] stringArray = new String[1];
|
String[] stringArray = new String[1];
|
||||||
boolean boolArray [] = new boolean[100];
|
boolean boolArray[] = new boolean[100];
|
||||||
|
|
||||||
// Un altro modo per dichiarare & inizializzare un vettore
|
// Un altro modo per dichiarare ed insieme inizializzare un vettore.
|
||||||
int [] y = {9000, 1000, 1337};
|
int[] y = {9000, 1000, 1337};
|
||||||
String nomi [] = {"Andrea", "Bob", "Pippo", "Susan"};
|
String names[] = {"Gianni", "Anna", "Luca", "Cristina"};
|
||||||
boolean bools[] = new boolean[] {true, false, false};
|
boolean bools[] = new boolean[] {true, false, false};
|
||||||
|
|
||||||
// I vettori vengono indicizzati a parire dallo 0
|
// Per accedere ad un elemento di un vettore
|
||||||
System.out.println("intArray @ 0: " + intArray[0]);
|
System.out.println("intArray @ 0: " + intArray[0]);
|
||||||
|
|
||||||
// e' possibile un accesso diretto ad un elemento
|
// I vettori non sono immutabili (ma la loro dimensione si!)
|
||||||
|
// e gli indici partono da 0.
|
||||||
intArray[1] = 1;
|
intArray[1] = 1;
|
||||||
System.out.println("intArray @ 1: " + intArray[1]); // => 1
|
System.out.println("intArray @ 1: " + intArray[1]); // => 1
|
||||||
|
|
||||||
// Altro da vedere:
|
// Ci sono altri tipo di dato interessanti.
|
||||||
// Liste di array - come i vettori ma piu' funzionali
|
// ArrayList - Simili ai vettori, pero' offrono altre funzionalita',
|
||||||
// e la loro grandezza puo' variare in corso di esecuzione
|
// e la loro dimensione puo' essere modificata.
|
||||||
// Liste concatenate di memoria
|
// LinkedList - Si tratta di una lista linkata doppia, e come tale
|
||||||
|
// implementa tutte le operazioni del caso.
|
||||||
|
// Map - Un insieme di oggetti che fa corrispondere delle chiavi
|
||||||
|
// a dei valori. Non permette l'inserimento di chiavi uguali.
|
||||||
|
// HashMap - Questa classe usa una tabella di hash per implementare
|
||||||
|
// l'interfaccia di tipo Map. Questo permette di effettuare
|
||||||
|
// operazioni basilari, come inserimento e cancellazione,
|
||||||
|
// in tempo costante anche su insiemi molto grandi.
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Operatori
|
// Operatori
|
||||||
|
@ -1,29 +1,36 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
language: json
|
language: json
|
||||||
contributors:
|
contributors:
|
||||||
- ["Anna Harren", "https://github.com/iirelu"]
|
- ["Anna Harren", "https://github.com/iirelu"]
|
||||||
- ["Marco Scannadinari", "https://github.com/marcoms"]
|
- ["Marco Scannadinari", "https://github.com/marcoms"]
|
||||||
|
- ["himanshu", "https://github.com/himanshu81494"]
|
||||||
translators:
|
translators:
|
||||||
- ["Robert Margelli", "http://github.com/sinkswim/"]
|
- ["Robert Margelli", "http://github.com/sinkswim/"]
|
||||||
|
- ["Christian Grasso", "http://chris54721.net"]
|
||||||
lang: it-it
|
lang: it-it
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Dato che JSON è un formato per lo scambio di dati estremamente semplice, questo sarà con molta probabilità
|
JSON è un formato per l'interscambio di dati estremamente semplice, per cui questo sarà
|
||||||
il più semplice Learn X in Y Minutes.
|
con molta probabilità il più semplice Learn X in Y Minutes.
|
||||||
|
|
||||||
Nella sua forma più pura JSON non ha commenti, ma molti parser accettano
|
Nella sua forma più pura JSON non ha commenti, ma molti parser accettano
|
||||||
commenti in stile C (//, /\* \*/). Per lo scopo prefissato, tuttavia, tutto sarà
|
commenti in stile C (//, /\* \*/). Per lo scopo prefissato, tuttavia, tutto sarà
|
||||||
100% JSON valido. Fortunatamente, si spiega da sè.
|
100% JSON valido. Fortunatamente, si spiega da sè.
|
||||||
|
|
||||||
|
I tipi supportati da JSON comprendono: numeri, stringhe, boolean, array, oggetti e null.
|
||||||
|
I browser supportati sono: Firefox (Mozilla) 3.5+, Internet Explorer 8+, Google Chrome,
|
||||||
|
Opera 10+, Safari 4+.
|
||||||
|
I file JSON sono salvati nel formato ".json". Il MIME type per documenti JSON è
|
||||||
|
"application/json". Gli svantaggi del JSON includono l'assenza di una definizione dei tipi
|
||||||
|
e di una sorta di [DTD](https://it.wikipedia.org/wiki/Document_Type_Definition).
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"chiave": "valore",
|
"chiave": "valore",
|
||||||
|
|
||||||
"chiavi": "devono sempre essere racchiuse tra doppi apici",
|
"chiavi": "devono sempre essere racchiuse tra doppi apici",
|
||||||
"numeri": 0,
|
"numeri": 0,
|
||||||
"stringhe": "Ciaø, møndø. Tutti gli unicode sono permessi, assieme con l \"escaping\".",
|
"stringhe": "Ciaø, møndø. Tutti i caratteri Unicode sono permessi, insieme all'\"escaping\".",
|
||||||
"ha booleani?": true,
|
"ha booleani?": true,
|
||||||
"il nulla": null,
|
"il nulla": null,
|
||||||
|
|
||||||
@ -52,8 +59,8 @@ commenti in stile C (//, /\* \*/). Per lo scopo prefissato, tuttavia, tutto sar
|
|||||||
],
|
],
|
||||||
|
|
||||||
"stile alternativo": {
|
"stile alternativo": {
|
||||||
"commento": "Guarda quà!"
|
"commento": "Guarda qua!"
|
||||||
, "posizione della virgola": "non conta - fintantochè è prima del valore, allora è valida"
|
, "posizione della virgola": "non conta - se è prima della chiave successiva, allora è valida"
|
||||||
, "un altro commento": "che bello"
|
, "un altro commento": "che bello"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@ contributors:
|
|||||||
- ["Jakukyo Friel", "http://weakish.github.io"]
|
- ["Jakukyo Friel", "http://weakish.github.io"]
|
||||||
- ["Madison Dickson", "http://github.com/mix3d"]
|
- ["Madison Dickson", "http://github.com/mix3d"]
|
||||||
- ["Simon Morgan", "http://sjm.io/"]
|
- ["Simon Morgan", "http://sjm.io/"]
|
||||||
|
- ["Zachary Ferguson", "http://github.com/zfergus2"]
|
||||||
|
- ["Cameron Schermerhorn", "http://github.com/cschermerhorn"]
|
||||||
|
- ["Rachel Stiyer", "https://github.com/rstiyer"]
|
||||||
filename: LearnJava.java
|
filename: LearnJava.java
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -31,7 +34,7 @@ import java.security.*;
|
|||||||
// the file.
|
// the file.
|
||||||
public class LearnJava {
|
public class LearnJava {
|
||||||
|
|
||||||
// A program must have a main method as an entry point.
|
// In order to run a java program, it must have a main method as an entry point.
|
||||||
public static void main (String[] args) {
|
public static void main (String[] args) {
|
||||||
|
|
||||||
// Use System.out.println() to print lines.
|
// Use System.out.println() to print lines.
|
||||||
@ -45,12 +48,34 @@ public class LearnJava {
|
|||||||
System.out.print("Hello ");
|
System.out.print("Hello ");
|
||||||
System.out.print("World");
|
System.out.print("World");
|
||||||
|
|
||||||
|
// Use System.out.printf() for easy formatted printing.
|
||||||
|
System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Types & Variables
|
// Variables
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variable Declaration
|
||||||
|
*/
|
||||||
// Declare a variable using <type> <name>
|
// Declare a variable using <type> <name>
|
||||||
|
int fooInt;
|
||||||
|
// Declare multiple variables of the same type <type> <name1>, <name2>, <name3>
|
||||||
|
int fooInt1, fooInt2, fooInt3;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variable Initialization
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Initialize a variable using <type> <name> = <val>
|
||||||
|
int fooInt = 1;
|
||||||
|
// Initialize multiple variables of same type with same value <type> <name1>, <name2>, <name3> = <val>
|
||||||
|
int fooInt1, fooInt2, fooInt3;
|
||||||
|
fooInt1 = fooInt2 = fooInt3 = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variable types
|
||||||
|
*/
|
||||||
// Byte - 8-bit signed two's complement integer
|
// Byte - 8-bit signed two's complement integer
|
||||||
// (-128 <= byte <= 127)
|
// (-128 <= byte <= 127)
|
||||||
byte fooByte = 100;
|
byte fooByte = 100;
|
||||||
@ -72,11 +97,13 @@ public class LearnJava {
|
|||||||
// Note: Java has no unsigned types.
|
// Note: Java has no unsigned types.
|
||||||
|
|
||||||
// Float - Single-precision 32-bit IEEE 754 Floating Point
|
// Float - Single-precision 32-bit IEEE 754 Floating Point
|
||||||
|
// 2^-149 <= float <= (2-2^-23) * 2^127
|
||||||
float fooFloat = 234.5f;
|
float fooFloat = 234.5f;
|
||||||
// f is used to denote that this variable value is of type float;
|
// f or F is used to denote that this variable value is of type float;
|
||||||
// otherwise it is treated as double.
|
// otherwise it is treated as double.
|
||||||
|
|
||||||
// Double - Double-precision 64-bit IEEE 754 Floating Point
|
// Double - Double-precision 64-bit IEEE 754 Floating Point
|
||||||
|
// 2^-1074 <= x <= (2-2^-52) * 2^1023
|
||||||
double fooDouble = 123.4;
|
double fooDouble = 123.4;
|
||||||
|
|
||||||
// Boolean - true & false
|
// Boolean - true & false
|
||||||
@ -86,8 +113,44 @@ public class LearnJava {
|
|||||||
// Char - A single 16-bit Unicode character
|
// Char - A single 16-bit Unicode character
|
||||||
char fooChar = 'A';
|
char fooChar = 'A';
|
||||||
|
|
||||||
// final variables can't be reassigned to another object.
|
// final variables can't be reassigned to another object,
|
||||||
final int HOURS_I_WORK_PER_WEEK = 9001;
|
final int HOURS_I_WORK_PER_WEEK = 9001;
|
||||||
|
// but they can be initialized later.
|
||||||
|
final double E;
|
||||||
|
E = 2.71828;
|
||||||
|
|
||||||
|
|
||||||
|
// BigInteger - Immutable arbitrary-precision integers
|
||||||
|
//
|
||||||
|
// BigInteger is a data type that allows programmers to manipulate
|
||||||
|
// integers longer than 64-bits. Integers are stored as an array of
|
||||||
|
// of bytes and are manipulated using functions built into BigInteger
|
||||||
|
//
|
||||||
|
// BigInteger can be initialized using an array of bytes or a string.
|
||||||
|
|
||||||
|
BigInteger fooBigInteger = new BigInteger(fooByteArray);
|
||||||
|
|
||||||
|
|
||||||
|
// BigDecimal - Immutable, arbitrary-precision signed decimal number
|
||||||
|
//
|
||||||
|
// A BigDecimal takes two parts: an arbitrary precision integer
|
||||||
|
// unscaled value and a 32-bit integer scale
|
||||||
|
//
|
||||||
|
// BigDecimal allows the programmer complete control over decimal
|
||||||
|
// rounding. It is recommended to use BigDecimal with currency values
|
||||||
|
// and where exact decimal precision is required.
|
||||||
|
//
|
||||||
|
// BigDecimal can be initialized with an int, long, double or String
|
||||||
|
// or by initializing the unscaled value (BigInteger) and scale (int).
|
||||||
|
|
||||||
|
BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
|
||||||
|
|
||||||
|
// Be wary of the constructor that takes a float or double as
|
||||||
|
// the inaccuracy of the float/double will be copied in BigDecimal.
|
||||||
|
// Prefer the String constructor when you need an exact value.
|
||||||
|
|
||||||
|
BigDecimal tenCents = new BigDecimal("0.1");
|
||||||
|
|
||||||
|
|
||||||
// Strings
|
// Strings
|
||||||
String fooString = "My String Is Here!";
|
String fooString = "My String Is Here!";
|
||||||
@ -127,8 +190,12 @@ public class LearnJava {
|
|||||||
// LinkedLists - Implementation of doubly-linked list. All of the
|
// LinkedLists - Implementation of doubly-linked list. All of the
|
||||||
// operations perform as could be expected for a
|
// operations perform as could be expected for a
|
||||||
// doubly-linked list.
|
// doubly-linked list.
|
||||||
// Maps - A set of objects that maps keys to values. A map cannot
|
// Maps - A set of objects that map keys to values. Map is
|
||||||
// contain duplicate keys; each key can map to at most one value.
|
// an interface and therefore cannot be instantiated.
|
||||||
|
// The type of keys and values contained in a Map must
|
||||||
|
// be specified upon instantiation of the implementing
|
||||||
|
// class. Each key may map to only one corresponding value,
|
||||||
|
// and each key may appear only once (no duplicates).
|
||||||
// HashMaps - This class uses a hashtable to implement the Map
|
// HashMaps - This class uses a hashtable to implement the Map
|
||||||
// interface. This allows the execution time of basic
|
// interface. This allows the execution time of basic
|
||||||
// operations, such as get and insert element, to remain
|
// operations, such as get and insert element, to remain
|
||||||
@ -145,7 +212,8 @@ public class LearnJava {
|
|||||||
System.out.println("1+2 = " + (i1 + i2)); // => 3
|
System.out.println("1+2 = " + (i1 + i2)); // => 3
|
||||||
System.out.println("2-1 = " + (i2 - i1)); // => 1
|
System.out.println("2-1 = " + (i2 - i1)); // => 1
|
||||||
System.out.println("2*1 = " + (i2 * i1)); // => 2
|
System.out.println("2*1 = " + (i2 * i1)); // => 2
|
||||||
System.out.println("1/2 = " + (i1 / i2)); // => 0 (0.5 truncated down)
|
System.out.println("1/2 = " + (i1 / i2)); // => 0 (int/int returns an int)
|
||||||
|
System.out.println("1/2 = " + (i1 / (double)i2)); // => 0.5
|
||||||
|
|
||||||
// Modulo
|
// Modulo
|
||||||
System.out.println("11%3 = "+(11 % 3)); // => 2
|
System.out.println("11%3 = "+(11 % 3)); // => 2
|
||||||
@ -158,12 +226,17 @@ public class LearnJava {
|
|||||||
System.out.println("2 <= 2? " + (2 <= 2)); // => true
|
System.out.println("2 <= 2? " + (2 <= 2)); // => true
|
||||||
System.out.println("2 >= 2? " + (2 >= 2)); // => true
|
System.out.println("2 >= 2? " + (2 >= 2)); // => true
|
||||||
|
|
||||||
|
// Boolean operators
|
||||||
|
System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false
|
||||||
|
System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true
|
||||||
|
System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true
|
||||||
|
|
||||||
// Bitwise operators!
|
// Bitwise operators!
|
||||||
/*
|
/*
|
||||||
~ Unary bitwise complement
|
~ Unary bitwise complement
|
||||||
<< Signed left shift
|
<< Signed left shift
|
||||||
>> Signed right shift
|
>> Signed/Arithmetic right shift
|
||||||
>>> Unsigned right shift
|
>>> Unsigned/Logical right shift
|
||||||
& Bitwise AND
|
& Bitwise AND
|
||||||
^ Bitwise exclusive OR
|
^ Bitwise exclusive OR
|
||||||
| Bitwise inclusive OR
|
| Bitwise inclusive OR
|
||||||
@ -187,7 +260,7 @@ public class LearnJava {
|
|||||||
|
|
||||||
// If statements are c-like
|
// If statements are c-like
|
||||||
int j = 10;
|
int j = 10;
|
||||||
if (j == 10){
|
if (j == 10) {
|
||||||
System.out.println("I get printed");
|
System.out.println("I get printed");
|
||||||
} else if (j > 10) {
|
} else if (j > 10) {
|
||||||
System.out.println("I don't");
|
System.out.println("I don't");
|
||||||
@ -216,14 +289,24 @@ public class LearnJava {
|
|||||||
System.out.println("fooDoWhile Value: " + fooDoWhile);
|
System.out.println("fooDoWhile Value: " + fooDoWhile);
|
||||||
|
|
||||||
// For Loop
|
// For Loop
|
||||||
int fooFor;
|
|
||||||
// for loop structure => for(<start_statement>; <conditional>; <step>)
|
// for loop structure => for(<start_statement>; <conditional>; <step>)
|
||||||
for (fooFor = 0; fooFor < 10; fooFor++) {
|
for (int fooFor = 0; fooFor < 10; fooFor++) {
|
||||||
System.out.println(fooFor);
|
System.out.println(fooFor);
|
||||||
// Iterated 10 times, fooFor 0->9
|
// Iterated 10 times, fooFor 0->9
|
||||||
}
|
}
|
||||||
System.out.println("fooFor Value: " + fooFor);
|
System.out.println("fooFor Value: " + fooFor);
|
||||||
|
|
||||||
|
// Nested For Loop Exit with Label
|
||||||
|
outer:
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
for (int j = 0; j < 10; j++) {
|
||||||
|
if (i == 5 && j ==5) {
|
||||||
|
break outer;
|
||||||
|
// breaks out of outer loop instead of only the inner one
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For Each Loop
|
// For Each Loop
|
||||||
// The for loop is also able to iterate over arrays as well as objects
|
// The for loop is also able to iterate over arrays as well as objects
|
||||||
// that implement the Iterable interface.
|
// that implement the Iterable interface.
|
||||||
@ -255,6 +338,23 @@ public class LearnJava {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
System.out.println("Switch Case Result: " + monthString);
|
System.out.println("Switch Case Result: " + monthString);
|
||||||
|
|
||||||
|
// Starting in Java 7 and above, switching Strings works like this:
|
||||||
|
String myAnswer = "maybe";
|
||||||
|
switch(myAnswer) {
|
||||||
|
case "yes":
|
||||||
|
System.out.println("You answered yes.");
|
||||||
|
break;
|
||||||
|
case "no":
|
||||||
|
System.out.println("You answered no.");
|
||||||
|
break;
|
||||||
|
case "maybe":
|
||||||
|
System.out.println("You answered maybe.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.out.println("You answered " + myAnswer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Conditional Shorthand
|
// Conditional Shorthand
|
||||||
// You can use the '?' operator for quick assignments or logic forks.
|
// You can use the '?' operator for quick assignments or logic forks.
|
||||||
@ -306,11 +406,39 @@ public class LearnJava {
|
|||||||
// toString returns this Object's string representation.
|
// toString returns this Object's string representation.
|
||||||
System.out.println("trek info: " + trek.toString());
|
System.out.println("trek info: " + trek.toString());
|
||||||
|
|
||||||
|
// Double Brace Initialization
|
||||||
|
// The Java Language has no syntax for how to create static Collections
|
||||||
|
// in an easy way. Usually you end up in the following way:
|
||||||
|
|
||||||
|
private static final Set<String> COUNTRIES = new HashSet<String>();
|
||||||
|
static {
|
||||||
|
validCodes.add("DENMARK");
|
||||||
|
validCodes.add("SWEDEN");
|
||||||
|
validCodes.add("FINLAND");
|
||||||
|
}
|
||||||
|
|
||||||
|
// But there's a nifty way to achieve the same thing in an
|
||||||
|
// easier way, by using something that is called Double Brace
|
||||||
|
// Initialization.
|
||||||
|
|
||||||
|
private static final Set<String> COUNTRIES = new HashSet<String>() {{
|
||||||
|
add("DENMARK");
|
||||||
|
add("SWEDEN");
|
||||||
|
add("FINLAND");
|
||||||
|
}}
|
||||||
|
|
||||||
|
// The first brace is creating a new AnonymousInnerClass and the
|
||||||
|
// second one declares an instance initializer block. This block
|
||||||
|
// is called when the anonymous inner class is created.
|
||||||
|
// This does not only work for Collections, it works for all
|
||||||
|
// non-final classes.
|
||||||
|
|
||||||
} // End main method
|
} // End main method
|
||||||
} // End LearnJava class
|
} // End LearnJava class
|
||||||
|
|
||||||
|
|
||||||
// You can include other, non-public outer-level classes in a .java file
|
// You can include other, non-public outer-level classes in a .java file,
|
||||||
|
// but it is good practice. Instead split classes into separate files.
|
||||||
|
|
||||||
|
|
||||||
// Class Declaration Syntax:
|
// Class Declaration Syntax:
|
||||||
@ -327,9 +455,22 @@ class Bicycle {
|
|||||||
protected int gear; // Protected: Accessible from the class and subclasses
|
protected int gear; // Protected: Accessible from the class and subclasses
|
||||||
String name; // default: Only accessible from within this package
|
String name; // default: Only accessible from within this package
|
||||||
|
|
||||||
|
static String className; // Static class variable
|
||||||
|
|
||||||
|
// Static block
|
||||||
|
// Java has no implementation of static constructors, but
|
||||||
|
// has a static block that can be used to initialize class variables
|
||||||
|
// (static variables).
|
||||||
|
// This block will be called when the class is loaded.
|
||||||
|
static {
|
||||||
|
className = "Bicycle";
|
||||||
|
}
|
||||||
|
|
||||||
// Constructors are a way of creating classes
|
// Constructors are a way of creating classes
|
||||||
// This is a constructor
|
// This is a constructor
|
||||||
public Bicycle() {
|
public Bicycle() {
|
||||||
|
// You can also call another constructor:
|
||||||
|
// this(1, 50, 5, "Bontrager");
|
||||||
gear = 1;
|
gear = 1;
|
||||||
cadence = 50;
|
cadence = 50;
|
||||||
speed = 5;
|
speed = 5;
|
||||||
@ -345,13 +486,13 @@ class Bicycle {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function Syntax:
|
// Method Syntax:
|
||||||
// <public/private/protected> <return type> <function name>(<args>)
|
// <public/private/protected> <return type> <function name>(<args>)
|
||||||
|
|
||||||
// Java classes often implement getters and setters for their fields
|
// Java classes often implement getters and setters for their fields
|
||||||
|
|
||||||
// Method declaration syntax:
|
// Method declaration syntax:
|
||||||
// <scope> <return type> <method name>(<args>)
|
// <access modifier> <return type> <method name>(<args>)
|
||||||
public int getCadence() {
|
public int getCadence() {
|
||||||
return cadence;
|
return cadence;
|
||||||
}
|
}
|
||||||
@ -382,7 +523,7 @@ class Bicycle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Method to display the attribute values of this Object.
|
//Method to display the attribute values of this Object.
|
||||||
@Override
|
@Override // Inherited from the Object class.
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
|
return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
|
||||||
" name: " + name;
|
" name: " + name;
|
||||||
@ -417,40 +558,210 @@ class PennyFarthing extends Bicycle {
|
|||||||
|
|
||||||
// Example - Food:
|
// Example - Food:
|
||||||
public interface Edible {
|
public interface Edible {
|
||||||
public void eat(); // Any class that implements this interface, must
|
public void eat(); // Any class that implements this interface, must
|
||||||
// implement this method.
|
// implement this method.
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Digestible {
|
public interface Digestible {
|
||||||
public void digest();
|
public void digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// We can now create a class that implements both of these interfaces.
|
// We can now create a class that implements both of these interfaces.
|
||||||
public class Fruit implements Edible, Digestible {
|
public class Fruit implements Edible, Digestible {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eat() {
|
public void eat() {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void digest() {
|
public void digest() {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In Java, you can extend only one class, but you can implement many
|
// In Java, you can extend only one class, but you can implement many
|
||||||
// interfaces. For example:
|
// interfaces. For example:
|
||||||
public class ExampleClass extends ExampleClassParent implements InterfaceOne,
|
public class ExampleClass extends ExampleClassParent implements InterfaceOne,
|
||||||
InterfaceTwo {
|
InterfaceTwo {
|
||||||
@Override
|
|
||||||
public void InterfaceOneMethod() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void InterfaceTwoMethod() {
|
public void InterfaceOneMethod() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void InterfaceTwoMethod() {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Abstract Classes
|
||||||
|
|
||||||
|
// Abstract Class declaration syntax
|
||||||
|
// <access-level> abstract <abstract-class-name> extends <super-abstract-classes> {
|
||||||
|
// // Constants and variables
|
||||||
|
// // Method declarations
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Marking a class as abstract means that it contains abstract methods that must
|
||||||
|
// be defined in a child class. Similar to interfaces, abstract classes cannot
|
||||||
|
// be instantiated, but instead must be extended and the abstract methods
|
||||||
|
// defined. Different from interfaces, abstract classes can contain a mixture of
|
||||||
|
// concrete and abstract methods. Methods in an interface cannot have a body,
|
||||||
|
// unless the method is static, and variables are final by default, unlike an
|
||||||
|
// abstract class. Also abstract classes CAN have the "main" method.
|
||||||
|
|
||||||
|
public abstract class Animal
|
||||||
|
{
|
||||||
|
public abstract void makeSound();
|
||||||
|
|
||||||
|
// Method can have a body
|
||||||
|
public void eat()
|
||||||
|
{
|
||||||
|
System.out.println("I am an animal and I am Eating.");
|
||||||
|
// Note: We can access private variable here.
|
||||||
|
age = 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No need to initialize, however in an interface
|
||||||
|
// a variable is implicitly final and hence has
|
||||||
|
// to be initialized.
|
||||||
|
protected int age;
|
||||||
|
|
||||||
|
public void printAge()
|
||||||
|
{
|
||||||
|
System.out.println(age);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Abstract classes can have main function.
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
System.out.println("I am abstract");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Dog extends Animal
|
||||||
|
{
|
||||||
|
// Note still have to override the abstract methods in the
|
||||||
|
// abstract class.
|
||||||
|
@Override
|
||||||
|
public void makeSound()
|
||||||
|
{
|
||||||
|
System.out.println("Bark");
|
||||||
|
// age = 30; ==> ERROR! age is private to Animal
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: You will get an error if you used the
|
||||||
|
// @Override annotation here, since java doesn't allow
|
||||||
|
// overriding of static methods.
|
||||||
|
// What is happening here is called METHOD HIDING.
|
||||||
|
// Check out this awesome SO post: http://stackoverflow.com/questions/16313649/
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
Dog pluto = new Dog();
|
||||||
|
pluto.makeSound();
|
||||||
|
pluto.eat();
|
||||||
|
pluto.printAge();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final Classes
|
||||||
|
|
||||||
|
// Final Class declaration syntax
|
||||||
|
// <access-level> final <final-class-name> {
|
||||||
|
// // Constants and variables
|
||||||
|
// // Method declarations
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Final classes are classes that cannot be inherited from and are therefore a
|
||||||
|
// final child. In a way, final classes are the opposite of abstract classes
|
||||||
|
// because abstract classes must be extended, but final classes cannot be
|
||||||
|
// extended.
|
||||||
|
public final class SaberToothedCat extends Animal
|
||||||
|
{
|
||||||
|
// Note still have to override the abstract methods in the
|
||||||
|
// abstract class.
|
||||||
|
@Override
|
||||||
|
public void makeSound()
|
||||||
|
{
|
||||||
|
System.out.println("Roar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final Methods
|
||||||
|
public abstract class Mammal()
|
||||||
|
{
|
||||||
|
// Final Method Syntax:
|
||||||
|
// <access modifier> final <return type> <function name>(<args>)
|
||||||
|
|
||||||
|
// Final methods, like, final classes cannot be overridden by a child class,
|
||||||
|
// and are therefore the final implementation of the method.
|
||||||
|
public final boolean isWarmBlooded()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Enum Type
|
||||||
|
//
|
||||||
|
// An enum type is a special data type that enables for a variable to be a set
|
||||||
|
// of predefined constants. The variable must be equal to one of the values that
|
||||||
|
// have been predefined for it. Because they are constants, the names of an enum
|
||||||
|
// type's fields are in uppercase letters. In the Java programming language, you
|
||||||
|
// define an enum type by using the enum keyword. For example, you would specify
|
||||||
|
// a days-of-the-week enum type as:
|
||||||
|
|
||||||
|
public enum Day {
|
||||||
|
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
|
||||||
|
THURSDAY, FRIDAY, SATURDAY
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can use our enum Day like that:
|
||||||
|
|
||||||
|
public class EnumTest {
|
||||||
|
|
||||||
|
// Variable Enum
|
||||||
|
Day day;
|
||||||
|
|
||||||
|
public EnumTest(Day day) {
|
||||||
|
this.day = day;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tellItLikeItIs() {
|
||||||
|
switch (day) {
|
||||||
|
case MONDAY:
|
||||||
|
System.out.println("Mondays are bad.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FRIDAY:
|
||||||
|
System.out.println("Fridays are better.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SATURDAY:
|
||||||
|
case SUNDAY:
|
||||||
|
System.out.println("Weekends are best.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
System.out.println("Midweek days are so-so.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
EnumTest firstDay = new EnumTest(Day.MONDAY);
|
||||||
|
firstDay.tellItLikeItIs(); // => Mondays are bad.
|
||||||
|
EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
|
||||||
|
thirdDay.tellItLikeItIs(); // => Midweek days are so-so.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enum types are much more powerful than we show above.
|
||||||
|
// The enum body can include methods and other fields.
|
||||||
|
// You can se more at https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
@ -474,7 +785,7 @@ The links provided here below are just to get an understanding of the topic, fee
|
|||||||
|
|
||||||
* [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
|
* [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
|
||||||
|
|
||||||
* [Java Code Conventions](http://www.oracle.com/technetwork/java/codeconv-138413.html)
|
* [Java Code Conventions](http://www.oracle.com/technetwork/java/codeconvtoc-136057.html)
|
||||||
|
|
||||||
**Online Practice and Tutorials**
|
**Online Practice and Tutorials**
|
||||||
|
|
||||||
|
@ -16,13 +16,14 @@ JavaScript isn't just limited to web browsers, though: Node.js, a project that
|
|||||||
provides a standalone runtime for Google Chrome's V8 JavaScript engine, is
|
provides a standalone runtime for Google Chrome's V8 JavaScript engine, is
|
||||||
becoming more and more popular.
|
becoming more and more popular.
|
||||||
|
|
||||||
Feedback would be highly appreciated! You can reach me at
|
JavaScript has a C-like syntax, so if you've used languages like C or Java,
|
||||||
[@adambrenecki](https://twitter.com/adambrenecki), or
|
a lot of the basic syntax will already be familiar. Despite this, and despite
|
||||||
[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
|
the similarity in name, JavaScript's object model is significantly different to
|
||||||
|
Java's.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Comments are like C. Single-line comments start with two slashes,
|
// Single-line comments start with two slashes.
|
||||||
/* and multiline comments start with slash-star
|
/* Multiline comments start with slash-star,
|
||||||
and end with star-slash */
|
and end with star-slash */
|
||||||
|
|
||||||
// Statements can be terminated by ;
|
// Statements can be terminated by ;
|
||||||
@ -40,7 +41,7 @@ doStuff()
|
|||||||
|
|
||||||
// JavaScript has one number type (which is a 64-bit IEEE 754 double).
|
// JavaScript has one number type (which is a 64-bit IEEE 754 double).
|
||||||
// Doubles have a 52-bit mantissa, which is enough to store integers
|
// Doubles have a 52-bit mantissa, which is enough to store integers
|
||||||
// up to about 9✕10¹⁵ precisely.
|
// up to about 9✕10¹⁵ precisely.
|
||||||
3; // = 3
|
3; // = 3
|
||||||
1.5; // = 1.5
|
1.5; // = 1.5
|
||||||
|
|
||||||
@ -54,6 +55,11 @@ doStuff()
|
|||||||
// Including uneven division.
|
// Including uneven division.
|
||||||
5 / 2; // = 2.5
|
5 / 2; // = 2.5
|
||||||
|
|
||||||
|
// And modulo division.
|
||||||
|
10 % 2; // = 0
|
||||||
|
30 % 4; // = 2
|
||||||
|
18.5 % 7; // = 4.5
|
||||||
|
|
||||||
// Bitwise operations also work; when you perform a bitwise operation your float
|
// Bitwise operations also work; when you perform a bitwise operation your float
|
||||||
// is converted to a signed int *up to* 32 bits.
|
// is converted to a signed int *up to* 32 bits.
|
||||||
1 << 2; // = 4
|
1 << 2; // = 4
|
||||||
@ -64,7 +70,7 @@ doStuff()
|
|||||||
// There are three special not-a-real-number values:
|
// There are three special not-a-real-number values:
|
||||||
Infinity; // result of e.g. 1/0
|
Infinity; // result of e.g. 1/0
|
||||||
-Infinity; // result of e.g. -1/0
|
-Infinity; // result of e.g. -1/0
|
||||||
NaN; // result of e.g. 0/0
|
NaN; // result of e.g. 0/0, stands for 'Not a Number'
|
||||||
|
|
||||||
// There's also a boolean type.
|
// There's also a boolean type.
|
||||||
true;
|
true;
|
||||||
@ -95,6 +101,10 @@ false;
|
|||||||
// Strings are concatenated with +
|
// Strings are concatenated with +
|
||||||
"Hello " + "world!"; // = "Hello world!"
|
"Hello " + "world!"; // = "Hello world!"
|
||||||
|
|
||||||
|
// ... which works with more than just strings
|
||||||
|
"1, 2, " + 3; // = "1, 2, 3"
|
||||||
|
"Hello " + ["world", "!"] // = "Hello world,!"
|
||||||
|
|
||||||
// and are compared with < and >
|
// and are compared with < and >
|
||||||
"a" < "b"; // = true
|
"a" < "b"; // = true
|
||||||
|
|
||||||
@ -104,7 +114,7 @@ null == undefined; // = true
|
|||||||
|
|
||||||
// ...unless you use ===
|
// ...unless you use ===
|
||||||
"5" === 5; // = false
|
"5" === 5; // = false
|
||||||
null === undefined; // = false
|
null === undefined; // = false
|
||||||
|
|
||||||
// ...which can result in some weird behaviour...
|
// ...which can result in some weird behaviour...
|
||||||
13 + !0; // 14
|
13 + !0; // 14
|
||||||
@ -135,7 +145,7 @@ undefined; // used to indicate a value is not currently present (although
|
|||||||
// character.
|
// character.
|
||||||
var someVar = 5;
|
var someVar = 5;
|
||||||
|
|
||||||
// if you leave the var keyword off, you won't get an error...
|
// If you leave the var keyword off, you won't get an error...
|
||||||
someOtherVar = 10;
|
someOtherVar = 10;
|
||||||
|
|
||||||
// ...but your variable will be created in the global scope, not in the scope
|
// ...but your variable will be created in the global scope, not in the scope
|
||||||
@ -144,6 +154,10 @@ someOtherVar = 10;
|
|||||||
// Variables declared without being assigned to are set to undefined.
|
// Variables declared without being assigned to are set to undefined.
|
||||||
var someThirdVar; // = undefined
|
var someThirdVar; // = undefined
|
||||||
|
|
||||||
|
// If you want to declare a couple of variables, then you could use a comma
|
||||||
|
// separator
|
||||||
|
var someFourthVar = 2, someFifthVar = 4;
|
||||||
|
|
||||||
// There's shorthand for performing math operations on variables:
|
// There's shorthand for performing math operations on variables:
|
||||||
someVar += 5; // equivalent to someVar = someVar + 5; someVar is 10 now
|
someVar += 5; // equivalent to someVar = someVar + 5; someVar is 10 now
|
||||||
someVar *= 10; // now someVar is 100
|
someVar *= 10; // now someVar is 100
|
||||||
@ -189,8 +203,6 @@ myObj.myFourthKey; // = undefined
|
|||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
// 3. Logic and Control Structures
|
// 3. Logic and Control Structures
|
||||||
|
|
||||||
// The syntax for this section is almost identical to Java's.
|
|
||||||
|
|
||||||
// The `if` structure works as you'd expect.
|
// The `if` structure works as you'd expect.
|
||||||
var count = 1;
|
var count = 1;
|
||||||
if (count == 3){
|
if (count == 3){
|
||||||
@ -218,6 +230,27 @@ for (var i = 0; i < 5; i++){
|
|||||||
// will run 5 times
|
// will run 5 times
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The for/in statement iterates over every property across the entire prototype chain.
|
||||||
|
var description = "";
|
||||||
|
var person = {fname:"Paul", lname:"Ken", age:18};
|
||||||
|
for (var x in person){
|
||||||
|
description += person[x] + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// To only consider properties attached to the object itself
|
||||||
|
// and not its prototypes, use the `hasOwnProperty()` check.
|
||||||
|
var description = "";
|
||||||
|
var person = {fname:"Paul", lname:"Ken", age:18};
|
||||||
|
for (var x in person){
|
||||||
|
if (person.hasOwnProperty(x)){
|
||||||
|
description += person[x] + " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For/in should not be used to iterate over an Array where the index order
|
||||||
|
// is important, as there is no guarantee that for/in will return the indexes
|
||||||
|
// in any particular order.
|
||||||
|
|
||||||
// && is logical and, || is logical or
|
// && is logical and, || is logical or
|
||||||
if (house.size == "big" && house.colour == "blue"){
|
if (house.size == "big" && house.colour == "blue"){
|
||||||
house.contains = "bear";
|
house.contains = "bear";
|
||||||
@ -231,8 +264,8 @@ var name = otherName || "default";
|
|||||||
|
|
||||||
|
|
||||||
// The `switch` statement checks for equality with `===`.
|
// The `switch` statement checks for equality with `===`.
|
||||||
// use 'break' after each case
|
// Use 'break' after each case
|
||||||
// or the cases after the correct one will be executed too.
|
// or the cases after the correct one will be executed too.
|
||||||
grade = 'B';
|
grade = 'B';
|
||||||
switch (grade) {
|
switch (grade) {
|
||||||
case 'A':
|
case 'A':
|
||||||
@ -262,12 +295,9 @@ myFunction("foo"); // = "FOO"
|
|||||||
// Note that the value to be returned must start on the same line as the
|
// Note that the value to be returned must start on the same line as the
|
||||||
// `return` keyword, otherwise you'll always return `undefined` due to
|
// `return` keyword, otherwise you'll always return `undefined` due to
|
||||||
// automatic semicolon insertion. Watch out for this when using Allman style.
|
// automatic semicolon insertion. Watch out for this when using Allman style.
|
||||||
function myFunction()
|
function myFunction(){
|
||||||
{
|
|
||||||
return // <- semicolon automatically inserted here
|
return // <- semicolon automatically inserted here
|
||||||
{
|
{thisIsAn: 'object literal'}
|
||||||
thisIsAn: 'object literal'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
myFunction(); // = undefined
|
myFunction(); // = undefined
|
||||||
|
|
||||||
@ -281,6 +311,12 @@ setTimeout(myFunction, 5000);
|
|||||||
// Note: setTimeout isn't part of the JS language, but is provided by browsers
|
// Note: setTimeout isn't part of the JS language, but is provided by browsers
|
||||||
// and Node.js.
|
// and Node.js.
|
||||||
|
|
||||||
|
// Another function provided by browsers is setInterval
|
||||||
|
function myFunction(){
|
||||||
|
// this code will be called every 5 seconds
|
||||||
|
}
|
||||||
|
setInterval(myFunction, 5000);
|
||||||
|
|
||||||
// Function objects don't even have to be declared with a name - you can write
|
// Function objects don't even have to be declared with a name - you can write
|
||||||
// an anonymous function definition directly into the arguments of another.
|
// an anonymous function definition directly into the arguments of another.
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
@ -299,7 +335,7 @@ i; // = 5 - not undefined as you'd expect in a block-scoped language
|
|||||||
// scope.
|
// scope.
|
||||||
(function(){
|
(function(){
|
||||||
var temporary = 5;
|
var temporary = 5;
|
||||||
// We can access the global scope by assiging to the "global object", which
|
// We can access the global scope by assigning to the "global object", which
|
||||||
// in a web browser is always `window`. The global object may have a
|
// in a web browser is always `window`. The global object may have a
|
||||||
// different name in non-browser environments such as Node.js.
|
// different name in non-browser environments such as Node.js.
|
||||||
window.permanent = 10;
|
window.permanent = 10;
|
||||||
@ -393,7 +429,7 @@ var doubler = product.bind(this, 2);
|
|||||||
doubler(8); // = 16
|
doubler(8); // = 16
|
||||||
|
|
||||||
// When you call a function with the `new` keyword, a new object is created, and
|
// When you call a function with the `new` keyword, a new object is created, and
|
||||||
// made available to the function via the this keyword. Functions designed to be
|
// made available to the function via the `this` keyword. Functions designed to be
|
||||||
// called like that are called constructors.
|
// called like that are called constructors.
|
||||||
|
|
||||||
var MyConstructor = function(){
|
var MyConstructor = function(){
|
||||||
@ -475,6 +511,10 @@ myNumber === myNumberObj; // = false
|
|||||||
if (0){
|
if (0){
|
||||||
// This code won't execute, because 0 is falsy.
|
// This code won't execute, because 0 is falsy.
|
||||||
}
|
}
|
||||||
|
if (new Number(0)){
|
||||||
|
// This code will execute, because wrapped numbers are objects, and objects
|
||||||
|
// are always truthy.
|
||||||
|
}
|
||||||
|
|
||||||
// However, the wrapper objects and the regular builtins share a prototype, so
|
// However, the wrapper objects and the regular builtins share a prototype, so
|
||||||
// you can actually add functionality to a string, for instance.
|
// you can actually add functionality to a string, for instance.
|
||||||
@ -502,28 +542,42 @@ if (Object.create === undefined){ // don't overwrite it if it exists
|
|||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
|
||||||
The [Mozilla Developer
|
The [Mozilla Developer Network][1] provides excellent documentation for
|
||||||
Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript) provides
|
JavaScript as it's used in browsers. Plus, it's a wiki, so as you learn more you
|
||||||
excellent documentation for JavaScript as it's used in browsers. Plus, it's a
|
can help others out by sharing your own knowledge.
|
||||||
wiki, so as you learn more you can help others out by sharing your own
|
|
||||||
knowledge.
|
|
||||||
|
|
||||||
MDN's [A re-introduction to
|
MDN's [A re-introduction to JavaScript][2] covers much of the concepts covered
|
||||||
JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
here in more detail. This guide has quite deliberately only covered the
|
||||||
covers much of the concepts covered here in more detail. This guide has quite
|
JavaScript language itself; if you want to learn more about how to use
|
||||||
deliberately only covered the JavaScript language itself; if you want to learn
|
JavaScript in web pages, start by learning about the [Document Object Model][3].
|
||||||
more about how to use JavaScript in web pages, start by learning about the
|
|
||||||
[Document Object
|
|
||||||
Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)
|
|
||||||
|
|
||||||
[Learn Javascript by Example and with Challenges](http://www.learneroo.com/modules/64/nodes/350) is a variant of this reference with built-in challenges.
|
[Learn Javascript by Example and with Challenges][4] is a variant of this
|
||||||
|
reference with built-in challenges.
|
||||||
|
|
||||||
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) is an in-depth
|
[JavaScript Garden][5] is an in-depth guide of all the counter-intuitive parts
|
||||||
guide of all the counter-intuitive parts of the language.
|
of the language.
|
||||||
|
|
||||||
[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) is a classic guide / reference book.
|
[JavaScript: The Definitive Guide][6] is a classic guide and reference book.
|
||||||
|
|
||||||
In addition to direct contributors to this article, some content is adapted
|
[Eloquent Javascript][8] by Marijn Haverbeke is an excellent JS book/ebook with attached terminal
|
||||||
from Louie Dinh's Python tutorial on this site, and the [JS
|
|
||||||
Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
[Eloquent Javascript - The Annotated Version][9] by Gordon Zhu is also a great derivative of Eloquent Javascript with extra explanations and clarifications for some of the more complicated examples.
|
||||||
on the Mozilla Developer Network.
|
|
||||||
|
[Javascript: The Right Way][10] is a guide intended to introduce new developers to JavaScript and help experienced developers learn more about its best practices.
|
||||||
|
|
||||||
|
|
||||||
|
In addition to direct contributors to this article, some content is adapted from
|
||||||
|
Louie Dinh's Python tutorial on this site, and the [JS Tutorial][7] on the
|
||||||
|
Mozilla Developer Network.
|
||||||
|
|
||||||
|
|
||||||
|
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript
|
||||||
|
[2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
|
||||||
|
[3]: https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core
|
||||||
|
[4]: http://www.learneroo.com/modules/64/nodes/350
|
||||||
|
[5]: http://bonsaiden.github.io/JavaScript-Garden/
|
||||||
|
[6]: http://www.amazon.com/gp/product/0596805527/
|
||||||
|
[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
|
||||||
|
[8]: http://eloquentjavascript.net/
|
||||||
|
[9]: http://watchandcode.com/courses/eloquent-javascript-the-annotated-version
|
||||||
|
[10]: http://jstherightway.org/
|
||||||
|
@ -4,19 +4,33 @@ filename: learnjson.json
|
|||||||
contributors:
|
contributors:
|
||||||
- ["Anna Harren", "https://github.com/iirelu"]
|
- ["Anna Harren", "https://github.com/iirelu"]
|
||||||
- ["Marco Scannadinari", "https://github.com/marcoms"]
|
- ["Marco Scannadinari", "https://github.com/marcoms"]
|
||||||
|
- ["himanshu", "https://github.com/himanshu81494"]
|
||||||
|
- ["Michael Neth", "https://github.com/infernocloud"]
|
||||||
---
|
---
|
||||||
|
|
||||||
As JSON is an extremely simple data-interchange format, this is most likely going
|
JSON is an extremely simple data-interchange format. As [json.org](http://json.org) says, it is easy for humans to read and write and for machines to parse and generate.
|
||||||
to be the simplest Learn X in Y Minutes ever.
|
|
||||||
|
|
||||||
JSON in its purest form has no actual comments, but most parsers will accept
|
A piece of JSON must represent either:
|
||||||
C-style (`//`, `/* */`) comments. For the purposes of this, however, everything is
|
* A collection of name/value pairs (`{ }`). In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
|
||||||
going to be 100% valid JSON. Luckily, it kind of speaks for itself.
|
* An ordered list of values (`[ ]`). In various languages, this is realized as an array, vector, list, or sequence.
|
||||||
|
an array/list/sequence (`[ ]`) or a dictionary/object/associated array (`{ }`).
|
||||||
|
|
||||||
|
JSON in its purest form has no actual comments, but most parsers will accept C-style (`//`, `/* */`) comments. Some parsers also tolerate a trailing comma (i.e. a comma after the last element of an array or the after the last property of an object), but they should be avoided for better compatibility.
|
||||||
|
|
||||||
|
For the purposes of this tutorial, everything is going to be 100% valid JSON. Luckily, it kind of speaks for itself.
|
||||||
|
|
||||||
|
Supported data types:
|
||||||
|
|
||||||
|
* Strings: `"hello"`, `"\"A quote.\""`, `"\u0abe"`, `"Newline.\n"`
|
||||||
|
* Numbers: `23`, `0.11`, `12e10`, `3.141e-10`, `1.23e+4`
|
||||||
|
* Objects: `{ "key": "value" }`
|
||||||
|
* Arrays: `["Values"]`
|
||||||
|
* Miscellaneous: `true`, `false`, `null`
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"key": "value",
|
"key": "value",
|
||||||
|
|
||||||
"keys": "must always be enclosed in double quotes",
|
"keys": "must always be enclosed in double quotes",
|
||||||
"numbers": 0,
|
"numbers": 0,
|
||||||
"strings": "Hellø, wørld. All unicode is allowed, along with \"escaping\".",
|
"strings": "Hellø, wørld. All unicode is allowed, along with \"escaping\".",
|
||||||
@ -46,13 +60,23 @@ going to be 100% valid JSON. Luckily, it kind of speaks for itself.
|
|||||||
[0, 0, 0, 1]
|
[0, 0, 0, 1]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
|
||||||
"alternative style": {
|
"alternative style": {
|
||||||
"comment": "check this out!"
|
"comment": "check this out!"
|
||||||
, "comma position": "doesn't matter - as long as its before the value, then its valid"
|
, "comma position": "doesn't matter, if it's before the next key, it's valid"
|
||||||
, "another comment": "how nice"
|
, "another comment": "how nice"
|
||||||
},
|
},
|
||||||
|
|
||||||
"that was short": "And, you're done. You now know everything JSON has to offer."
|
|
||||||
|
|
||||||
|
"whitespace": "Does not matter.",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"that was short": "And done. You now know everything JSON has to offer."
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Further Reading
|
||||||
|
|
||||||
|
* [JSON.org](http://json.org) All of JSON beautifully explained using flowchart-like graphics.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
language: Julia
|
language: Julia
|
||||||
contributors:
|
contributors:
|
||||||
- ["Leah Hanson", "http://leahhanson.us"]
|
- ["Leah Hanson", "http://leahhanson.us"]
|
||||||
|
- ["Pranit Bauva", "http://github.com/pranitbauva1997"]
|
||||||
filename: learnjulia.jl
|
filename: learnjulia.jl
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ This is based on Julia 0.3.
|
|||||||
|
|
||||||
# Single line comments start with a hash (pound) symbol.
|
# Single line comments start with a hash (pound) symbol.
|
||||||
#= Multiline comments can be written
|
#= Multiline comments can be written
|
||||||
by putting '#=' before the text and '=#'
|
by putting '#=' before the text and '=#'
|
||||||
after the text. They can also be nested.
|
after the text. They can also be nested.
|
||||||
=#
|
=#
|
||||||
|
|
||||||
@ -81,10 +82,13 @@ false
|
|||||||
# Strings are created with "
|
# Strings are created with "
|
||||||
"This is a string."
|
"This is a string."
|
||||||
|
|
||||||
|
# Julia has several types of strings, including ASCIIString and UTF8String.
|
||||||
|
# More on this in the Types section.
|
||||||
|
|
||||||
# Character literals are written with '
|
# Character literals are written with '
|
||||||
'a'
|
'a'
|
||||||
|
|
||||||
# A string can be indexed like an array of characters
|
# Some strings can be indexed like an array of characters
|
||||||
"This is a string"[1] # => 'T' # Julia indexes from 1
|
"This is a string"[1] # => 'T' # Julia indexes from 1
|
||||||
# However, this is will not work well for UTF8 strings,
|
# However, this is will not work well for UTF8 strings,
|
||||||
# so iterating over strings is recommended (map, for loops, etc).
|
# so iterating over strings is recommended (map, for loops, etc).
|
||||||
@ -99,6 +103,11 @@ false
|
|||||||
# Printing is easy
|
# Printing is easy
|
||||||
println("I'm Julia. Nice to meet you!")
|
println("I'm Julia. Nice to meet you!")
|
||||||
|
|
||||||
|
# String can be compared lexicographically
|
||||||
|
"good" > "bye" # => true
|
||||||
|
"good" == "good" # => true
|
||||||
|
"1 + 2 = 3" == "1 + 2 = $(1+2)" # => true
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
## 2. Variables and Collections
|
## 2. Variables and Collections
|
||||||
####################################################
|
####################################################
|
||||||
@ -114,11 +123,11 @@ catch e
|
|||||||
println(e)
|
println(e)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Variable names start with a letter.
|
# Variable names start with a letter or underscore.
|
||||||
# After that, you can use letters, digits, underscores, and exclamation points.
|
# After that, you can use letters, digits, underscores, and exclamation points.
|
||||||
SomeOtherVar123! = 6 # => 6
|
SomeOtherVar123! = 6 # => 6
|
||||||
|
|
||||||
# You can also use unicode characters
|
# You can also use certain unicode characters
|
||||||
☃ = 8 # => 8
|
☃ = 8 # => 8
|
||||||
# These are especially handy for mathematical notation
|
# These are especially handy for mathematical notation
|
||||||
2 * π # => 6.283185307179586
|
2 * π # => 6.283185307179586
|
||||||
@ -314,7 +323,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
# For loops iterate over iterables.
|
# For loops iterate over iterables.
|
||||||
# Iterable types include Range, Array, Set, Dict, and String.
|
# Iterable types include Range, Array, Set, Dict, and AbstractString.
|
||||||
for animal=["dog", "cat", "mouse"]
|
for animal=["dog", "cat", "mouse"]
|
||||||
println("$animal is a mammal")
|
println("$animal is a mammal")
|
||||||
# You can use $ to interpolate variables or expression into strings
|
# You can use $ to interpolate variables or expression into strings
|
||||||
@ -387,6 +396,14 @@ end
|
|||||||
|
|
||||||
add(5, 6) # => 11 after printing out "x is 5 and y is 6"
|
add(5, 6) # => 11 after printing out "x is 5 and y is 6"
|
||||||
|
|
||||||
|
# Compact assignment of functions
|
||||||
|
f_add(x, y) = x + y # => "f (generic function with 1 method)"
|
||||||
|
f_add(3, 4) # => 7
|
||||||
|
|
||||||
|
# Function can also return multiple values as tuple
|
||||||
|
f(x, y) = x + y, x - y
|
||||||
|
f(3, 4) # => (7, -1)
|
||||||
|
|
||||||
# You can define functions that take a variable number of
|
# You can define functions that take a variable number of
|
||||||
# positional arguments
|
# positional arguments
|
||||||
function varargs(args...)
|
function varargs(args...)
|
||||||
@ -537,6 +554,17 @@ subtypes(Number) # => 6-element Array{Any,1}:
|
|||||||
# Real
|
# Real
|
||||||
subtypes(Cat) # => 0-element Array{Any,1}
|
subtypes(Cat) # => 0-element Array{Any,1}
|
||||||
|
|
||||||
|
# AbstractString, as the name implies, is also an abstract type
|
||||||
|
subtypes(AbstractString) # 8-element Array{Any,1}:
|
||||||
|
# Base.SubstitutionString{T<:AbstractString}
|
||||||
|
# DirectIndexString
|
||||||
|
# RepString
|
||||||
|
# RevString{T<:AbstractString}
|
||||||
|
# RopeString
|
||||||
|
# SubString{T<:AbstractString}
|
||||||
|
# UTF16String
|
||||||
|
# UTF8String
|
||||||
|
|
||||||
# Every type has a super type; use the `super` function to get it.
|
# Every type has a super type; use the `super` function to get it.
|
||||||
typeof(5) # => Int64
|
typeof(5) # => Int64
|
||||||
super(Int64) # => Signed
|
super(Int64) # => Signed
|
||||||
@ -546,17 +574,21 @@ super(Number) # => Any
|
|||||||
super(super(Signed)) # => Number
|
super(super(Signed)) # => Number
|
||||||
super(Any) # => Any
|
super(Any) # => Any
|
||||||
# All of these type, except for Int64, are abstract.
|
# All of these type, except for Int64, are abstract.
|
||||||
|
typeof("fire") # => ASCIIString
|
||||||
|
super(ASCIIString) # => DirectIndexString
|
||||||
|
super(DirectIndexString) # => AbstractString
|
||||||
|
# Likewise here with ASCIIString
|
||||||
|
|
||||||
# <: is the subtyping operator
|
# <: is the subtyping operator
|
||||||
type Lion <: Cat # Lion is a subtype of Cat
|
type Lion <: Cat # Lion is a subtype of Cat
|
||||||
mane_color
|
mane_color
|
||||||
roar::String
|
roar::AbstractString
|
||||||
end
|
end
|
||||||
|
|
||||||
# You can define more constructors for your type
|
# You can define more constructors for your type
|
||||||
# Just define a function of the same name as the type
|
# Just define a function of the same name as the type
|
||||||
# and call an existing constructor to get a value of the correct type
|
# and call an existing constructor to get a value of the correct type
|
||||||
Lion(roar::String) = Lion("green",roar)
|
Lion(roar::AbstractString) = Lion("green",roar)
|
||||||
# This is an outer constructor because it's outside the type definition
|
# This is an outer constructor because it's outside the type definition
|
||||||
|
|
||||||
type Panther <: Cat # Panther is also a subtype of Cat
|
type Panther <: Cat # Panther is also a subtype of Cat
|
||||||
@ -670,7 +702,7 @@ square_area(l) = l * l # square_area (generic function with 1 method)
|
|||||||
square_area(5) #25
|
square_area(5) #25
|
||||||
|
|
||||||
# What happens when we feed square_area an integer?
|
# What happens when we feed square_area an integer?
|
||||||
code_native(square_area, (Int32,))
|
code_native(square_area, (Int32,))
|
||||||
# .section __TEXT,__text,regular,pure_instructions
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
# Filename: none
|
# Filename: none
|
||||||
# Source line: 1 # Prologue
|
# Source line: 1 # Prologue
|
||||||
@ -703,10 +735,10 @@ code_native(square_area, (Float64,))
|
|||||||
# vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX)
|
# vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX)
|
||||||
# pop RBP
|
# pop RBP
|
||||||
# ret
|
# ret
|
||||||
#
|
#
|
||||||
# Note that julia will use floating point instructions if any of the
|
# Note that julia will use floating point instructions if any of the
|
||||||
# arguements are floats.
|
# arguments are floats.
|
||||||
# Let's calculate the area of a circle
|
# Let's calculate the area of a circle
|
||||||
circle_area(r) = pi * r * r # circle_area (generic function with 1 method)
|
circle_area(r) = pi * r * r # circle_area (generic function with 1 method)
|
||||||
circle_area(5) # 78.53981633974483
|
circle_area(5) # 78.53981633974483
|
||||||
|
|
||||||
@ -737,7 +769,7 @@ code_native(circle_area, (Float64,))
|
|||||||
# vmulsd XMM0, XMM1, XMM0
|
# vmulsd XMM0, XMM1, XMM0
|
||||||
# pop RBP
|
# pop RBP
|
||||||
# ret
|
# ret
|
||||||
#
|
#
|
||||||
```
|
```
|
||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
@ -387,9 +387,6 @@ myNumber === myNumberObj // = false
|
|||||||
if (0){
|
if (0){
|
||||||
// 0은 거짓이라서 이 코드는 실행되지 않습니다.
|
// 0은 거짓이라서 이 코드는 실행되지 않습니다.
|
||||||
}
|
}
|
||||||
if (Number(0)){
|
|
||||||
// Number(0)은 참이라서 이 코드는 *실행됩니다*.
|
|
||||||
}
|
|
||||||
|
|
||||||
// 하지만 래퍼 객체와 일반 내장 함수는 프로토타입을 공유하기 때문에
|
// 하지만 래퍼 객체와 일반 내장 함수는 프로토타입을 공유하기 때문에
|
||||||
// 가령 문자열에 실제로 기능을 추가할 수 있습니다.
|
// 가령 문자열에 실제로 기능을 추가할 수 있습니다.
|
||||||
|
247
latex.html.markdown
Normal file
247
latex.html.markdown
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
---
|
||||||
|
language: latex
|
||||||
|
contributors:
|
||||||
|
- ["Chaitanya Krishna Ande", "http://icymist.github.io"]
|
||||||
|
- ["Colton Kohnke", "http://github.com/voltnor"]
|
||||||
|
- ["Sricharan Chiruvolu", "http://sricharan.xyz"]
|
||||||
|
- ["Ramanan Balakrishnan", "https://github.com/ramananbalakrishnan"]
|
||||||
|
filename: learn-latex.tex
|
||||||
|
---
|
||||||
|
|
||||||
|
```tex
|
||||||
|
% All comment lines start with %
|
||||||
|
% There are no multi-line comments
|
||||||
|
|
||||||
|
% LaTeX is NOT a "What You See Is What You Get" word processing software like
|
||||||
|
% MS Word, or OpenOffice Writer
|
||||||
|
|
||||||
|
% Every LaTeX command starts with a backslash (\)
|
||||||
|
|
||||||
|
% LaTeX documents start with a defining the type of document it's compiling
|
||||||
|
% Other document types include book, report, presentations, etc.
|
||||||
|
% The options for the document appear in the [] brackets. In this case
|
||||||
|
% it specifies we want to use 12pt font.
|
||||||
|
\documentclass[12pt]{article}
|
||||||
|
|
||||||
|
% Next we define the packages the document uses.
|
||||||
|
% If you want to include graphics, colored text, or
|
||||||
|
% source code from another language file into your document,
|
||||||
|
% you need to enhance the capabilities of LaTeX. This is done by adding packages.
|
||||||
|
% I'm going to include the float and caption packages for figures.
|
||||||
|
\usepackage{caption}
|
||||||
|
\usepackage{float}
|
||||||
|
|
||||||
|
% We can define some other document properties too!
|
||||||
|
\author{Chaitanya Krishna Ande, Colton Kohnke \& Sricharan Chiruvolu}
|
||||||
|
\date{\today}
|
||||||
|
\title{Learn LaTeX in Y Minutes!}
|
||||||
|
|
||||||
|
% Now we're ready to begin the document
|
||||||
|
% Everything before this line is called "The Preamble"
|
||||||
|
\begin{document}
|
||||||
|
% if we set the author, date, title fields, we can have LaTeX
|
||||||
|
% create a title page for us.
|
||||||
|
\maketitle
|
||||||
|
|
||||||
|
% Most research papers have abstract, you can use the predefined commands for this.
|
||||||
|
% This should appear in its logical order, therefore, after the top matter,
|
||||||
|
% but before the main sections of the body.
|
||||||
|
% This command is available in the document classes article and report.
|
||||||
|
\begin{abstract}
|
||||||
|
LaTeX documentation written as LaTeX! How novel and totally not my idea!
|
||||||
|
\end{abstract}
|
||||||
|
|
||||||
|
% Section commands are intuitive.
|
||||||
|
% All the titles of the sections are added automatically to the table of contents.
|
||||||
|
\section{Introduction}
|
||||||
|
Hello, my name is Colton and together we're going to explore LaTeX!
|
||||||
|
|
||||||
|
\section{Another section}
|
||||||
|
This is the text for another section. I think it needs a subsection.
|
||||||
|
|
||||||
|
\subsection{This is a subsection} % Subsections are also intuitive.
|
||||||
|
I think we need another one
|
||||||
|
|
||||||
|
\subsubsection{Pythagoras}
|
||||||
|
Much better now.
|
||||||
|
\label{subsec:pythagoras}
|
||||||
|
|
||||||
|
% By using the asterisk we can suppress LaTeX's inbuilt numbering.
|
||||||
|
% This works for other LaTeX commands as well.
|
||||||
|
\section*{This is an unnumbered section}
|
||||||
|
However not all sections have to be numbered!
|
||||||
|
|
||||||
|
\section{Some Text notes}
|
||||||
|
LaTeX is generally pretty good about placing text where it should go. If
|
||||||
|
a line \\ needs \\ to \\ break \\ you add \textbackslash\textbackslash to
|
||||||
|
the source code. \\
|
||||||
|
|
||||||
|
\section{Lists}
|
||||||
|
Lists are one of the easiest things to create in LaTeX! I need to go shopping
|
||||||
|
tomorrow, so let's make a grocery list.
|
||||||
|
\begin{enumerate} % This creates an "enumerate" environment.
|
||||||
|
% \item tells the enumerate to increment
|
||||||
|
\item Salad.
|
||||||
|
\item 27 watermelon.
|
||||||
|
\item A single jackrabbit.
|
||||||
|
% we can even override the item number by using []
|
||||||
|
\item[how many?] Medium sized squirt guns.
|
||||||
|
|
||||||
|
Not a list item, but still part of the enumerate.
|
||||||
|
|
||||||
|
\end{enumerate} % All environments must have an end.
|
||||||
|
|
||||||
|
\section{Math}
|
||||||
|
|
||||||
|
One of the primary uses for LaTeX is to produce academic articles or
|
||||||
|
technical papers. Usually in the realm of math and science. As such,
|
||||||
|
we need to be able to add special symbols to our paper! \\
|
||||||
|
|
||||||
|
Math has many symbols, far beyond what you can find on a keyboard;
|
||||||
|
Set and relation symbols, arrows, operators, and Greek letters to name a few.\\
|
||||||
|
|
||||||
|
Sets and relations play a vital role in many mathematical research papers.
|
||||||
|
Here's how you state all y that belong to X, $\forall$ x $\in$ X. \\
|
||||||
|
% Notice how I needed to add $ signs before and after the symbols. This is
|
||||||
|
% because when writing, we are in text-mode.
|
||||||
|
% However, the math symbols only exist in math-mode.
|
||||||
|
% We can enter math-mode from text mode with the $ signs.
|
||||||
|
% The opposite also holds true. Variable can also be rendered in math-mode.
|
||||||
|
% We can also enter math mode with \[\]
|
||||||
|
|
||||||
|
\[a^2 + b^2 = c^2 \]
|
||||||
|
|
||||||
|
My favorite Greek letter is $\xi$. I also like $\beta$, $\gamma$ and $\sigma$.
|
||||||
|
I haven't found a Greek letter that yet that LaTeX doesn't know about!
|
||||||
|
|
||||||
|
Operators are essential parts of a mathematical document:
|
||||||
|
trigonometric functions ($\sin$, $\cos$, $\tan$),
|
||||||
|
logarithms and exponentials ($\log$, $\exp$),
|
||||||
|
limits ($\lim$), etc.
|
||||||
|
have per-defined LaTeX commands.
|
||||||
|
Let's write an equation to see how it's done: \\
|
||||||
|
|
||||||
|
$\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$
|
||||||
|
|
||||||
|
Fractions(Numerator-denominators) can be written in these forms:
|
||||||
|
|
||||||
|
% 10 / 7
|
||||||
|
$^{10}/_{7}$
|
||||||
|
|
||||||
|
% Relatively complex fractions can be written as
|
||||||
|
% \frac{numerator}{denominator}
|
||||||
|
$\frac{n!}{k!(n - k)!}$ \\
|
||||||
|
|
||||||
|
We can also insert equations in an "equation environment".
|
||||||
|
|
||||||
|
% Display math with the equation 'environment'
|
||||||
|
\begin{equation} % enters math-mode
|
||||||
|
c^2 = a^2 + b^2.
|
||||||
|
\label{eq:pythagoras} % for referencing
|
||||||
|
\end{equation} % all \begin statements must have an end statement
|
||||||
|
|
||||||
|
We can then reference our new equation!
|
||||||
|
Eqn.~\ref{eq:pythagoras} is also known as the Pythagoras Theorem which is also
|
||||||
|
the subject of Sec.~\ref{subsec:pythagoras}. A lot of things can be labeled:
|
||||||
|
figures, equations, sections, etc.
|
||||||
|
|
||||||
|
Summations and Integrals are written with sum and int commands:
|
||||||
|
|
||||||
|
% Some LaTeX compilers will complain if there are blank lines
|
||||||
|
% In an equation environment.
|
||||||
|
\begin{equation}
|
||||||
|
\sum_{i=0}^{5} f_{i}
|
||||||
|
\end{equation}
|
||||||
|
\begin{equation}
|
||||||
|
\int_{0}^{\infty} \mathrm{e}^{-x} \mathrm{d}x
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
|
\section{Figures}
|
||||||
|
|
||||||
|
Let's insert a Figure. Figure placement can get a little tricky.
|
||||||
|
I definitely have to lookup the placement options each time.
|
||||||
|
|
||||||
|
\begin{figure}[H] % H here denoted the placement option.
|
||||||
|
\centering % centers the figure on the page
|
||||||
|
% Inserts a figure scaled to 0.8 the width of the page.
|
||||||
|
%\includegraphics[width=0.8\linewidth]{right-triangle.png}
|
||||||
|
% Commented out for compilation purposes. Please use your imagination.
|
||||||
|
\caption{Right triangle with sides $a$, $b$, $c$}
|
||||||
|
\label{fig:right-triangle}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsection{Table}
|
||||||
|
We can also insert Tables in the same way as figures.
|
||||||
|
|
||||||
|
\begin{table}[H]
|
||||||
|
\caption{Caption for the Table.}
|
||||||
|
% the {} arguments below describe how each row of the table is drawn.
|
||||||
|
% Again, I have to look these up. Each. And. Every. Time.
|
||||||
|
\begin{tabular}{c|cc}
|
||||||
|
Number & Last Name & First Name \\ % Column rows are separated by $
|
||||||
|
\hline % a horizontal line
|
||||||
|
1 & Biggus & Dickus \\
|
||||||
|
2 & Monty & Python
|
||||||
|
\end{tabular}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
% \section{Hyperlinks} % Coming soon
|
||||||
|
|
||||||
|
\section{Getting LaTeX to not compile something (i.e. Source Code)}
|
||||||
|
Let's say we want to include some code into our LaTeX document,
|
||||||
|
we would then need LaTeX to not try and interpret that text and
|
||||||
|
instead just print it to the document. We do this we a verbatim
|
||||||
|
environment.
|
||||||
|
|
||||||
|
% There are other packages that exist (i.e. minty, lstlisting, etc.)
|
||||||
|
% but verbatim is the bare-bones basic one.
|
||||||
|
\begin{verbatim}
|
||||||
|
print("Hello World!")
|
||||||
|
a%b; % look! We can use % signs in verbatim.
|
||||||
|
random = 4; #decided by fair random dice roll
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
\section{Compiling}
|
||||||
|
|
||||||
|
By now you're probably wondering how to compile this fabulous document
|
||||||
|
and look at the glorious glory that is a LaTeX pdf.
|
||||||
|
(yes, this document actually does compiles). \\
|
||||||
|
Getting to the final document using LaTeX consists of the following steps:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item Write the document in plain text (the "source code").
|
||||||
|
\item Compile source code to produce a pdf.
|
||||||
|
The compilation step looks something like this (in Linux): \\
|
||||||
|
\begin{verbatim}
|
||||||
|
$pdflatex learn-latex.tex learn-latex.pdf
|
||||||
|
\end{verbatim}
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
A number of LaTeX editors combine both Step 1 and Step 2 in the same piece of
|
||||||
|
software. So, you get to see Step 1, but not Step 2 completely.
|
||||||
|
Step 2 is still happening behind the scenes.
|
||||||
|
|
||||||
|
You write all your formatting information in plain text in Step 1.
|
||||||
|
The compilation part in Step 2 takes care of producing the document in the
|
||||||
|
format you defined in Step 1.
|
||||||
|
|
||||||
|
\section{End}
|
||||||
|
|
||||||
|
That's all for now!
|
||||||
|
|
||||||
|
% Most often, you would want to have a references section in your document.
|
||||||
|
% The easiest way to set this up would be by using the bibliography section
|
||||||
|
\begin{thebibliography}{1}
|
||||||
|
% similar to other lists, the \bibitem command can be used to list items
|
||||||
|
% each entry can then be cited directly in the body of the text
|
||||||
|
\bibitem{latexwiki} The amazing LaTeX wikibook: {\em https://en.wikibooks.org/wiki/LaTeX}
|
||||||
|
\bibitem{latextutorial} An actual tutorial: {\em http://www.latex-tutorial.com}
|
||||||
|
\end{thebibliography}
|
||||||
|
|
||||||
|
% end the document
|
||||||
|
\end{document}
|
||||||
|
```
|
||||||
|
|
||||||
|
## More on LaTeX
|
||||||
|
|
||||||
|
* The amazing LaTeX wikibook: [https://en.wikibooks.org/wiki/LaTeX](https://en.wikibooks.org/wiki/LaTeX)
|
||||||
|
* An actual tutorial: [http://www.latex-tutorial.com/](http://www.latex-tutorial.com/)
|
379
less.html.markdown
Normal file
379
less.html.markdown
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
---
|
||||||
|
language: less
|
||||||
|
filename: learnless.less
|
||||||
|
contributors:
|
||||||
|
- ["Saravanan Ganesh", "http://srrvnn.me"]
|
||||||
|
---
|
||||||
|
|
||||||
|
Less is a CSS pre-processor, that adds features such as variables, nesting, mixins and more.
|
||||||
|
Less (and other preprocessors, such as [Sass](http://sass-lang.com/) help developers to write maintainable and DRY (Don't Repeat Yourself) code.
|
||||||
|
|
||||||
|
```less
|
||||||
|
|
||||||
|
|
||||||
|
//Single line comments are removed when Less is compiled to CSS.
|
||||||
|
|
||||||
|
/*Multi line comments are preserved. */
|
||||||
|
|
||||||
|
|
||||||
|
/*Variables
|
||||||
|
==============================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* You can store a CSS value (such as a color) in a variable.
|
||||||
|
Use the '@' symbol to create a variable. */
|
||||||
|
|
||||||
|
@primary-color: #A3A4FF;
|
||||||
|
@secondary-color: #51527F;
|
||||||
|
@body-font: 'Roboto', sans-serif;
|
||||||
|
|
||||||
|
/* You can use the variables throughout your stylesheet.
|
||||||
|
Now if you want to change a color, you only have to make the change once.*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: @primary-color;
|
||||||
|
color: @secondary-color;
|
||||||
|
font-family: @body-font;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This would compile to: */
|
||||||
|
body {
|
||||||
|
background-color: #A3A4FF;
|
||||||
|
color: #51527F;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is much more maintainable than having to change the color
|
||||||
|
each time it appears throughout your stylesheet. */
|
||||||
|
|
||||||
|
|
||||||
|
/*Mixins
|
||||||
|
==============================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* If you find you are writing the same code for more than one
|
||||||
|
element, you might want to reuse that easily.*/
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* You can use the mixin by simply adding the selector as a style */
|
||||||
|
|
||||||
|
div {
|
||||||
|
.center;
|
||||||
|
background-color: @primary-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Which would compile to: */
|
||||||
|
.center {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: #A3A4FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* You can omit the mixin code from being compiled by adding paranthesis
|
||||||
|
after the selector */
|
||||||
|
|
||||||
|
.center() {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
.center;
|
||||||
|
background-color: @primary-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Which would compile to: */
|
||||||
|
div {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: #A3A4FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*Functions
|
||||||
|
==============================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Less provides functions that can be used to accomplish a variety of
|
||||||
|
tasks. Consider the following */
|
||||||
|
|
||||||
|
/* Functions can be invoked by using their name and passing in the
|
||||||
|
required arguments */
|
||||||
|
body {
|
||||||
|
width: round(10.25px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background-color: fadeout(#000000, 0.25)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compiles to: */
|
||||||
|
|
||||||
|
body {
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background-color: rgba(0, 0, 0, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* You may also define your own functions. Functions are very similar to
|
||||||
|
mixins. When trying to choose between a function or a mixin, remember
|
||||||
|
that mixins are best for generating CSS while functions are better for
|
||||||
|
logic that might be used throughout your Less code. The examples in
|
||||||
|
the Math Operators' section are ideal candidates for becoming a reusable
|
||||||
|
function. */
|
||||||
|
|
||||||
|
/* This function will take a target size and the parent size and calculate
|
||||||
|
and return the percentage */
|
||||||
|
|
||||||
|
.average(@x, @y) {
|
||||||
|
@average_result: ((@x + @y) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
.average(16px, 50px); // "call" the mixin
|
||||||
|
padding: @average_result; // use its "return" value
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compiles to: */
|
||||||
|
|
||||||
|
div {
|
||||||
|
padding: 33px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Extend (Inheritance)
|
||||||
|
==============================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*Extend is a way to share the properties of one selector with another. */
|
||||||
|
|
||||||
|
.display {
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-success {
|
||||||
|
&:extend(.display);
|
||||||
|
border-color: #22df56;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compiles to: */
|
||||||
|
.display,
|
||||||
|
.display-success {
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
.display-success {
|
||||||
|
border-color: #22df56;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extending a CSS statement is preferable to creating a mixin
|
||||||
|
because of the way it groups together the classes that all share
|
||||||
|
the same base styling. If this was done with a mixin, the properties
|
||||||
|
would be duplicated for each statement that
|
||||||
|
called the mixin. While it won't affect your workflow, it will
|
||||||
|
add unnecessary bloat to the files created by the Less compiler. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*Nesting
|
||||||
|
==============================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*Less allows you to nest selectors within selectors */
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-top: 2em;
|
||||||
|
|
||||||
|
li {
|
||||||
|
background-color: #FF0000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* '&' will be replaced by the parent selector. */
|
||||||
|
/* You can also nest pseudo-classes. */
|
||||||
|
/* Keep in mind that over-nesting will make your code less maintainable.
|
||||||
|
Best practices recommend going no more than 3 levels deep when nesting.
|
||||||
|
For example: */
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-top: 2em;
|
||||||
|
|
||||||
|
li {
|
||||||
|
background-color: red;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compiles to: */
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li:hover {
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*Partials and Imports
|
||||||
|
==============================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Less allows you to create partial files. This can help keep your Less
|
||||||
|
code modularized. Partial files conventionally begin with an '_',
|
||||||
|
e.g. _reset.less. and are imported into a main less file that gets
|
||||||
|
compiled into CSS */
|
||||||
|
|
||||||
|
/* Consider the following CSS which we'll put in a file called _reset.less */
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Less offers @import which can be used to import partials into a file.
|
||||||
|
This differs from the traditional CSS @import statement which makes
|
||||||
|
another HTTP request to fetch the imported file. Less takes the
|
||||||
|
imported file and combines it with the compiled code. */
|
||||||
|
|
||||||
|
@import 'reset';
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: Helvetica, Arial, Sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compiles to: */
|
||||||
|
|
||||||
|
html, body, ul, ol {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: Helvetica, Arial, Sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*Math Operations
|
||||||
|
==============================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Less provides the following operators: +, -, *, /, and %. These can
|
||||||
|
be useful for calculating values directly in your Less files instead
|
||||||
|
of using values that you've already calculated by hand. Below is an example
|
||||||
|
of a setting up a simple two column design. */
|
||||||
|
|
||||||
|
@content-area: 960px;
|
||||||
|
@main-content: 600px;
|
||||||
|
@sidebar-content: 300px;
|
||||||
|
|
||||||
|
@main-size: @main-content / @content-area * 100%;
|
||||||
|
@sidebar-size: @sidebar-content / @content-area * 100%;
|
||||||
|
@gutter: 100% - (@main-size + @sidebar-size);
|
||||||
|
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
width: @main-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: @sidebar-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gutter {
|
||||||
|
width: @gutter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compiles to: */
|
||||||
|
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
width: 62.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: 31.25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gutter {
|
||||||
|
width: 6.25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Practice Less
|
||||||
|
|
||||||
|
If you want to play with Less in your browser, check out [LESS2CSS](http://lesscss.org/less-preview/).
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
Less can be used in any project as long as you have a program to compile it
|
||||||
|
into CSS. You'll want to verify that the CSS you're using is compatible
|
||||||
|
with your target browsers.
|
||||||
|
|
||||||
|
[QuirksMode CSS](http://www.quirksmode.org/css/) and [CanIUse](http://caniuse.com) are great resources for checking compatibility.
|
||||||
|
|
||||||
|
## Further reading
|
||||||
|
* [Official Documentation](http://lesscss.org/features/)
|
@ -166,7 +166,7 @@ not false # => true
|
|||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
## 3. Functions
|
## 3. Functions
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
# Since LiveScript is functional, you'd expect functions to get a nice
|
# Since LiveScript is functional, you'd expect functions to get a nice
|
||||||
# treatment. In LiveScript it's even more apparent that functions are
|
# treatment. In LiveScript it's even more apparent that functions are
|
||||||
@ -229,7 +229,7 @@ double-minus-one = (- 1) . (* 2)
|
|||||||
|
|
||||||
# Other than the usual `f . g` mathematical formulae, you get the `>>`
|
# Other than the usual `f . g` mathematical formulae, you get the `>>`
|
||||||
# and `<<` operators, that describe how the flow of values through the
|
# and `<<` operators, that describe how the flow of values through the
|
||||||
# functions.
|
# functions.
|
||||||
double-minus-one = (* 2) >> (- 1)
|
double-minus-one = (* 2) >> (- 1)
|
||||||
double-minus-one = (- 1) << (* 2)
|
double-minus-one = (- 1) << (* 2)
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ kitten.hug! # => "*Mei (a cat) is hugged*"
|
|||||||
## Further reading
|
## Further reading
|
||||||
|
|
||||||
There's just so much more to LiveScript, but this should be enough to
|
There's just so much more to LiveScript, but this should be enough to
|
||||||
get you started writing little functional things in it. The
|
get you started writing little functional things in it. The
|
||||||
[official website](http://livescript.net/) has a lot of information on the
|
[official website](http://livescript.net/) has a lot of information on the
|
||||||
language, and a nice online compiler for you to try stuff out!
|
language, and a nice online compiler for you to try stuff out!
|
||||||
|
|
||||||
|
81
lt-lt/json-lt.html.markdown
Normal file
81
lt-lt/json-lt.html.markdown
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
---
|
||||||
|
language: json
|
||||||
|
filename: learnjson.json
|
||||||
|
lang: lt-lt
|
||||||
|
contributors:
|
||||||
|
- ["Zygimantus", "https://github.com/zygimantus"]
|
||||||
|
---
|
||||||
|
|
||||||
|
JSON („džeisonas“) yra itin paprastas duomenų mainų formatas, todėl tai bus pati lengviausia „Learn X in Y Minutes“ pamoka.
|
||||||
|
|
||||||
|
JSON savo gryniausioje formoje neturi jokių komentarų, tačiau dauguma analizatorių priimtų C stiliaus komentarus (`//`, `/* */`). Kai kurie analizatoriai taip pat toleruoja gale esantį kablelį, pvz., kablelis po kiekvieno masyvo paskutinio elemento arba po paskutinio objekto lauko, tačiau jų reikėtų vengti dėl geresnio suderinamumo.
|
||||||
|
|
||||||
|
JSON reikšmė privalo būti skaičius, eilutė, masyvas, objektas arba viena reikšmė iš šių: true, false, null.
|
||||||
|
|
||||||
|
Palaikančios naršyklės yra: Firefox 3.5+, Internet Explorer 8.0+, Chrome 1.0+, Opera 10.0+, and Safari 4.0+.
|
||||||
|
|
||||||
|
Failo plėtinys JSON failams yra „.json“, o MIME tipas yra „application/json“.
|
||||||
|
|
||||||
|
Dauguma programavimo kalbų palaiko JSON duomenų serializaciją (kodavimą) ir deserializaciją (dekodavimą) į natyviasias duomenų struktūras. Javascript turi visišką JSON teksto kaip duomenų manipuliavimo palaikymą.
|
||||||
|
|
||||||
|
Daugiau informacijos galima rasti http://www.json.org/
|
||||||
|
|
||||||
|
JSON yra pastatytas iš dviejų struktūrų:
|
||||||
|
* Vardų/reikšmių porų rinkinys. Daugomoje kalbų, tai yra realizuojama kaip objektas, įrašas, struktūra, žodynas, hash lentelė, sąrašas su raktais arba asociatyvusis masyvas.
|
||||||
|
* Rūšiuotas reikšmių sąrašas. Daugumoje kalbų, toks sąrašas yra realizuojama kaip masyvas, vektorius, sąrašas arba seka.
|
||||||
|
|
||||||
|
Objektas su įvairiomis vardo/reikšmės poromis.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"raktas": "reikšmė",
|
||||||
|
|
||||||
|
"raktai": "privalo visada būti uždaryti dvigubomis kabutėmis",
|
||||||
|
"skaičiai": 0,
|
||||||
|
"eilutės": "Labas, pasauli. Visas unikodas yra leidžiamas, kartu su \"vengimu\".",
|
||||||
|
"turi logiką?": true,
|
||||||
|
"niekas": null,
|
||||||
|
|
||||||
|
"didelis skaičius": 1.2e+100,
|
||||||
|
|
||||||
|
"objektai": {
|
||||||
|
"komentaras": "Dauguma tavo struktūrų ateis iš objektų.",
|
||||||
|
|
||||||
|
"masyvas": [0, 1, 2, 3, "Masyvas gali turėti bet ką savyje.", 5],
|
||||||
|
|
||||||
|
"kitas objektas": {
|
||||||
|
"komentaras": "Šie dalykai gali būti įdedami naudingai."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"kvailumas": [
|
||||||
|
{
|
||||||
|
"kalio šaltiniai": ["bananai"]
|
||||||
|
},
|
||||||
|
[
|
||||||
|
[1, 0, 0, 0],
|
||||||
|
[0, 1, 0, 0],
|
||||||
|
[0, 0, 1, "neo"],
|
||||||
|
[0, 0, 0, 1]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
"alternativus stilius": {
|
||||||
|
"komentaras": "tik pažiūrėk!"
|
||||||
|
, "kablelio padėti": "nesvarbi - kol jis prieš kitą raktą, tada teisingas"
|
||||||
|
, "kitas komentaras": "kaip gražu"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Paprastas reikšmių masyvas pats savaime yra galiojantis JSON.
|
||||||
|
|
||||||
|
```json
|
||||||
|
[1, 2, 3, "tekstas", true]
|
||||||
|
```
|
||||||
|
|
||||||
|
Objektai taip pat gali būti masyvų dalis.
|
||||||
|
|
||||||
|
```json
|
||||||
|
[{"vardas": "Jonas", "amžius": 25}, {"vardas": "Eglė", "amžius": 29}, {"vardas": "Petras", "amžius": 31}]
|
||||||
|
```
|
@ -190,7 +190,7 @@ end
|
|||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- A table can have a metatable that gives the table operator-overloadish
|
-- A table can have a metatable that gives the table operator-overloadish
|
||||||
-- behavior. Later we'll see how metatables support js-prototypey behavior.
|
-- behaviour. Later we'll see how metatables support js-prototypey behaviour.
|
||||||
|
|
||||||
f1 = {a = 1, b = 2} -- Represents the fraction a/b.
|
f1 = {a = 1, b = 2} -- Represents the fraction a/b.
|
||||||
f2 = {a = 2, b = 3}
|
f2 = {a = 2, b = 3}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user