mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-09-02 19:22:49 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
120
ar-ar/html-ar.html.markdown
Normal file
120
ar-ar/html-ar.html.markdown
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
---
|
||||||
|
language: html
|
||||||
|
filename: learnhtml-tf.html
|
||||||
|
contributors:
|
||||||
|
- ["Christophe THOMAS", "https://github.com/WinChris"]
|
||||||
|
translators:
|
||||||
|
- ["Ader", "https://github.com/y1n0"]
|
||||||
|
---
|
||||||
|
|
||||||
|
HTML اختصار ل HyperText Markup Language، أي "لغة ترميز النص التشعبي".
|
||||||
|
هي لغة تمكننا من كتابة صفحات موجهة لشبكة الويب العالمي.
|
||||||
|
هي لغة توصيف للنص، تسمح بكتابة صفحات ويب عن طريق تحديد كيفية عرض النصوص والمعلومات.
|
||||||
|
في الحقيقة، ملفات html هي ملفات تحتوي على نصوص بسيطة.
|
||||||
|
ما هو توصيف النص هذا؟ هو طريقة لتنظيم معلومات النص عن طريق إحاطته بوُسوم فتح ووسوم غلق.
|
||||||
|
هذه الوسوم تعطي معاني محددة للنص الذي تحيطه.
|
||||||
|
كباقي لغات الحاسوب، هناك الكثير من إصدارات HTML. سنتحدث هنا عن HTLM5.
|
||||||
|
|
||||||
|
**ملاحظة:** يمكنك تجريب مختلف الوسوم والعناصر بينما تقرأ الدرس عبر موقع كـ [codepen](http://codepen.io/pen/) حتى ترى تأثيرها وتعرف كيف تعمل وتتعود على استعمالها.
|
||||||
|
هذه المادة تُعنى أساسا بتركيب HTML .وبعض النصائح المفيدة
|
||||||
|
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- التعاليق تحاط بوسوم كما في هذا السطر -->
|
||||||
|
|
||||||
|
<!-- #################### الوسوم #################### -->
|
||||||
|
|
||||||
|
<!-- هنا مثال لملف html الذي سنقوم بالعمل عليه. -->
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>موقعي</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>مرحبا بالعالم!</h1>
|
||||||
|
<a href = "http://codepen.io/anon/pen/xwjLbZ">الق نظرة كيف يبدو هذا من هنا</a>
|
||||||
|
<p>هذه فقرة.</p>
|
||||||
|
<p>هذه فقرة أخرى.</p>
|
||||||
|
<ul>
|
||||||
|
<li>هذا عنصر من لائحة غير مرقمة. (لائحة بالعرائض)</li>
|
||||||
|
<li>هذا عنصر آخر</li>
|
||||||
|
<li>وهذا آخر عنصر في اللائحة</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<!-- ملف HTML يُبتدأ دائما بتبيين أنه ملف HTML للمتصفح -->
|
||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<!-- بعد هذا، يبدأ بفتح الوسم <html> -->
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<!-- الذي سيغلق في نهاية الملف بـ </html>. -->
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<!-- لا يجب كتابة أي شيء بعد وسم النهاية ذاك. -->
|
||||||
|
|
||||||
|
<!-- داخل هذين الوسمين (<html></html>) نجد: -->
|
||||||
|
|
||||||
|
<!-- "ترئيس" محدد ب <head> (يجب أن يغلق بـ </head>) -->
|
||||||
|
<!-- الترأيس يحتوي على أوصاف وبعض المعلومات الإضافية التي لا تظهر في المتصفح, تدعي metadata (المعلومات الوصفية) -->
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>موقعي</title><!-- الوسم <title> يحدد للمتصفح العنوان الذي يظهر في المكان المخصص للعنوان في نافذة المتصفح. -->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<!-- بعد الجزء الخاص بـ <head>، نجد الوسم <body> -->
|
||||||
|
<!-- حتى هنا، لا شيء مما كُتب سيظهر في النافذة الرئيسية للمتصفح. -->
|
||||||
|
<!-- يجب ان نملأ "جسد" الصفحة بالمحتوى الذي نريد أن نُظهر -->
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>مرحبا بالعالم!</h1> <!-- الوسم <h1> خاص بالعناوين الكبيرة. -->
|
||||||
|
<!-- هناك أيضا وسوم خاصة بالعناوين الفرعية من h1، الأكثر أهمية h2 والذي يليه حتى h6 الذي هو آخر عنوان داخلي. -->
|
||||||
|
<a href = "http://codepen.io/anon/pen/xwjLbZ">ألق نظرة كيف يبدو هذا من هنا</a> <!-- يظهر رابطا للصفحة التي داخل السمة href="" -->
|
||||||
|
<p>هذه فقرة.</p> <!-- يمكن من اضافة نصوص للصفحة. يميز الفقرات -->
|
||||||
|
<p>هذه فقرة أخرى.</p>
|
||||||
|
<ul> <!-- الوسم <ul> يخلق لائحة بالعرائض -->
|
||||||
|
<!-- إذا أردت لائحة مرقمة، هناك الوسم <ol>. ويكون الترتيب فيه حسب تموضع العناصر داخله، الأول فالأول. -->
|
||||||
|
<li>هذا عنصر من لائحة غير مرقمة. (لائحة بالعرائض)</li>
|
||||||
|
<li>هذا عنصر آخر</li>
|
||||||
|
<li>وهذا آخر عنصر في اللائحة</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<!-- وهكذا، كتابة ملفات HTML جد بسيطة -->
|
||||||
|
|
||||||
|
<!-- يمكنك كذلك إضافة أنواع أخرى من الوسوم -->
|
||||||
|
|
||||||
|
<!-- لادخال صورة: -->
|
||||||
|
<img src="http://i.imgur.com/XWG0O.gif"/> <!-- مصدر الصورة يحدد داخل السمة: src="" -->
|
||||||
|
<!-- مصدرها يمكن أن يكون رابطا أو مسارا لصورة في حاسوبك -->
|
||||||
|
|
||||||
|
<!-- يمكنك كذلك تشكيل جداول. -->
|
||||||
|
|
||||||
|
<table> <!-- نفتح الجدول بالوسم <table> -->
|
||||||
|
<tr> <!-- <tr> تسمح بتشكيل صف. -->
|
||||||
|
<th>العنوان الأول</th> <!-- <th> تسمح لنا بإعطاء عنوان لهذا العمود. -->
|
||||||
|
<th>العنوان الثاني</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>الصف الأول، العمود الأول</td> <!-- <td> تسمح بتشكيل الأعمدة، أو خانات داخل كل صف. -->
|
||||||
|
<td>الصف الأول، العمود الثاني</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>الصف الثاني، العمود الأول</td>
|
||||||
|
<td>الصف الثاني، العمود الأول</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## الاستعمال
|
||||||
|
|
||||||
|
HTML يُكتب في ملفات تنتهي بـ `.html`.
|
||||||
|
|
||||||
|
## لمعرفة المزيد
|
||||||
|
|
||||||
|
* [wikipedia](https://en.wikipedia.org/wiki/HTML)
|
||||||
|
* [HTML tutorial](https://developer.mozilla.org/en-US/docs/Web/HTML)
|
||||||
|
* [W3School](http://www.w3schools.com/html/html_intro.asp)
|
@@ -54,19 +54,19 @@ not False -- True
|
|||||||
["příliš", "žluťoučký", "kůň", "úpěl"]
|
["příliš", "žluťoučký", "kůň", "úpěl"]
|
||||||
[1, 2, 3, 4, 5]
|
[1, 2, 3, 4, 5]
|
||||||
-- Druhý příklad lze zapsat také pomocí dvou teček.
|
-- Druhý příklad lze zapsat také pomocí dvou teček.
|
||||||
[1..5]
|
List.range 1 5
|
||||||
|
|
||||||
-- Spojovat seznamy lze stejně jako řetězce.
|
-- Spojovat seznamy lze stejně jako řetězce.
|
||||||
[1..5] ++ [6..10] == [1..10] -- True
|
List.range 1 5 ++ List.range 6 10 == List.range 1 10 -- True
|
||||||
|
|
||||||
-- K přidání položky do seznamu použijte funkci "cons".
|
-- K přidání položky do seznamu použijte funkci "cons".
|
||||||
0 :: [1..5] -- [0, 1, 2, 3, 4, 5]
|
0 :: List.range 1 5 -- [0, 1, 2, 3, 4, 5]
|
||||||
|
|
||||||
-- Funkce "head" pro získání první položky seznamu i funkce "tail" pro získání následujích položek
|
-- Funkce "head" pro získání první položky seznamu i funkce "tail" pro získání následujích položek
|
||||||
-- vrací typ Maybe. Místo zjišťování, jestli nějaká položka není null,
|
-- vrací typ Maybe. Místo zjišťování, jestli nějaká položka není null,
|
||||||
-- se s chybějcími hodnotami vypořádáme explicitně.
|
-- se s chybějcími hodnotami vypořádáme explicitně.
|
||||||
List.head [1..5] -- Just 1
|
List.head (List.range 1 5) -- Just 1
|
||||||
List.tail [1..5] -- Just [2, 3, 4, 5]
|
List.tail (List.range 1 5) -- Just [2, 3, 4, 5]
|
||||||
List.head [] -- Nothing
|
List.head [] -- Nothing
|
||||||
-- List.nazevFunkce odkazuje na funkci, která žije v modulu List.
|
-- List.nazevFunkce odkazuje na funkci, která žije v modulu List.
|
||||||
|
|
||||||
@@ -153,10 +153,10 @@ odpoved =
|
|||||||
42
|
42
|
||||||
|
|
||||||
-- Předejte funkci jako parametr jiným funkcím.
|
-- Předejte funkci jako parametr jiným funkcím.
|
||||||
List.map zdvoj [1..4] -- [2, 4, 6, 8]
|
List.map zdvoj (List.range 1 4) -- [2, 4, 6, 8]
|
||||||
|
|
||||||
-- Nebo použijte anonymní funkci.
|
-- Nebo použijte anonymní funkci.
|
||||||
List.map (\a -> a * 2) [1..4] -- [2, 4, 6, 8]
|
List.map (\a -> a * 2) (List.range 1 4) -- [2, 4, 6, 8]
|
||||||
|
|
||||||
-- V definici funkce lze zapsat vzor, může-li nastat pouze jeden případ.
|
-- V definici funkce lze zapsat vzor, může-li nastat pouze jeden případ.
|
||||||
-- Tato funkce přijímá jednu dvojici místo dvou parametrů.
|
-- Tato funkce přijímá jednu dvojici místo dvou parametrů.
|
||||||
@@ -182,7 +182,7 @@ fib n =
|
|||||||
else
|
else
|
||||||
fib (n - 1) + fib (n - 2)
|
fib (n - 1) + fib (n - 2)
|
||||||
|
|
||||||
List.map fib [0..8] -- [1, 1, 2, 3, 5, 8, 13, 21, 34]
|
List.map fib (List.range 0 8) -- [1, 1, 2, 3, 5, 8, 13, 21, 34]
|
||||||
|
|
||||||
-- Jiná rekurzivní funkce (v praxi použijte List.length).
|
-- Jiná rekurzivní funkce (v praxi použijte List.length).
|
||||||
delkaSeznamu seznam =
|
delkaSeznamu seznam =
|
||||||
@@ -339,10 +339,10 @@ $ elm repl
|
|||||||
|
|
||||||
-- Balíčky jsou určeny uživatelským jménem na GitHubu a názvem repozitáře.
|
-- Balíčky jsou určeny uživatelským jménem na GitHubu a názvem repozitáře.
|
||||||
-- Nainstalujte nový balíček a uložte jej v souboru elm-package.json.
|
-- Nainstalujte nový balíček a uložte jej v souboru elm-package.json.
|
||||||
$ elm package install evancz/elm-html
|
$ elm package install evancz/elm-lang/html
|
||||||
|
|
||||||
-- Porovnejte změny mezi verzemi jednoho balíčku.
|
-- Porovnejte změny mezi verzemi jednoho balíčku.
|
||||||
$ elm package diff evancz/elm-html 3.0.0 4.0.2
|
$ elm package diff elm-lang/html 1.1.0 2.0.0
|
||||||
-- Správce balíčků v Elmu vyžaduje sémantické verzování,
|
-- Správce balíčků v Elmu vyžaduje sémantické verzování,
|
||||||
-- takže minor verze nikdy nerozbije váš build.
|
-- takže minor verze nikdy nerozbije váš build.
|
||||||
```
|
```
|
||||||
|
@@ -9,7 +9,7 @@ translators:
|
|||||||
|
|
||||||
HTML stands for HyperText Markup Language.
|
HTML stands for HyperText Markup Language.
|
||||||
It is a language which allows us to write pages for the world wide web.
|
It is a language which allows us to write pages for the world wide web.
|
||||||
It is a markup language, it enables us to write to write webpages using code to indicate how text and data should be displayed.
|
It is a markup language, it enables us to write webpages using code to indicate how text and data should be displayed.
|
||||||
In fact, html files are simple text files.
|
In fact, html files are simple text files.
|
||||||
What is this markup? It is a method of organising the page's data by surrounding it with opening tags and closing tags.
|
What is this markup? It is a method of organising the page's data by surrounding it with opening tags and closing tags.
|
||||||
This markup serves to give significance to the text that it encloses.
|
This markup serves to give significance to the text that it encloses.
|
||||||
|
@@ -773,6 +773,6 @@ code_native(circle_area, (Float64,))
|
|||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
|
||||||
You can get a lot more detail from [The Julia Manual](http://docs.julialang.org/en/latest/manual/)
|
You can get a lot more detail from [The Julia Manual](http://docs.julialang.org/en/latest/#Manual-1)
|
||||||
|
|
||||||
The best place to get help with Julia is the (very friendly) [mailing list](https://groups.google.com/forum/#!forum/julia-users).
|
The best place to get help with Julia is the (very friendly) [mailing list](https://groups.google.com/forum/#!forum/julia-users).
|
||||||
|
382
ko-kr/bash-kr.html.markdown
Normal file
382
ko-kr/bash-kr.html.markdown
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
---
|
||||||
|
category: tool
|
||||||
|
tool: bash
|
||||||
|
contributors:
|
||||||
|
- ["Max Yankov", "https://github.com/golergka"]
|
||||||
|
- ["Darren Lin", "https://github.com/CogBear"]
|
||||||
|
- ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
|
||||||
|
- ["Denis Arh", "https://github.com/darh"]
|
||||||
|
- ["akirahirose", "https://twitter.com/akirahirose"]
|
||||||
|
- ["Anton Strömkvist", "http://lutic.org/"]
|
||||||
|
- ["Rahil Momin", "https://github.com/iamrahil"]
|
||||||
|
- ["Gregrory Kielian", "https://github.com/gskielian"]
|
||||||
|
- ["Etan Reisner", "https://github.com/deryni"]
|
||||||
|
- ["Jonathan Wang", "https://github.com/Jonathansw"]
|
||||||
|
- ["Leo Rudberg", "https://github.com/LOZORD"]
|
||||||
|
- ["Betsy Lorton", "https://github.com/schbetsy"]
|
||||||
|
- ["John Detter", "https://github.com/jdetter"]
|
||||||
|
translators:
|
||||||
|
- ["Wooseop Kim", "https://github.com/linterpreteur"]
|
||||||
|
filename: LearnBash-kr.sh
|
||||||
|
lang: ko-kr
|
||||||
|
---
|
||||||
|
|
||||||
|
Bash는 유닉스 셸의 이름이며, 리눅스와 맥 OS X의 기본 셸로 그리고 GNU 운영체제를 위한 셸로서 배포되었습니다.
|
||||||
|
이하의 거의 모든 예시들은 셸 스크립트의 일부이거나 셸에서 바로 실행할 수 있습니다.
|
||||||
|
|
||||||
|
[(영어) 이곳에서 더 알아보세요.](http://www.gnu.org/software/bash/manual/bashref.html)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# 스크립트의 첫 줄은 시스템에게 스크립트의 실행법을 알려주는 '셔뱅'입니다.
|
||||||
|
# https://ko.wikipedia.org/wiki/%EC%85%94%EB%B1%85
|
||||||
|
# 이미 보았듯이 주석은 #으로 시작합니다. 셔뱅 또한 주석입니다.
|
||||||
|
|
||||||
|
# 간단한 헬로 월드
|
||||||
|
echo 헬로 월드!
|
||||||
|
|
||||||
|
# 각각의 명령어는 개행 혹은 세미콜론 이후에 시작됩니다.
|
||||||
|
echo '첫번째 줄'; echo '두번째 줄'
|
||||||
|
|
||||||
|
# 변수 선언은 다음과 같습니다.
|
||||||
|
Variable="어떤 문자열"
|
||||||
|
|
||||||
|
# 하지만 다음은 틀린 형태입니다.
|
||||||
|
Variable = "어떤 문자열"
|
||||||
|
# Bash는 Variable이 실행해야 하는 명령어라고 판단할 것이고, 해당 명령어를 찾을
|
||||||
|
# 수 없기 때문에 에러를 발생시킬 것입니다.
|
||||||
|
|
||||||
|
# 다음도 같습니다.
|
||||||
|
Variable= '어떤 문자열'
|
||||||
|
# Bash는 '어떤 문자열'이 실행해야 하는 명령어라고 판단하여 에러를 발생시킬 것입니다.
|
||||||
|
# (이 경우에 'Variable=' 부분은 '어떤 문자열' 명령어의 스코프에서만 유효한
|
||||||
|
# 변수 할당으로 해석됩니다.)
|
||||||
|
|
||||||
|
# 변수 사용은 다음과 같습니다.
|
||||||
|
echo $Variable
|
||||||
|
echo "$Variable"
|
||||||
|
echo '$Variable'
|
||||||
|
# 할당, 내보내기 등 변수 자체를 사용할 때에는 $ 없이 이름을 적습니다.
|
||||||
|
# 변수의 값을 사용할 때에는 $를 사용해야 합니다.
|
||||||
|
# 작은 따옴표는 변수를 확장시키지 않는다는 사실에 주의하세요.
|
||||||
|
# (역자 주: '$Variable'은 변수 Variable의 값이 아닌 문자열 "$Variable"입니다.)
|
||||||
|
|
||||||
|
# 인수 확장은 ${ }입니다.
|
||||||
|
echo ${Variable}
|
||||||
|
# 이는 인수 확장의 간단한 예시입니다.
|
||||||
|
# 인수 확장은 변수로부터 값을 받아 그 값을 "확장"하거나 출력합니다.
|
||||||
|
# 확장을 통해 인수나 그 값이 변경될 수 있습니다.
|
||||||
|
# 이하는 확장에 대한 다른 예시들입니다.
|
||||||
|
|
||||||
|
# 변수에서의 문자열 치환
|
||||||
|
echo ${Variable/Some/A}
|
||||||
|
# 처음으로 나타나는 "Some"를 "A"로 치환합니다.
|
||||||
|
|
||||||
|
# 변수의 부분열
|
||||||
|
Length=7
|
||||||
|
echo ${Variable:0:Length}
|
||||||
|
# 변수 값에서 처음 7개 문자만을 반환합니다.
|
||||||
|
|
||||||
|
# 변수의 기본값
|
||||||
|
echo ${Foo:-"Foo가_없거나_비어_있을_때의_기본값"}
|
||||||
|
# null(Foo=) 값이나 빈 문자열(Foo="")일 경우에만 작동합니다. 0은 (Foo=0)은 0입니다.
|
||||||
|
# 기본값을 반환할 뿐 변수 값을 변경하지는 않는다는 사실에 주목하세요.
|
||||||
|
|
||||||
|
# 중괄호 확장 { }
|
||||||
|
# 임의의 문자열을 생성합니다.
|
||||||
|
echo {1..10}
|
||||||
|
echo {a..z}
|
||||||
|
# 시작 값으로부터 끝 값까지의 범위를 출력합니다.
|
||||||
|
|
||||||
|
# 내장 변수
|
||||||
|
# 유용한 내장 변수들이 있습니다.
|
||||||
|
echo "마지막 프로그램의 반환값: $?"
|
||||||
|
echo "스크립트의 PID: $$"
|
||||||
|
echo "스크립트에 넘겨진 인자의 개수: $#"
|
||||||
|
echo "스크립트에 넘겨진 모든 인자: $@"
|
||||||
|
echo "각각 변수로 쪼개진 스크립트 인자: $1 $2..."
|
||||||
|
|
||||||
|
# echo와 변수의 사용법을 알게 되었으니,
|
||||||
|
# bash의 기초를 조금 더 배워봅시다!
|
||||||
|
|
||||||
|
# 현재 디렉토리는 `pwd` 명령어로 알 수 있습니다.
|
||||||
|
# `pwd`는 "print working directory(작업 디렉토리 출력)"의 약자입니다.
|
||||||
|
# 내장 변수`$PWD`를 사용할 수도 있습니다.
|
||||||
|
# 이하는 모두 동일합니다.
|
||||||
|
echo "I'm in $(pwd)" # `pwd`를 실행하여 문자열에 보간
|
||||||
|
echo "I'm in $PWD" # 변수를 보간
|
||||||
|
|
||||||
|
# 터미널이나 결과의 출력물이 너무 많다면
|
||||||
|
# 명령어 `clear`를 이용해 화면을 지울 수 있습니다.
|
||||||
|
clear
|
||||||
|
# 컨트롤+L 또한 화면을 지울 수 있습니다.
|
||||||
|
|
||||||
|
# 입력 값 읽기
|
||||||
|
echo "이름이 뭐에요?"
|
||||||
|
read Name # 변수 선언이 필요 없다는 데 주목하세요.
|
||||||
|
echo $Name님, 안녕하세요!
|
||||||
|
|
||||||
|
# 평범한 if 구조도 있습니다.
|
||||||
|
# 'man test'로 조건문에 대해 더 알아보세요.
|
||||||
|
if [ $Name != $USER ]
|
||||||
|
then
|
||||||
|
echo "사용자가 아닙니다."
|
||||||
|
else
|
||||||
|
echo "사용자입니다."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# $Name이 비어 있다면, bash는 위의 조건을 다음과 같이 인식합니다.
|
||||||
|
if [ != $USER ]
|
||||||
|
# 이는 문법적으로 유효하지 않습니다.
|
||||||
|
# 따라서 bash에서 비어 있을 수 있는 변수를 "안전하게" 사용하는 법은 다음과 같습니다.
|
||||||
|
if [ "$Name" != $USER ] ...
|
||||||
|
# $Name이 비어 있다면 bash는
|
||||||
|
if [ "" != $USER ] ...
|
||||||
|
# 와 같이 인식하여 예상한 대로 동작합니다.
|
||||||
|
|
||||||
|
# 조건부 실행도 있습니다.
|
||||||
|
echo "항상 실행" || echo "첫 명령어가 실패해야 실행"
|
||||||
|
echo "항상 실행" && echo "첫 명령어가 실패하지 않아야 실행"
|
||||||
|
|
||||||
|
# if문과 함께 &&와 ||을 사용하려면, 대괄호가 여러 쌍 필요합니다.
|
||||||
|
if [ "$Name" == "철수" ] && [ "$Age" -eq 15 ]
|
||||||
|
then
|
||||||
|
echo "$Name이 철수이고 $Age가 15일 때 실행"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$Name" == "민희" ] || [ "$Name" == "상민" ]
|
||||||
|
then
|
||||||
|
echo "$Name이 민희이거나 상민일 때 실행"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 표현식은 다음 형식으로 표기됩니다.
|
||||||
|
echo $(( 10 + 5 ))
|
||||||
|
|
||||||
|
# 다른 프로그래밍 언어와는 달리, bash는 셸이기 때문에 현재 디렉토리의 컨텍스트에서
|
||||||
|
# 실행됩니다. 현재 디렉토리의 파일과 디렉토리를 ls 명령어로 나열할 수 있습니다.
|
||||||
|
ls
|
||||||
|
|
||||||
|
# 다음은 실행을 제어하는 옵션의 예시입니다.
|
||||||
|
ls -l # 모든 파일과 디렉토리를 분리된 줄에 나열
|
||||||
|
ls -t # 디렉토리 내용을 마지막으로 수정된 날짜(내림차순)에 따라 정렬
|
||||||
|
ls -R # 이 디렉토리와 그 안의 모든 디렉토리에 대해 재귀적으로 `ls` 실행
|
||||||
|
|
||||||
|
# 이전 명령어의 결과는 다음 명령어에 입력될 수 있습니다.
|
||||||
|
# grep 명령어는 입력을 주어진 패턴에 따라 필터링합니다. 다음은 현재 디렉토리의
|
||||||
|
# .txt 파일을 나열하는 방법입니다.
|
||||||
|
ls -l | grep "\.txt"
|
||||||
|
|
||||||
|
# `cat`을 이용해 stdout으로 파일을 출력합니다.
|
||||||
|
cat file.txt
|
||||||
|
|
||||||
|
# `cat`으로 파일을 읽을 수도 있습니다.
|
||||||
|
Contents=$(cat file.txt)
|
||||||
|
echo "파일 시작\n$Contents\n파일 끝"
|
||||||
|
|
||||||
|
# `cp`를 이용해 파일이나 디렉토리를 다른 곳으로 복사할 수 있습니다.
|
||||||
|
# `cp`는 원본의 새로운 버전을 생성하므로 사본을 편집하는 것은
|
||||||
|
# 원본에 영향을 주지 않으며 그 반대도 마찬가지입니다.
|
||||||
|
# 목표 위치에 이미 파일이 있다면 덮어쓰게 됩니다.
|
||||||
|
cp srcFile.txt clone.txt
|
||||||
|
cp -r srcDirectory/ dst/ # 재귀적으로 복사
|
||||||
|
|
||||||
|
# 컴퓨터 간에 파일을 공유하려고 한다면 `scp` 혹은 `sftp`를 사용합니다.
|
||||||
|
# `scp`는 `cp`와 매우 유사하게 동작하며
|
||||||
|
# `sftp`는 더 상호작용적입니다.
|
||||||
|
|
||||||
|
# `mv`로 파일 혹은 디렉토리를 다른 곳으로 이동합니다.
|
||||||
|
# `mv`는 `cp`와 유사하지만 원본을 삭제합니다.
|
||||||
|
# 또한 `mv`로 파일의 이름을 바꿀 수도 있습니다.
|
||||||
|
mv s0urc3.txt dst.txt # sorry, l33t hackers...
|
||||||
|
|
||||||
|
# bash는 현재 디렉토리의 컨텍스트에서 실행되기 때문에, 다른 디렉토리에서 명령어를
|
||||||
|
# 실행하고 싶으실 수 있습니다. cd를 이용해 위치를 변경합니다.
|
||||||
|
cd ~ # 홈 디렉토리로 변경
|
||||||
|
cd .. # 한 디렉토리 위로 이동
|
||||||
|
# (즉 /home/username/Downloads에서 /home/username로)
|
||||||
|
cd /home/username/Documents # 특정 디렉토리로 이동
|
||||||
|
cd ~/Documents/.. # 아직도 홈 디렉토리... 아닌가??
|
||||||
|
|
||||||
|
# 서브셸로 디렉토리를 넘어서 작업할 수도 있습니다.
|
||||||
|
(echo "처음엔 여기 $PWD") && (cd 어딘가; echo "이제는 여기 $PWD")
|
||||||
|
pwd # 아직도 첫 디렉토리에 있음
|
||||||
|
|
||||||
|
# `mkdir`로 새 디렉토리를 만듭니다.
|
||||||
|
mkdir myNewDir
|
||||||
|
# `-p` 플래그는 필요하다면 해당 디렉토리의 경로 중간에 있는 디렉토리를 생성합니다.
|
||||||
|
mkdir -p myNewDir/with/intermediate/directories
|
||||||
|
|
||||||
|
# (stdin, stdout, stderr로) 명령어의 입출력을 리디렉션할 수 있습니다.
|
||||||
|
# stdin의 내용을 ^EOF$까지 읽고 hello.py에 그 내용을 덮어씁니다.
|
||||||
|
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
|
||||||
|
|
||||||
|
# stdin, stdoutk, stderr을 다양한 방법으로 리디렉션하여 hello.py를 실행합니다.
|
||||||
|
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
|
||||||
|
# 출력 오류는 이미 파일이 있을 경우 덮어쓰지만,
|
||||||
|
# 덮어쓰는 대신에 내용에 추가하고 싶다면 ">>"를 사용합니다.
|
||||||
|
python hello.py >> "output.out" 2>> "error.err"
|
||||||
|
|
||||||
|
# output.out에 덮어쓰고, error.err에 추가하고, 줄을 세기
|
||||||
|
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
|
||||||
|
wc -l output.out error.err
|
||||||
|
|
||||||
|
# 명령어를 실행하고 그 파일 디스크립터를 출력 (예: /dev/fd/123)
|
||||||
|
# man fd 참고
|
||||||
|
echo <(echo "#helloworld")
|
||||||
|
|
||||||
|
# output.out을 "#helloworld"으로 덮어쓰기
|
||||||
|
cat > output.out <(echo "#helloworld")
|
||||||
|
echo "#helloworld" > output.out
|
||||||
|
echo "#helloworld" | cat > output.out
|
||||||
|
echo "#helloworld" | tee output.out >/dev/null
|
||||||
|
|
||||||
|
# 임시 파일을 지울 수 있습니다. ('-i'로 대화식 실행)
|
||||||
|
# 경고: `rm` 명령어는 되돌릴 수 없습니다.
|
||||||
|
rm -v output.out error.err output-and-error.log
|
||||||
|
rm -r tempDir/ # 재귀적으로 삭제
|
||||||
|
|
||||||
|
# 다른 명령어에서 $()을 이용해 명령어를 치환할 수도 있습니다.
|
||||||
|
# 다음 명령어는 현재 디렉토리의 파일 및 디렉토리의 수를 표시합니다.
|
||||||
|
echo "$(ls | wc -l)개 항목이 있습니다."
|
||||||
|
|
||||||
|
# 백틱(``)을 이용할 수도 있지만 이 방식을 이용하면 중첩할 수 없기 때문에
|
||||||
|
# $()을 사용하는 것이 더 좋습니다.
|
||||||
|
echo "`ls | wc -l`개 항목이 있습니다."
|
||||||
|
|
||||||
|
# 자바나 C++의 switch와 비슷하게 동작하는 case 문을 사용할 수 있습니다.
|
||||||
|
case "$Variable" in
|
||||||
|
# 충족시킬 조건을 나열
|
||||||
|
0) echo "0입니다.";;
|
||||||
|
1) echo "1입니다.";;
|
||||||
|
*) echo "널이 아닌 값입니다.";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# for 반복문은 주어진 인자만큼 반복합니다.
|
||||||
|
# 다음은 $Variable을 세 번 출력합니다.
|
||||||
|
for Variable in {1..3}
|
||||||
|
do
|
||||||
|
echo "$Variable"
|
||||||
|
done
|
||||||
|
|
||||||
|
# 혹은 "전통적인 for 반복문" 방식을 쓸 수도 있습니다.
|
||||||
|
for ((a=1; a <= 3; a++))
|
||||||
|
do
|
||||||
|
echo $a
|
||||||
|
done
|
||||||
|
|
||||||
|
# 파일에도 적용될 수 있습니다.
|
||||||
|
# 다음은 file1과 file2에 'cat' 명령어를 실행합니다.
|
||||||
|
for Variable in file1 file2
|
||||||
|
do
|
||||||
|
cat "$Variable"
|
||||||
|
done
|
||||||
|
|
||||||
|
# 혹은 명령어의 결과에도 이용할 수 있습니다.
|
||||||
|
# 다음은 ls의 결과를 cat합니다.
|
||||||
|
for Output in $(ls)
|
||||||
|
do
|
||||||
|
cat "$Output"
|
||||||
|
done
|
||||||
|
|
||||||
|
# while 반복문
|
||||||
|
while [ true ]
|
||||||
|
do
|
||||||
|
echo "반복문 몸체"
|
||||||
|
break
|
||||||
|
done
|
||||||
|
|
||||||
|
# 함수를 정의할 수도 있습니다.
|
||||||
|
# 정의:
|
||||||
|
function foo ()
|
||||||
|
{
|
||||||
|
echo "인자는 함수 인자처럼 작동합니다. $@"
|
||||||
|
echo "그리고 $1 $2..."
|
||||||
|
echo "함수입니다."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 혹은 단순하게
|
||||||
|
bar ()
|
||||||
|
{
|
||||||
|
echo "함수를 선언하는 다른 방법"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 함수 호출
|
||||||
|
foo "My name is" $Name
|
||||||
|
|
||||||
|
# 몇 가지 유용한 명령어를 알아두면 좋습니다.
|
||||||
|
# file.txt의 마지막 10줄 출력
|
||||||
|
tail -n 10 file.txt
|
||||||
|
# file.txt의 첫 10줄 출력
|
||||||
|
head -n 10 file.txt
|
||||||
|
# file.txt 줄 별로 정렬
|
||||||
|
sort file.txt
|
||||||
|
# 중복되는 줄을 생략하거나 -d를 이용하여 보고
|
||||||
|
uniq -d file.txt
|
||||||
|
# ',' 문자 이전의 첫 열만 출력
|
||||||
|
cut -d ',' -f 1 file.txt
|
||||||
|
# file.txt에서 'okay'를 모두 'great'로 교체 (정규식 호환)
|
||||||
|
sed -i 's/okay/great/g' file.txt
|
||||||
|
# file.txt에서 정규식에 맞는 모든 줄을 stdin에 출력
|
||||||
|
# 다음 예시는 "foo"로 시작해 "bar"로 끝나는 줄 출력
|
||||||
|
grep "^foo.*bar$" file.txt
|
||||||
|
# "-c" 옵션을 넘겨 줄 번호를 대신 출력
|
||||||
|
grep -c "^foo.*bar$" file.txt
|
||||||
|
# 다른 유용한 옵션
|
||||||
|
grep -r "^foo.*bar$" someDir/ # 재귀적으로 `grep`
|
||||||
|
grep -n "^foo.*bar$" file.txt # 줄 번호 매기기
|
||||||
|
grep -rI "^foo.*bar$" someDir/ # 재귀적으로 `grep`하되 바이너리 파일은 무시
|
||||||
|
# 같은 검색으로 시작하여 "baz"를 포함하는 줄만 필터
|
||||||
|
grep "^foo.*bar$" file.txt | grep -v "baz"
|
||||||
|
|
||||||
|
# 정규식이 아니라 문자열로 검색하고 싶다면
|
||||||
|
# fgrep 혹은 grep -F
|
||||||
|
fgrep "foobar" file.txt
|
||||||
|
|
||||||
|
# trap 명령어로 스크립트에서 신호를 받을 때 명령어를 실행할 수 있습니다.
|
||||||
|
# 다음 명령어는 셋 중 한 가지 신호를 받으면 rm 명령어를 실행합니다.
|
||||||
|
trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM
|
||||||
|
|
||||||
|
# `sudo`를 통해 슈퍼이용자로 명령어를 실행합니다.
|
||||||
|
NAME1=$(whoami)
|
||||||
|
NAME2=$(sudo whoami)
|
||||||
|
echo "$NAME1였다가 더 강한 $NAME2가 되었다"
|
||||||
|
|
||||||
|
# 'help' 명령어로 내장 문서를 읽을 수 있습니다.
|
||||||
|
help
|
||||||
|
help help
|
||||||
|
help for
|
||||||
|
help return
|
||||||
|
help source
|
||||||
|
help .
|
||||||
|
|
||||||
|
# man으로 매뉴얼을 읽을 수도 있습니다.
|
||||||
|
apropos bash
|
||||||
|
man 1 bash
|
||||||
|
man bash
|
||||||
|
|
||||||
|
# info 명령어로 문서를 읽습니다. (?로 도움말)
|
||||||
|
apropos info | grep '^info.*('
|
||||||
|
man info
|
||||||
|
info info
|
||||||
|
info 5 info
|
||||||
|
|
||||||
|
# bash의 info 문서를 읽어 보세요.
|
||||||
|
info bash
|
||||||
|
info bash 'Bash Features'
|
||||||
|
info bash 6
|
||||||
|
info --apropos bash
|
||||||
|
```
|
235
ko-kr/vim-kr.html.markdown
Normal file
235
ko-kr/vim-kr.html.markdown
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
---
|
||||||
|
category: tool
|
||||||
|
tool: vim
|
||||||
|
contributors:
|
||||||
|
- ["RadhikaG", "https://github.com/RadhikaG"]
|
||||||
|
translators:
|
||||||
|
- ["Wooseop Kim", "https://github.com/linterpreteur"]
|
||||||
|
filename: LearnVim-kr.txt
|
||||||
|
lang: ko-kr
|
||||||
|
---
|
||||||
|
|
||||||
|
[Vim](www.vim.org)
|
||||||
|
(Vi IMproved)은 유닉스의 인기 있는 vi 에디터의 클론입니다. Vim은 속도와 생산성을 위해
|
||||||
|
설계된 텍스트 에디터로, 대부분의 유닉스 기반 시스템에 내장되어 있습니다. 다양한 단축 키를 통해
|
||||||
|
파일 안에서 빠르게 이동하고 편집할 수 있습니다.
|
||||||
|
|
||||||
|
## Vim 조작의 기본
|
||||||
|
|
||||||
|
```
|
||||||
|
vim <filename> # vim으로 <filename> 열기
|
||||||
|
:q # vim 종료
|
||||||
|
:w # 현재 파일 저장
|
||||||
|
:wq # 파일 저장 후 종료
|
||||||
|
:q! # 저장하지 않고 종료
|
||||||
|
# ! *강제로* :q를 실행하여, 저장 없이 종료
|
||||||
|
:x # 파일 저장 후 종료 (짧은 :wq)
|
||||||
|
|
||||||
|
u # 동작 취소
|
||||||
|
CTRL+R # 되돌리기
|
||||||
|
|
||||||
|
h # 한 글자 왼쪽으로 이동
|
||||||
|
j # 아래로 한 줄 이동
|
||||||
|
k # 위로 한 줄 이동
|
||||||
|
l # 한 글자 오른쪽으로 이동
|
||||||
|
|
||||||
|
# 줄 안에서의 이동
|
||||||
|
|
||||||
|
0 # 줄 시작으로 이동
|
||||||
|
$ # 줄 끝으로 이동
|
||||||
|
^ # 줄의 공백이 아닌 첫 문자로 이동
|
||||||
|
|
||||||
|
# 텍스트 검색
|
||||||
|
|
||||||
|
/word # 커서 뒤에 나타나는 해당 단어를 모두 하이라이트
|
||||||
|
?word # 커서 앞에 나타나는 해당 단어를 모두 하이라이트
|
||||||
|
n # 해당 단어를 검색 후 다음으로 나타나는 위치로 이동
|
||||||
|
N # 이전에 나타나는 위치로 이동
|
||||||
|
|
||||||
|
:%s/foo/bar/g # 파일 모든 줄에 있는 'foo'를 'bar'로 치환
|
||||||
|
:s/foo/bar/g # 현재 줄에 있는 'foo'를 'bar'로 치환
|
||||||
|
|
||||||
|
# 문자로 이동
|
||||||
|
|
||||||
|
f<character> # <character>로 건너뛰기
|
||||||
|
t<character> # <character>의 바로 뒤로 건너뛰기
|
||||||
|
|
||||||
|
# 예를 들어,
|
||||||
|
f< # <로 건너뛰기
|
||||||
|
t< # <의 바로 뒤로 건너뛰기
|
||||||
|
|
||||||
|
# 단어 단위로 이동
|
||||||
|
|
||||||
|
w # 한 단어 오른쪽으로 이동
|
||||||
|
b # 한 단어 왼쪽으로 이동
|
||||||
|
e # 현재 단어의 끝으로 이동
|
||||||
|
|
||||||
|
# 기타 이동 명령어
|
||||||
|
|
||||||
|
gg # 파일 맨 위로 이동
|
||||||
|
G # 파일 맨 아래로 이동
|
||||||
|
:NUM # 줄 수 NUM(숫자)로 가기
|
||||||
|
H # 화면 꼭대기로 이동
|
||||||
|
M # 화면 중간으로 이동
|
||||||
|
L # 화면 바닥으로 이동
|
||||||
|
```
|
||||||
|
|
||||||
|
## 모드
|
||||||
|
|
||||||
|
Vim은 **모드**의 개념에 기초를 두고 있습니다.
|
||||||
|
|
||||||
|
명령어 모드 - vim을 시작하면 처음에 이 모드입니다. 이동과 명령어 입력에 사용합니다.
|
||||||
|
삽입 모드 - 파일을 수정합니다.
|
||||||
|
비주얼 모드 - 텍스트를 하이라이트하고 그 텍스트에 대한 작업을 합니다.
|
||||||
|
실행 모드 - ':' 이후 명령어를 입력합니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
i # 커서 위치 앞에서 삽입 모드로 변경
|
||||||
|
a # 커서 위치 뒤에서 삽입 모드로 변경
|
||||||
|
v # 비주얼 모드로 변경
|
||||||
|
: # 실행 모드로 변경
|
||||||
|
<esc> # 현재 모드를 벗어나 명령어 모드로 변경
|
||||||
|
|
||||||
|
# 복사와 붙여넣기
|
||||||
|
|
||||||
|
y # 선택한 객체 복사(Yank)
|
||||||
|
yy # 현재 줄 복사
|
||||||
|
d # 선택한 객체 삭제
|
||||||
|
dd # 현재 줄 삭제
|
||||||
|
p # 커서 위치 뒤에 복사한 텍스트 붙여넣기
|
||||||
|
P # 커서 위치 뒤에 복사한 텍스트 붙여넣기
|
||||||
|
x # 현재 커서 위치의 문자 삭제
|
||||||
|
```
|
||||||
|
|
||||||
|
## vim의 문법
|
||||||
|
|
||||||
|
Vim의 명령어는 '서술어-수식어-목적어'로 생각할 수 있습니다.
|
||||||
|
|
||||||
|
서술어 - 취할 동작
|
||||||
|
수식어 - 동작을 취할 방식
|
||||||
|
목적어 - 동작을 취할 객체
|
||||||
|
|
||||||
|
'서술어', '수식어', '목적어'의 예시는 다음과 같습니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
# '서술어'
|
||||||
|
|
||||||
|
d # 지운다
|
||||||
|
c # 바꾼다
|
||||||
|
y # 복사한다
|
||||||
|
v # 선택한다
|
||||||
|
|
||||||
|
# '수식어'
|
||||||
|
|
||||||
|
i # 안에
|
||||||
|
a # 근처에
|
||||||
|
NUM # (숫자)
|
||||||
|
f # 찾아서 그곳에
|
||||||
|
t # 찾아서 그 앞에
|
||||||
|
/ # 문자열을 커서 뒤로 찾아서
|
||||||
|
? # 문자열을 커서 앞으로 찾아서
|
||||||
|
|
||||||
|
# '목적어'
|
||||||
|
|
||||||
|
w # 단어를
|
||||||
|
s # 문장을
|
||||||
|
p # 문단을
|
||||||
|
b # 블락을
|
||||||
|
|
||||||
|
# 예시 '문장' (명령어)
|
||||||
|
|
||||||
|
d2w # 단어 2개를 지운다
|
||||||
|
cis # 문장 안을 바꾼다
|
||||||
|
yip # 문단 안을 복사한다
|
||||||
|
ct< # 여는 괄호까지 바꾼다
|
||||||
|
# 현재 위치에서 다음 여는 괄호까지의 텍스트를 바꾼다
|
||||||
|
d$ # 줄 끝까지 지운다
|
||||||
|
```
|
||||||
|
|
||||||
|
## 몇 가지 트릭
|
||||||
|
|
||||||
|
<!--TODO: Add more!-->
|
||||||
|
```
|
||||||
|
> # 선택한 영역 한 칸 들여쓰기
|
||||||
|
< # 선택한 영역 한 칸 내어쓰기
|
||||||
|
:earlier 15m # 15분 전의 상태로 되돌리기
|
||||||
|
:later 15m # 위의 명령어를 취소
|
||||||
|
ddp # 이어지는 줄과 위치 맞바꾸기 (dd 후 p)
|
||||||
|
. # 이전 동작 반복
|
||||||
|
:w !sudo tee % # 현재 파일을 루트 권한으로 저장
|
||||||
|
```
|
||||||
|
|
||||||
|
## 매크로
|
||||||
|
|
||||||
|
매크로는 기본적으로 녹화할 수 있는 동작을 말합니다.
|
||||||
|
매크로를 녹화하기 시작하면, 끝날 때까지 **모든** 동작과 명령어가 녹화됩니다.
|
||||||
|
매크로를 호출하면 선택한 텍스트에 대해 정확히 같은 순서의 동작과 명령어가 실행됩니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
qa # 'a'라는 이름의 매크로 녹화 시작
|
||||||
|
q # 녹화 중지
|
||||||
|
@a # 매크로 실행
|
||||||
|
```
|
||||||
|
|
||||||
|
### ~/.vimrc 설정
|
||||||
|
|
||||||
|
.vimrc 파일은 Vim이 시작할 때의 설정을 결정합니다.
|
||||||
|
|
||||||
|
다음은 ~/.vimrc 파일의 예시입니다.
|
||||||
|
|
||||||
|
```
|
||||||
|
" ~/.vimrc 예시
|
||||||
|
" 2015.10
|
||||||
|
|
||||||
|
" vim이 iMprove 되려면 필요
|
||||||
|
set nocompatible
|
||||||
|
|
||||||
|
" 자동 들여쓰기 등을 위해 파일 명으로부터 타입 결정
|
||||||
|
filetype indent plugin on
|
||||||
|
|
||||||
|
" 신택스 하이라이팅 켜기
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
" 커맨드 라인 완성 향상
|
||||||
|
set wildmenu
|
||||||
|
|
||||||
|
" 대문자를 썼을 때가 아니면 대소문자 구분하지 않고 검색
|
||||||
|
set ignorecase
|
||||||
|
set smartcase
|
||||||
|
|
||||||
|
" 줄넘김을 했을 때 파일에 따른 들여쓰기가 켜져 있지 않다면
|
||||||
|
" 현재 줄과 같은 들여쓰기를 유지
|
||||||
|
set autoindent
|
||||||
|
|
||||||
|
" 좌측에 줄 번호 표시
|
||||||
|
set number
|
||||||
|
|
||||||
|
" 들여쓰기 설정 (개인 기호에 따라 변경)
|
||||||
|
|
||||||
|
" 탭 하나와 시각적으로 같을 스페이스 개수
|
||||||
|
set tabstop=4
|
||||||
|
|
||||||
|
" 편집할 때 탭 하나에 들어갈 스페이스 수
|
||||||
|
set softtabstop=4
|
||||||
|
|
||||||
|
" 들여쓰기 혹은 내어쓰기 작업(>>, <<)을 했을 때 움직일 스페이스 개수
|
||||||
|
set shiftwidth=4
|
||||||
|
|
||||||
|
" 탭을 스페이스로 변환
|
||||||
|
set expandtab
|
||||||
|
|
||||||
|
" 들여쓰기와 정렬에 자동 탭 및 스페이스 사용
|
||||||
|
set smarttab
|
||||||
|
```
|
||||||
|
|
||||||
|
### 참고 자료
|
||||||
|
|
||||||
|
[(영어) Vim 홈페이지](http://www.vim.org/index.php)
|
||||||
|
|
||||||
|
`$ vimtutor`
|
||||||
|
|
||||||
|
[(영어) vim 입문과 기초](https://danielmiessler.com/study/vim/)
|
||||||
|
|
||||||
|
[(영어) 엄마가 말해주지 않은 Vim의 어두운 구석들 (Stack Overflow 게시물)](http://stackoverflow.com/questions/726894/what-are-the-dark-corners-of-vim-your-mom-never-told-you-about)
|
||||||
|
|
||||||
|
[(영어) 아치 리눅스 위키](https://wiki.archlinux.org/index.php/Vim)
|
@@ -217,8 +217,6 @@ bar ()
|
|||||||
# Å kalle en funksjon:
|
# Å kalle en funksjon:
|
||||||
foo "Mitt navn er" $NAME
|
foo "Mitt navn er" $NAME
|
||||||
|
|
||||||
# There are a lot of useful commands you should learn:
|
|
||||||
# prints last 10 lines of file.txt
|
|
||||||
# Det er mange nyttige kommandoer du bør lære deg:
|
# Det er mange nyttige kommandoer du bør lære deg:
|
||||||
# "tail" skriver ut slutten av en fil, i dette tilfellet de siste 10 linjene
|
# "tail" skriver ut slutten av en fil, i dette tilfellet de siste 10 linjene
|
||||||
tail -n 10 file.txt
|
tail -n 10 file.txt
|
||||||
|
@@ -51,6 +51,13 @@ my @mixed = ("camel", 42, 1.23);
|
|||||||
# indicate one value will be returned.
|
# indicate one value will be returned.
|
||||||
my $second = $animals[1];
|
my $second = $animals[1];
|
||||||
|
|
||||||
|
# The size of an array is retrieved by accessing the array in a scalar
|
||||||
|
# context, such as assigning it to a scalar variable or using the
|
||||||
|
# "scalar" operator.
|
||||||
|
|
||||||
|
my $num_animals = @animals;
|
||||||
|
print "Number of numbers: ", scalar(@numbers), "\n";
|
||||||
|
|
||||||
## Hashes
|
## Hashes
|
||||||
# A hash represents a set of key/value pairs:
|
# A hash represents a set of key/value pairs:
|
||||||
|
|
||||||
@@ -67,6 +74,11 @@ my %fruit_color = (
|
|||||||
# Hash elements are accessed using curly braces, again with the $ sigil.
|
# Hash elements are accessed using curly braces, again with the $ sigil.
|
||||||
my $color = $fruit_color{apple};
|
my $color = $fruit_color{apple};
|
||||||
|
|
||||||
|
# All of the keys or values that exist in a hash can be accessed using
|
||||||
|
# the "keys" and "values" functions.
|
||||||
|
my @fruits = keys %fruit_color;
|
||||||
|
my @colors = values %fruit_color;
|
||||||
|
|
||||||
# Scalars, arrays and hashes are documented more fully in perldata.
|
# Scalars, arrays and hashes are documented more fully in perldata.
|
||||||
# (perldoc perldata).
|
# (perldoc perldata).
|
||||||
|
|
||||||
@@ -144,6 +156,12 @@ for (@elements) {
|
|||||||
print;
|
print;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# iterating through a hash (for and foreach are equivalent)
|
||||||
|
|
||||||
|
foreach my $key (keys %hash) {
|
||||||
|
print $key, ': ', $hash{$key}, "\n";
|
||||||
|
}
|
||||||
|
|
||||||
# the Perlish post-condition way again
|
# the Perlish post-condition way again
|
||||||
print for @elements;
|
print for @elements;
|
||||||
|
|
||||||
@@ -170,8 +188,11 @@ $x =~ s/foo/bar/g; # replaces ALL INSTANCES of foo with bar in $x
|
|||||||
|
|
||||||
# You can open a file for input or output using the "open()" function.
|
# You can open a file for input or output using the "open()" function.
|
||||||
|
|
||||||
|
# For reading:
|
||||||
open(my $in, "<", "input.txt") or die "Can't open input.txt: $!";
|
open(my $in, "<", "input.txt") or die "Can't open input.txt: $!";
|
||||||
|
# For writing (clears file if it exists):
|
||||||
open(my $out, ">", "output.txt") or die "Can't open output.txt: $!";
|
open(my $out, ">", "output.txt") or die "Can't open output.txt: $!";
|
||||||
|
# For writing (appends to end of file):
|
||||||
open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
|
open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
|
||||||
|
|
||||||
# You can read from an open filehandle using the "<>" operator. In
|
# You can read from an open filehandle using the "<>" operator. In
|
||||||
@@ -182,6 +203,12 @@ open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
|
|||||||
my $line = <$in>;
|
my $line = <$in>;
|
||||||
my @lines = <$in>;
|
my @lines = <$in>;
|
||||||
|
|
||||||
|
# You can write to an open filehandle using the standard "print"
|
||||||
|
# function.
|
||||||
|
|
||||||
|
print $out @lines;
|
||||||
|
print $log $msg, "\n";
|
||||||
|
|
||||||
#### Writing subroutines
|
#### Writing subroutines
|
||||||
|
|
||||||
# Writing subroutines is easy:
|
# Writing subroutines is easy:
|
||||||
|
@@ -125,8 +125,8 @@ hello-to; #=> Hello, World !
|
|||||||
hello-to(); #=> Hello, World !
|
hello-to(); #=> Hello, World !
|
||||||
hello-to('You'); #=> Hello, You !
|
hello-to('You'); #=> Hello, You !
|
||||||
|
|
||||||
## You can also, by using a syntax akin to the one of hashes (yay unified syntax !),
|
## You can also, by using a syntax akin to the one of hashes
|
||||||
## pass *named* arguments to a `sub`.
|
## (yay unified syntax !), pass *named* arguments to a `sub`.
|
||||||
# They're optional, and will default to "Any".
|
# They're optional, and will default to "Any".
|
||||||
sub with-named($normal-arg, :$named) {
|
sub with-named($normal-arg, :$named) {
|
||||||
say $normal-arg + $named;
|
say $normal-arg + $named;
|
||||||
@@ -169,9 +169,9 @@ my &s = &say-hello;
|
|||||||
my &other-s = sub { say "Anonymous function !" }
|
my &other-s = sub { say "Anonymous function !" }
|
||||||
|
|
||||||
# A sub can have a "slurpy" parameter, or "doesn't-matter-how-many"
|
# A sub can have a "slurpy" parameter, or "doesn't-matter-how-many"
|
||||||
sub as-many($head, *@rest) { # `*@` (slurpy) will basically "take everything else".
|
sub as-many($head, *@rest) { #`*@` (slurpy) will "take everything else"
|
||||||
# Note: you can have parameters *before* (like here)
|
# Note: you can have parameters *before* a slurpy one (like here),
|
||||||
# a slurpy one, but not *after*.
|
# but not *after*.
|
||||||
say @rest.join(' / ') ~ " !";
|
say @rest.join(' / ') ~ " !";
|
||||||
}
|
}
|
||||||
say as-many('Happy', 'Happy', 'Birthday'); #=> Happy / Birthday !
|
say as-many('Happy', 'Happy', 'Birthday'); #=> Happy / Birthday !
|
||||||
@@ -224,7 +224,7 @@ say $x; #=> 52
|
|||||||
# - `if`
|
# - `if`
|
||||||
# Before talking about `if`, we need to know which values are "Truthy"
|
# Before talking about `if`, we need to know which values are "Truthy"
|
||||||
# (represent True), and which are "Falsey" (or "Falsy") -- represent False.
|
# (represent True), and which are "Falsey" (or "Falsy") -- represent False.
|
||||||
# Only these values are Falsey: 0, (), {}, "", Nil, A type (like `Str` or `Int`),
|
# Only these values are Falsey: 0, (), {}, "", Nil, A type (like `Str` or `Int`)
|
||||||
# and of course False itself.
|
# and of course False itself.
|
||||||
# Every other value is Truthy.
|
# Every other value is Truthy.
|
||||||
if True {
|
if True {
|
||||||
@@ -265,13 +265,14 @@ say $age > 18 ?? "You are an adult" !! "You are under 18";
|
|||||||
|
|
||||||
given "foo bar" {
|
given "foo bar" {
|
||||||
say $_; #=> foo bar
|
say $_; #=> foo bar
|
||||||
when /foo/ { # Don't worry about smart matching yet – just know `when` uses it.
|
when /foo/ { # Don't worry about smart matching yet – just know `when` uses it
|
||||||
# This is equivalent to `if $_ ~~ /foo/`.
|
# This is equivalent to `if $_ ~~ /foo/`.
|
||||||
say "Yay !";
|
say "Yay !";
|
||||||
}
|
}
|
||||||
when $_.chars > 50 { # smart matching anything with True (`$a ~~ True`) is True,
|
when $_.chars > 50 { # smart matching anything with True is True,
|
||||||
|
# i.e. (`$a ~~ True`)
|
||||||
# so you can also put "normal" conditionals.
|
# so you can also put "normal" conditionals.
|
||||||
# This when is equivalent to this `if`:
|
# This `when` is equivalent to this `if`:
|
||||||
# if $_ ~~ ($_.chars > 50) {...}
|
# if $_ ~~ ($_.chars > 50) {...}
|
||||||
# Which means:
|
# Which means:
|
||||||
# if $_.chars > 50 {...}
|
# if $_.chars > 50 {...}
|
||||||
@@ -288,7 +289,8 @@ given "foo bar" {
|
|||||||
# but can also be a C-style `for` loop:
|
# but can also be a C-style `for` loop:
|
||||||
loop {
|
loop {
|
||||||
say "This is an infinite loop !";
|
say "This is an infinite loop !";
|
||||||
last; # last breaks out of the loop, like the `break` keyword in other languages
|
last; # last breaks out of the loop, like the `break` keyword in other
|
||||||
|
# languages
|
||||||
}
|
}
|
||||||
|
|
||||||
loop (my $i = 0; $i < 5; $i++) {
|
loop (my $i = 0; $i < 5; $i++) {
|
||||||
|
444
pl-pl/haskell-pl.html.markdown
Normal file
444
pl-pl/haskell-pl.html.markdown
Normal file
@@ -0,0 +1,444 @@
|
|||||||
|
---
|
||||||
|
language: Haskell
|
||||||
|
lang: pl-pl
|
||||||
|
contributors:
|
||||||
|
- ["Remigiusz Suwalski", "https://github.com/remigiusz-suwalski"]
|
||||||
|
---
|
||||||
|
|
||||||
|
Haskell został zaprojektowany jako praktyczny, czysto funkcyjny język
|
||||||
|
programowania. Jest znany przede wszystkim ze względu na jego monady oraz system
|
||||||
|
typów, ale ja lubię do niego wracać przez jego elegancję. Sprawił on, że
|
||||||
|
programowanie jest prawdziwą przyjemnością.
|
||||||
|
|
||||||
|
```haskell
|
||||||
|
-- Komentarze jednolinijkowe zaczynają się od dwóch myślników
|
||||||
|
{- Komentarze wielolinijkowe należy
|
||||||
|
zamykać w bloki klamrami.
|
||||||
|
-}
|
||||||
|
|
||||||
|
----------------------------------------------------
|
||||||
|
-- 1. Podstawowe typy danych oraz operatory
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
-- Mamy liczby
|
||||||
|
3 -- 3
|
||||||
|
|
||||||
|
-- Podstawowe działania działają tak, jak powinny
|
||||||
|
1 + 1 -- 2
|
||||||
|
8 - 1 -- 7
|
||||||
|
10 * 2 -- 20
|
||||||
|
35 / 5 -- 7.0
|
||||||
|
|
||||||
|
-- dzielenie domyślnie zwraca ,,dokładny'' wynik
|
||||||
|
35 / 4 -- 8.75
|
||||||
|
|
||||||
|
-- dzielenie całkowitoliczbowe
|
||||||
|
35 `div` 4 -- 8
|
||||||
|
|
||||||
|
-- wartości logiczne także są podstawowym typem danych:
|
||||||
|
True
|
||||||
|
False
|
||||||
|
|
||||||
|
-- operacje logiczne: negacja oraz porównania
|
||||||
|
not True -- False
|
||||||
|
not False -- True
|
||||||
|
1 == 1 -- True
|
||||||
|
1 /= 1 -- False
|
||||||
|
1 < 10 -- True
|
||||||
|
|
||||||
|
-- W powyższych przykładach, `not` jest funkcją przyjmującą jeden argument.
|
||||||
|
-- Haskell nie potrzebuje nawiasów, by wywołać funkcję: argumenty są po prostu
|
||||||
|
-- wypisywane jeden za drugim. Ogólnie wygląda to tak:
|
||||||
|
-- funkcja arg1 arg2 arg3...
|
||||||
|
-- Sekcja poświęcona funkcjom zawiera informacje, jak stworzyć własne.
|
||||||
|
|
||||||
|
-- Łańcuchy znaków (stringi) i pojedyncze znaki:
|
||||||
|
"To jest lancuch."
|
||||||
|
'a' -- znak
|
||||||
|
'Nie mozna laczyc apostrofow z lancuchami.' -- błąd!
|
||||||
|
|
||||||
|
-- Łańcuchy można sklejać
|
||||||
|
"Hello " ++ "world!" -- "Hello world!"
|
||||||
|
|
||||||
|
-- Łańcuch jest listą własnych znaków
|
||||||
|
['H', 'e', 'l', 'l', 'o'] -- "Hello"
|
||||||
|
"To jest lancuch" !! 0 -- 'T'
|
||||||
|
|
||||||
|
----------------------------------------------------
|
||||||
|
-- Listy oraz krotki
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
-- Wszystkie elementy listy muszą być tego samego typu.
|
||||||
|
-- Poniższe dwie listy są identyczne:
|
||||||
|
[1, 2, 3, 4, 5]
|
||||||
|
[1..5]
|
||||||
|
|
||||||
|
-- Zakresy są uniwersalne.
|
||||||
|
['A'..'F'] -- "ABCDEF"
|
||||||
|
|
||||||
|
-- Przy tworzeniu zakresów można określić krok.
|
||||||
|
[0,2..10] -- [0, 2, 4, 6, 8, 10]
|
||||||
|
[5..1] -- To nie zadziała, gdyż w Haskellu zakresy tworzone są domyślnie rosnąco
|
||||||
|
[5,4..1] -- [5, 4, 3, 2, 1]
|
||||||
|
|
||||||
|
-- indeksowanie listy od zera
|
||||||
|
[1..10] !! 3 -- 4
|
||||||
|
|
||||||
|
-- Można nawet tworzyć listy nieskończone!
|
||||||
|
[1..] -- lista wszystkich liczb naturalnych
|
||||||
|
|
||||||
|
-- Nieskończone listy mają prawo działać, ponieważ Haskell cechuje się leniwym
|
||||||
|
-- wartościowaniem. To oznacza, że obliczane są jedynie te elementy listy,
|
||||||
|
-- których istotnie potrzebujemy. Możemy poprosić o tysiączny element i
|
||||||
|
-- dostaniemy go:
|
||||||
|
|
||||||
|
[1..] !! 999 -- 1000
|
||||||
|
|
||||||
|
-- Haskell wyznaczył pierwsze tysiąc elementów listy, ale cała jej reszta
|
||||||
|
-- jeszcze nie istnieje! Nie zostanie obliczona ich wartość, póki nie zajdzie
|
||||||
|
-- taka potrzeba.
|
||||||
|
|
||||||
|
-- łączenie dwóch list
|
||||||
|
[1..5] ++ [6..10]
|
||||||
|
|
||||||
|
-- dodawanie pojedynczego elementu na początek listy
|
||||||
|
0:[1..5] -- [0, 1, 2, 3, 4, 5]
|
||||||
|
|
||||||
|
-- więcej operacji na listach
|
||||||
|
head [1..5] -- 1
|
||||||
|
tail [1..5] -- [2, 3, 4, 5]
|
||||||
|
init [1..5] -- [1, 2, 3, 4]
|
||||||
|
last [1..5] -- 5
|
||||||
|
|
||||||
|
-- list comprehensions
|
||||||
|
[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
|
||||||
|
|
||||||
|
-- z dodatkowym warunkiem
|
||||||
|
[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
|
||||||
|
|
||||||
|
-- każdy element krotki może być innego typu, jednak sama krotka musi być stałej
|
||||||
|
-- długości. Przykładowo:
|
||||||
|
("haskell", 1)
|
||||||
|
|
||||||
|
-- dostęp do elementów pary (krotki długości 2):
|
||||||
|
fst ("haskell", 1) -- "haskell"
|
||||||
|
snd ("haskell", 1) -- 1
|
||||||
|
|
||||||
|
----------------------------------------------------
|
||||||
|
-- 3. Funkcje
|
||||||
|
----------------------------------------------------
|
||||||
|
-- Prosta funkcja przyjmująca dwa argumenty
|
||||||
|
add a b = a + b
|
||||||
|
|
||||||
|
-- Pamiętaj, że podczas stosowania ghci, interpretera Haskella, wszelkie
|
||||||
|
-- definicje muszą zostać poprzedzone słowem `let`, na przykład:
|
||||||
|
-- let add a b = a + b
|
||||||
|
|
||||||
|
-- Używanie funkcji:
|
||||||
|
add 1 2 -- 3
|
||||||
|
|
||||||
|
-- Nazwę funkcji można podać między dwoma argumentami, ale wtedy musi zostać
|
||||||
|
-- otoczona grawisami:
|
||||||
|
1 `add` 2 -- 3
|
||||||
|
|
||||||
|
-- Nazwa funkcji nie musi zawierać żadnych liter, przykładem czego jest
|
||||||
|
-- operator dzielenia:
|
||||||
|
(//) a b = a `div` b
|
||||||
|
35 // 4 -- 8
|
||||||
|
|
||||||
|
-- Strażnicy: prosty sposób na rozbijanie funkcji na przypadki
|
||||||
|
fib x
|
||||||
|
| x < 2 = 1
|
||||||
|
| otherwise = fib (x - 1) + fib (x - 2)
|
||||||
|
|
||||||
|
-- Dopasowanie wzorca jest podobne. Haskell sam automatycznie wybierze, która
|
||||||
|
-- z poniższych definicji fib powinna zostać użyta:
|
||||||
|
fib 1 = 1
|
||||||
|
fib 2 = 2
|
||||||
|
fib x = fib (x - 1) + fib (x - 2)
|
||||||
|
|
||||||
|
-- Dopasowanie z krotkami:
|
||||||
|
foo (x, y) = (x + 1, y + 2)
|
||||||
|
|
||||||
|
-- Dopasowanie z listami. Tutaj `x` jest pierwszym elementem listy,
|
||||||
|
-- natomiast `xs` to jej reszta (ogon). Poniższa funkcja nakłada funkcję
|
||||||
|
-- na każdy z elementów listy:
|
||||||
|
myMap func [] = []
|
||||||
|
myMap func (x:xs) = func x:(myMap func xs)
|
||||||
|
|
||||||
|
-- Funkcje anonimowe tworzone są przy użyciu w-tył-ciachu, po którym następują
|
||||||
|
-- wszystkie argumenty:
|
||||||
|
myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
|
||||||
|
|
||||||
|
-- używanie zwijania z anonimowymi funkcjami: foldl1 zwija z lewej strony,
|
||||||
|
-- przyjmując jako wartość początkową zbieracza pierwszy element listy.
|
||||||
|
foldl1 (\acc x -> acc + x) [1..5] -- 15
|
||||||
|
|
||||||
|
----------------------------------------------------
|
||||||
|
-- 4. Więcej funkcji
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
-- częściowe nakładanie: jeśli funkcja nie otrzyma wszystkich swoich argumentów,
|
||||||
|
-- zostaje cześciowo nałożona - zwraca funkcję, która przyjmuje pozostałe,
|
||||||
|
-- brakujące argumenty.
|
||||||
|
|
||||||
|
add a b = a + b
|
||||||
|
foo = add 10 -- foo jest teraz funkcją, która przyjmuje liczbę, zwiększa ją o 10
|
||||||
|
foo 5 -- 15
|
||||||
|
|
||||||
|
-- Inny sposób na zapisanie tego samego:
|
||||||
|
foo = (10+)
|
||||||
|
foo 5 -- 15
|
||||||
|
|
||||||
|
-- składanie funkcji:
|
||||||
|
-- operator `.` składa wiele funkcji w jedną.
|
||||||
|
-- Dla przykładu, foo jest funkcją, która powiększa swój argument o 10, mnoży
|
||||||
|
-- tak uzyskaną liczbę przez 4 i zwraca wynik:
|
||||||
|
foo = (4*) . (10+)
|
||||||
|
|
||||||
|
-- 4*(10 + 5) = 60
|
||||||
|
foo 5 -- 60
|
||||||
|
|
||||||
|
-- ustalanie kolejności
|
||||||
|
-- Haskell posiada inny operator, `$`, który nakłada funkcję do podanego
|
||||||
|
-- parametru. W przeciwieństwie do zwykłego lewostronnie łącznego nakładania
|
||||||
|
-- funkcji, którego priorytet jest najwyższy (10), operator `$` posiada
|
||||||
|
-- priorytet 0 i jest prawostronnie łączny. Tak niski priorytet oznacza, że
|
||||||
|
-- wyrażenie po prawej traktowane jest jako parametr funkcji po lewej
|
||||||
|
|
||||||
|
-- wcześniej
|
||||||
|
even (fib 7) -- fałsz
|
||||||
|
|
||||||
|
-- równoważnie
|
||||||
|
even $ fib 7 -- fałsz
|
||||||
|
|
||||||
|
-- składanie funkcji
|
||||||
|
even . fib $ 7 -- fałsz
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------
|
||||||
|
-- 5. Sygnatury typów
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
-- Haskell posiada wyjątkowo silny system typów, w którym każde poprawne
|
||||||
|
-- wyrażenie ma swój typ.
|
||||||
|
|
||||||
|
-- Kilka podstawowych typów:
|
||||||
|
5 :: Integer
|
||||||
|
"hello" :: String
|
||||||
|
True :: Bool
|
||||||
|
|
||||||
|
-- Funkcje też są określonego typu.
|
||||||
|
-- `not` przyjmuje wartość logiczną i taką też zwraca:
|
||||||
|
-- not :: Bool -> Bool
|
||||||
|
|
||||||
|
-- Przykład funkcji przyjmującej dwa argumenty
|
||||||
|
-- add :: Integer -> Integer -> Integer
|
||||||
|
|
||||||
|
-- Dobrą praktyką podczas definiowania wartości jest napisanie nad nią
|
||||||
|
-- także jej typu:
|
||||||
|
double :: Integer -> Integer
|
||||||
|
double x = x * 2
|
||||||
|
|
||||||
|
----------------------------------------------------
|
||||||
|
-- 6. Wyrażenia warunkowe
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
-- wyrażenie warunkowe
|
||||||
|
haskell = if 1 == 1 then "wspaniale" else "paskudnie" -- haskell = "wspaniale"
|
||||||
|
|
||||||
|
-- wyrażenie warunkowe można rozbić na wiele linii,
|
||||||
|
-- ale trzeba uważać na wcięcia w kodzie
|
||||||
|
haskell = if 1 == 1
|
||||||
|
then "wspaniale"
|
||||||
|
else "paskudnie"
|
||||||
|
|
||||||
|
-- rozpatrywanie przypadków: oto jak można parsować argumenty z linii poleceń:
|
||||||
|
case args of
|
||||||
|
"help" -> printHelp
|
||||||
|
"start" -> startProgram
|
||||||
|
_ -> putStrLn "bad args"
|
||||||
|
|
||||||
|
-- Haskell zastępuje pętle (których nie ma) rekurencyjnymi wywołaniami funkcji.
|
||||||
|
-- map aplikuje funkcję do każdego elementu listy:
|
||||||
|
|
||||||
|
map (*2) [1..5] -- [2, 4, 6, 8, 10]
|
||||||
|
|
||||||
|
-- możesz zdefiniować funkcję for przy użyciu map:
|
||||||
|
for array func = map func array
|
||||||
|
|
||||||
|
-- a następnie użyć jej:
|
||||||
|
for [0..5] $ \i -> show i
|
||||||
|
|
||||||
|
-- mogliśmy użyć krótszego zapisu bez zmiany działania funkcji for:
|
||||||
|
for [0..5] show
|
||||||
|
|
||||||
|
-- Do redukcji listy służy polecenie foldl (foldr):
|
||||||
|
-- foldl <fn> <initial value> <list>
|
||||||
|
foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
|
||||||
|
|
||||||
|
-- Jest to równoważne z:
|
||||||
|
(2 * (2 * (2 * 4 + 1) + 2) + 3)
|
||||||
|
|
||||||
|
-- foldl składa od od lewej strony, foldr od prawej
|
||||||
|
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
|
||||||
|
|
||||||
|
-- To zaś równoważne jest:
|
||||||
|
(2 * 1 + (2 * 2 + (2 * 3 + 4)))
|
||||||
|
|
||||||
|
----------------------------------------------------
|
||||||
|
-- 7. Typy danych
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
-- Oto jak tworzy się nowe typy danych w Haskellu:
|
||||||
|
|
||||||
|
data Color = Red | Blue | Green
|
||||||
|
|
||||||
|
-- Teraz można używać ich we własnych funkcjach:
|
||||||
|
|
||||||
|
say :: Color -> String
|
||||||
|
say Red = "You are Red!"
|
||||||
|
say Blue = "You are Blue!"
|
||||||
|
say Green = "You are Green!"
|
||||||
|
|
||||||
|
-- Twoje typy danych mogą posiadać nawet parametry:
|
||||||
|
|
||||||
|
data Maybe a = Nothing | Just a
|
||||||
|
|
||||||
|
-- Wszystkie poniższe są typu Maybe
|
||||||
|
Just "hello" -- typu `Maybe String`
|
||||||
|
Just 1 -- typu `Maybe Int`
|
||||||
|
Nothing -- typu `Maybe a` for any `a`
|
||||||
|
|
||||||
|
----------------------------------------------------
|
||||||
|
-- 8. Haskell IO
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
-- Chociaż obsługa wejścia i wyjścia nie może zostać wyjaśniona przez poznaniem
|
||||||
|
-- monad, spróbujemy zrobić to częściowo
|
||||||
|
|
||||||
|
-- Wykonanie programu napisanego w Haskellu wywołuje funkcję `main`
|
||||||
|
-- Musi zwrócić wartość typu `IO a` dla pewnego `a`. Przykład:
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = putStrLn $ "Hello, sky! " ++ (say Blue)
|
||||||
|
-- putStrLn has type String -> IO ()
|
||||||
|
|
||||||
|
-- Najłatwiej obsłużyć wejście i wyjście, kiedy program zostanie
|
||||||
|
-- zaimplementowany jako funkcja String -> String. Funkcja
|
||||||
|
-- interact :: (String -> String) -> IO ()
|
||||||
|
-- pobiera pewien tekst, wykonuje na nim operacje, po czym wypisuje wynik.
|
||||||
|
|
||||||
|
countLines :: String -> String
|
||||||
|
countLines = show . length . lines
|
||||||
|
|
||||||
|
main' = interact countLines
|
||||||
|
|
||||||
|
-- Możesz myśleć o wartości typu `IO ()` jako reprezentującej ciąg czynności,
|
||||||
|
-- które komputer ma wykonać, zupełnie niczym program komputerowy w imperatywnym
|
||||||
|
-- języku programowania. Akcje można łączyć przy użyciu notacji `do`:
|
||||||
|
|
||||||
|
sayHello :: IO ()
|
||||||
|
sayHello = do
|
||||||
|
putStrLn "What is your name?"
|
||||||
|
name <- getLine -- this gets a line and gives it the name "name"
|
||||||
|
putStrLn $ "Hello, " ++ name
|
||||||
|
|
||||||
|
-- Ćwiczenie: napisz własną wersję `interact`,
|
||||||
|
-- która czyta tylko jedną linię wejścia.
|
||||||
|
|
||||||
|
-- Kod w `sayHello` nigdy się nie wykona. Jedyną akcją, która zostanie
|
||||||
|
-- uruchomiona, jest wartość `main`.
|
||||||
|
-- Aby uruchomić `sayHello`, należy zastąpić poprzednią definicję `main` przez
|
||||||
|
-- main = sayHello
|
||||||
|
|
||||||
|
-- Spróbujmy lepiej zrozumieć, jak działa funkcja `getLine`, której właśnie
|
||||||
|
-- użyliśmy. Jej typem jest
|
||||||
|
-- getLine :: IO String
|
||||||
|
-- Możesz myśleć o wartości typu `IO a` jako reprezentującej program, który
|
||||||
|
-- wygeneruje wartość typu `a`, poza wszystkim innym, co jeszcze zrobi.
|
||||||
|
-- Możemy także tworzyć własne akcje typu `IO String`:
|
||||||
|
|
||||||
|
action :: IO String
|
||||||
|
action = do
|
||||||
|
putStrLn "This is a line. Duh"
|
||||||
|
input1 <- getLine
|
||||||
|
input2 <- getLine
|
||||||
|
-- The type of the `do` statement is that of its last line.
|
||||||
|
-- `return` is not a keyword, but merely a function
|
||||||
|
return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
|
||||||
|
|
||||||
|
-- Możemy użyć tego tak jak używaliśmy `getLine`:
|
||||||
|
|
||||||
|
main'' = do
|
||||||
|
putStrLn "I will echo two lines!"
|
||||||
|
result <- action
|
||||||
|
putStrLn result
|
||||||
|
putStrLn "This was all, folks!"
|
||||||
|
|
||||||
|
-- Typ `IO` jest przykładem monady. Sposób w jakim Haskell używa monad do
|
||||||
|
-- obsługi wejścia i wyjścia pozwala mu być czysto funkcyjnym językiem.
|
||||||
|
-- Każda funkcja, która wchodzi w interakcje ze światem zewnętrznym, oznaczana
|
||||||
|
-- jest jako `IO` w jej sygnaturze typu, co umożliwia odróżnianie funkcji
|
||||||
|
-- czystych od zależnych od świata lub modyfikujących stan.
|
||||||
|
|
||||||
|
-- To naprawdę użyteczna własność, dzięki której jesteśmy w stanie uruchamiać
|
||||||
|
-- czyste funkcje jednocześnie.
|
||||||
|
|
||||||
|
----------------------------------------------------
|
||||||
|
-- 9. Interaktywne środowisko programowania
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
-- Aby uruchomić repl (read-eval-print loop, interaktywne środowisko), należy
|
||||||
|
-- wpisać `ghci`. Można już programować. Do definiowania nowych wartości służy
|
||||||
|
-- słowo kluczowe `let`:
|
||||||
|
|
||||||
|
let foo = 5
|
||||||
|
|
||||||
|
-- Do sprawdzania typów dowolnej wartości (wyrażenia) wykorzystuje się `:t`:
|
||||||
|
|
||||||
|
> :t foo
|
||||||
|
foo :: Integer
|
||||||
|
|
||||||
|
-- Działania takie jak `+`, `:` czy `$`, są funkcjami.
|
||||||
|
-- Przed sprawdzeniem ich typu należy otoczyć je nawiasami:
|
||||||
|
|
||||||
|
> :t (:)
|
||||||
|
(:) :: a -> [a] -> [a]
|
||||||
|
|
||||||
|
-- Dodatkowych informacji dostarcza `:i`:
|
||||||
|
|
||||||
|
> :i (+)
|
||||||
|
class Num a where
|
||||||
|
(+) :: a -> a -> a
|
||||||
|
...
|
||||||
|
-- Defined in ‘GHC.Num’
|
||||||
|
infixl 6 +
|
||||||
|
|
||||||
|
-- Można nawet wykonywać akcje typu `IO ()`!
|
||||||
|
|
||||||
|
> sayHello
|
||||||
|
What is your name?
|
||||||
|
Friend!
|
||||||
|
Hello, Friend!
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Pominęliśmy wiele aspektów Haskella, wliczając w to monady. To właśnie one
|
||||||
|
sprawiają, że programowanie w Haskellu sprawia tyle frajdy. Na zakończenie
|
||||||
|
pokażę Tobie implementację algorytmu quicksort w Haskellu:
|
||||||
|
|
||||||
|
```haskell
|
||||||
|
qsort [] = []
|
||||||
|
qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
|
||||||
|
where lesser = filter (< p) xs
|
||||||
|
greater = filter (>= p) xs
|
||||||
|
```
|
||||||
|
|
||||||
|
Haskell może zostać zainstalowany na co najmniej dwa sposoby:
|
||||||
|
- tradycyjnie [przy użyciu Cabala](http://www.haskell.org/platform/),
|
||||||
|
- nowocześnie [z pomocą Stack](https://www.stackage.org/install).
|
||||||
|
|
||||||
|
Godnymi poleceniami wprowadzeniami są wspaniałe
|
||||||
|
[Learn you a Haskell](http://learnyouahaskell.com/) albo
|
||||||
|
[Real World Haskell](http://book.realworldhaskell.org/).
|
668
pt-br/scala-pt.html.markdown
Normal file
668
pt-br/scala-pt.html.markdown
Normal file
@@ -0,0 +1,668 @@
|
|||||||
|
---
|
||||||
|
language: Scala
|
||||||
|
filename: learnscala-pt.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"]
|
||||||
|
translators:
|
||||||
|
- ["Francieli Viane", "https://github.com/FFrancieli"]
|
||||||
|
lang: pt-br
|
||||||
|
---
|
||||||
|
|
||||||
|
Scala - a linguagem escalável
|
||||||
|
|
||||||
|
```scala
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 0. O básico
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Configurando o Scala:
|
||||||
|
|
||||||
|
1) Baixe o instalador do Scala - http://www.scala-lang.org/downloads
|
||||||
|
2) Extraia (unzip ou tar) para sua localização favorita e coloque o subdiretório
|
||||||
|
bin na variável de ambiente `PATH`
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tente o REPL
|
||||||
|
|
||||||
|
Scala tem uma ferramenta chamada REPL (Read-Eval-Print Loop) que é análogo a
|
||||||
|
interpretadores de linha de comando de outras linguagens. Você pode digitar
|
||||||
|
qualquer expressão de Scala e o resultado será calculado e impresso.
|
||||||
|
|
||||||
|
O REPL é uma ferramenta muito conveniente para testar e verificar código. Use-o
|
||||||
|
enquanto você lê o tutorial para explorar os conceitos rapidamente por conta própria.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Inicialize um REPL de Scala executando o comando scala no terminal. Você deve ver o prompt:
|
||||||
|
$ scala
|
||||||
|
scala>
|
||||||
|
|
||||||
|
//Por padrão, cada expressão que você executa é salva como um novo valor enumerado:
|
||||||
|
scala> 2 + 2
|
||||||
|
res0: Int = 4
|
||||||
|
|
||||||
|
// Valores padrões podem ser reutilizados. Observe o tipo do valor exibido no resultado...
|
||||||
|
scala> res0 + 2
|
||||||
|
res1: Int = 6
|
||||||
|
|
||||||
|
// Scala é uma linguagem fortemente tipada. Você pode usar o REPL para verfificar o tipo
|
||||||
|
// sem avaliar uma expressão.
|
||||||
|
|
||||||
|
scala> :type (true, 2.0)
|
||||||
|
(Boolean, Double)
|
||||||
|
|
||||||
|
// As sessões do REPL podem ser salvas
|
||||||
|
scala> :save /sites/repl-test.scala
|
||||||
|
|
||||||
|
//Arquivos podem ser carregados no REPL
|
||||||
|
scala> :load /sites/repl-test.scala
|
||||||
|
Loading /sites/repl-test.scala...
|
||||||
|
res2: Int = 4
|
||||||
|
res3: Int = 6
|
||||||
|
|
||||||
|
// Você pode pesquisar em seu histórico recente
|
||||||
|
scala> :h?
|
||||||
|
1 2 + 2
|
||||||
|
2 res0 + 2
|
||||||
|
3 :save /sites/repl-test.scala
|
||||||
|
4 :load /sites/repl-test.scala
|
||||||
|
5 :h?
|
||||||
|
|
||||||
|
// Agora que você já sabe brincar, vamos aprender um pouco de Scala...
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 1. Introdução
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Comentários de uma linha começam com duas barras
|
||||||
|
|
||||||
|
/*
|
||||||
|
Comentários com múltiplas linhas, como você já pode ver, são assim.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Imprimir e forçar uma linha na próxima impressão
|
||||||
|
println("Hello world!")
|
||||||
|
println(10)
|
||||||
|
// Hello world!
|
||||||
|
// 10
|
||||||
|
|
||||||
|
//Imprimir sem forçar uma nova linha na próxima impressão
|
||||||
|
print("Hello world")
|
||||||
|
print(10)
|
||||||
|
// Hello world10
|
||||||
|
|
||||||
|
//A declaração de valores pode ser feita usando tanto o var quanto o val.
|
||||||
|
// Declarações feitas com `val` são imutáveis, enquanto que declarações feitas
|
||||||
|
// com var são mutáveis. Imutabilidade é uma coisa boa.
|
||||||
|
val x = 10 // x is now 10
|
||||||
|
x = 20 // error: reassignment to val
|
||||||
|
var y = 10
|
||||||
|
= 20 // y agora é 20
|
||||||
|
|
||||||
|
/*
|
||||||
|
Scala é uma linguagem estaticamente tipada. Observe ainda que nas declarações
|
||||||
|
acima nós não especificamos um tipo. Isso se deve a um recurso da linguagem
|
||||||
|
chamado de inferência. Na maioria dos casos, o compilador do Scala consegue
|
||||||
|
adivinhar qual tipo é, de forma que você não precisa digitar sempre. Nós
|
||||||
|
podemos declarar o tipo da variável de maneira explícita asim:
|
||||||
|
*/
|
||||||
|
|
||||||
|
val z: Int = 10
|
||||||
|
val a: Double = 1.0
|
||||||
|
|
||||||
|
// Note que a conversão automática de Int para Double, o resultado é 10.0, não 10
|
||||||
|
val b: Double = 10
|
||||||
|
|
||||||
|
//Valores booleanos
|
||||||
|
true
|
||||||
|
false
|
||||||
|
|
||||||
|
//Operações booleanas
|
||||||
|
!true // false
|
||||||
|
!false // true
|
||||||
|
true == false // false
|
||||||
|
10 > 5 // true
|
||||||
|
|
||||||
|
// Matemática é como o de costume
|
||||||
|
1 + 1 // 2
|
||||||
|
2 - 1 // 1
|
||||||
|
5 * 3 // 15
|
||||||
|
6 / 2 // 3
|
||||||
|
6 / 4 // 1
|
||||||
|
6.0 / 4 // 1.5
|
||||||
|
6 / 4.0 // 1.5
|
||||||
|
|
||||||
|
// Calcular uma expressão no REPL te dá o tipo e o valor do resultado
|
||||||
|
1 + 7
|
||||||
|
|
||||||
|
/* A linha acima resulta em:
|
||||||
|
scala> 1 + 7
|
||||||
|
res29: Int = 8
|
||||||
|
|
||||||
|
Isso significa que o resultado ao culcular 1 + 7 é um objeto do tipo Int com
|
||||||
|
valor 8.
|
||||||
|
|
||||||
|
Note que "res29" é o nome de uma variável gerada sequencialmente para guardar
|
||||||
|
os resultados das expressões que você executa, logo seu nome pode ser
|
||||||
|
diferente.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"Strings em Scala são delimitadas por aspas duplas"
|
||||||
|
'a' // Um caractere em Scala
|
||||||
|
// 'Strings com aspas simples não existem em Scala.' <= isso causa um erro.
|
||||||
|
|
||||||
|
// Strings possuem os métodos comuns de Java definidos
|
||||||
|
"hello world".length
|
||||||
|
"hello world".substring(2, 6)
|
||||||
|
"hello world".replace("C", "3")
|
||||||
|
|
||||||
|
// Elas também possuem alguns métodos extras do Scala. Veja também:
|
||||||
|
scala.collection.immutable.StringOps
|
||||||
|
"hello world".take(5)
|
||||||
|
"hello world".drop(5)
|
||||||
|
|
||||||
|
//Interpolação de string: observe o prefixo "s"
|
||||||
|
val n = 45
|
||||||
|
s"We have $n apples" // => "We have 45 apples"
|
||||||
|
|
||||||
|
// Também é possível ter expressões dentro de interpolação de strings
|
||||||
|
val a = Array(11, 9, 6)
|
||||||
|
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"
|
||||||
|
|
||||||
|
// Formatação de strings interpoladas com o prefixo "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"
|
||||||
|
|
||||||
|
|
||||||
|
// Strings cruas, ignorando caracteres especiais
|
||||||
|
raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r."
|
||||||
|
|
||||||
|
//Alguns caracteres precisam ser "escapados", ex. uma aspa dupla dentro de uma string
|
||||||
|
|
||||||
|
"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown""
|
||||||
|
|
||||||
|
// Aspas triplas permitem strings a abrangerem múltiplas linhas e conter Aspas
|
||||||
|
val html = """<form id="daform">
|
||||||
|
<p>Press belo', Joe</p>
|
||||||
|
<input type="submit">
|
||||||
|
</form>"""
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 2. Funções
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Funções são definidas da seguinte maneira:
|
||||||
|
//
|
||||||
|
// def nomeDaFuncao(args ...): TipoDeRetorno = {body ...}
|
||||||
|
//
|
||||||
|
// Se você vem de linguagens mais tradicionais, note a omissão da palavra chave
|
||||||
|
//return. Em Scala a última expressão no bloco da função é o valor de retorno
|
||||||
|
def sumOfSquares(x: Int, y: Int): Int = {
|
||||||
|
val x2 = x * x
|
||||||
|
val y2 = y * y
|
||||||
|
x2 + y2
|
||||||
|
}
|
||||||
|
|
||||||
|
// As { } podem ser omitidas se o corpo da função possui apenas uma expressão:
|
||||||
|
def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y
|
||||||
|
|
||||||
|
// A sintaxe para chamar funções é familiar:
|
||||||
|
sumOfSquares(3, 4) // => 25
|
||||||
|
|
||||||
|
// Você poode usar o nome dos parâmetros para especificá-los numa ordem diferente
|
||||||
|
def subtract(x: Int, y: Int): Int = x - y
|
||||||
|
|
||||||
|
subtract(10, 3) // => 7
|
||||||
|
subtract(y=10, x=3) // => -7
|
||||||
|
|
||||||
|
// Na maioria dos casos (sendo funções recursivas a a exceção mais notável) o
|
||||||
|
// tipo de retorno da função pode ser omitido, e o mesmo tipo de inferência que
|
||||||
|
// vimos nas variáveis funcionará com o valor de retorno da função:
|
||||||
|
def sq(x: Int) = x * x // O compilador consegue adivinhar que o tipo de retorno é Int
|
||||||
|
|
||||||
|
// Funções podem ter parâmetros padrão:
|
||||||
|
def addWithDefault(x: Int, y: Int = 5) = x + y
|
||||||
|
addWithDefault(1, 2) // => 3
|
||||||
|
addWithDefault(1) // => 6
|
||||||
|
|
||||||
|
// Funções anônimas são semelhantes a essa:
|
||||||
|
(x: Int) => x * x
|
||||||
|
|
||||||
|
// Diferente de defs, até mesmo a entrada de funções anônimas podem ser omitidas
|
||||||
|
// se o contexto deixar isso claro. Observe o tipo "Int => Int", que significa
|
||||||
|
// uma função que recebe umn Int e retorna um Int.
|
||||||
|
val sq: Int => Int = x => x * x
|
||||||
|
|
||||||
|
// Se cada argumento na sua função anônima é usado apenas uma vez, Scala te fornece
|
||||||
|
// uma maneira ainda mais curta de definí-lo. Estas funções anônimas acabam por
|
||||||
|
// ser muito comuns, como será mostrado na sessão de estrutura de dados.
|
||||||
|
val addOne: Int => Int = _ + 1
|
||||||
|
val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
|
||||||
|
|
||||||
|
addOne(5) // => 6
|
||||||
|
weirdSum(2, 4) // => 16
|
||||||
|
|
||||||
|
// A palavra chave return existe em Scala, mas só retorna do def mais profundo que o cerca.
|
||||||
|
//AVISO: O uso do return em Scala é propenso a erros e deve ser evitado.
|
||||||
|
//Não há efeito em funções anônimas. Per exemplo:
|
||||||
|
def foo(x: Int): Int = {
|
||||||
|
val anonFunc: Int => Int = { z =>
|
||||||
|
if (z > 5)
|
||||||
|
return z // Esta linha faz Z retornar o valor de foo!
|
||||||
|
else
|
||||||
|
z + 2 // Esta linha retorna o valor de anonFunc
|
||||||
|
}
|
||||||
|
anonFunc(x) // Esta linha retorna o valor de foo
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 3. Controle de Fluxo
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
1 to 5
|
||||||
|
val r = 1 to 5
|
||||||
|
r.foreach(println)
|
||||||
|
|
||||||
|
r foreach println
|
||||||
|
///N.B.: Scala é bem flexível quando se fala de pontos e parêntesis - estude as regras
|
||||||
|
//separadamente. Isso ajuda a escrever DSLs e APIs que são lidas como inglês.
|
||||||
|
|
||||||
|
(5 to 1 by -1) foreach (println)
|
||||||
|
|
||||||
|
// Um loop while
|
||||||
|
var i = 0
|
||||||
|
while (i < 10) { println("i " + i); i += 1 }
|
||||||
|
|
||||||
|
while (i < 10) { println("i " + i); i += 1 } // Sim, de novo. O que aconteceu? Por quê?
|
||||||
|
|
||||||
|
i // Exibe o valor de i. Note que o while é um loop no senso clássico -
|
||||||
|
// executa sequencialmente enquanto muda a variável do loop. While é muito
|
||||||
|
// rápido, mas usar os combinadores e compreenões acima é mais fácil
|
||||||
|
// para entender e paralizar
|
||||||
|
|
||||||
|
// Um loop do-while
|
||||||
|
i = 0
|
||||||
|
do {
|
||||||
|
println("i ainda é menor que 10")
|
||||||
|
i += 1
|
||||||
|
} while (i < 10)
|
||||||
|
|
||||||
|
|
||||||
|
// Recursão é a forma mais idiomática de repetir uma ação em Scala (assim como na
|
||||||
|
// maioria das linguagens de programação funcional)
|
||||||
|
// Funções recursivas precisam de um tipo de retorno explícito, o compilador não
|
||||||
|
// consegue inferir;
|
||||||
|
// Aqui está o Unit
|
||||||
|
def showNumbersInRange(a: Int, b: Int): Unit = {
|
||||||
|
print(a)
|
||||||
|
if (a < b)
|
||||||
|
showNumbersInRange(a + 1, b)
|
||||||
|
}
|
||||||
|
showNumbersInRange(1, 14)
|
||||||
|
|
||||||
|
// Condicionais
|
||||||
|
|
||||||
|
al 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. Estrutura de Dados
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
val a = Array(1, 2, 3, 5, 8, 13)
|
||||||
|
a(0) // Int = 1
|
||||||
|
a(3) // Int = 5
|
||||||
|
a(21) // Lança uma exceção
|
||||||
|
|
||||||
|
val safeM = m.withDefaultValue("no lo se")
|
||||||
|
safeM("bottle") // java.lang.String = no lo se
|
||||||
|
|
||||||
|
val s = Set(1, 3, 7)
|
||||||
|
s(0) // Boolean = false
|
||||||
|
s(1) // Boolean = true
|
||||||
|
|
||||||
|
/* Veja a documantação do map aqui -
|
||||||
|
* http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
|
||||||
|
* e garanta que você leia
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Tuplas
|
||||||
|
|
||||||
|
(1, 2)
|
||||||
|
|
||||||
|
(4, 3, 2)
|
||||||
|
|
||||||
|
(1, 2, "three")
|
||||||
|
|
||||||
|
(a, 2, "three")
|
||||||
|
|
||||||
|
//Por que ter isso?
|
||||||
|
val divideInts = (x: Int, y: Int) => (x / y, x % y)
|
||||||
|
|
||||||
|
//A função divideInts te dá o resultado e o resultado
|
||||||
|
divideInts(10, 3) // (Int, Int) = (3,1)
|
||||||
|
|
||||||
|
//Para acessar os elementos de uma tupla, use _._n onde n é o índex do elemento
|
||||||
|
|
||||||
|
val d = divideInts(10, 3) // (Int, Int) = (3,1)
|
||||||
|
|
||||||
|
d._1 // Int = 3
|
||||||
|
d._2 // Int = 1
|
||||||
|
|
||||||
|
// Alternativamente, você pode atribuir múltiplas variáveis para uma tupla, o
|
||||||
|
// que é mais conveniente e legível em muitos casos
|
||||||
|
val (div, mod) = divideInts(10, 3)
|
||||||
|
|
||||||
|
div // Int = 3
|
||||||
|
mod // Int = 1
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 5. Object Oriented Programming
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tudo o que vimos até agora neste tutorial foram expressões simples (valores, funções, etc).
|
||||||
|
Essas expressões são boas para digitar no interpretador da linha de comando para
|
||||||
|
testes rápidos, mas elas não podem existir por si só em um arquivo Scala. Por exemplo,
|
||||||
|
você não pode ter simplesmente "val x = 5" em um arquivo Scala. Ao invés disso, os únicos
|
||||||
|
construtores de alto nível permitidos em Scala são:
|
||||||
|
|
||||||
|
- objects
|
||||||
|
- classes
|
||||||
|
- case classes
|
||||||
|
- traits
|
||||||
|
|
||||||
|
E agora vamos explicar o que é cada um deles.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//classes são similares a classes em outras linguagens. Os argumentos do construtor
|
||||||
|
// são declarados logo depois do nome da classe e a inicialização é feita no corpo da classe.
|
||||||
|
|
||||||
|
class Dog(br: String) {
|
||||||
|
// codigo do construtor aqui
|
||||||
|
var breed: String = br
|
||||||
|
|
||||||
|
// Define um método chamado bark que retorna uma String
|
||||||
|
def bark = "Woof, woof!"
|
||||||
|
|
||||||
|
// Assume-se que os métodos e valores são públicos. As palavras chave "protected"
|
||||||
|
// e "private" também estão disponíveis.
|
||||||
|
private def sleep(hours: Int) =
|
||||||
|
println(s"I'm sleeping for $hours hours")
|
||||||
|
|
||||||
|
// Métodos abstratos são simplesmente métodos sem corpo. Se a gente remover o
|
||||||
|
// comentário da próxima linha a classe Dog teria que ser declarada como abstrata
|
||||||
|
|
||||||
|
// abstract class Dog(...) { ... }
|
||||||
|
// def chaseAfter(what: String): String
|
||||||
|
}
|
||||||
|
|
||||||
|
// A palavra chave "object" cria um tipo e uma instância singlenton desse tipo.
|
||||||
|
// É comum para classes em Scala ter um "companion object" (objeto companheiro),
|
||||||
|
// onde, por exemlo, o comportamento é capturado pelas classes em si, mas o comportamento
|
||||||
|
// relacionado a toda instância da classe vai em objects. A diferença é semelhante
|
||||||
|
// a métodos versus métodos estáticos em outras linguagens. Note que objects e
|
||||||
|
// classes podem ter o mesmo nome.
|
||||||
|
|
||||||
|
object Dog {
|
||||||
|
def allKnownBreeds = List("pitbull", "shepherd", "retriever")
|
||||||
|
def createDog(breed: String) = new Dog(breed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case classes são classes que possuem uma funcionalidade extra incorporada.
|
||||||
|
// Uma dúvida comum para iniciantes em Scala é quando usar classes e quando usar
|
||||||
|
// case classes. A linha é bem tênue, mas em geral classes tendem a focar em encapsulamento,
|
||||||
|
// polimorfismo e comportamento. Os valores nestas classes tendem a ser privados e
|
||||||
|
// apenas métodos ficam expostos. O propósito primário de uma case class é guardar
|
||||||
|
// dados imutáveis. Às vezes as case classes possuem alguns poucos métodos, os quais
|
||||||
|
// raramente possuem efeitos colaterais (side effects).
|
||||||
|
case class Person(name: String, phoneNumber: String)
|
||||||
|
|
||||||
|
// Cria uma nova instância. Observe que case classes não precisam de usar "new" ao serem instanciadas
|
||||||
|
val george = Person("George", "1234")
|
||||||
|
val kate = Person("Kate", "4567")
|
||||||
|
|
||||||
|
// Com case classes você ganha algumas regalias, como getters:
|
||||||
|
// With case classes, you get a few perks for free, like getters:
|
||||||
|
george.phoneNumber // => "1234"
|
||||||
|
|
||||||
|
// Verificação de igualdade por campo (sem a necessidade de sobrescrever o método equals)
|
||||||
|
Person("George", "1234") == Person("Kate", "1236") // => false
|
||||||
|
|
||||||
|
// Uma maneira fácil de copiar
|
||||||
|
// otherGeorge == Person("george", "9876")
|
||||||
|
val otherGeorge = george.copy(phoneNumber = "9876")
|
||||||
|
|
||||||
|
// E muitas outras. Case classes também possuem pattern matching de graça. Veja no próximo tópico.
|
||||||
|
|
||||||
|
// Traits a caminho.
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 6. Pattern Matching
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Pattern matching é um recurso muito poderoso e muito usado em Scala. Aqui
|
||||||
|
// mostramos como o seu pattern se adequa a uma case class.
|
||||||
|
// NB: Diferente de outras linguagens, Scala não precisa de quebras. Entrar em
|
||||||
|
// todas as condições do pattern matching simples não acontece.
|
||||||
|
|
||||||
|
def matchPerson(person: Person): String = person match {
|
||||||
|
// Enrão você especifica os padrões
|
||||||
|
case Person("George", number) => "We found George! His number is " + number
|
||||||
|
case Person("Kate", number) => "We found Kate! Her number is " + number
|
||||||
|
case Person(name, number) => "We matched someone : " + name + ", phone : " + number
|
||||||
|
}
|
||||||
|
|
||||||
|
val email = "(.*)@(.*)".r // Define uma regex para o próximo exemplo.
|
||||||
|
|
||||||
|
// Pattern matching pode parecer com o comando switch nas liguagens da família C,
|
||||||
|
// mas é muito mais poderoso. Em Scala você pode encontrar mais correpondências:
|
||||||
|
|
||||||
|
def matchEverything(obj: Any): String = obj match {
|
||||||
|
// Você pode encontrar valores correspondentes:
|
||||||
|
case "Hello world" => "Got the string Hello world"
|
||||||
|
|
||||||
|
// Você pode fazer correspondência por tipo:
|
||||||
|
case x: Double => "Got a Double: " + x
|
||||||
|
|
||||||
|
// Você pode especificar condições:
|
||||||
|
case x: Int if x > 10000 => "Got a pretty big number!"
|
||||||
|
|
||||||
|
// Você pode encontrar correspondência com case classes, como fizemos antes:
|
||||||
|
case Person(name, number) => s"Got contact info for $name!"
|
||||||
|
|
||||||
|
// Você pode encontrar correspondências por regex:
|
||||||
|
case email(name, domain) => s"Got email address $name@$domain"
|
||||||
|
|
||||||
|
// Você pode encontrar correspondencias por tuplas:
|
||||||
|
case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c"
|
||||||
|
|
||||||
|
// Você pode encontrar corresponências por estruturas de dados:
|
||||||
|
case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
|
||||||
|
|
||||||
|
// Você pode aninhar padrões:
|
||||||
|
case List(List((1, 2, "YAY"))) => "Got a list of list of tuple"
|
||||||
|
|
||||||
|
// Retornar qualquer valor (padrão - default) caso nenhuma das possibilidades é correspondente.
|
||||||
|
case _ => "Got unknown object"
|
||||||
|
|
||||||
|
// Na verdade, você pode fazer correspondência de padrão de qualquer objeto que
|
||||||
|
// tenha o método "unnaply". Este recurso é tão poderoso que o Scala te deixa
|
||||||
|
// criar funções inteiras como patterns:
|
||||||
|
|
||||||
|
val patternFunc: Person => String = {
|
||||||
|
case Person("George", number) => s"George's number: $number"
|
||||||
|
case Person(name, number) => s"Random person's number: $number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 7. Programação Funcional
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Scala permite que métodos e funções recebam ou retornem outras funções ou métodos.
|
||||||
|
|
||||||
|
val add10: Int => Int = _ + 10 // A function taking an Int and returning an Int
|
||||||
|
List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element
|
||||||
|
|
||||||
|
// Funções anônimas podem ser usadas ao invés de funções com nomes:
|
||||||
|
List(1, 2, 3) map (x => x + 10)
|
||||||
|
|
||||||
|
// E o símbolo underline ("_") pode ser usado quando há apenas um argumento para a função anônima.
|
||||||
|
List(1, 2, 3) map (_ + 10)
|
||||||
|
|
||||||
|
// Se tanto o bloco animo quanto a função que você estiver usando receberem apenas
|
||||||
|
// um argumento, você pode inclusive omitir o símbolo _
|
||||||
|
List(1, 2, 3) map (_ + 10)
|
||||||
|
|
||||||
|
// Combinadores
|
||||||
|
|
||||||
|
s.map(sq)
|
||||||
|
|
||||||
|
val sSquared = s. map(sq)
|
||||||
|
|
||||||
|
sSquared.filter(_ < 10)
|
||||||
|
|
||||||
|
sSquared.reduce (_+_)
|
||||||
|
|
||||||
|
// A função filter recebe um predicado (uma função do tipo A -> Boolean) e seleciona
|
||||||
|
// todos os elementos que satisfazem o predicado.
|
||||||
|
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))
|
||||||
|
|
||||||
|
// Scala tem o método foreach definido em algumas collections em específico, o qual
|
||||||
|
// recebe um tipo e retorna Unit (um método void)
|
||||||
|
val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
|
||||||
|
aListOfNumbers foreach (x => println(x))
|
||||||
|
aListOfNumbers foreach println
|
||||||
|
|
||||||
|
/* NB Ests não são laços for. A semântica dos laços for é 'repetir' enquanto um
|
||||||
|
for-comprehension define um relacionamento entre dois conjuntos de dados */
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 8. Implicits
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/* ALERTA ALERTA:
|
||||||
|
Implicits são um conjunto de recursos poderosos de Scala e consequentemente é
|
||||||
|
fácil abusar deles. Iniciantes em Scala deveriam resistir a tentação de usá-los
|
||||||
|
até que eles entendam não apenas como eles funcionam mas também as melhores práticas
|
||||||
|
deles. Incluimos uma sessão neste tutorial sobre isso porque implicits são tão
|
||||||
|
corriqueiros em bibliotecas do Scala que é impossível fazer qualqeuer coisa expressiva
|
||||||
|
sem utilizar uma biblioteca que usa implicits. Isto é para você entender e trabalhar
|
||||||
|
com implicits. Não declare seus próprios implicits por conta própria.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// qualquer valor (val, function, objects, etc) pode ser declarado para ser implícito
|
||||||
|
// usando a, você adivinhou, palavra chave "implicit". Usaremos a classe Dog definida
|
||||||
|
// na sessão 5 para os próximos exemplos.
|
||||||
|
implicit val myImplicitInt = 100
|
||||||
|
implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed)
|
||||||
|
|
||||||
|
// A palavra chave implicit não muda o comportamento do valor por si só, então
|
||||||
|
// os valores acima podem ser usados como de costume.
|
||||||
|
myImplicitInt + 2 // => 102
|
||||||
|
myImplicitFunction("Pitbull").breed // => "Golden Pitbull"
|
||||||
|
|
||||||
|
A diferença é que agora esses valores são elegíveis para serem usados quando outra
|
||||||
|
// parte do código "precisa" de um valor implícito. Uma situação é uma função
|
||||||
|
// com argumentos implícitos:
|
||||||
|
def sendGreetings(toWhom: String)(implicit howMany: Int) =
|
||||||
|
s"Hello $toWhom, $howMany blessings to you and yours!"
|
||||||
|
|
||||||
|
// Se fornecermos um valor para "howMany" a função se comporta como sempre
|
||||||
|
sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!"
|
||||||
|
|
||||||
|
// Mas se omitirmos o parâmetro implícito um valor implícito de mesmo tipo é usado,
|
||||||
|
// neste caso, "myImplicitInt":
|
||||||
|
sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
|
||||||
|
|
||||||
|
// Parâmetros implícitos de funções nos permitem simular type classes em outras
|
||||||
|
//linguagens funcionais. As linhas abaixo são a mesma coisa:
|
||||||
|
// def foo[T](implicit c: C[T]) = ...
|
||||||
|
// def foo[T : C] = ...
|
||||||
|
|
||||||
|
// Outro caso no qual o compilador procura por um implicit é quando você tem obj.method(...)
|
||||||
|
// mas "obj" não possui "method" como um método. Neste caso, se houver uma conversão
|
||||||
|
// de implicit do tipo A => B, onde A é o tipo do "obj" e B tem um método chamado
|
||||||
|
// "method", a conversão é aplicada. Então, tendo myImplicitFunction acima em escopo, podemos dizer:
|
||||||
|
"Retriever".breed // => "Golden Retriever"
|
||||||
|
"Sheperd".bark // => "Woof, woof!"
|
||||||
|
|
||||||
|
// Aqui, a String é convertida para Dog usando nossa função acima, então o método
|
||||||
|
// apropriado é chamado. Isso é um recurso extremamente poderoso, mas de novo, não
|
||||||
|
// é para ser usado de maneira leviana. Na verdade, quando você define a função
|
||||||
|
// implícita, o seu compilador deve exibir um aviso de que você não deveria fazer isso,
|
||||||
|
// a menos que você realmente saiba o que você está fazendo.
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// 9. Misc
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Importando coisas
|
||||||
|
import scala.collection.immutable.List
|
||||||
|
|
||||||
|
// Importando todos os sub pacotes
|
||||||
|
import scala.collection.immutable._
|
||||||
|
|
||||||
|
// Importando várias classes em um único comando
|
||||||
|
import scala.collection.immutable.{List, Map}
|
||||||
|
|
||||||
|
// Renomeando um import usando '=>'
|
||||||
|
import scala.collection.immutable.{List => ImmutableList}
|
||||||
|
|
||||||
|
// Importa todas as classes, com exceção de algumas. O import abaixo importa todas as classes excluindo Map e Set:
|
||||||
|
import scala.collection.immutable.{Map => _, Set => _, _}
|
||||||
|
|
||||||
|
// Classes Java também podem ser importadas. A syntaxe de Scala pode ser usada:
|
||||||
|
import java.swing.{JFrame, JWindow}
|
||||||
|
|
||||||
|
// O ponto de entrada do seu programa é definido em um arquivo Scala usando um object com um único método main:
|
||||||
|
object Application {
|
||||||
|
def main(args: Array[String]): Unit = {
|
||||||
|
// o código fica aqui
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arquivos podem ter múltiplas classes e objects. Compile com scalac
|
||||||
|
|
||||||
|
// Entrada e saída
|
||||||
|
|
||||||
|
// Para ler um arquivo linha a linha
|
||||||
|
import scala.io.Source
|
||||||
|
for(line <- Source.fromFile("myfile.txt").getLines())
|
||||||
|
println(line)
|
||||||
|
|
||||||
|
// Para escrever um arquivo use o PrintWriter do Javaval writer = new PrintWriter("myfile.txt")
|
||||||
|
writer.write("Writing line for line" + util.Properties.lineSeparator)
|
||||||
|
writer.write("Another line here" + util.Properties.lineSeparator)
|
||||||
|
writer.close()
|
||||||
|
|
||||||
|
## Recursos adicionais
|
||||||
|
|
||||||
|
* [Scala for the impatient](http://horstmann.com/scala/)
|
||||||
|
* [Twitter Scala school](http://twitter.github.io/scala_school/)
|
||||||
|
* [Documentação de Scala](http://docs.scala-lang.org/)
|
||||||
|
* [Tente Scala no seu navegador](http://scalatutorials.com/tour/)
|
||||||
|
* Junte [Scala user group](https://groups.google.com/forum/#!forum/scala-user)
|
||||||
|
```
|
@@ -706,6 +706,7 @@ def double_numbers(iterable):
|
|||||||
double_arr = []
|
double_arr = []
|
||||||
for i in iterable:
|
for i in iterable:
|
||||||
double_arr.append(i + i)
|
double_arr.append(i + i)
|
||||||
|
return double_arr
|
||||||
|
|
||||||
|
|
||||||
# Running the following would mean we'll double all values first and return all
|
# Running the following would mean we'll double all values first and return all
|
||||||
|
@@ -71,11 +71,14 @@ True and False # => False
|
|||||||
False or True # => True
|
False or True # => True
|
||||||
|
|
||||||
# Note using Bool operators with ints
|
# Note using Bool operators with ints
|
||||||
|
# False is 0 and True is 1
|
||||||
|
# Don't mix up with bool(ints) and bitwise and/or (&,|)
|
||||||
0 and 2 # => 0
|
0 and 2 # => 0
|
||||||
-5 or 0 # => -5
|
-5 or 0 # => -5
|
||||||
0 == False # => True
|
0 == False # => True
|
||||||
2 == True # => False
|
2 == True # => False
|
||||||
1 == True # => True
|
1 == True # => True
|
||||||
|
-5 != False != True #=> True
|
||||||
|
|
||||||
# Equality is ==
|
# Equality is ==
|
||||||
1 == 1 # => True
|
1 == 1 # => True
|
||||||
|
@@ -2,12 +2,13 @@
|
|||||||
language: restructured text
|
language: restructured text
|
||||||
contributors:
|
contributors:
|
||||||
- ["DamienVGN", "https://github.com/martin-damien"]
|
- ["DamienVGN", "https://github.com/martin-damien"]
|
||||||
|
- ["Andre Polykanine", "https://github.com/Oire"]
|
||||||
filename: restructuredtext.rst
|
filename: restructuredtext.rst
|
||||||
---
|
---
|
||||||
|
|
||||||
RST is file format formely created by Python community to write documentation (and so, is part of Docutils).
|
RST is a file format formely created by Python community to write documentation (and so, is part of Docutils).
|
||||||
|
|
||||||
RST files are simple text files with lightweight syntaxe (comparing to HTML).
|
RST files are simple text files with lightweight syntax (comparing to HTML).
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
@@ -20,25 +21,25 @@ To use Restructured Text, you will have to install [Python](http://www.python.or
|
|||||||
$ easy_install docutils
|
$ easy_install docutils
|
||||||
```
|
```
|
||||||
|
|
||||||
If your system have `pip`, you can use it too:
|
If your system has `pip`, you can use it too:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ pip install docutils
|
$ pip install docutils
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## File syntaxe
|
## File syntax
|
||||||
|
|
||||||
A simple example of the file syntax:
|
A simple example of the file syntax:
|
||||||
|
|
||||||
```rst
|
```rst
|
||||||
.. Line with two dotes are special commands. But if no command can be found, the line is considered as a comment
|
.. Lines starting with two dots are special commands. But if no command can be found, the line is considered as a comment
|
||||||
|
|
||||||
=========================================================
|
=========================================================
|
||||||
Main titles are written using equals signs over and under
|
Main titles are written using equals signs over and under
|
||||||
=========================================================
|
=========================================================
|
||||||
|
|
||||||
Note that theire must be as many equals signs as title characters.
|
Note that there must be as many equals signs as title characters.
|
||||||
|
|
||||||
Title are underlined with equals signs too
|
Title are underlined with equals signs too
|
||||||
==========================================
|
==========================================
|
||||||
@@ -46,12 +47,12 @@ Title are underlined with equals signs too
|
|||||||
Subtitles with dashes
|
Subtitles with dashes
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
And sub-subtitles with tilde
|
And sub-subtitles with tildes
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``: ``print()``.
|
You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``: ``print()``.
|
||||||
|
|
||||||
Lists are as simple as markdown:
|
Lists are as simple as in Markdown:
|
||||||
|
|
||||||
- First item
|
- First item
|
||||||
- Second item
|
- Second item
|
||||||
@@ -72,22 +73,22 @@ France Paris
|
|||||||
Japan Tokyo
|
Japan Tokyo
|
||||||
=========== ========
|
=========== ========
|
||||||
|
|
||||||
More complexe tabless can be done easily (merged columns and/or rows) but I suggest you to read the complete doc for this :)
|
More complex tabless can be done easily (merged columns and/or rows) but I suggest you to read the complete doc for this :)
|
||||||
|
|
||||||
Their is multiple ways to make links:
|
There are multiple ways to make links:
|
||||||
|
|
||||||
- By adding an underscore after a word : Github_ and by adding the target after the text (this have the advantage to not insert un-necessary URL inside the readed text).
|
- By adding an underscore after a word : Github_ and by adding the target URL after the text (this way has the advantage to not insert unnecessary URLs inside readable text).
|
||||||
- By typing a full comprehensible URL : https://github.com/ (will be automatically converted in link)
|
- By typing a full comprehensible URL : https://github.com/ (will be automatically converted to a link)
|
||||||
- By making a more "markdown" link: `Github <https://github.com/>`_ .
|
- By making a more Markdown-like link: `Github <https://github.com/>`_ .
|
||||||
|
|
||||||
.. _Github https://github.com/
|
.. _Github https://github.com/
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## How to use it
|
## How to Use It
|
||||||
|
|
||||||
RST comes with docutils in which you have `rst2html` for exemple:
|
RST comes with docutils where you have `rst2html`, for example:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ rst2html myfile.rst output.html
|
$ rst2html myfile.rst output.html
|
||||||
@@ -95,7 +96,7 @@ $ rst2html myfile.rst output.html
|
|||||||
|
|
||||||
*Note : On some systems the command could be rst2html.py*
|
*Note : On some systems the command could be rst2html.py*
|
||||||
|
|
||||||
But their is more complexe applications that uses RST file format:
|
But there are more complex applications that use the RST format:
|
||||||
|
|
||||||
- [Pelican](http://blog.getpelican.com/), a static site generator
|
- [Pelican](http://blog.getpelican.com/), a static site generator
|
||||||
- [Sphinx](http://sphinx-doc.org/), a documentation generator
|
- [Sphinx](http://sphinx-doc.org/), a documentation generator
|
||||||
|
@@ -104,6 +104,11 @@ if let someOptionalStringConstant = someOptionalString {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The nil-coalescing operator ?? unwraps an optional if it contains a non-nil value, or returns a default value.
|
||||||
|
var someOptionalString: String?
|
||||||
|
let someString = someOptionalString ?? "abc"
|
||||||
|
print(someString) // abc
|
||||||
|
|
||||||
// Swift has support for storing a value of any type.
|
// Swift has support for storing a value of any type.
|
||||||
// For that purposes there is two keywords: `Any` and `AnyObject`
|
// For that purposes there is two keywords: `Any` and `AnyObject`
|
||||||
// `AnyObject` == `id` from Objective-C
|
// `AnyObject` == `id` from Objective-C
|
||||||
|
@@ -268,7 +268,7 @@ proc fold {cmd args} {
|
|||||||
foreach arg $args {
|
foreach arg $args {
|
||||||
set res [$cmd $res $arg]
|
set res [$cmd $res $arg]
|
||||||
}
|
}
|
||||||
return res
|
return $res
|
||||||
}
|
}
|
||||||
fold ::tcl::mathop::* 5 3 3 ;# -> 45
|
fold ::tcl::mathop::* 5 3 3 ;# -> 45
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
language: swift
|
language: swift
|
||||||
contributors:
|
contributors:
|
||||||
- ["Özgür Şahin", "https://github.com/ozgurshn/"]
|
- ["Özgür Şahin", "https://github.com/ozgurshn/"]
|
||||||
filename: learnswift.swift
|
filename: learnswift-tr.swift
|
||||||
lang: tr-tr
|
lang: tr-tr
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@@ -13,7 +13,7 @@ This article will focus only on TypeScript extra syntax, as opposed to [JavaScri
|
|||||||
|
|
||||||
To test TypeScript's compiler, head to the [Playground] (http://www.typescriptlang.org/Playground) where you will be able to type code, have auto completion and directly see the emitted JavaScript.
|
To test TypeScript's compiler, head to the [Playground] (http://www.typescriptlang.org/Playground) where you will be able to type code, have auto completion and directly see the emitted JavaScript.
|
||||||
|
|
||||||
```js
|
```ts
|
||||||
// There are 3 basic types in TypeScript
|
// There are 3 basic types in TypeScript
|
||||||
var isDone: boolean = false;
|
var isDone: boolean = false;
|
||||||
var lines: number = 42;
|
var lines: number = 42;
|
||||||
|
Reference in New Issue
Block a user