1
0
mirror of https://github.com/adambard/learnxinyminutes-docs.git synced 2025-09-02 11:14:15 +02:00

Simplify language codes in directories

This commit is contained in:
Boris Verkhovskiy
2024-12-08 20:29:09 -07:00
parent 3da692272f
commit 912da583da
489 changed files with 0 additions and 0 deletions

440
fi/go.md Normal file
View File

@@ -0,0 +1,440 @@
---
category: language
language: Go
filename: learngo-fi.go
contributors:
- ["Sonia Keys", "https://github.com/soniakeys"]
- ["Christopher Bess", "https://github.com/cbess"]
- ["Jesse Johnson", "https://github.com/holocronweaver"]
- ["Quint Guvernator", "https://github.com/qguv"]
- ["Jose Donizetti", "https://github.com/josedonizetti"]
- ["Alexej Friesen", "https://github.com/heyalexej"]
- ["Clayton Walker", "https://github.com/cwalk"]
translators:
- ["Timo Virkkunen", "https://github.com/ComSecNinja"]
lang: fi-fi
---
Go luotiin työn tekemistä varten. Se ei ole tietojenkäsittelyn uusin trendi,
mutta se on uusin nopein tapa ratkaista oikean maailman ongelmia.
Sillä on staattisesti tyypitetyistä imperatiivisista kielistä tuttuja
konsepteja. Se kääntyy ja suorittuu nopeasti, lisää helposti käsitettävän
samanaikaisten komentojen suorittamisen nykyaikaisten moniytimisten
prosessoreiden hyödyntämiseksi ja antaa käyttäjälle ominaisuuksia suurten
projektien käsittelemiseksi.
Go tuo mukanaan loistavan oletuskirjaston sekä innokkaan yhteisön.
```go
// Yhden rivin kommentti
/* Useamman
rivin kommentti */
// Package -lausekkeella aloitetaan jokainen lähdekooditiedosto.
// main on erityinen nimi joka ilmoittaa
// suoritettavan tiedoston kirjaston sijasta.
package main
// Import -lauseke ilmoittaa tässä tiedostossa käytetyt kirjastot.
import (
"fmt" // Paketti Go:n oletuskirjastosta.
"io/ioutil" // Implementoi hyödyllisiä I/O -funktioita.
m "math" // Matematiikkakirjasto jolla on paikallinen nimi m.
"net/http" // Kyllä, web-palvelin!
"strconv" // Kirjainjonojen muuntajia.
)
// Funktion määrittelijä. Main on erityinen: se on ohjelman suorittamisen
// aloittamisen alkupiste. Rakasta tai vihaa sitä, Go käyttää aaltosulkeita.
func main() {
// Println tulostaa rivin stdoutiin.
// Se tulee paketin fmt mukana, joten paketin nimi on mainittava.
fmt.Println("Hei maailma!")
// Kutsu toista funktiota tämän paketin sisällä.
beyondHello()
}
// Funktioilla voi olla parametrejä sulkeissa.
// Vaikkei parametrejä olisikaan, sulkeet ovat silti pakolliset.
func beyondHello() {
var x int // Muuttujan ilmoittaminen: ne täytyy ilmoittaa ennen käyttöä.
x = 3 // Arvon antaminen muuttujalle.
// "Lyhyet" ilmoitukset käyttävät := joka päättelee tyypin, ilmoittaa
// sekä antaa arvon muuttujalle.
y := 4
sum, prod := learnMultiple(x, y) // Funktio palauttaa kaksi arvoa.
fmt.Println("summa:", sum, "tulo:", prod) // Yksinkertainen tuloste.
learnTypes() // < y minuuttia, opi lisää!
}
/* <- usean rivin kommentti
Funktioilla voi olla parametrejä ja (useita!) palautusarvoja.
Tässä `x`, `y` ovat argumenttejä ja `sum`, `prod` ovat ne, mitä palautetaan.
Huomaa että `x` ja `sum` saavat tyyin `int`.
*/
func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // Palauta kaksi arvoa.
}
// Sisäänrakennettuja tyyppejä ja todellisarvoja.
func learnTypes() {
// Lyhyt ilmoitus antaa yleensä haluamasi.
str := "Opi Go!" // merkkijonotyyppi.
s2 := `"raaka" todellisarvoinen merkkijono
voi sisältää rivinvaihtoja.` // Sama merkkijonotyyppi.
// Ei-ASCII todellisarvo. Go-lähdekoodi on UTF-8.
g := 'Σ' // riimutyyppi, lempinimi int32:lle, sisältää unicode-koodipisteen.
f := 3.14159 //float64, IEEE-754 64-bittinen liukuluku.
c := 3 + 4i // complex128, sisäisesti ilmaistu kahdella float64:lla.
// var -syntaksi alkuarvoilla.
var u uint = 7 // Etumerkitön, toteutus riippuvainen koosta kuten int.
var pi float32 = 22. / 7
// Muuntosyntaksi lyhyellä ilmoituksella.
n := byte('\n') // byte on leminimi uint8:lle.
// Listoilla on kiinteä koko kääntöhetkellä.
var a4 [4]int // 4 int:in lista, alkiot ovat alustettu nolliksi.
a3 := [...]int{3, 1, 5} // Listan alustaja jonka kiinteäksi kooksi tulee 3
// alkiota, jotka saavat arvot 3, 1, ja 5.
// Siivuilla on muuttuva koko. Sekä listoilla että siivuilla on puolensa,
// mutta siivut ovat yleisempiä käyttötapojensa vuoksi.
s3 := []int{4, 5, 9} // Vertaa a3: ei sananheittoa (...).
s4 := make([]int, 4) // Varaa 4 int:n siivun, alkiot alustettu nolliksi.
var d2 [][]float64 // Vain ilmoitus, muistia ei varata.
bs := []byte("a slice") // Tyypinmuuntosyntaksi.
// Koska siivut ovat dynaamisia, niitä voidaan yhdistellä sellaisinaan.
// Lisätäksesi alkioita siivuun, käytä sisäänrakennettua append()-funktiota.
// Ensimmäinen argumentti on siivu, johon alkoita lisätään.
s := []int{1, 2, 3} // Tuloksena on kolmen alkion pituinen lista.
s = append(s, 4, 5, 6) // Lisätty kolme alkiota. Siivun pituudeksi tulee 6.
fmt.Println(s) // Päivitetty siivu on nyt [1 2 3 4 5 6]
// Lisätäksesi siivun toiseen voit antaa append-funktiolle referenssin
// siivuun tai todellisarvoiseen siivuun lisäämällä sanaheiton argumentin
// perään. Tämä tapa purkaa siivun alkiot ja lisää ne siivuun s.
s = append(s, []int{7, 8, 9}...) // 2. argumentti on todellisarvoinen siivu.
fmt.Println(s) // Päivitetty siivu on nyt [1 2 3 4 5 6 7 8 9]
p, q := learnMemory() // Ilmoittaa p ja q olevan tyyppiä osoittaja int:iin.
fmt.Println(*p, *q) // * seuraa osoittajaa. Tämä tulostaa kaksi int:ä.
// Kartat ovat dynaamisesti kasvavia assosiatiivisia listoja, kuten hash tai
// dictionary toisissa kielissä.
m := map[string]int{"three": 3, "four": 4}
m["one"] = 1
// Käyttämättömät muuttujat ovat virheitä Go:ssa.
// Alaviiva antaa sinun "käyttää" muuttujan mutta hylätä sen arvon.
_, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs
// Tulostaminen tietysti lasketaan muuttujan käyttämiseksi.
fmt.Println(s, c, a4, s3, d2, m)
learnFlowControl() // Takaisin flowiin.
}
// Go:ssa on useista muista kielistä poiketen mahdollista käyttää nimettyjä
// palautusarvoja.
// Nimen antaminen palautettavan arvon tyypille funktion ilmoitusrivillä
// mahdollistaa helpon palaamisen useasta eri funktion suorituskohdasta sekä
// pelkän return-lausekkeen käytön ilman muita mainintoja.
func learnNamedReturns(x, y int) (z int) {
z = x * y
return // z on epäsuorasti tässä, koska nimesimme sen aiemmin.
}
// Go kerää kaikki roskansa. Siinä on osoittajia mutta ei niiden laskentoa.
// Voit tehdä virheen mitättömällä osoittajalla, mutta et
// kasvattamalla osoittajaa.
func learnMemory() (p, q *int) {
// Nimetyillä palautusarvoilla p ja q on tyyppi osoittaja int:iin.
p = new(int) // Sisäänrakennettu funktio new varaa muistia.
// Varattu int on alustettu nollaksi, p ei ole enää mitätön.
s := make([]int, 20) // Varaa 20 int:ä yhteen kohtaan muistissa.
s[3] = 7 // Anna yhdelle niistä arvo.
r := -2 // Ilmoita toinen paikallinen muuttuja.
return &s[3], &r // & ottaa asian osoitteen muistissa.
}
func expensiveComputation() float64 {
return m.Exp(10)
}
func learnFlowControl() {
// If -lausekkeet vaativat aaltosulkeet mutta ei tavallisia sulkeita.
if true {
fmt.Println("mitä mä sanoin")
}
// Muotoilu on standardoitu käyttämällä komentorivin komentoa "go fmt".
if false {
// Nyrpistys.
} else {
// Nautinto.
}
// Käytä switch -lauseketta ketjutettujen if -lausekkeiden sijasta.
x := 42.0
switch x {
case 0:
case 1:
case 42:
// Tapaukset eivät "tipu läpi".
/*
Kuitenkin meillä on erikseen `fallthrough` -avainsana. Katso:
https://go.dev/wiki/Switch#fall-through
*/
case 43:
// Saavuttamaton.
default:
// Oletustapaus (default) on valinnainen.
}
// Kuten if, for -lauseke ei myöskään käytä tavallisia sulkeita.
// for- ja if- lausekkeissa ilmoitetut muuttujat ovat paikallisia niiden
// piireissä.
for x := 0; x < 3; x++ { // ++ on lauseke. Sama kuin "x = x + 1".
fmt.Println("iteraatio", x)
}
// x == 42 tässä.
// For on kielen ainoa silmukkalauseke mutta sillä on vaihtoehtosia muotoja.
for { // Päättymätön silmukka.
break // Kunhan vitsailin.
continue // Saavuttamaton.
}
// Voit käyttää range -lauseketta iteroidaksesi listojen, siivujen, merkki-
// jonojen, karttojen tai kanavien läpi. range palauttaa yhden (kanava) tai
// kaksi arvoa (lista, siivu, merkkijono ja kartta).
for key, value := range map[string]int{"yksi": 1, "kaksi": 2, "kolme": 3} {
// jokaista kartan paria kohden, tulosta avain ja arvo
fmt.Printf("avain=%s, arvo=%d\n", key, value)
}
// Kuten for -lausekkeessa := if -lausekkeessa tarkoittaa ilmoittamista ja
// arvon asettamista.
// Aseta ensin y, sitten testaa onko y > x.
if y := expensiveComputation(); y > x {
x = y
}
// Todellisarvoiset funktiot ovat sulkeumia.
xBig := func() bool {
return x > 10000 // Viittaa ylempänä ilmoitettuun x:ään.
}
fmt.Println("xBig:", xBig()) // tosi (viimeisin arvo on e^10).
x = 1.3e3 // Tämä tekee x == 1300
fmt.Println("xBig:", xBig()) // epätosi nyt.
// Lisäksi todellisarvoiset funktiot voidaan samalla sekä ilmoittaa että
// kutsua, jolloin niitä voidaan käyttää funtioiden argumentteina kunhan:
// a) todellisarvoinen funktio kutsutaan välittömästi (),
// b) palautettu tyyppi vastaa odotettua argumentin tyyppiä.
fmt.Println("Lisää ja tuplaa kaksi numeroa: ",
func(a, b int) int {
return (a + b) * 2
}(10, 2)) // Kutsuttu argumenteilla 10 ja 2
// => Lisää ja tuplaa kaksi numeroa: 24
// Kun tarvitset sitä, rakastat sitä.
goto love
love:
learnFunctionFactory() // Funktioita palauttavat funktiot
learnDefer() // Nopea kiertoreitti tärkeään avainsanaan.
learnInterfaces() // Hyvää kamaa tulossa!
}
func learnFunctionFactory() {
// Seuraavat kaksi ovat vastaavia, mutta toinen on käytännöllisempi
fmt.Println(sentenceFactory("kesä")("Kaunis", "päivä!"))
d := sentenceFactory("kesä")
fmt.Println(d("Kaunis", "päivä!"))
fmt.Println(d("Laiska", "iltapäivä!"))
}
// Somisteet ovat yleisiä toisissa kielissä. Sama saavutetaan Go:ssa käyttämällä
// todellisarvoisia funktioita jotka ottavat vastaan argumentteja.
func sentenceFactory(mystring string) func(before, after string) string {
return func(before, after string) string {
return fmt.Sprintf("%s %s %s", before, mystring, after) // uusi jono
}
}
func learnDefer() (ok bool) {
// Lykätyt lausekkeet suoritetaan juuri ennen funktiosta palaamista.
defer fmt.Println("lykätyt lausekkeet suorittuvat")
defer fmt.Println("käänteisessä järjestyksessä (LIFO).")
defer fmt.Println("\nTämä rivi tulostuu ensin, koska")
// Defer -lauseketta käytetään yleisesti tiedoston sulkemiseksi, jotta
// tiedoston sulkeva funktio pysyy lähellä sen avannutta funktiota.
return true
}
// Määrittele Stringer rajapintatyypiksi jolla on
// yksi jäsenfunktio eli metodi, String.
type Stringer interface {
String() string
}
// Määrittele pair rakenteeksi jossa on kaksi kenttää, x ja y tyyppiä int.
type pair struct {
x, y int
}
// Määrittele jäsenfunktio pair:lle. Pair tyydyttää nyt Stringer -rajapinnan.
func (p pair) String() string { // p:tä kutsutaan nimellä "receiver"
// Sprintf on toinen julkinen funktio paketissa fmt.
// Pistesyntaksilla viitataan P:n kenttiin.
return fmt.Sprintf("(%d, %d)", p.x, p.y)
}
func learnInterfaces() {
// Aaltosuljesyntaksi on "todellisarvoinen rakenne". Se todentuu alustetuksi
// rakenteeksi. := -syntaksi ilmoittaa ja alustaa p:n täksi rakenteeksi.
p := pair{3, 4}
fmt.Println(p.String()) // Kutsu p:n (tyyppiä pair) jäsenfunktiota String.
var i Stringer // Ilmoita i Stringer-rajapintatyypiksi.
i = p // Pätevä koska pair tyydyttää rajapinnan Stringer.
// Kutsu i:n (Stringer) jäsenfunktiota String. Tuloste on sama kuin yllä.
fmt.Println(i.String())
// Funktiot fmt-paketissa kutsuvat argumenttien String-jäsenfunktiota
// selvittääkseen onko niistä saatavilla tulostettavaa vastinetta.
fmt.Println(p) // Tuloste on sama kuin yllä. Println kutsuu String-metodia.
fmt.Println(i) // Tuloste on sama kuin yllä.
learnVariadicParams("loistavaa", "oppimista", "täällä!")
}
// Funktioilla voi olla muuttuva eli variteettinen
// määrä argumentteja eli parametrejä.
func learnVariadicParams(myStrings ...interface{}) {
// Iteroi jokaisen argumentin läpi.
// Tässä alaviivalla sivuutetaan argumenttilistan kunkin kohdan indeksi.
for _, param := range myStrings {
fmt.Println("param:", param)
}
// Luovuta variteettinen arvo variteettisena parametrinä.
fmt.Println("params:", fmt.Sprintln(myStrings...))
learnErrorHandling()
}
func learnErrorHandling() {
// "; ok" -muotoa käytetään selvittääksemme toimiko jokin vai ei.
m := map[int]string{3: "kolme", 4: "neljä"}
if x, ok := m[1]; !ok { // ok on epätosi koska 1 ei ole kartassa.
fmt.Println("ei ketään täällä")
} else {
fmt.Print(x) // x olisi arvo jos se olisi kartassa.
}
// Virhearvo voi kertoa muutakin ongelmasta.
if _, err := strconv.Atoi("ei-luku"); err != nil { // _ sivuuttaa arvon
// tulostaa strconv.ParseInt: parsing "ei-luku": invalid syntax
fmt.Println(err)
}
// Palaamme rajapintoihin hieman myöhemmin. Sillä välin,
learnConcurrency()
}
// c on kanava, samanaikaisturvallinen viestintäolio.
func inc(i int, c chan int) {
c <- i + 1 // <- on "lähetysoperaattori" kun kanava on siitä vasemmalla.
}
// Käytämme inc -funktiota samanaikaiseen lukujen lisäämiseen.
func learnConcurrency() {
// Sama make -funktio jota käytimme aikaisemmin siivun luomiseksi. Make
// varaa muistin ja alustaa siivut, kartat ja kanavat.
c := make(chan int)
// Aloita kolme samanaikaista gorutiinia (goroutine). Luvut kasvavat
// samanaikaisesti ja ehkäpä rinnakkain jos laite on kykenevä ja oikein
// määritelty. Kaikki kolme lähettävät samalle kanavalle.
go inc(0, c) // go -lauseke aloittaa uuden gorutiinin.
go inc(10, c)
go inc(-805, c)
// Lue kolme palautusarvoa kanavalta ja tulosta ne.
// Niiden saapumisjärjestystä ei voida taata!
// <- on "vastaanotto-operaattori" jos kanava on oikealla
fmt.Println(<-c, <-c, <-c)
cs := make(chan string) // Toinen kanava joka käsittelee merkkijonoja.
ccs := make(chan chan string) // Kanava joka käsittelee merkkijonokanavia.
go func() { c <- 84 }() // Aloita uusi gorutiini arvon lähettämiseksi.
go func() { cs <- "sanaa" }() // Uudestaan, mutta cs -kanava tällä kertaa.
// Select -lausekkeella on syntaksi kuten switch -lausekkeella mutta
// jokainen tapaus sisältää kanavaoperaation. Se valitsee satunnaisen
// tapauksen niistä kanavista, jotka ovat kommunikaatiovalmiita
select {
case i := <-c: // Vastaanotettu arvo voidaan antaa muuttujalle
fmt.Printf("se on %T", i)
case <-cs: // tai vastaanotettu arvo voidaan sivuuttaa.
fmt.Println("se on merkkijono")
case <-ccs: // Tyhjä kanava; ei valmis kommunikaatioon.
fmt.Println("ei tapahtunut.")
}
// Tässä vaiheessa arvo oli otettu joko c:ltä tai cs:ltä. Yksi kahdesta
// ylempänä aloitetusta gorutiinista on valmistunut, toinen pysyy tukossa.
learnWebProgramming() // Go tekee sitä. Sinäkin haluat tehdä sitä.
}
// Yksittäinen funktio http -paketista aloittaa web-palvelimen.
func learnWebProgramming() {
// ListenAndServe:n ensimmäinen parametri on TCP-osoite, jota kuunnellaan.
// Toinen parametri on rajapinta, http.Handler.
go func() {
err := http.ListenAndServe(":8080", pair{})
fmt.Println(err) // älä sivuuta virheitä.
}()
requestServer()
}
// Tee pair:sta http.Handler implementoimalla sen ainoa metodi, ServeHTTP.
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Tarjoa dataa metodilla http.ResponseWriter.
w.Write([]byte("Opit Go:n Y minuutissa!"))
}
func requestServer() {
resp, err := http.Get("http://localhost:8080")
fmt.Println(err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Printf("\nWeb-palvelin sanoo: `%s`", string(body))
}
```
## Lisää luettavaa
Go-tietämyksen alku ja juuri on sen [virallinen verkkosivu](https://go.dev/).
Siellä voit seurata oppitunteja, askarrella vuorovaikutteisesti sekä lukea paljon.
Kierroksen lisäksi [dokumentaatio](https://go.dev/doc/) pitää sisällään tietoa
siistin Go-koodin kirjoittamisesta, pakettien ja komentojen käytöstä sekä julkaisuhistoriasta.
Kielen määritelmä itsessään on suuresti suositeltavissa. Se on helppolukuinen ja
yllättävän lyhyt (niissä määrin kuin kielimääritelmät nykypäivänä ovat.)
Voit askarrella parissa kanssa [Go playgroundissa](https://go.dev/play/p/tnWMjr16Mm).
Muuttele sitä ja aja se selaimestasi! Huomaa, että voit käyttää [https://go.dev/play/](https://go.dev/play/)
[REPL:na](https://en.wikipedia.org/wiki/Read-eval-print_loop) testataksesi ja koodataksesi selaimessasi, ilman Go:n asentamista.
Go:n opiskelijoiden lukulistalla on [oletuskirjaston lähdekoodi](https://go.dev/src/).
Kattavasti dokumentoituna se antaa parhaan kuvan helppolukuisesta ja ymmärrettävästä Go-koodista,
-tyylistä ja -tavoista. Voit klikata funktion nimeä [doukumentaatiossa](https://go.dev/pkg/) ja
lähdekoodi tulee esille!
Toinen loistava paikka oppia on [Go by example](https://gobyexample.com/).
Go Mobile lisää tuen mobiilialustoille (Android ja iOS). Voit kirjoittaa pelkällä Go:lla natiiveja applikaatioita tai tehdä kirjaston joka sisältää sidoksia
Go-paketista, jotka puolestaan voidaan kutsua Javasta (Android) ja Objective-C:stä (iOS). Katso [lisätietoja](https://go.dev/wiki/Mobile).

259
fi/markdown.md Normal file
View File

@@ -0,0 +1,259 @@
---
language: Markdown
filename: markdown-fi.md
contributors:
- ["Dan Turkel", "http://danturkel.com/"]
translators:
- ["Timo Virkkunen", "https://github.com/ComSecNinja"]
lang: fi-fi
---
John Gruber loi Markdownin vuona 2004. Sen tarkoitus on olla helposti luettava ja kirjoitettava syntaksi joka muuntuu helposti HTML:ksi (ja nyt myös moneksi muuksi formaatiksi).
```md
<!-- Jokainen HTML-tiedosto on pätevää Markdownia. Tämä tarkoittaa että voimme
käyttää HTML-elementtejä Markdownissa, kuten kommentteja, ilman että markdown
-jäsennin vaikuttaa niihin. Tästä johtuen et voi kuitenkaan käyttää markdownia
HTML-elementtien sisällä jos luot sellaisen markdown-tiedostoon. -->
<!-- Markdownin toteutus vaihtelee jäsentimestä toiseen. Tämä opas yrittää
selventää mitkä ominaisuudet ovat yleisiä ja mitkä ovat eritysesti tiettyjen
jäsentimien ominaisuuksia. -->
<!-- Otsikot -->
<!-- Voit luoda HTML-elementtejä <h1> - <h6> helposti aloittamalla rivin
haluamallasi määrällä ristikkomerkkejä (#). -->
# Tämä on <h1>
## Tämä on <h2>
### Tämä on <h3>
#### Tämä on <h4>
##### Tämä on <h5>
###### Tämä on <h6>
<!-- Markdownissa on myös vaihtoehtoisia tapoja ilmaista h1 ja h2. -->
Tämä on h1
=============
Tämä on h2
-------------
<!-- Yksinkertaiset tekstimuotoilut -->
<!-- Tekstin voi helposti muotoilla kursiiviksi tai lihavoiduksi. -->
*Tämä teksti on kursivoitua.*
_Kuten on myös tämä teksti._
**Tämä teksti on lihavoitua.**
__Kuten on tämäkin teksti.__
***Tämä teksti on molempia.***
**_Kuten tämäkin!_**
*__Kuten tämäkin!__*
<!-- GitHub-tyylisessä Markdownissa, jota käytetään tiedostojen esittämiseksi
GitHubissa, meillä on käytössämme myös yliviivaus: -->
~~Tämä teksti on yliviivattua.~~
<!-- Kappaleet ovat yhdellä tai useammalla peräkkäisellä tekstirivillä jotka
erotellaan yhdellä tai useammalla tyhjällä rivillä -->
Tämä on kappala. Kirjoittelen kappaleeseen, eikö tämä olekin hauskaa?
Nyt olen kappaleessa 2.
Olen edelleen toisessa kappaleessa!
Olen kolmannessa kappaleessa!
<!-- Jos haluat lisätä <br /> HTML-elementin, päätä kappale kahdella tai
useammalla välilyönnillä ja aloita sitten uusi kappale -->
Päätän tämän kahteen välilyöntiin (maalaa minut nähdäksesi ne).
There's a <br /> above me!
<!-- Lainaukset ovat helppoja ja ne tehdään >-merkillä -->
> Tämä on lainaus. Voit joko
> manuaalisesti rivittää tekstisi ja laittaa >-merkin jokaisen rivin eteen tai antaa jäsentimen rivittää pitkät tekstirivit.
> Sillä ei ole merkitystä kunhan rivit alkavat >-merkillä.
> Voit myös käyttää useampaa
>> sisennystasoa
> Kuinka hienoa se on?
<!-- Listat -->
<!-- Järjestämättömät listat tehdään asteriskilla, plussalla tai viivalla -->
* Kohta
* Kohta
* Kolmas kohta
tai
+ Kohta
+ Kohta
+ Kolmas kohta
tai
- Kohta
- Kohta
- Kolmas kohta
<!-- Järjestetyt listat tehdään järjestysluvuilla. -->
1. Kohta yksi
2. Kohta kaksi
3. Kohta kolme
<!-- Sinun ei tarvitse edes merkitä kohtia oikein ja silti markdown näyttää
oikean järjestyksen, mutta se ei välttämättä ole hyvä idea. -->
1. Kohta yksi
1. Kohta kaksi
1. Kohta kolme
<!-- (Tämä korjaantuu samanlaiseksi kuin yllä oleva esimerkki) -->
<!-- Voit myös käyttää alalistoja. -->
1. Kohta yksi
2. Kohta kaksi
3. Kohta kolme
* Alakohta
* Alakohta
4. Kohta neljä
<!-- Myös tehtävälistoja on olemassa. Tämä tekee HTML-valintaruutuja. -->
Alla olevat ruudut ilman x-merkkiä ovat merkitsemättömiä HTML-valintaruutuja.
- [ ] Ensimmäinen suoritettava tehtävä.
- [ ] Toinen tehtävä joka täytyy tehdä
Tämä alla oleva ruutu on merkitty HTML-valintaruutu.
- [x] Tämä tehtävä on suoritettu
<!-- Koodiosiot -->
<!-- Voit merkitä koodiosion (jaka käyttää <code> -elementtiä) sisentämällä
rivin neljällä välilyönnillä tai tabulaattorilla. -->
Tämä on koodia
Kuten tämäkin
<!-- Voit myös sisentää koodia samalla tavalla. -->
my_array.each do |item|
puts item
end
<!-- Muun tekstin seassa oleva koodi merkitään kahden `-merkin väliin -->
John ei tiennyt edes mitä `go_to()` -funktio teki!
<!-- GitHubin Markdownissa voit käyttää erityissyntaksia koodille. -->
\`\`\`ruby <!-- paitsi että poista nuo kenoviivat, vain ```ruby ! -->
def foobar
puts "Hello world!"
end
\`\`\` <!-- tästä myös, ei kenoviivoja, vain ``` -->
<!-- Yllä oleva teksti ei vaadi sisennystä. Lisäksi GitHub käyttää ``` jälkeen
mainitsemasi kielen syntaksin korostusta -->
<!-- Vaakaviiva (<hr />) -->
<!-- Vaakaviivojen lisääminen käy näppärästi kolmella tai useammalla
asteriskilla taikka viivalla, välilyönneillä tai ilman -->
***
---
- - -
****************
<!-- Linkit -->
<!-- yksi markdownin parhaita ominaisuuksia on yksinkertaiset hyperlinkit. Laita
näytettävä teksti hakasulkuihin [] ja URL-osoite perään sulkeissa (). -->
[Klikkaa tästä!](http://example.com/)
<!-- Voit myös lisätä linkin otsikon heittomerkeissä osoitteen perään. -->
[Klikkaa tästä!](http://example.com/ "Linkki Example.com:iin")
<!-- Suhteelliset polut toimivat myös. -->
[Musiikkia](/musiikki/).
<!-- Markdown tukee myös viittaustyylisiä linkkejä. -->
[Klikkaa tätä linkkiä][link1] saadaksesi lisätietoja!
[Katso myös tämä linkki][foobar] jos haluat.
[link1]: http://example.com/ "Siistii!"
[foobar]: http://foobar.biz/ "Selkis!"
<!-- Otsikko voi olla myös ykittäisissä heittomerkeissä tai sulkeissa, tai
ohitettu kokonaan. Viittaukset voivat olla missä tahansa kohdassa dokumenttia ja
viittausten ID:t voivat olla mitä tahansa kunhan ne ovat uniikkeja. -->
<!-- Voit myös käyttää linkin tekstiä ID:nä näin: -->
[This][] is a link.
[this]: http://tämäonlinkki.com/
<!-- Mutta tämä tapa ei ole yleinen. -->
<!-- Kuvat -->
<!-- Kuvat tehdään samalla tavalla kuin linkitkin, mutta huutomerkki edessä! -->
![Kuvan alt-attribuutti](http://imgur.com/munkuva.jpg "Vaihtoehtoinen otsikko")
<!-- Ja viittaukset toimivat odotetusti. -->
![Tämä on se alt-attribuutti][munkuva]
[munkuva]: suhteellinen/polku/siitii/kuva.jpg "otsikko tähän tarvittaessa"
<!-- Sekalaista -->
<!-- Automaattiset linkit -->
<http://testwebsite.com/> on sama kuin
[http://testwebsite.com/](http://testwebsite.com/)
<!-- Automaattiset sähköpostilinkit -->
<foo@bar.com>
<!-- Varattujen merkkien käyttö -->
haluan kirjoittaa *tämän tekstin jonka ympärillä on asteriskit* mutta en halua
sen kursivoituvan, joten teen näin: \*tämän tekstin ympärillä on asteriskit\*.
<!-- Näppäimistön näppäimet -->
<!-- GitHubin Markdownissa, voit käyttää <kbd> -tagia esittämään näppäimiä -->
Tietokoneesi kaatui? Kokeile painaa
<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
<!-- Taulukot -->
<!-- Taulukot ovat saatavilla vain GitHubin markdownissa ja ne ovat melko
vaivalloisia käyttää, mutta jos todella haluat: -->
| Kolumni1 | Kolumni2 | Kolumni3 |
| :----------- | :------: | ------------: |
| Vasemmalle | Keskelle | Oikealle |
| blaa | blaa | blaa |
<!-- vaihtoehtoisesti, sama tulos -->
Kolumni 1 | Kolumni 2 | Kolumni 3
:-- | :-: | --:
Hyi tämä on ruma | saa se | loppumaan
<!-- Loppu! -->
```
Lisää tietoa löydät John Gruberin [virallisesta julkaisusta](http://daringfireball.net/projects/markdown/syntax)
ja Adam Pritchardin loistavasta [lunttilapusta](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).

607
fi/ruby.md Normal file
View File

@@ -0,0 +1,607 @@
---
language: Ruby
filename: learnruby-fi.rb
contributors:
- ["David Underwood", "http://theflyingdeveloper.com"]
- ["Joel Walden", "http://joelwalden.net"]
- ["Luke Holder", "http://twitter.com/lukeholder"]
- ["Tristan Hume", "http://thume.ca/"]
- ["Nick LaMuro", "https://github.com/NickLaMuro"]
- ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
- ["Levi Bostian", "https://github.com/levibostian"]
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gabriel Halley", "https://github.com/ghalley"]
- ["Persa Zula", "http://persazula.com"]
- ["Jake Faris", "https://github.com/farisj"]
translators:
- ["Oliver Vartiainen", "https://github.com/firoxer"]
lang: fi-fi
---
```ruby
# Tässä yhden rivin kommentti
=begin
Tässä usean rivin kommentti
Näitä ei kylläkään käytetä
Joten käytetään vastedes vain yksirivisiä
=end
# Tärkeintä on muistaa, että Rubyssa kaikki pohjautuu olioihin.
# Luvutkin ovat olioita:
3.class #=> Fixnum
3.to_s #=> "3"
# Peruslaskutoimituksia:
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
35 / 5 #=> 7
2**5 #=> 32
5 % 3 #=> 2
# Bittioperaatioita:
3 & 5 #=> 1
3 | 5 #=> 7
3 ^ 5 #=> 6
# Laskutoimitukset ovat vain syntaksisokeria lukuolion laskumetodin kutsulle:
1.+(3) #=> 4
10.* 5 #=> 50
# Erityisarvotkin ovat olioita:
nil # vastaa joidenkin kielten "null"-arvoa
true # tosi
false # epätosi
nil.class #=> NilClass
true.class #=> TrueClass
false.class #=> FalseClass
# Samanvertaisuuden testaus:
1 == 1 #=> true
2 == 1 #=> false
# ...ja sama eriarvoisuudelle:
1 != 1 #=> false
2 != 1 #=> true
# "nil" ja "false" ovat ainoat epätodet arvot; kaikki muu ymmärretään todeksi:
!nil #=> true
!false #=> true
!0 #=> false
# Lisää vertailuoperaatioita:
1 < 10 #=> true
1 > 10 #=> false
2 <= 2 #=> true
2 >= 2 #=> true
# Kahdensuuntainen vertailuoperaattori:
1 <=> 10 #=> -1
10 <=> 1 #=> 1
1 <=> 1 #=> 0
# Logiikkaoperaattorit:
true && false #=> false
true || false #=> true
!true #=> false
# Merkkipohjaisten logiikkaoperaattorien vaihtoehtona on sanalliset muodot,
# joilla on hyvin matala presedenssi. Niillä voi muokata ohjelman kulkua
# esimerkiksi väitelausekkeita ketjuttaen.
# Metodia `do_something_else` kutsutaan vain, jos `do_something` onnistuu:
do_something() and do_something_else()
# Metodia `log_error` kutsutaan vain, jos `do_something` epäonnistuu:
do_something() or log_error()
# Merkkijonot ovat olioita:
'Tässä on merkkijono'.class #=> String
"Rajaavat lainausmerkit voivat olla yksin- tai kaksinkertaisia".class #=> String
täyte = 'sisällyttää muita merkkijonoja'
"Kaksinkertaisilla lainausmerkeillä voi #{täyte}"
#=> "Kaksinkertaisilla lainausmerkeillä voi sisällyttää muita merkkijonoja"
# Yksinkertaisia lainausmerkkejä kannattaa silti suosia, sillä kaksinkertaiset
# merkit saattavat aiheuttaa turhia kielensisäisiä tarkistuksia.
# Merkkijonoja voi yhdistellä toisiinsa:
'hello ' + 'world' #=> "hello world"
# ...mutta luvut vaativat ensin tyyppimuunnoksen:
'hello ' + 3 #=> TypeError: can't convert Fixnum into String
'hello ' + 3.to_s #=> "hello 3"
# Merkkijonoja voi soveltaa laskutoimituksiin... odotettavin seurauksin:
'hello ' * 3 #=> "hello hello hello "
# Merkkijonoa voi jatkaa toisella:
'hello' << ' world' #=> "hello world"
# Tulosteen luonti kera rivinvaihdon:
puts "I'm printing!"
#=> I'm printing!
#=> nil
# ...ja ilman rivinvaihtoa:
print "I'm printing!"
#=> I'm printing! => nil
# Muuttujien määrittely:
x = 25 #=> 25
x #=> 25
# Arvon asettaminen palauttaa arvon itsensä, joten usean muuttujan arvon
# yhtäaikainen määrittely käy vaivatta:
x = y = 10 #=> 10
x #=> 10
y #=> 10
# Muuttujien sanaerottimena käytetään alaviivaa:
snake_case = true
# Lisäksi Rubyssa suositaan ytimekkäitä nimiä:
path_to_project_root = '/good/name/'
path = '/bad/name/'
# Symbolit
# Symbolit ovat muuttumattomia, uudelleenkäytettäviä vakioita.
# Niitä käytetään merkkijonojen sijaan, kun tarkoitus on viitata arvoon,
# jolla on tietty, pysyvä merkitys:
:pending.class #=> Symbol
status = :pending
status == :pending #=> true
status == 'pending' #=> false
status == :approved #=> false
# Taulukot
# Tässä taulukko:
array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
# Taulukko saa koostua erityyppisistä arvoista:
[1, 'hello', false] #=> [1, "hello", false]
# Taulukon alkioihin voi viitata järjestysnumerolla nollasta alkaen:
array[0] #=> 1
array.first #=> 1
array[12] #=> nil
# Kuten laskutoimituksissa nähty syntaksisokeri on myös taulukon alkioiden haku
# pohjimmiltaan vain taulukko-olioon kuuluvan "[]"-metodin kutsu:
array.[] 0 #=> 1
array.[] 12 #=> nil
# Haku käy myös lopustapäin:
array[-1] #=> 5
array.last #=> 5
# Alitaulukon haku käy indeksiparilla...
array[2, 3] #=> [3, 4, 5]
# ...tai määrittelemällä väli:
array[1..3] #=> [2, 3, 4]
# Taulukon voi kääntää:
a=[1,2,3]
a.reverse! #=> [3,2,1]
# Ja sitä voi jatkaa näin...
array << 6 #=> [1, 2, 3, 4, 5, 6]
# ...tai näin:
array.push(6) #=> [1, 2, 3, 4, 5, 6]
# Alkion olemassaolon tarkistus:
array.include?(1) #=> true
# Hashit eli assosiaatiotaulut ovat Rubyn tärkein avain-/arvoparirakenne.
# Hash luodaan aaltosulkeilla:
hash = { 'color' => 'green', 'number' => 5 }
hash.keys #=> ['color', 'number']
# Hash toimii erityisen nopeasti, kun haetaan arvoa avaimen perusteella:
hash['color'] #=> 'green'
hash['number'] #=> 5
# Jos hashistä ei löyty avainta vastaavaa arvoa, palautetaan nil-arvo:
hash['nothing here'] #=> nil
# Symbolihashin määrittelylle on oma syntaksinsa (alkaen Rubyn versiosta 1.9):
new_hash = { defcon: 3, action: true }
new_hash.keys #=> [:defcon, :action]
# Hashin avaimen ja arvon olemassaolon tarkistus:
new_hash.key?(:defcon) #=> true
new_hash.value?(3) #=> true
# Vinkki! Sekä taulukot että hashit sisältävät Enumerable-moduulin,
# johon kuuluu useita hyödyllisiä iterointimetodeja kuten .each, .map,
# .reduce ja .count
# Rakenteita
if true
'if statement'
elsif false
'else if, optional'
else
'else, also optional'
end
for counter in 1..5
puts "iteration #{counter}"
end
#=> iteration 1
#=> iteration 2
#=> iteration 3
#=> iteration 4
#=> iteration 5
# HUOMAA, että for-rakennetta kannattaa välttää, sillä Rubyssa suosittu
# each-metodi ajaa saman asian idiomaattisemmin. Each-metodi ottaa ainoana
# argumenttinaan lohkon. Lohkot toimivat pitkälti samoin kuin muiden kielten
# anonyymit funktiot, lambdat tai sulkeumat.
# Lukuvälit vastaavat each-metodiin, jolloin sille annettu lohko ajetaan
# kerran jokaiselle välin kokonaisluvulle.
# Lukuvälin each-rakenne lohkoineen näyttää tältä:
(1..5).each do |counter|
puts "iteration #{counter}"
end
#=> iteration 1
#=> iteration 2
#=> iteration 3
#=> iteration 4
#=> iteration 5
# Lohkoa ympäröivät do/end-avainsanat voi korvata myös aaltosulkeilla:
(1..5).each { |counter| puts "iteration #{counter}" }
# Lukuvälien lisäksi myös tietorakenteita voidaan iteroida each-metodilla:
array.each do |element|
puts "#{element} is part of the array"
end
hash.each do |key, value|
puts "#{key} is #{value}"
end
# Taulukoita voi iteroida metodilla each_with_index, jolloin lohko saa
# argumenteikseen sekä alkion että indeksin:
array.each_with_index do |element, index|
puts "#{element} is number #{index} in the array"
end
counter = 1
while counter <= 5 do
puts "iteration #{counter}"
counter += 1
end
#=> iteration 1
#=> iteration 2
#=> iteration 3
#=> iteration 4
#=> iteration 5
# Each-metodin lisäksi Rubyssa on useita muita iterointimetodeja kuten
# "map" ja "reduce". Näistä "map" kutsuttuna taulukolla ottaa argumentikseen
# lohkon, suorittaa sen kerran jokaiselle rakenteen jäsenelle, ja lopuksi
# palauttaa uuden taulukon, jonka jäsenet ovat lohkon suorituksen tuloksia.
array = [1, 2, 3, 4, 5]
doubled = array.map do |element|
element * 2
end
puts doubled
#=> [2,4,6,8,10]
puts array
#=> [1,2,3,4,5]
# Case-rakenne siirtää ohjelman kulun yhdelle monista määritellyistä poluista:
grade = 'B'
case grade
when 'A'
puts 'Way to go kiddo'
when 'B'
puts 'Better luck next time'
when 'C'
puts 'You can do better'
when 'D'
puts 'Scraping through'
when 'F'
puts 'You failed!'
else
puts 'Alternative grading system, eh?'
end
#=> "Better luck next time"
# Case-rakenteessa voidaan hyödyntää lukuvälejä:
grade = 82
case grade
when 90..100
puts 'Hooray!'
when 80...90
puts 'OK job'
else
puts 'You failed!'
end
#=> "OK job"
# Virheidenkäsittely:
begin
# Seuraava koodinpätkä aiheuttaa NoMemoryError-poikkeuksen
raise NoMemoryError, 'You ran out of memory.'
rescue NoMemoryError => exception_variable
puts 'NoMemoryError was raised', exception_variable
rescue RuntimeError => other_exception_variable
puts 'RuntimeError was raised now'
else
puts 'This runs if no exceptions were thrown at all'
ensure
puts 'This code always runs no matter what'
end
# Ylimmän näkyvyysalueen metodi näyttää itsenäiseltä funktiolta:
def double(x)
x * 2
end
# Funktiot (ja lohkot) palauttavat implisiittisesti
# viimeiseksi ajamansa lausekkeen arvon:
double(2) #=> 4
# Metodikutsun argumentteja ympäröivät kaarisulkeet voi jättää pois,
# kunhan koodi ei muutu monitulkintaiseksi:
double 3 #=> 6
double double 3 #=> 12
def sum(x, y)
x + y
end
# Argumentit erotetaan pilkuilla:
sum 3, 4 #=> 7
sum sum(3, 4), 5 #=> 12
# Kaikilla metodeilla on implisiittinen lohkoparametri,
# joka voidaan suorittaa yield-avainsanalla:
def surround
puts '{'
yield
puts '}'
end
surround { puts 'hello world' }
# {
# hello world
# }
# Metodille annetun lohkon voi nimetä parametrilistassa &-merkin avulla,
# minkä jälkeen se suoritetaan call-metodilla:
def guests(&block)
block.call 'some_argument'
end
# Metodille voi antaa vaihtelevan määrän muuttujia. Ne siirretään taulukkoon,
# jolle annetaan parametrilistassa nimi \*-merkin avulla
def guests(*array)
array.each { |guest| puts guest }
end
# Luokan määritys aloitetaan class-avainsanalla:
class Human
# Tässä luokkamuuttuja, joka on yhteinen kaikille luokan olioille:
@@species = 'H. sapiens'
# Alustusmetodin määrittely:
def initialize(name, age = 0)
# name-oliomuuttujan arvon asetus metodille annetun name-muuttujan mukaan:
@name = name
# Jos tätä metodia kutsuessa jätetään toinen argumentti (age) antamatta,
# saa se parametriluettelossa määritetyn arvon 0:
@age = age
end
# Tyypillinen oliomuuttujan arvon asettava metodi:
def name=(name)
@name = name
end
# Tyypillinen oliomuuttujan arvon palauttava metodi:
def name
@name
end
# Edelliset kaksi metodia voi ilmaista idiomaattisemmin myös näin:
attr_accessor :name
# Lisäksi arvon palauttavan ja asettavan metodin voi määritellä erikseen:
attr_reader :name
attr_writer :name
# Luokkametodeissa käytetään avainsanaa self erotuksena oliometodeista.
# Luokkametodia voi kutsua vain luokalla itsellään, ei olioilla:
def self.say(msg)
puts msg
end
def species
@@species
end
end
# Olion luonti:
jim = Human.new('Jim Halpert')
dwight = Human.new('Dwight K. Schrute')
# Olion metodien kutsuja:
jim.species #=> "H. sapiens"
jim.name #=> "Jim Halpert"
jim.name = "Jim Halpert II" #=> "Jim Halpert II"
jim.name #=> "Jim Halpert II"
dwight.species #=> "H. sapiens"
dwight.name #=> "Dwight K. Schrute"
# Luokkametodin kutsu:
Human.say('Hi') #=> "Hi"
# Muuttujan näkyvyysalueen voi määritellä etuliitteellä.
# $-alkuiset muuttujat ovat globaaleja:
$var = "I'm a global var"
defined? $var #=> "global-variable"
# @-alkuiset muuttujat kuuluvat oliolle,
# jonka näkyvyysalueella määrittely tehdään:
@var = "I'm an instance var"
defined? @var #=> "instance-variable"
# @@-alkuiset muuttujat kuuluvat vastaavasti näkyvyysalueensa luokalle:
@@var = "I'm a class var"
defined? @@var #=> "class variable"
# Isolla alkukirjaimella nimetyt muuttujat ovatkin vakioita:
Var = "I'm a constant"
defined? Var #=> "constant"
# Kuten odottaa saattaa, myös luokat itsessään ovat olioita.
# Siksi niille voi määritellä muuttujia, jotka ovat yhteisiä kaikille
# luokan ilmentymille ja perillisille.
# Tavallisen luokan määrittely:
class Human
@@foo = 0
def self.foo
@@foo
end
def self.foo=(value)
@@foo = value
end
end
# Perillisluokan määrittely:
class Worker < Human
end
Human.foo # 0
Worker.foo # 0
Human.foo = 2 # 2
Worker.foo # 2
# Oliomuuttuja on kuitenkin olion oma eikä periydy:
class Human
@bar = 0
def self.bar
@bar
end
def self.bar=(value)
@bar = value
end
end
class Doctor < Human
end
Human.bar # 0
Doctor.bar # nil
module ModuleExample
def foo
'foo'
end
end
# Moduulien lisääminen luokkaan "include"-avainsanalla siirtää moduulin metodit
# luokan ilmentymille, kun taas "extend" avainsana siirtää metodit
# luokalle itselleen:
class Person
include ModuleExample
end
class Book
extend ModuleExample
end
Person.foo # => NoMethodError: undefined method `foo' for Person:Class
Person.new.foo # => 'foo'
Book.foo # => 'foo'
Book.new.foo # => NoMethodError: undefined method `foo'
# Callback-tyyppiset metodit suoritetaan moduulia sisällyttäessä:
module ConcernExample
def self.included(base)
base.extend(ClassMethods)
base.send(:include, InstanceMethods)
end
module ClassMethods
def bar
'bar'
end
end
module InstanceMethods
def qux
'qux'
end
end
end
class Something
include ConcernExample
end
Something.bar # => 'bar'
Something.qux # => NoMethodError: undefined method `qux'
Something.new.bar # => NoMethodError: undefined method `bar'
Something.new.qux # => 'qux'
```
## Lisämateriaalia englanniksi
- [An Interactive Tutorial for Ruby](https://rubymonk.com/)
- [Official Documentation](http://www.ruby-doc.org/core-2.1.1/) - Virallinen dokumentaatio
- [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/)
- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - Vanhempi, mutta [ilmainen painos](http://ruby-doc.com/docs/ProgrammingRuby/) on luettavissa netissä
- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - Yhteisön luoma Ruby-tyyliopas
- [Try Ruby](https://try.ruby-lang.org/) - Rubyn perusteet interaktiivisesti