mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-11-27 04:44:08 +03:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
5254804c1c
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"]
|
||||
[1, 2, 3, 4, 5]
|
||||
-- Druhý příklad lze zapsat také pomocí dvou teček.
|
||||
[1..5]
|
||||
List.range 1 5
|
||||
|
||||
-- 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".
|
||||
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
|
||||
-- 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ě.
|
||||
List.head [1..5] -- Just 1
|
||||
List.tail [1..5] -- Just [2, 3, 4, 5]
|
||||
List.head (List.range 1 5) -- Just 1
|
||||
List.tail (List.range 1 5) -- Just [2, 3, 4, 5]
|
||||
List.head [] -- Nothing
|
||||
-- List.nazevFunkce odkazuje na funkci, která žije v modulu List.
|
||||
|
||||
@ -82,7 +82,7 @@ snd ("elm", 42) -- 42
|
||||
-- Je to jediná hodnota svého typu, který se také nazývá "Unit".
|
||||
()
|
||||
|
||||
-- Záznamy jsou podobné n-ticím, ale prvky jsou pojmenovány. Na pořadí nezáleží.
|
||||
-- Záznamy jsou podobné n-ticím, ale prvky jsou pojmenovány. Na pořadí nezáleží.
|
||||
-- Povšimněte si, že hodnoty vlastností se přiřazují rovnítky, ne dvojtečkami.
|
||||
{ x = 3, y = 7 }
|
||||
|
||||
@ -153,10 +153,10 @@ odpoved =
|
||||
42
|
||||
|
||||
-- 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.
|
||||
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.
|
||||
-- Tato funkce přijímá jednu dvojici místo dvou parametrů.
|
||||
@ -182,7 +182,7 @@ fib n =
|
||||
else
|
||||
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).
|
||||
delkaSeznamu seznam =
|
||||
@ -339,11 +339,11 @@ $ elm repl
|
||||
|
||||
-- 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.
|
||||
$ elm package install evancz/elm-html
|
||||
$ elm package install evancz/elm-lang/html
|
||||
|
||||
-- Porovnejte změny mezi verzemi jednoho balíčku.
|
||||
$ elm package diff evancz/elm-html 3.0.0 4.0.2
|
||||
-- Správce balíčků v Elmu vyžaduje sémantické verzování,
|
||||
$ elm package diff elm-lang/html 1.1.0 2.0.0
|
||||
-- Správce balíčků v Elmu vyžaduje sémantické verzování,
|
||||
-- takže minor verze nikdy nerozbije váš build.
|
||||
```
|
||||
|
||||
|
@ -9,7 +9,7 @@ translators:
|
||||
|
||||
HTML stands for HyperText Markup Language.
|
||||
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.
|
||||
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.
|
||||
|
@ -773,6 +773,6 @@ code_native(circle_area, (Float64,))
|
||||
|
||||
## 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).
|
||||
|
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:
|
||||
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:
|
||||
# "tail" skriver ut slutten av en fil, i dette tilfellet de siste 10 linjene
|
||||
tail -n 10 file.txt
|
||||
|
@ -51,6 +51,13 @@ my @mixed = ("camel", 42, 1.23);
|
||||
# indicate one value will be returned.
|
||||
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
|
||||
# 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.
|
||||
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.
|
||||
# (perldoc perldata).
|
||||
|
||||
@ -144,6 +156,12 @@ for (@elements) {
|
||||
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
|
||||
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.
|
||||
|
||||
# For reading:
|
||||
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: $!";
|
||||
# For writing (appends to end of file):
|
||||
open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
|
||||
|
||||
# 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 @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 is easy:
|
||||
|
@ -86,10 +86,10 @@ my %hash = key1 => 'value1', key2 => 'value2'; # same result as above
|
||||
|
||||
# You can also use the "colon pair" syntax:
|
||||
# (especially handy for named parameters that you'll see later)
|
||||
my %hash = :w(1), # equivalent to `w => 1`
|
||||
# this is useful for the `True` shortcut:
|
||||
:truey, # equivalent to `:truey(True)`, or `truey => True`
|
||||
# and for the `False` one:
|
||||
my %hash = :w(1), # equivalent to `w => 1`
|
||||
# this is useful for the `True` shortcut:
|
||||
:truey, # equivalent to `:truey(True)`, or `truey => True`
|
||||
# and for the `False` one:
|
||||
:!falsey, # equivalent to `:falsey(False)`, or `falsey => False`
|
||||
;
|
||||
|
||||
@ -125,8 +125,8 @@ hello-to; #=> Hello, World !
|
||||
hello-to(); #=> Hello, World !
|
||||
hello-to('You'); #=> Hello, You !
|
||||
|
||||
## You can also, by using a syntax akin to the one of hashes (yay unified syntax !),
|
||||
## pass *named* arguments to a `sub`.
|
||||
## You can also, by using a syntax akin to the one of hashes
|
||||
## (yay unified syntax !), pass *named* arguments to a `sub`.
|
||||
# They're optional, and will default to "Any".
|
||||
sub with-named($normal-arg, :$named) {
|
||||
say $normal-arg + $named;
|
||||
@ -145,8 +145,8 @@ sub with-mandatory-named(:$str!) {
|
||||
say "$str !";
|
||||
}
|
||||
with-mandatory-named(str => "My String"); #=> My String !
|
||||
with-mandatory-named; # run time error: "Required named parameter not passed"
|
||||
with-mandatory-named(3); # run time error: "Too many positional parameters passed"
|
||||
with-mandatory-named; # run time error: "Required named parameter not passed"
|
||||
with-mandatory-named(3);# run time error:"Too many positional parameters passed"
|
||||
|
||||
## If a sub takes a named boolean argument ...
|
||||
sub takes-a-bool($name, :$bool) {
|
||||
@ -169,9 +169,9 @@ my &s = &say-hello;
|
||||
my &other-s = sub { say "Anonymous function !" }
|
||||
|
||||
# A sub can have a "slurpy" parameter, or "doesn't-matter-how-many"
|
||||
sub as-many($head, *@rest) { # `*@` (slurpy) will basically "take everything else".
|
||||
# Note: you can have parameters *before* (like here)
|
||||
# a slurpy one, but not *after*.
|
||||
sub as-many($head, *@rest) { #`*@` (slurpy) will "take everything else"
|
||||
# Note: you can have parameters *before* a slurpy one (like here),
|
||||
# but not *after*.
|
||||
say @rest.join(' / ') ~ " !";
|
||||
}
|
||||
say as-many('Happy', 'Happy', 'Birthday'); #=> Happy / Birthday !
|
||||
@ -223,9 +223,9 @@ say $x; #=> 52
|
||||
|
||||
# - `if`
|
||||
# Before talking about `if`, we need to know which values are "Truthy"
|
||||
# (represent True), and which are "Falsey" (or "Falsy") -- represent False.
|
||||
# Only these values are Falsey: 0, (), {}, "", Nil, A type (like `Str` or `Int`),
|
||||
# and of course False itself.
|
||||
# (represent True), and which are "Falsey" (or "Falsy") -- represent False.
|
||||
# Only these values are Falsey: 0, (), {}, "", Nil, A type (like `Str` or `Int`)
|
||||
# and of course False itself.
|
||||
# Every other value is Truthy.
|
||||
if True {
|
||||
say "It's true !";
|
||||
@ -265,13 +265,14 @@ say $age > 18 ?? "You are an adult" !! "You are under 18";
|
||||
|
||||
given "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/`.
|
||||
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.
|
||||
# This when is equivalent to this `if`:
|
||||
# This `when` is equivalent to this `if`:
|
||||
# if $_ ~~ ($_.chars > 50) {...}
|
||||
# Which means:
|
||||
# if $_.chars > 50 {...}
|
||||
@ -288,7 +289,8 @@ given "foo bar" {
|
||||
# but can also be a C-style `for` loop:
|
||||
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++) {
|
||||
|
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 = []
|
||||
for i in iterable:
|
||||
double_arr.append(i + i)
|
||||
return double_arr
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
-5 or 0 # => -5
|
||||
0 == False # => True
|
||||
2 == True # => False
|
||||
1 == True # => True
|
||||
-5 != False != True #=> True
|
||||
|
||||
# Equality is ==
|
||||
1 == 1 # => True
|
||||
|
@ -2,12 +2,13 @@
|
||||
language: restructured text
|
||||
contributors:
|
||||
- ["DamienVGN", "https://github.com/martin-damien"]
|
||||
- ["Andre Polykanine", "https://github.com/Oire"]
|
||||
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
|
||||
@ -20,25 +21,25 @@ To use Restructured Text, you will have to install [Python](http://www.python.or
|
||||
$ easy_install docutils
|
||||
```
|
||||
|
||||
If your system have `pip`, you can use it too:
|
||||
If your system has `pip`, you can use it too:
|
||||
|
||||
```bash
|
||||
$ pip install docutils
|
||||
```
|
||||
|
||||
|
||||
## File syntaxe
|
||||
## File syntax
|
||||
|
||||
A simple example of the file syntax:
|
||||
|
||||
```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
|
||||
=========================================================
|
||||
|
||||
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
|
||||
==========================================
|
||||
@ -46,12 +47,12 @@ Title are underlined with equals signs too
|
||||
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()``.
|
||||
|
||||
Lists are as simple as markdown:
|
||||
Lists are as simple as in Markdown:
|
||||
|
||||
- First item
|
||||
- Second item
|
||||
@ -72,22 +73,22 @@ France Paris
|
||||
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 typing a full comprehensible URL : https://github.com/ (will be automatically converted in link)
|
||||
- By making a more "markdown" link: `Github <https://github.com/>`_ .
|
||||
- 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 to a link)
|
||||
- By making a more Markdown-like link: `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
|
||||
$ rst2html myfile.rst output.html
|
||||
@ -95,7 +96,7 @@ $ rst2html myfile.rst output.html
|
||||
|
||||
*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
|
||||
- [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.
|
||||
// For that purposes there is two keywords: `Any` and `AnyObject`
|
||||
// `AnyObject` == `id` from Objective-C
|
||||
|
@ -268,7 +268,7 @@ proc fold {cmd args} {
|
||||
foreach arg $args {
|
||||
set res [$cmd $res $arg]
|
||||
}
|
||||
return res
|
||||
return $res
|
||||
}
|
||||
fold ::tcl::mathop::* 5 3 3 ;# -> 45
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
language: swift
|
||||
contributors:
|
||||
- ["Özgür Şahin", "https://github.com/ozgurshn/"]
|
||||
filename: learnswift.swift
|
||||
filename: learnswift-tr.swift
|
||||
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.
|
||||
|
||||
```js
|
||||
```ts
|
||||
// There are 3 basic types in TypeScript
|
||||
var isDone: boolean = false;
|
||||
var lines: number = 42;
|
||||
|
Loading…
Reference in New Issue
Block a user