mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-01-17 13:38:38 +01:00
Merge branch 'master' into elixir-casing
This commit is contained in:
commit
616e40816d
607
ATS.html.markdown
Normal file
607
ATS.html.markdown
Normal file
@ -0,0 +1,607 @@
|
||||
---
|
||||
language: ATS
|
||||
contributors:
|
||||
- ["Mark Barbone", "https://github.com/mb64"]
|
||||
filename: learnats.dats
|
||||
---
|
||||
|
||||
ATS is a low-level functional programming language. It has a powerful type
|
||||
system which lets you write programs with the same level of control and
|
||||
efficiency as C, but in a memory safe and type safe way.
|
||||
|
||||
The ATS type system supports:
|
||||
|
||||
* Full type erasure: ATS compiles to efficient C
|
||||
* Dependent types, including [LF](http://twelf.org/wiki/LF) and proving
|
||||
metatheorems
|
||||
* Refinement types
|
||||
* Linearity for resource tracking
|
||||
* An effect system that tracks exceptions, mutation, termination, and other
|
||||
side effects
|
||||
|
||||
This tutorial is not an introduction to functional programming, dependent types,
|
||||
or linear types, but rather to how they all fit together in ATS. That said, ATS
|
||||
is a very complex language, and this tutorial doesn't cover it all. Not only
|
||||
does ATS's type system boast a wide array of confusing features, its
|
||||
idiosyncratic syntax can make even "simple" examples hard to understand. In the
|
||||
interest of keeping it a reasonable length, this document is meant to give a
|
||||
taste of ATS, giving a high-level overview of what's possible and how, rather
|
||||
than attempting to fully explain how everything works.
|
||||
|
||||
You can [try ATS in your browser](http://www.ats-lang.org/SERVER/MYCODE/Patsoptaas_serve.php),
|
||||
or install it from [http://www.ats-lang.org/](http://www.ats-lang.org/).
|
||||
|
||||
|
||||
```ocaml
|
||||
// Include the standard library
|
||||
#include "share/atspre_define.hats"
|
||||
#include "share/atspre_staload.hats"
|
||||
|
||||
// To compile, either use
|
||||
// $ patscc -DATS_MEMALLOC_LIBC program.dats -o program
|
||||
// or install the ats-acc wrapper https://github.com/sparverius/ats-acc and use
|
||||
// $ acc pc program.dats
|
||||
|
||||
// C-style line comments
|
||||
/* and C-style block comments */
|
||||
(* as well as ML-style block comments *)
|
||||
|
||||
/*************** Part 1: the ML fragment ****************/
|
||||
|
||||
val () = print "Hello, World!\n"
|
||||
|
||||
// No currying
|
||||
fn add (x: int, y: int) = x + y
|
||||
|
||||
// fn vs fun is like the difference between let and let rec in OCaml/F#
|
||||
fun fact (n: int): int = if n = 0 then 1 else n * fact (n-1)
|
||||
|
||||
// Multi-argument functions need parentheses when you call them; single-argument
|
||||
// functions can omit parentheses
|
||||
val forty_three = add (fact 4, 19)
|
||||
|
||||
// let is like let in SML
|
||||
fn sum_and_prod (x: int, y: int): (int, int) =
|
||||
let
|
||||
val sum = x + y
|
||||
val prod = x * y
|
||||
in (sum, prod) end
|
||||
|
||||
// 'type' is the type of all heap-allocated, non-linear types
|
||||
// Polymorphic parameters go in {} after the function name
|
||||
fn id {a:type} (x: a) = x
|
||||
|
||||
// ints aren't heap-allocated, so we can't pass them to 'id'
|
||||
// val y: int = id 7 // doesn't compile
|
||||
|
||||
// 't@ype' is the type of all non-linear potentially unboxed types. It is a
|
||||
// supertype of 'type'.
|
||||
// Templated parameters go in {} before the function name
|
||||
fn {a:t@ype} id2 (x: a) = x
|
||||
|
||||
val y: int = id2 7 // works
|
||||
|
||||
// can't have polymorphic t@ype parameters
|
||||
// fn id3 {a:t@ype} (x: a) = x // doesn't compile
|
||||
|
||||
// explicity specifying type parameters:
|
||||
fn id4 {a:type} (x: a) = id {a} x // {} for non-template parameters
|
||||
fn id5 {a:type} (x: a) = id2<a> x // <> for template parameters
|
||||
fn id6 {a:type} (x: a) = id {..} x // {..} to explicitly infer it
|
||||
|
||||
// Heap allocated shareable datatypes
|
||||
// using datatypes leaks memory
|
||||
datatype These (a:t@ype, b:t@ype) = This of a
|
||||
| That of b
|
||||
| These of (a, b)
|
||||
|
||||
// Pattern matching using 'case'
|
||||
fn {a,b: t@ype} from_these (x: a, y: b, these: These(a,b)): (a, b) =
|
||||
case these of
|
||||
| This(x) => (x, y) // Shadowing of variable names is fine; here, x shadows
|
||||
// the parameter x
|
||||
| That(y) => (x, y)
|
||||
| These(x, y) => (x, y)
|
||||
|
||||
// Partial pattern match using 'case-'
|
||||
// Will throw an exception if passed This
|
||||
fn {a,b:t@ype} unwrap_that (these: These(a,b)): b =
|
||||
case- these of
|
||||
| That(y) => y
|
||||
| These(_, y) => y
|
||||
|
||||
|
||||
/*************** Part 2: refinements ****************/
|
||||
|
||||
// Parameterize functions by what values they take and return
|
||||
fn cool_add {n:int} {m:int} (x: int n, y: int m): int (n+m) = x + y
|
||||
|
||||
// list(a, n) is a list of n a's
|
||||
fun square_all {n:int} (xs: list(int, n)): list(int, n) =
|
||||
case xs of
|
||||
| list_nil() => list_nil()
|
||||
| list_cons(x, rest) => list_cons(x * x, square_all rest)
|
||||
|
||||
fn {a:t@ype} get_first {n:int | n >= 1} (xs: list(a, n)): a =
|
||||
case+ xs of // '+' asks ATS to prove it's total
|
||||
| list_cons(x, _) => x
|
||||
|
||||
// Can't run get_first on lists of length 0
|
||||
// val x: int = get_first (list_nil()) // doesn't compile
|
||||
|
||||
// in the stdlib:
|
||||
// sortdef nat = {n:int | n >= 0}
|
||||
// sortdef pos = {n:int | n >= 1}
|
||||
|
||||
fn {a:t@ype} also_get_first {n:pos} (xs: list(a, n)): a =
|
||||
let
|
||||
val+ list_cons(x, _) = xs // val+ also works
|
||||
in x end
|
||||
|
||||
// tail-recursive reverse
|
||||
fun {a:t@ype} reverse {n:int} (xs: list(a, n)): list(a, n) =
|
||||
let
|
||||
// local functions can use type variables from their enclosing scope
|
||||
// this one uses both 'a' and 'n'
|
||||
fun rev_helper {i:nat} (xs: list(a, n-i), acc: list(a, i)): list(a, n) =
|
||||
case xs of
|
||||
| list_nil() => acc
|
||||
| list_cons(x, rest) => rev_helper(rest, list_cons(x, acc))
|
||||
in rev_helper(xs, list_nil) end
|
||||
|
||||
// ATS has three context-dependent namespaces
|
||||
// the two 'int's mean different things in this example, as do the two 'n's
|
||||
fn namespace_example {n:int} (n: int n): int n = n
|
||||
// ^^^ sort namespace
|
||||
// ^ ^^^ ^ ^^^ ^ statics namespace
|
||||
// ^^^^^^^^^^^^^^^^^ ^ ^ value namespace
|
||||
|
||||
// a termination metric can go in .< >.
|
||||
// it must decrease on each recursive call
|
||||
// then ATS will prove it doesn't infinitely recurse
|
||||
fun terminating_factorial {n:nat} .<n>. (n: int n): int =
|
||||
if n = 0 then 1 else n * terminating_factorial (n-1)
|
||||
|
||||
|
||||
/*************** Part 3: the LF fragment ****************/
|
||||
|
||||
// ATS supports proving theorems in LF (http://twelf.org/wiki/LF)
|
||||
|
||||
// Relations are represented by inductive types
|
||||
|
||||
// Proofs that the nth fibonacci number is f
|
||||
dataprop Fib(n:int, m:int) =
|
||||
| FibZero(0, 0)
|
||||
| FibOne(1, 1)
|
||||
| {n, f1, f2: int} FibInd(n, f1 + f2) of (Fib(n-1,f1), Fib(n-2,f2))
|
||||
|
||||
// Proved-correct fibonacci implementation
|
||||
// [A] B is an existential type: "there exists A such that B"
|
||||
// (proof | value)
|
||||
fun fib {n:nat} .<n>. (n: int n): [f:int] (Fib(n,f) | int f) =
|
||||
if n = 0 then (FibZero | 0) else
|
||||
if n = 1 then (FibOne | 1) else
|
||||
let
|
||||
val (proof1 | val1) = fib (n-1)
|
||||
val (proof2 | val2) = fib (n-2)
|
||||
// the existential type is inferred
|
||||
in (FibInd(proof1, proof2) | val1 + val2) end
|
||||
|
||||
// Faster proved-correct fibonacci implementation
|
||||
fn fib_tail {n:nat} (n: int n): [f:int] (Fib(n,f) | int f) =
|
||||
let
|
||||
fun loop {i:int | i < n} {f1, f2: int} .<n - i>.
|
||||
(p1: Fib(i,f1), p2: Fib(i+1,f2)
|
||||
| i: int i, f1: int f1, f2: int f2, n: int n
|
||||
): [f:int] (Fib(n,f) | int f) =
|
||||
if i = n - 1
|
||||
then (p2 | f2)
|
||||
else loop (p2, FibInd(p2,p1) | i+1, f2, f1+f2, n)
|
||||
in if n = 0 then (FibZero | 0) else loop (FibZero, FibOne | 0, 0, 1, n) end
|
||||
|
||||
// Proof-level lists of ints, of type 'sort'
|
||||
datasort IntList = ILNil of ()
|
||||
| ILCons of (int, IntList)
|
||||
|
||||
// ILAppend(x,y,z) iff x ++ y = z
|
||||
dataprop ILAppend(IntList, IntList, IntList) =
|
||||
| {y:IntList} AppendNil(ILNil, y, y)
|
||||
| {a:int} {x,y,z: IntList}
|
||||
AppendCons(ILCons(a,x), y, ILCons(a,z)) of ILAppend(x,y,z)
|
||||
|
||||
// prfuns/prfns are compile-time functions acting on proofs
|
||||
|
||||
// metatheorem: append is total
|
||||
prfun append_total {x,y: IntList} .<x>. (): [z:IntList] ILAppend(x,y,z)
|
||||
= scase x of // scase lets you inspect static arguments (only in prfuns)
|
||||
| ILNil() => AppendNil
|
||||
| ILCons(a,rest) => AppendCons(append_total())
|
||||
|
||||
|
||||
/*************** Part 4: views ****************/
|
||||
|
||||
// views are like props, but linear; ie they must be consumed exactly once
|
||||
// prop is a subtype of view
|
||||
|
||||
// 'type @ address' is the most basic view
|
||||
|
||||
fn {a:t@ype} read_ptr {l:addr} (pf: a@l | p: ptr l): (a@l | a) =
|
||||
let
|
||||
// !p searches for usable proofs that say something is at that address
|
||||
val x = !p
|
||||
in (pf | x) end
|
||||
|
||||
// oops, tried to dereference a potentially invalid pointer
|
||||
// fn {a:t@ype} bad {l:addr} (p: ptr l): a = !p // doesn't compile
|
||||
|
||||
// oops, dropped the proof (leaked the memory)
|
||||
// fn {a:t@ype} bad {l:addr} (pf: a@l | p: ptr l): a = !p // doesn't compile
|
||||
|
||||
fn inc_at_ptr {l:addr} (pf: int@l | p: ptr l): (int@l | void) =
|
||||
let
|
||||
// !p := value writes value to the location at p
|
||||
// like !p, it implicitly searches for usable proofs that are in scope
|
||||
val () = !p := !p + 1
|
||||
in (pf | ()) end
|
||||
|
||||
// threading proofs through gets annoying
|
||||
fn inc_three_times {l:addr} (pf: int@l | p: ptr l): (int@l | void) =
|
||||
let
|
||||
val (pf2 | ()) = inc_at_ptr (pf | p)
|
||||
val (pf3 | ()) = inc_at_ptr (pf2 | p)
|
||||
val (pf4 | ()) = inc_at_ptr (pf3 | p)
|
||||
in (pf4 | ()) end
|
||||
|
||||
// so there's special syntactic sugar for when you don't consume a proof
|
||||
fn dec_at_ptr {l:addr} (pf: !int@l | p: ptr l): void =
|
||||
!p := !p - 1 // ^ note the exclamation point
|
||||
|
||||
fn dec_three_times {l:addr} (pf: !int@l | p: ptr l): void =
|
||||
let
|
||||
val () = dec_at_ptr (pf | p)
|
||||
val () = dec_at_ptr (pf | p)
|
||||
val () = dec_at_ptr (pf | p)
|
||||
in () end
|
||||
|
||||
// dataview is like dataprop, but linear
|
||||
// A proof that either the address is null, or there is a value there
|
||||
dataview MaybeNull(a:t@ype, addr) =
|
||||
| NullPtr(a, null)
|
||||
| {l:addr | l > null} NonNullPtr(a, l) of (a @ l)
|
||||
|
||||
fn maybe_inc {l:addr} (pf: !MaybeNull(int, l) | p: ptr l): void =
|
||||
if ptr1_is_null p
|
||||
then ()
|
||||
else let
|
||||
// Deconstruct the proof to access the proof of a @ l
|
||||
prval NonNullPtr(value_exists) = pf
|
||||
val () = !p := !p + 1
|
||||
// Reconstruct it again for the caller
|
||||
prval () = pf := NonNullPtr(value_exists)
|
||||
in () end
|
||||
|
||||
// array_v(a,l,n) represents and array of n a's at location l
|
||||
// this gets compiled into an efficient for loop, since all proofs are erased
|
||||
fn sum_array {l:addr}{n:nat} (pf: !array_v(int,l,n) | p: ptr l, n: int n): int =
|
||||
let
|
||||
fun loop {l:addr}{n:nat} .<n>. (
|
||||
pf: !array_v(int,l,n)
|
||||
| ptr: ptr l,
|
||||
length: int n,
|
||||
acc: int
|
||||
): int = if length = 0
|
||||
then acc
|
||||
else let
|
||||
prval (head, rest) = array_v_uncons(pf)
|
||||
val result = loop(rest | ptr_add<int>(ptr, 1), length - 1, acc + !ptr)
|
||||
prval () = pf := array_v_cons(head, rest)
|
||||
in result end
|
||||
in loop (pf | p, n, 0) end
|
||||
|
||||
// 'var' is used to create stack-allocated (lvalue) variables
|
||||
val seven: int = let
|
||||
var res: int = 3
|
||||
// they can be modified
|
||||
val () = res := res + 1
|
||||
// addr@ res is a pointer to it, and view@ res is the associated proof
|
||||
val (pf | ()) = inc_three_times(view@ res | addr@ res)
|
||||
// need to give back the view before the variable goes out of scope
|
||||
prval () = view@ res := pf
|
||||
in res end
|
||||
|
||||
// References let you pass lvalues, like in C++
|
||||
fn square (x: &int): void =
|
||||
x := x * x // they can be modified
|
||||
|
||||
val sixteen: int = let
|
||||
var res: int = 4
|
||||
val () = square res
|
||||
in res end
|
||||
|
||||
fn inc_at_ref (x: &int): void =
|
||||
let
|
||||
// like vars, references have views and addresses
|
||||
val (pf | ()) = inc_at_ptr(view@ x | addr@ x)
|
||||
prval () = view@ x := pf
|
||||
in () end
|
||||
|
||||
// Like ! for views, & references are only legal as argument types
|
||||
// fn bad (x: &int): &int = x // doesn't compile
|
||||
|
||||
// this takes a proof int n @ l, but returns a proof int (n+1) @ l
|
||||
// since they're different types, we can't use !int @ l like before
|
||||
fn refined_inc_at_ptr {n:int}{l:addr} (
|
||||
pf: int n @ l | p: ptr l
|
||||
): (int (n+1) @ l | void) =
|
||||
let
|
||||
val () = !p := !p + 1
|
||||
in (pf | ()) end
|
||||
|
||||
// special syntactic sugar for returning a proof at a different type
|
||||
fn refined_dec_at_ptr {n:int}{l:addr} (
|
||||
pf: !int n @ l >> int (n-1) @ l | p: ptr l
|
||||
): void =
|
||||
!p := !p - 1
|
||||
|
||||
// legal but very bad code
|
||||
prfn swap_proofs {v1,v2:view} (a: !v1 >> v2, b: !v2 >> v1): void =
|
||||
let
|
||||
prval tmp = a
|
||||
prval () = a := b
|
||||
prval () = b := tmp
|
||||
in () end
|
||||
|
||||
// also works with references
|
||||
fn refined_square {n:int} (x: &int n >> int (n*n)): void =
|
||||
x := x * x
|
||||
|
||||
fn replace {a,b:vtype} (dest: &a >> b, src: b): a =
|
||||
let
|
||||
val old = dest
|
||||
val () = dest := src
|
||||
in old end
|
||||
|
||||
// values can be uninitialized
|
||||
fn {a:vt@ype} write (place: &a? >> a, value: a): void =
|
||||
place := value
|
||||
|
||||
val forty: int = let
|
||||
var res: int
|
||||
val () = write (res, 40)
|
||||
in res end
|
||||
|
||||
// viewtype: a view and a type
|
||||
viewtypedef MaybeNullPtr(a:t@ype) = [l:addr] (MaybeNull(a, l) | ptr l)
|
||||
// MaybeNullPtr has type 'viewtype' (aka 'vtype')
|
||||
// type is a subtype of vtype and t@ype is a subtype of vt@ype
|
||||
|
||||
// The most general identity function:
|
||||
fn {a:vt@ype} id7 (x: a) = x
|
||||
|
||||
// since they contain views, viewtypes must be used linearly
|
||||
// fn {a:vt@ype} duplicate (x: a) = (x, x) // doesn't compile
|
||||
// fn {a:vt@ype} ignore (x: a) = () // doesn't compile
|
||||
|
||||
// arrayptr(a,l,n) is a convenient built-in viewtype
|
||||
fn easier_sum_array {l:addr}{n:nat} (p: !arrayptr(int,l,n), n: int n): int =
|
||||
let
|
||||
fun loop {i:nat | i <= n} (
|
||||
p: !arrayptr(int,l,n), n: int n, i: int i, acc: int
|
||||
): int =
|
||||
if i = n
|
||||
then acc
|
||||
else loop(p, n, i+1, acc + p[i])
|
||||
in loop(p, n, 0, 0) end
|
||||
|
||||
|
||||
/*************** Part 5: dataviewtypes ****************/
|
||||
|
||||
// a dataviewtype is a heap-allocated non-shared inductive type
|
||||
|
||||
// in the stdlib:
|
||||
// dataviewtype list_vt(a:vt@ype, int) =
|
||||
// | list_vt_nil(a, 0)
|
||||
// | {n:nat} list_vt_cons(a, n+1) of (a, list_vt(a, n))
|
||||
|
||||
fn {a:vt@ype} length {n:int} (l: !list_vt(a, n)): int n =
|
||||
let // ^ since we're not consuming it
|
||||
fun loop {acc:int} (l: !list_vt(a, n-acc), acc: int acc): int n =
|
||||
case l of
|
||||
| list_vt_nil() => acc
|
||||
| list_vt_cons(head, tail) => loop(tail, acc + 1)
|
||||
in loop (l, 0) end
|
||||
|
||||
// vvvvv not vt@ype, because you can't easily get rid of a vt@ype
|
||||
fun {a:t@ype} destroy_list {n:nat} (l: list_vt(a,n)): void =
|
||||
case l of
|
||||
// ~ pattern match consumes and frees that node
|
||||
| ~list_vt_nil() => ()
|
||||
| ~list_vt_cons(_, tail) => destroy_list tail
|
||||
|
||||
// unlike a datatype, a dataviewtype can be modified:
|
||||
fun {a:vt@ype} push_back {n:nat} (
|
||||
x: a,
|
||||
l: &list_vt(a,n) >> list_vt(a,n+1)
|
||||
): void =
|
||||
case l of
|
||||
| ~list_vt_nil() => l := list_vt_cons(x, list_vt_nil)
|
||||
// @ pattern match disassembles/"unfolds" the datavtype's view, so you can
|
||||
// modify its components
|
||||
| @list_vt_cons(head, tail) => let
|
||||
val () = push_back (x, tail)
|
||||
// reassemble it with fold@
|
||||
prval () = fold@ l
|
||||
in () end
|
||||
|
||||
fun {a:vt@ype} pop_last {n:pos} (l: &list_vt(a,n) >> list_vt(a,n-1)): a =
|
||||
let
|
||||
val+ @list_vt_cons(head, tail) = l
|
||||
in case tail of
|
||||
| list_vt_cons _ => let
|
||||
val res = pop_last tail
|
||||
prval () = fold@ l
|
||||
in res end
|
||||
| ~list_vt_nil() => let
|
||||
val head = head
|
||||
// Deallocate empty datavtype nodes with free@
|
||||
val () = free@{..}{0} l
|
||||
val () = l := list_vt_nil()
|
||||
in head end
|
||||
/** Equivalently:
|
||||
* | ~list_vt_nil() => let
|
||||
* prval () = fold@ l
|
||||
* val+ ~list_vt_cons(head, ~list_vt_nil()) = l
|
||||
* val () = l := list_vt_nil()
|
||||
* in head end
|
||||
*/
|
||||
end
|
||||
|
||||
// "holes" (ie uninitialized memory) can be created with _ on the RHS
|
||||
// This function uses destination-passing-style to copy the list in a single
|
||||
// tail-recursive pass.
|
||||
fn {a:t@ype} copy_list {n:nat} (l: !list_vt(a, n)): list_vt(a, n) =
|
||||
let
|
||||
var res: ptr
|
||||
fun loop {k:nat} (l: !list_vt(a, k), hole: &ptr? >> list_vt(a, k)): void =
|
||||
case l of
|
||||
| list_vt_nil() => hole := list_vt_nil
|
||||
| list_vt_cons(first, rest) => let
|
||||
val () = hole := list_vt_cons{..}{k-1}(first, _)
|
||||
// ^ on RHS: a hole
|
||||
val+list_vt_cons(_, new_hole) = hole
|
||||
// ^ on LHS: wildcard pattern (not a hole)
|
||||
val () = loop (rest, new_hole)
|
||||
prval () = fold@ hole
|
||||
in () end
|
||||
val () = loop (l, res)
|
||||
in res end
|
||||
|
||||
// Reverse a linked-list *in place* -- no allocations or frees
|
||||
fn {a:vt@ype} in_place_reverse {n:nat} (l: list_vt(a, n)): list_vt(a, n) =
|
||||
let
|
||||
fun loop {k:nat} (l: list_vt(a, n-k), acc: list_vt(a, k)): list_vt(a, n) =
|
||||
case l of
|
||||
| ~list_vt_nil() => acc
|
||||
| @list_vt_cons(x, tail) => let
|
||||
val rest = replace(tail, acc)
|
||||
// the node 'l' is now part of acc instead of the original list
|
||||
prval () = fold@ l
|
||||
in loop (rest, l) end
|
||||
in loop (l, list_vt_nil) end
|
||||
|
||||
|
||||
/*************** Part 6: miscellaneous extras ****************/
|
||||
|
||||
// a record
|
||||
// Point has type 't@ype'
|
||||
typedef Point = @{ x= int, y= int }
|
||||
val origin: Point = @{ x= 0, y= 0 }
|
||||
|
||||
// tuples and records are normally unboxed, but there are boxed variants
|
||||
// BoxedPoint has type 'type'
|
||||
typedef BoxedPoint = '{ x= int, y= int }
|
||||
val boxed_pair: '(int,int) = '(5, 3)
|
||||
|
||||
// When passing a pair as the single argument to a function, it needs to be
|
||||
// written @(a,b) to avoid ambiguity with multi-argument functions
|
||||
val six_plus_seven = let
|
||||
fun sum_of_pair (pair: (int,int)) = pair.0 + pair.1
|
||||
in sum_of_pair @(6, 7) end
|
||||
|
||||
// When a constructor has no associated data, such as None(), the parentheses
|
||||
// are optional in expressions. However, they are mandatory in patterns
|
||||
fn inc_option (opt: Option int) =
|
||||
case opt of
|
||||
| Some(x) => Some(x+1)
|
||||
| None() => None
|
||||
|
||||
// ATS has a simple FFI, since it compiles to C and (mostly) uses the C ABI
|
||||
%{
|
||||
// Inline C code
|
||||
int scanf_wrapper(void *format, void *value) {
|
||||
return scanf((char *) format, (int *) value);
|
||||
}
|
||||
%}
|
||||
// If you wanted to, you could define a custom dataviewtype more accurately
|
||||
// describing the result of scanf
|
||||
extern fn scanf (format: string, value: &int): int = "scanf_wrapper"
|
||||
|
||||
fn get_input_number (): Option int =
|
||||
let
|
||||
var x: int = 0
|
||||
in
|
||||
if scanf("%d\n", x) = 1
|
||||
then Some(x)
|
||||
else None
|
||||
end
|
||||
|
||||
// extern is also used for separate declarations and definitions
|
||||
extern fn say_hi (): void
|
||||
// later on, or in another file:
|
||||
implement say_hi () = print "hi\n"
|
||||
|
||||
// if you implement main0, it will run as the main function
|
||||
// implmnt is an alias for implement
|
||||
implmnt main0 () = ()
|
||||
|
||||
// as well as for axioms:
|
||||
extern praxi view_id {a:view} (x: a): a
|
||||
// you don't need to actually implement the axioms, but you could
|
||||
primplmnt view_id x = x
|
||||
// primplmnt is an alias for primplement
|
||||
|
||||
// Some standard aliases are:
|
||||
// List0(a) = [n:nat] list(a,n) and List0_vt(a) = [n:nat] list_vt(a,n)
|
||||
// t0p = t@ype and vt0p = vt@ype
|
||||
fun {a:t0p} append (xs: List0 a, ys: List0 a): List0 a =
|
||||
case xs of
|
||||
| list_nil() => ys
|
||||
| list_cons(x, xs) => list_cons(x, append(xs, ys))
|
||||
|
||||
// there are many ways of doing things after one another
|
||||
val let_in_example = let
|
||||
val () = print "thing one\n"
|
||||
val () = print "thing two\n"
|
||||
in () end
|
||||
|
||||
val parens_example = (print "thing one\n"; print "thing two\n")
|
||||
|
||||
val begin_end_example = begin
|
||||
print "thing one\n";
|
||||
print "thing two\n"; // optional trailing semicolon
|
||||
end
|
||||
|
||||
// and many ways to use local variables
|
||||
fun times_four_let x =
|
||||
let
|
||||
fun times_two (x: int) = x * 2
|
||||
in times_two (times_two x) end
|
||||
|
||||
local
|
||||
fun times_two (x: int) = x * 2
|
||||
in
|
||||
fun times_four_local x = times_two (times_two x)
|
||||
end
|
||||
|
||||
fun times_four_where x = times_two (times_two x)
|
||||
where {
|
||||
fun times_two (x: int) = x * 2
|
||||
}
|
||||
|
||||
//// The last kind of comment in ATS is an end-of-file comment.
|
||||
|
||||
Anything between the four slashes and the end of the file is ignored.
|
||||
|
||||
Have fun with ATS!
|
||||
```
|
||||
|
||||
## Learn more
|
||||
|
||||
This isn't all there is to ATS -- notably, some core features like closures and
|
||||
the effect system are left out, as well as other less type-y stuff like modules
|
||||
and the build system. If you'd like to write these sections yourself,
|
||||
contributions would be welcome!
|
||||
|
||||
To learn more about ATS, visit the [ATS website](http://www.ats-lang.org/), in
|
||||
particular the [documentation page](http://www.ats-lang.org/Documents.html).
|
||||
|
416
ada.html.markdown
Normal file
416
ada.html.markdown
Normal file
@ -0,0 +1,416 @@
|
||||
---
|
||||
language: Ada
|
||||
filename: learn.ada
|
||||
contributors:
|
||||
- ["Luke A. Guest", "https://github.com/Lucretia"]
|
||||
- ["Fernando Oleo Blanco", "https://github.com/Irvise"]
|
||||
- ["Fabien Chouteau", "https://github.com/Fabien-Chouteau"]
|
||||
- ["Manuel", "https://github.com/mgrojo"]
|
||||
---
|
||||
|
||||
Ada is a strong statically typed imperative, [object-oriented](https://ada-lang.io/docs/arm/AA-3/AA-3.9), [real-time](https://ada-lang.io/docs/arm/AA-D), [parallel](https://ada-lang.io/docs/arm/AA-9) and [distributed](https://ada-lang.io/docs/arm/AA-9) programming language from the Pascal/Algol family of languages, but nowadays, it only has a passing resemblance to Pascal, with the only remnants left being the ```begin/end``` keyword pair, the ```:=``` assignment symbol, records and ```if/case``` control statement structures.
|
||||
|
||||
Ada was originally designed to be an [object-based](https://ada-lang.io/docs/arm/AA-3/AA-3.3) language and to replace 100's of languages in use by the US government. This means that all entities are objects, not in the object-oriented sense. The language became [Object-Oriented](https://ada-lang.io/docs/arm/AA-3/AA-3.9) in 1995, and added [interfaces](https://ada-lang.io/docs/arm/AA-3/AA-3.9#Subclause_3.9.4) derived from Java in 2005. [Contract based](https://ada-lang.io/docs/arm/AA-13/AA-13.1#Subclause_13.1.1) programming was introduced with Ada 2012.
|
||||
|
||||
Ada was designed to be easy to read and learn, even for non-programmers, e.g. management within an organisation, therefore programs written in the language tend to be a bit more verbose.
|
||||
|
||||
Ada is a modern programming language, and now has a package manager like other modern languages, Alire, see below.
|
||||
|
||||
```ada
|
||||
-- Comments are written with a double hyphen and exist until the end of
|
||||
-- the line.
|
||||
|
||||
-- You do not need to call the entry point "Main" or "main," you should
|
||||
-- name it based on what the program does.
|
||||
procedure Empty is
|
||||
-- This is a declarative part.
|
||||
begin
|
||||
-- Statements go here.
|
||||
null; -- Do nothing here.
|
||||
end Empty;
|
||||
|
||||
-- Ada compilers accept compilation units which can be library packages,
|
||||
-- tasks, sub-programs, generics, etc.
|
||||
|
||||
-- This is where "context clauses" go, these can be pragmas or "with"
|
||||
-- statements. "with" is equivalent to "include" or "import" in other
|
||||
-- languages.
|
||||
with Ada.Text_IO; -- Get access to a library package.
|
||||
|
||||
procedure Hello is
|
||||
begin
|
||||
Ada.Text_IO.Put_Line ("Hello, world");
|
||||
|
||||
Ada.Text_IO.Put ("Hello again, world");
|
||||
Ada.Text_IO.New_Line;
|
||||
end Hello;
|
||||
|
||||
|
||||
-- Ada has a real module system. Modules are called packages and are split into
|
||||
-- two component parts, the specification and a body.
|
||||
-- It is important to introduce packages early, as you will be using them from
|
||||
-- the start.
|
||||
package Stuff is
|
||||
-- We could add the following line in order to tell the compiler that this
|
||||
-- package does not have to run any code before the "main" procedure starts.
|
||||
-- pragma Preelaborate;
|
||||
|
||||
-- Packages can be nested within the same file or externally.
|
||||
-- Nested packages are accessed via dot notation, e.g. Stuff.Things.My.
|
||||
package Things is
|
||||
My : constant Integer := 100;
|
||||
end Things;
|
||||
|
||||
-- If there are sub-programs declared within the specification, the body
|
||||
-- of the sub-program must be declared within the package body.
|
||||
procedure Do_Something; -- If a subprogram takes no parameters, empty
|
||||
-- parentheses are not required, unlike other
|
||||
-- languages.
|
||||
|
||||
-- We can also make generic sub-programs.
|
||||
generic
|
||||
type Element is (<>); -- The "(<>)" notation specifies that only
|
||||
-- discrete types can be passed into the generic.
|
||||
procedure Swap (Left, Right : in out Element);
|
||||
|
||||
-- Sometimes we want to hide how a type is defined from the outside world
|
||||
-- so that nobody can mess with it directly. The full type must be defined
|
||||
-- within the private section below.
|
||||
type Blobs is private;
|
||||
|
||||
-- We can also make types "limited" by putting this keyword after the "is"
|
||||
-- keyword, this means that the user cannot copy objects of that type
|
||||
-- around, like they normally could.
|
||||
private
|
||||
type Blobs is new Integer range -25 .. 25;
|
||||
end Stuff;
|
||||
|
||||
|
||||
package body Stuff is
|
||||
-- Sub-program body.
|
||||
procedure Do_Something is
|
||||
-- We can nest sub-programs too.
|
||||
-- Parameters are defined with the direction of travel, in, in out, out.
|
||||
-- If the direction of travel is not specified, they are in by default.
|
||||
function Times_4 (Value : in Integer) return Integer is
|
||||
begin
|
||||
return Value * 4;
|
||||
end Times_4;
|
||||
|
||||
I : Integer := 4;
|
||||
begin
|
||||
I := Times_4 (I);
|
||||
end Do_Something;
|
||||
|
||||
|
||||
-- Generic procedure body.
|
||||
procedure Swap (Left, Right : in out Element) is
|
||||
Temp : Element := Left;
|
||||
begin
|
||||
Left := Right;
|
||||
Right := Temp;
|
||||
end Swap;
|
||||
begin
|
||||
-- If we need to initialise something within the package, we can do it
|
||||
-- here.
|
||||
Do_Something;
|
||||
end Stuff;
|
||||
|
||||
|
||||
with Ada.Unchecked_Conversion;
|
||||
with Ada.Text_IO;
|
||||
with Stuff;
|
||||
|
||||
procedure LearnAdaInY is
|
||||
-- Indentation is 3 spaces.
|
||||
|
||||
-- The most important feature in Ada is the type. Objects have types and an
|
||||
-- object of one type cannot be assigned to an object of another type.
|
||||
|
||||
-- You can, and should, define your own types for the domain you are
|
||||
-- modelling. But you can use the standard types to start with and then
|
||||
-- replace them later with your own types, this could be called a form of
|
||||
-- gradual typing.
|
||||
|
||||
-- The standard types would only really be a good starting point for binding
|
||||
-- to other languages, like C. Ada is the only language with a standardised
|
||||
-- way to bind with C, Fortran and COBOL! See the links in the References
|
||||
-- section with more information on binding to these languages.
|
||||
|
||||
type Degrees is range 0 .. 360; -- This is a type. Its underlying
|
||||
-- representation is an Integer.
|
||||
|
||||
type Hues is (Red, Green, Blue, Purple, Yellow); -- So is this. Here, we
|
||||
-- are declaring an
|
||||
-- Enumeration.
|
||||
|
||||
-- This is a modular type. They behave like Integers that automatically
|
||||
-- wrap around. In this specific case, the range would be 0 .. 359.
|
||||
-- If we added 1 to a variable containing the value 359, we would receive
|
||||
-- back 0. They are very useful for arrays.
|
||||
type Degrees_Wrap is mod 360;
|
||||
|
||||
-- You can restrict a type's range using a subtype, this makes them
|
||||
-- compatible with each other, i.e. the subtype can be assigned to an
|
||||
-- object of the type, as can be seen below.
|
||||
subtype Primaries is Hues range Red .. Blue; -- This is a range.
|
||||
|
||||
-- You can define variables or constants like this:
|
||||
-- Var_Name : Type := Value;
|
||||
|
||||
-- 10 is a universal integer. These universal numerics can be used with
|
||||
-- any type which matches the base type.
|
||||
Angle : Degrees := 10;
|
||||
Value : Integer := 20;
|
||||
-- New_Angle : Degrees := Value; -- Incompatible types won't compile.
|
||||
-- New_Value : Integer := Angle;
|
||||
|
||||
Blue_Hue : Primaries := Blue; -- A variable.
|
||||
Red_Hue : constant Primaries := Red; -- A constant.
|
||||
Yellow_Hue : constant Hues := Yellow;
|
||||
Colour_1 : constant Hues := Red_Hue;
|
||||
-- Colour_2 : constant Primaries := Yellow_Hue; -- uncomment to compile.
|
||||
|
||||
-- You can force conversions, but then you are warned by the name of the
|
||||
-- package that you may be doing something unsafe.
|
||||
function Degrees_To_Int is new Ada.Unchecked_Conversion
|
||||
(Source => Degrees, -- Line continuations are indented by 2 spaces.
|
||||
Target => Integer);
|
||||
|
||||
New_Value_2 : Integer := Degrees_To_Int (Angle); -- Note, space before (.
|
||||
|
||||
-- GNAT is the GNU Ada Translator (compiler).
|
||||
-- Ada has a style guide and GNAT will warn you to adhere to it, and has
|
||||
-- option to check your style so that you can correct it so that all Ada
|
||||
-- source looks consistent. However, the style can be customized.
|
||||
|
||||
-- Yes, you can even define your own floating and fixed point types, this
|
||||
-- is a very rare and unique ability. "digits" refers to the minimum
|
||||
-- digit precision that the type should support. "delta" is for fixed
|
||||
-- point types and refers to the smallest change that the type will support.
|
||||
type Real_Angles is digits 3 range 0.0 .. 360.0;
|
||||
type Fixed_Angles is delta 0.01 digits 5 range 0.0 .. 360.0;
|
||||
|
||||
RA : constant Real_Angles := 36.45;
|
||||
FA : constant Fixed_Angles := 360.0; -- ".0" in order to make it a Float.
|
||||
|
||||
-- You can have normal Latin 1 based strings by default.
|
||||
Str : constant String := "This is a constant string";
|
||||
-- When initialising from a string literal, the compiler knows the bounds,
|
||||
-- so we don't have to define them.
|
||||
|
||||
-- Strings are arrays. Note how parentheses are used to access elements of
|
||||
-- an array? This is mathematical notation and was used because square
|
||||
-- brackets were not available on all keyboards at the time Ada was
|
||||
-- created. Also, because an array can be seen as a function from a
|
||||
-- mathematical perspective, so it made converting between arrays and
|
||||
-- functions easier.
|
||||
Char : constant Character := Str (Str'First); -- "'First" is a type
|
||||
-- attribute.
|
||||
|
||||
-- Ada 2022 includes the use of [] for array initialisation when using
|
||||
-- containers, which were added in Ada 2012.
|
||||
|
||||
-- Arrays are usually always defined as a type.
|
||||
-- They can be any dimension.
|
||||
type My_Array_1 is array (1 .. 4, 3 .. 7, -20 .. 20) of Integer;
|
||||
|
||||
-- Yes, unlike other languages, you can index arrays with other discrete
|
||||
-- types such as enumerations and modular types or arbitrary ranges.
|
||||
type Axes is (X, Y, Z);
|
||||
|
||||
-- You can define the array's range using the 'Range attribute from
|
||||
-- another type.
|
||||
type Vector is array (Axes'Range) of Float;
|
||||
|
||||
V1 : constant Vector := (0.0, 0.0, 1.0);
|
||||
|
||||
-- A record is the same as a structure in C, C++.
|
||||
type Entities is record
|
||||
Name : String (1 .. 10); -- Always starts at a positive value,
|
||||
-- inclusive range.
|
||||
Position : Vector;
|
||||
end record;
|
||||
|
||||
-- In Ada, array bounds are immutable. You therefore have to provide a
|
||||
-- string literal with a value for every character.
|
||||
E1 : constant Entities := ("Blob ", (0.0, 0.0, 0.0));
|
||||
|
||||
-- An alternative is to use an array aggregate and assign a default value
|
||||
-- to every element that wasn't previously assigned in this aggregate.
|
||||
-- "others" is used to indicate anything else that has not been
|
||||
-- explicitly initialized.
|
||||
E2 : constant Entities := (('B', 'l', 'o', 'b', others => ' '),
|
||||
(0.0, 0.0, 0.0));
|
||||
|
||||
-- There are dynamic length strings (see references section) available in
|
||||
-- the standard library.
|
||||
|
||||
-- We can make an object be initialised to its default values with the box
|
||||
-- notation, "<>". "others" is used to indicate anything else that has not
|
||||
-- been explicitly initialized.
|
||||
Null_Entity : constant Entities := (others => <>);
|
||||
|
||||
-- Object-orientation is accomplished via an extension of record syntax,
|
||||
-- tagged records, see link above in first paragraph.
|
||||
|
||||
-- We can rename objects (aliases) to make readability a bit better.
|
||||
package IO renames Ada.Text_IO;
|
||||
begin
|
||||
-- We can output enumerations as names.
|
||||
IO.Put_Line ("Blue_Hue = " & -- & is the string concatenation operator.
|
||||
Blue'Image); -- ' accesses attributes on objects.
|
||||
-- The Image attribute converts a value to a string.
|
||||
-- Ada 2022 has extended Image to custom types too.
|
||||
-- Access this with -gnat2022 compiler flag.
|
||||
IO.Put_Line ("Yellow_Hue = " &
|
||||
-- We can use the type's attribute.
|
||||
Primaries'Image (Yellow_Hue));
|
||||
|
||||
-- We can define local variables within a declare block, this can be made
|
||||
-- more readable by giving it a label.
|
||||
Enum_IO : declare
|
||||
package Hue_IO is new IO.Enumeration_IO (Hues);
|
||||
|
||||
-- Using a package makes everything inside that package visible within
|
||||
-- this block, it is good practice to only do this locally and not on
|
||||
-- a whole package within the context clause.
|
||||
use Hue_IO;
|
||||
begin
|
||||
-- We can print out the enumeration values too.
|
||||
Put (Purple); -- Note we don't have to prefix the Put procedure with
|
||||
-- Hue_IO.
|
||||
IO.New_Line; -- We still need to prefix with IO here.
|
||||
Put (Red_Hue);
|
||||
IO.New_Line;
|
||||
end Enum_IO;
|
||||
|
||||
-- Loops have a consistent form. "<form> loop ... end loop".
|
||||
-- Where "form" can be "while" or "for" or missing as below, if
|
||||
-- you place the "loop ... end loop;" construct on their own lines,
|
||||
-- you can comment out or experiment with different loop constructs more
|
||||
-- easily.
|
||||
declare
|
||||
Counter : Positive := Positive'First; -- This is 1.
|
||||
begin
|
||||
-- We can label loops so we can exit from them more easily if we need to.
|
||||
Infinite :
|
||||
loop
|
||||
IO.Put_Line ("[Infinite loop] Counter = " & Counter'Image);
|
||||
|
||||
Counter := Counter + 1;
|
||||
|
||||
-- This next line implements a repeat ... until or do ... while loop construct.
|
||||
-- Comment it out for an infinite loop.
|
||||
exit Infinite when Counter = 5; -- Equality tests use a single "=".
|
||||
end loop Infinite; -- Useful when implementing state machines.
|
||||
end;
|
||||
|
||||
declare -- We don't have to have a label.
|
||||
Counter : Positive := Positive'First; -- This is 1.
|
||||
begin
|
||||
while Counter < 10
|
||||
loop
|
||||
IO.Put_Line ("Counter = " & Counter'Image);
|
||||
|
||||
Counter := Counter + 1; -- There is no explicit inc/decrement.
|
||||
|
||||
-- Ada 2022 introduced @ for LHS, so the above would be written as
|
||||
-- Counter := @ + 1; -- Try it, -gnat2022.
|
||||
end loop;
|
||||
end;
|
||||
|
||||
declare
|
||||
package Hue_IO is new IO.Enumeration_IO (Hues);
|
||||
|
||||
-- We can have multiple packages on one line, but I tend to use one
|
||||
-- package per line for readability.
|
||||
use IO, Hue_IO;
|
||||
begin
|
||||
Put ("Hues : "); -- Note, no prefix.
|
||||
|
||||
-- Because we are using the 'Range attribute, the compiler knows it is
|
||||
-- safe and can omit run-time checks here.
|
||||
for Hue in Hues'Range
|
||||
loop
|
||||
Put (Hue);
|
||||
|
||||
-- Types and objects know about their bounds, their First .. Last
|
||||
-- values. These can be specified as range types.
|
||||
if Hue /= Hues'Last then -- The /= means "not equal to" like the
|
||||
-- maths symbol ≠.
|
||||
Put (", ");
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
IO.New_Line;
|
||||
end;
|
||||
|
||||
-- All objects know their bounds, including strings.
|
||||
declare
|
||||
C : Character := Str (50); -- Warning caused and exception raised at
|
||||
-- runtime.
|
||||
-- The exception raised above can only be handled by an outer scope,
|
||||
-- see wikibook link below.
|
||||
begin
|
||||
null; -- We will never get to this point because of the above.
|
||||
end;
|
||||
exception
|
||||
when Constraint_Error =>
|
||||
IO.Put_Line ("Caught the exception");
|
||||
end LearnAdaInY;
|
||||
```
|
||||
|
||||
Now, that's a lot of information for a basic intro to Ada, and I've only touched the surface, there's much more to look at in the references section below. I haven't even touched on dynamic memory allocation which includes [pools](https://ada-lang.io/docs/arm/AA-13/AA-13.11), this is because for the most part, Ada programs don't need it, you can do a lot without it.
|
||||
|
||||
As I stated above, Ada barely looks like Pascal and if you look at the original [Green specification](https://apps.dtic.mil/sti/trecms/pdf/ADB950587.pdf) (Warning: Huge 4575 page scanned PDF - starting on page 460), it looks nothing like it at all (page 505 of that PDF).
|
||||
|
||||
The above source code will compile, but also will give warnings showing the power of the strong static type system.
|
||||
|
||||
## Download this source
|
||||
|
||||
If you already have the GNAT toolchain installed, you can cut and paste the above into a new file, e.g. ```learn-ada-in-y.ada``` and then run the following:
|
||||
|
||||
```bash
|
||||
$ gnatchop learn-ada-in-y.ada # This breaks the program into its specification ".ads" and body ".adb".
|
||||
$ gnatmake empty.adb # gnatmake takes care of compilation of all units and linking.
|
||||
$ gnatmake hello.adb
|
||||
$ gnatmake learnadainy.adb
|
||||
```
|
||||
|
||||
Or, download [Alire](https://alire.ada.dev), copy it to somewhere in your PATH and then do the following:
|
||||
|
||||
**N.B.** Alire will automatically install the toolchain for you if you don't have one installed and will ask you to select which you want to use.
|
||||
|
||||
```bash
|
||||
$ alr search learnadainy
|
||||
$ alr get learnadainy
|
||||
$ cd learnadainy
|
||||
$ alr run empty
|
||||
$ alr run hello
|
||||
$ alr run learnadainy
|
||||
```
|
||||
|
||||
## Further Reading
|
||||
|
||||
* [Ada Programming Language](https://ada-lang.io)
|
||||
* [Ada 2022 Reference Manual](https://ada-lang.io/docs/arm)
|
||||
* [Ada Style Guide](https://ada-lang.io/docs/style-guide/Ada_Style_Guide)
|
||||
* [Learn more Ada/Spark at AdaCore's site](https://learn.adacore.com)
|
||||
|
||||
## References from the source above
|
||||
|
||||
1. [wikibook](https://en.wikibooks.org/wiki/Ada_Programming/Exceptions#Exception_handlers)
|
||||
2. [C](https://ada-lang.io/docs/arm/AA-B/AA-B.3)
|
||||
3. [Fortran](https://ada-lang.io/docs/arm/AA-B/AA-B.5/)
|
||||
4. [COBOL](https://ada-lang.io/docs/arm/AA-B/AA-B.4/)
|
||||
5. [dynamic length strings](https://ada-lang.io/docs/arm/AA-A/AA-A.4#Subclause_A.4.5)
|
||||
|
||||
### Multi-line comments
|
||||
|
||||
Multi-line comments are not allowed as they are error prone.
|
||||
|
||||
> Such comments would require a closing comment delimiter and this would again raise the dangers associated with the (unintentional) omission of the closing delimiter: entire sections of a program could be ignored by the compiler without the programmer realizing it
|
||||
>
|
||||
> [Ada 83 Rationale](http://archive.adaic.com/standards/83rat/html/ratl-02-01.html#2.1)
|
||||
|
135
ar-ar/sql-ar.html.markdown
Normal file
135
ar-ar/sql-ar.html.markdown
Normal file
@ -0,0 +1,135 @@
|
||||
---
|
||||
language: SQL
|
||||
filename: learnsql-ar.sql
|
||||
contributors:
|
||||
- ["Bob DuCharme", "http://bobdc.com/"]
|
||||
translators:
|
||||
- ["Ahmed Omar Eissa", "https://twitter.com/AhmedOmarEissa"]
|
||||
lang: ar-ar
|
||||
---
|
||||
<div dir="rtl">
|
||||
|
||||
لغة الاستعلام الهيكلية
|
||||
(SQL)
|
||||
هي لغة قياسية
|
||||
[ISO/IEC 9075](https://www.iso.org/standard/63555.html)
|
||||
لإنشاء قواعد البيانات المخزنة في مجموعة من الجداول التعامل معها. عادةً ما تضيف التطبيقات
|
||||
امتدادات خاصة بها إلى اللغة ؛ تعد
|
||||
[مقارنة نسخ SQL المختلفة](http://troels.arvin.dk/db/rdbms/)
|
||||
مرجعًا جيدًا لاختلافات النسخ.
|
||||
|
||||
توفر النسخ عادةً موجه سطر أوامر
|
||||
command line prompt
|
||||
حيث يمكنك إدخال الأوامر المعروضة هنا بشكل تفاعلي، كما أنها توفر طريقة لتنفيذ سلسلة من هذه الأوامر المخزنة في ملف نصي. إظهار رسالة الانتهاء من العمل مع الموجه التفاعلي مثال جيد على امكانية اضافة أوامر غير قياسية، معظم النسخ تدعم أحد أوامر
|
||||
QUIT , EXIT
|
||||
.أو كليهما
|
||||
|
||||
في الامثلة بالأسفل تعتمدالعديد من الأوامرأن قاعدة بيانات الموظفين
|
||||
[MySQL employee sample database](https://dev.mysql.com/doc/employee/en/)
|
||||
الموجودة على
|
||||
[github](https://github.com/datacharmer/test_db)
|
||||
قد تم تحميلها مسبقا. الملفات على
|
||||
github
|
||||
هي مجموعة من الاوامر تشبه الموجودة بالاسفل و تقوم الأوامر بإنشاء الجدوال وإدخال بيانات مجموعة من الموظفين المتخيلين في شركة. تعتمد الأوامر المستخدمة في هذا البرنامج على نسخة
|
||||
SQL
|
||||
التي تستخدمها،
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
```sql
|
||||
-- تبدأ التعليقات بشرطتين. قم بإنهاء كل أمر بفاصلة منقوطة
|
||||
|
||||
-- حساسة لحالة الاحرف SQL لا تعتبر
|
||||
-- فقط ليسهل تمييزها عن أسماه الأعمدة والجداول وقواعد البيانات UPPER-CASE الاوامر الموجودة هنا تستخدم الحالة العليا للاحرف
|
||||
|
||||
-- إنشاء ومسح قاعدة بيانات، أسماء قواعد البيانات والجداول حساسة لحالة الأحرف
|
||||
CREATE DATABASE someDatabase;
|
||||
DROP DATABASE someDatabase;
|
||||
|
||||
-- عرض قواعد البيانات الموجودة
|
||||
SHOW DATABASES;
|
||||
|
||||
--استخدام قاعدة بيانات محددة
|
||||
USE employees;
|
||||
|
||||
-- في قاعدة البيانات المستخدمة departments ارجاع كل السطور والاعمدة في جدول
|
||||
-- ستظهر النتائج على الشاشة بشكل تلقائي لتتصفحها.
|
||||
SELECT * FROM departments;
|
||||
|
||||
-- فقط dept_name و dept_no لكن سنسترجع عمودي departments استرجاع كل أسطر من جدول
|
||||
-- لا مانع من تقسيم الاوامر بين السطور
|
||||
|
||||
SELECT dept_no,
|
||||
dept_name FROM departments;
|
||||
|
||||
-- لكن هذه المرة سنسترجع ٥ أسطر فقط departments استرجاع كل الاعمدة من جدول
|
||||
SELECT * FROM departments LIMIT 5;
|
||||
|
||||
--en يحتوي علي dept_name في حالة أن عمود departments من جدول dept_name استرجاع عمود
|
||||
|
||||
SELECT dept_name FROM departments WHERE dept_name LIKE '%en%';
|
||||
|
||||
-- S استرجاع كل أعمدة جدول الاقسام في حالة أن اسم القسم يبدأ بحرف
|
||||
-- متبوعا بأربعة حروف
|
||||
|
||||
SELECT * FROM departments WHERE dept_name LIKE 'S____';
|
||||
|
||||
-- استرجاع قيم العناوين من جدول العناوين بدون تكرار
|
||||
SELECT DISTINCT title FROM titles;
|
||||
|
||||
-- نفس المثال السابق مع ترتيب العناوين أبجديا
|
||||
SELECT DISTINCT title FROM titles ORDER BY title;
|
||||
|
||||
-- اظهار عدد السطور في جدول الأقسام
|
||||
SELECT COUNT(*) FROM departments;
|
||||
|
||||
|
||||
-- en اظهار عدد السطور في جدول الأقسام التي تحتوي في عمود اسم القسم علي
|
||||
SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%';
|
||||
|
||||
|
||||
-- ربط المعلومات بين الجداول، جدول العناوين يظهر رقم كل موظف ومسماه الوظيفي
|
||||
-- ومتي حصل على هذا المسمى وإلي متى ولكن بدلا من اظهار رقم الموظف سنستخدم هذا الرقم
|
||||
-- للحصول على اسم الموظف الاول والأخير من جدول الموظفين مع إظهار ١٠ سطور فقط
|
||||
SELECT employees.first_name, employees.last_name,
|
||||
titles.title, titles.from_date, titles.to_date
|
||||
FROM titles INNER JOIN employees ON
|
||||
employees.emp_no = titles.emp_no LIMIT 10;
|
||||
|
||||
-- إظهار كل الجدوال في كل قواعد البيانات
|
||||
-- النسخ المختلفة تقدم اختصارات لمثل هذا الأمر لقاعدة البيانات المستخدمة
|
||||
|
||||
SELECT * FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_TYPE='BASE TABLE';
|
||||
|
||||
-- يحتوى على عمودان في قاعدة البيانات المستخدمة tablename1 أنشاء جدول يسمى
|
||||
-- يوجد العديد من الطرق لتعريف الاعمدة وأنواع البيانات في العمود
|
||||
CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20));
|
||||
|
||||
-- هذا بافتراض ان الجدول يمكن اضافة الاسطر له .tablename1 اضافة سطر في جدول
|
||||
INSERT INTO tablename1 VALUES('Richard','Mutt');
|
||||
|
||||
--John إلى fname سنغير قيمة عمود tablename1 في
|
||||
-- Mutt هي lname في حالة أن قيمة العمود
|
||||
UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
|
||||
|
||||
|
||||
-- 'M' تبدأ ب lname في حالة أن قيمة عمود tablename1 مسح السطور من جدول
|
||||
DELETE FROM tablename1 WHERE lname like 'M%';
|
||||
|
||||
-- مع ترك الجدول فارغ tablename1 مسح جميع السطور من جدول
|
||||
DELETE FROM tablename1;
|
||||
|
||||
-- تماما tablename1 إزالة جدول
|
||||
DROP TABLE tablename1;
|
||||
```
|
||||
<div dir="rtl">
|
||||
|
||||
## اقرأ أكثر
|
||||
|
||||
* [Codecademy - SQL](https://www.codecademy.com/learn/learn-sql)مقدمة جيدة للتعلم عن طريق التطبيق.
|
||||
* [Database System Concepts](https://www.db-book.com) الفصل رقم ٣ من الكتاب مقدمة في (SQL) تحتوى علي شرح مفصل لمفاهيم (SQL)
|
||||
|
||||
</div>
|
432
arturo.html.markdown
Normal file
432
arturo.html.markdown
Normal file
@ -0,0 +1,432 @@
|
||||
---
|
||||
language: arturo
|
||||
filename: learnarturo.art
|
||||
contributors:
|
||||
- ["Dr.Kameleon", "https://github.com/drkameleon"]
|
||||
---
|
||||
|
||||
```red
|
||||
; this is a comment
|
||||
; this is another comment
|
||||
|
||||
;---------------------------------
|
||||
; VARIABLES & VALUES
|
||||
;---------------------------------
|
||||
|
||||
; numbers
|
||||
a1: 2
|
||||
a2: 3.14
|
||||
a3: to :complex [1 2.0] ; 1.0+2.0i
|
||||
|
||||
; strings
|
||||
c1: "this is a string"
|
||||
c2: {
|
||||
this is a multiline string
|
||||
that is indentation-agnostic
|
||||
}
|
||||
c3: {:
|
||||
this is
|
||||
a verbatim
|
||||
multiline string
|
||||
which will remain exactly
|
||||
as the original
|
||||
:}
|
||||
|
||||
; characters
|
||||
ch: `c`
|
||||
|
||||
; blocks/arrays
|
||||
d: [1 2 3]
|
||||
|
||||
; dictionaries
|
||||
e: #[
|
||||
name: "John"
|
||||
surname: "Doe"
|
||||
age: 34
|
||||
likes: [pizza spaghetti]
|
||||
]
|
||||
|
||||
; yes, functions are values too
|
||||
f: function [x][
|
||||
2 * x
|
||||
]
|
||||
|
||||
; dates
|
||||
g: now ; 2021-05-03T17:10:48+02:00
|
||||
|
||||
; booleans
|
||||
h1: true
|
||||
h2: false
|
||||
|
||||
;---------------------------------
|
||||
; BASIC OPERATORS
|
||||
;---------------------------------
|
||||
|
||||
; simple arithmetic
|
||||
1 + 1 ; => 2
|
||||
8 - 1 ; => 7
|
||||
4.2 - 1.1 ; => 3.1
|
||||
10 * 2 ; => 20
|
||||
35 / 4 ; => 8
|
||||
35 // 4 ; => 8.75
|
||||
2 ^ 5 ; => 32
|
||||
5 % 3 ; => 2
|
||||
|
||||
; bitwise operators
|
||||
and 3 5 ; => 1
|
||||
or 3 5 ; => 7
|
||||
xor 3 5 ; => 6
|
||||
|
||||
; pre-defined constants
|
||||
pi ; => 3.141592653589793
|
||||
epsilon ; => 2.718281828459045
|
||||
null ; => null
|
||||
true ; => true
|
||||
false ; => false
|
||||
|
||||
;---------------------------------
|
||||
; COMPARISON OPERATORS
|
||||
;---------------------------------
|
||||
|
||||
; equality
|
||||
1 = 1 ; => true
|
||||
2 = 1 ; => false
|
||||
|
||||
; inequality
|
||||
1 <> 1 ; => false
|
||||
2 <> 1 ; => true
|
||||
|
||||
; more comparisons
|
||||
1 < 10 ; => true
|
||||
1 =< 10 ; => true
|
||||
10 =< 10 ; => true
|
||||
1 > 10 ; => false
|
||||
1 >= 10 ; => false
|
||||
11 >= 10 ; => true
|
||||
|
||||
;---------------------------------
|
||||
; CONDITIONALS
|
||||
;---------------------------------
|
||||
|
||||
; logical operators
|
||||
and? true true ; => true
|
||||
and? true false ; => false
|
||||
or? true false ; => true
|
||||
or? false false ; => false
|
||||
|
||||
and? [1=2][2<3] ; => false
|
||||
; (the second block will not be evaluated)
|
||||
|
||||
; simple if statements
|
||||
if 2 > 1 [ print "yes!"] ; yes!
|
||||
if 3 <> 2 -> print "true!" ; true!
|
||||
|
||||
; if/else statements
|
||||
if? 2 > 3 -> print "2 is greater than 3"
|
||||
else -> print "2 is not greater than 3" ; 2 is not greater than 3
|
||||
|
||||
; switch statements
|
||||
switch 2 > 3 -> print "2 is greater than 3"
|
||||
-> print "2 is not greater than 3" ; 2 is not greater than 3
|
||||
|
||||
a: (2 > 3)["yes"]["no"] ; a: "no"
|
||||
a: (2 > 3)? -> "yes" -> "no" ; a: "no" (exactly the same as above)
|
||||
|
||||
; case/when statements
|
||||
case [1]
|
||||
when? [>2] -> print "1 is greater than 2. what?!"
|
||||
when? [<0] -> print "1 is less than 0. nope..."
|
||||
else -> print "here we are!" ; here we are!
|
||||
|
||||
;---------------------------------
|
||||
; LOOPS
|
||||
;---------------------------------
|
||||
|
||||
; with `loop`
|
||||
arr: [1 4 5 3]
|
||||
loop arr 'x [
|
||||
print ["x =" x]
|
||||
]
|
||||
; x = 1
|
||||
; x = 4
|
||||
; x = 5
|
||||
; x = 3
|
||||
|
||||
; with loop and custom index
|
||||
loop.with:'i arr 'x [
|
||||
print ["item at position" i "=>" x]
|
||||
]
|
||||
; item at position 0 => 1
|
||||
; item at position 1 => 4
|
||||
; item at position 2 => 5
|
||||
; item at position 3 => 3
|
||||
|
||||
; using ranges
|
||||
loop 1..3 'x -> ; since it's a single statement
|
||||
print x ; there's no need for [block] notation
|
||||
; we can wrap it up using the `->` syntactic sugar
|
||||
|
||||
loop `a`..`c` 'ch ->
|
||||
print ch
|
||||
; a
|
||||
; b
|
||||
; c
|
||||
|
||||
; picking multiple items
|
||||
loop 1..10 [x y] ->
|
||||
print ["x =" x ", y =" y]
|
||||
; x = 1 , y = 2
|
||||
; x = 3 , y = 4
|
||||
; x = 5 , y = 6
|
||||
; x = 7 , y = 8
|
||||
; x = 9 , y = 10
|
||||
|
||||
; looping through a dictionary
|
||||
dict: #[name: "John", surname: "Doe", age: 34]
|
||||
loop dict [key value][
|
||||
print [key "->" value]
|
||||
]
|
||||
; name -> John
|
||||
; surname -> Doe
|
||||
; age -> 34
|
||||
|
||||
; while loops
|
||||
i: new 0
|
||||
while [i<3][
|
||||
print ["i =" i]
|
||||
inc 'i
|
||||
]
|
||||
; i = 0
|
||||
; i = 1
|
||||
; i = 2
|
||||
|
||||
;---------------------------------
|
||||
; STRINGS
|
||||
;---------------------------------
|
||||
|
||||
; case
|
||||
a: "tHis Is a stRinG"
|
||||
print upper a ; THIS IS A STRING
|
||||
print lower a ; this is a string
|
||||
print capitalize a ; tHis Is a stRinG
|
||||
|
||||
; concatenation
|
||||
a: "Hello " ++ "World!" ; a: "Hello World!"
|
||||
|
||||
; strings as an array
|
||||
split "hello" ; => [h e l l o]
|
||||
split.words "hello world" ; => [hello world]
|
||||
|
||||
print first "hello" ; h
|
||||
print last "hello" ; o
|
||||
|
||||
; conversion
|
||||
to :string 123 ; => "123"
|
||||
to :integer "123" ; => 123
|
||||
|
||||
; joining strings together
|
||||
join ["hello" "world"] ; => "helloworld"
|
||||
join.with:"-" ["hello" "world"] ; => "hello-world"
|
||||
|
||||
; string interpolation
|
||||
x: 2
|
||||
print ~"x = |x|" ; x = 2
|
||||
|
||||
; interpolation with `print`
|
||||
print ["x =" x] ; x = 2
|
||||
; (`print` works by calculating the given block
|
||||
; and joining the different values as strings
|
||||
; with a single space between them)
|
||||
|
||||
; templates
|
||||
print render.template {
|
||||
<||= switch x=2 [ ||>
|
||||
Yes, x = 2
|
||||
<||][||>
|
||||
No, x is not 2
|
||||
<||]||>
|
||||
} ; Yes, x = 2
|
||||
|
||||
; matching
|
||||
prefix? "hello" "he" ; => true
|
||||
suffix? "hello" "he" ; => false
|
||||
|
||||
contains? "hello" "ll" ; => true
|
||||
contains? "hello" "he" ; => true
|
||||
contains? "hello" "x" ; => false
|
||||
|
||||
in? "ll" "hello" ; => true
|
||||
in? "x" "hello" ; => false
|
||||
|
||||
;---------------------------------
|
||||
; BLOCKS
|
||||
;---------------------------------
|
||||
|
||||
; calculate a block
|
||||
arr: [1 1+1 1+1+1]
|
||||
@arr ; => [1 2 3]
|
||||
|
||||
; execute a block
|
||||
sth: [print "Hello world"] ; this is perfectly valid,
|
||||
; could contain *anything*
|
||||
; and will not be executed...
|
||||
|
||||
do sth ; Hello world
|
||||
; (...until we tell it to)
|
||||
|
||||
; array indexing
|
||||
arr: ["zero" "one" "two" "three"]
|
||||
print first arr ; zero
|
||||
print arr\0 ; zero
|
||||
print last arr ; three
|
||||
print arr\3 ; three
|
||||
|
||||
x: 2
|
||||
print get arr x ; two
|
||||
print arr \ 2 ; two
|
||||
; (using the `\` infix alias for get -
|
||||
; notice space between the operands!
|
||||
; otherwise, it'll be parsed as a path)
|
||||
|
||||
; setting an array element
|
||||
arr\0: "nada"
|
||||
set arr 2 "dos"
|
||||
print arr ; nada one dos three
|
||||
|
||||
; adding elements to an array
|
||||
arr: new []
|
||||
'arr ++ "one"
|
||||
'arr ++ "two"
|
||||
print arr ; one two
|
||||
|
||||
; remove elements from an array
|
||||
arr: new ["one" "two" "three" "four"]
|
||||
'arr -- "two" ; arr: ["one" "three" "four"]
|
||||
remove 'arr .index 0 ; arr: ["three" "four"]
|
||||
|
||||
; getting the size of an array
|
||||
arr: ["one" 2 "three" 4]
|
||||
print size arr ; 4
|
||||
|
||||
; getting a slice of an array
|
||||
print slice ["one" "two" "three" "four"] 0 1 ; one two
|
||||
|
||||
; check if array contains a specific element
|
||||
print contains? arr "one" ; true
|
||||
print contains? arr "five" ; false
|
||||
|
||||
; sorting array
|
||||
arr: [1 5 3 2 4]
|
||||
sort arr ; => [1 2 3 4 5]
|
||||
sort.descending arr ; => [5 4 3 2 1]
|
||||
|
||||
; mapping values
|
||||
map 1..10 [x][2*x] ; => [2 4 6 8 10 12 14 16 18 20]
|
||||
map 1..10 'x -> 2*x ; same as above
|
||||
map 1..10 => [2*&] ; same as above
|
||||
map 1..10 => [2*] ; same as above
|
||||
|
||||
; selecting/filtering array values
|
||||
select 1..10 [x][odd? x] ; => [1 3 5 7 9]
|
||||
select 1..10 => odd? ; same as above
|
||||
|
||||
filter 1..10 => odd? ; => [2 4 6 8 10]
|
||||
; (now, we leave out all odd numbers -
|
||||
; while select keeps them)
|
||||
|
||||
; misc operations
|
||||
arr: ["one" 2 "three" 4]
|
||||
reverse arr ; => [4 "three" 2 "one"]
|
||||
shuffle arr ; => [2 4 "three" "one"]
|
||||
unique [1 2 3 2 3 1] ; => [1 2 3]
|
||||
permutate [1 2 3] ; => [[1 2 3] [1 3 2] [3 1 2] [2 1 3] [2 3 1] [3 2 1]]
|
||||
take 1..10 3 ; => [1 2 3]
|
||||
repeat [1 2] 3 ; => [1 2 1 2 1 2]
|
||||
|
||||
;---------------------------------
|
||||
; FUNCTIONS
|
||||
;---------------------------------
|
||||
|
||||
; declaring a function
|
||||
f: function [x][ 2*x ]
|
||||
f: function [x]-> 2*x ; same as above
|
||||
f: $[x]->2*x ; same as above (only using the `$` alias
|
||||
; for the `function`... function)
|
||||
|
||||
; calling a function
|
||||
f 10 ; => 20
|
||||
|
||||
; returning a value
|
||||
g: function [x][
|
||||
if x < 2 -> return 0
|
||||
|
||||
res: 0
|
||||
loop 0..x 'z [
|
||||
res: res + z
|
||||
]
|
||||
return res
|
||||
]
|
||||
|
||||
;---------------------------------
|
||||
; CUSTOM TYPES
|
||||
;---------------------------------
|
||||
|
||||
; defining a custom type
|
||||
define :person [ ; define a new custom type "Person"
|
||||
name ; with fields: name, surname, age
|
||||
surname
|
||||
age
|
||||
][
|
||||
; with custom post-construction initializer
|
||||
init: [
|
||||
this\name: capitalize this\name
|
||||
]
|
||||
|
||||
; custom print function
|
||||
print: [
|
||||
render "NAME: |this\name|, SURNAME: |this\surname|, AGE: |this\age|"
|
||||
]
|
||||
|
||||
; custom comparison operator
|
||||
compare: 'age
|
||||
]
|
||||
|
||||
; create a method for our custom type
|
||||
sayHello: function [this][
|
||||
ensure -> is? :person this
|
||||
|
||||
print ["Hello" this\name]
|
||||
]
|
||||
|
||||
; create new objects of our custom type
|
||||
a: to :person ["John" "Doe" 34] ; let's create 2 "Person"s
|
||||
b: to :person ["jane" "Doe" 33] ; and another one
|
||||
|
||||
; call pseudo-inner method
|
||||
sayHello a ; Hello John
|
||||
sayHello b ; Hello Jane
|
||||
|
||||
; access object fields
|
||||
print ["The first person's name is:" a\name] ; The first person's name is: John
|
||||
print ["The second person's name is:" b\name] ; The second person's name is: Jane
|
||||
|
||||
; changing object fields
|
||||
a\name: "Bob"
|
||||
sayHello a ; Hello Bob
|
||||
|
||||
; verifying object type
|
||||
print type a ; :person
|
||||
print is? :person a ; true
|
||||
|
||||
; printing objects
|
||||
print a ; NAME: John, SURNAME: Doe, AGE: 34
|
||||
|
||||
; sorting user objects (using custom comparator)
|
||||
sort @[a b] ; Jane..., John...
|
||||
sort.descending @[a b] ; John..., Jane...
|
||||
```
|
||||
|
||||
## Additional resources
|
||||
|
||||
- [Official documentation](https://arturo-lang.io/documentation/) - Arturo official documentation & reference.
|
||||
- [Online playground](https://arturo-lang.io/playground/) - Online REPL for the Arturo programming language.
|
@ -3,7 +3,7 @@ language: asciidoc
|
||||
contributors:
|
||||
- ["Ryan Mavilia", "http://unoriginality.rocks/"]
|
||||
- ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
|
||||
filename: asciidoc.md
|
||||
filename: asciidoc.adoc
|
||||
---
|
||||
|
||||
AsciiDoc is a markup language similar to Markdown and it can be used for anything from books to blogs. Created in 2002 by Stuart Rackham the language is simple but it allows for a great amount of customization.
|
||||
|
202
assemblyscript.html.markdown
Normal file
202
assemblyscript.html.markdown
Normal file
@ -0,0 +1,202 @@
|
||||
---
|
||||
language: Assemblyscript
|
||||
contributors:
|
||||
- ["Philippe Vlérick", "https://github.com/pvlerick"]
|
||||
- ["Steve Huguenin-Elie", "https://github.com/StEvUgnIn"]
|
||||
- ["Sebastian Speitel", "https://github.com/SebastianSpeitel"]
|
||||
- ["Max Graey", "https://github.com/MaxGraey"]
|
||||
filename: learnassemblyscript.ts
|
||||
---
|
||||
|
||||
__AssemblyScript__ compiles a variant of __TypeScript__ (basically JavaScript with types) to __WebAssembly__ using __Binaryen__. It generates lean and mean WebAssembly modules while being just an `npm install` away.
|
||||
|
||||
This article will focus only on AssemblyScript extra syntax, as opposed to [TypeScript](/docs/typescript) and [JavaScript](/docs/javascript).
|
||||
|
||||
To test AssemblyScript's compiler, head to the
|
||||
[Playground](https://bit.ly/asplayground) where you will be able
|
||||
to type code, have auto completion and directly see the emitted WebAssembly.
|
||||
|
||||
```ts
|
||||
// There are many basic types in AssemblyScript,
|
||||
let isDone: boolean = false;
|
||||
let name: string = "Anders";
|
||||
|
||||
// but integer type come as signed (sized from 8 to 64 bits)
|
||||
let lines8: i8 = 42;
|
||||
let lines16: i16 = 42;
|
||||
let lines32: i32 = 42;
|
||||
let lines64: i64 = 42;
|
||||
|
||||
// and unsigned (sized from 8 to 64 bits),
|
||||
let ulines8: u8 = 42;
|
||||
let ulines16: u16 = 42;
|
||||
let ulines32: u32 = 42;
|
||||
let ulines64: u64 = 42;
|
||||
|
||||
// and float has two sizes possible (32/64).
|
||||
let rate32: f32 = 1.0
|
||||
let rate64: f64 = 1.0
|
||||
|
||||
// But you can omit the type annotation if the variables are derived
|
||||
// from explicit literals
|
||||
let _isDone = false;
|
||||
let _lines = 42;
|
||||
let _name = "Anders";
|
||||
|
||||
// Use const keyword for constants
|
||||
const numLivesForCat = 9;
|
||||
numLivesForCat = 1; // Error
|
||||
|
||||
// For collections, there are typed arrays and generic arrays
|
||||
let list1: i8[] = [1, 2, 3];
|
||||
// Alternatively, using the generic array type
|
||||
let list2: Array<i8> = [1, 2, 3];
|
||||
|
||||
// For enumerations:
|
||||
enum Color { Red, Green, Blue };
|
||||
let c: Color = Color.Green;
|
||||
|
||||
// Functions imported from JavaScript need to be declared as external
|
||||
// @ts-ignore decorator
|
||||
@external("alert")
|
||||
declare function alert(message: string): void;
|
||||
|
||||
// and you can also import JS functions in a namespace
|
||||
declare namespace window {
|
||||
// @ts-ignore decorator
|
||||
@external("window", "alert")
|
||||
function alert(message: string): void;
|
||||
}
|
||||
|
||||
// Lastly, "void" is used in the special case of a function returning nothing
|
||||
export function bigHorribleAlert(): void {
|
||||
alert("I'm a little annoying box!"); // calling JS function here
|
||||
}
|
||||
|
||||
// Functions are first class citizens, support the lambda "fat arrow" syntax
|
||||
|
||||
// The following are equivalent, the compiler does not offer any type
|
||||
// inference for functions yet, and same WebAssembly will be emitted.
|
||||
export function f1 (i: i32): i32 { return i * i; }
|
||||
// "Fat arrow" syntax
|
||||
let f2 = (i: i32): i32 => { return i * i; }
|
||||
// "Fat arrow" syntax, braceless means no return keyword needed
|
||||
let f3 = (i: i32): i32 => i * i;
|
||||
|
||||
// Classes - members are public by default
|
||||
export class Point {
|
||||
// Properties
|
||||
x: f64;
|
||||
|
||||
// Constructor - the public/private keywords in this context will generate
|
||||
// the boiler plate code for the property and the initialization in the
|
||||
// constructor.
|
||||
// In this example, "y" will be defined just like "x" is, but with less code
|
||||
// Default values are also supported
|
||||
|
||||
constructor(x: f64, public y: f64 = 0) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
// Functions
|
||||
dist(): f64 { return Math.sqrt(this.x * this.x + this.y * this.y); }
|
||||
|
||||
// Static members
|
||||
static origin: Point = new Point(0, 0);
|
||||
}
|
||||
|
||||
// Classes can be explicitly marked as extending a parent class.
|
||||
// Any missing properties will then cause an error at compile-time.
|
||||
export class PointPerson extends Point {
|
||||
constructor(x: f64, y: f64, public name: string) {
|
||||
super(x, y);
|
||||
}
|
||||
move(): void {}
|
||||
}
|
||||
|
||||
let p1 = new Point(10, 20);
|
||||
let p2 = new Point(25); //y will be 0
|
||||
|
||||
// Inheritance
|
||||
export class Point3D extends Point {
|
||||
constructor(x: f64, y: f64, public z: f64 = 0) {
|
||||
super(x, y); // Explicit call to the super class constructor is mandatory
|
||||
}
|
||||
|
||||
// Overwrite
|
||||
dist(): f64 {
|
||||
let d = super.dist();
|
||||
return Math.sqrt(d * d + this.z * this.z);
|
||||
}
|
||||
}
|
||||
|
||||
// Namespaces, "." can be used as separator for sub namespaces
|
||||
export namespace Geometry {
|
||||
class Square {
|
||||
constructor(public sideLength: f64 = 0) {
|
||||
}
|
||||
area(): f64 {
|
||||
return Math.pow(this.sideLength, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let s1 = new Geometry.Square(5);
|
||||
|
||||
// Generics
|
||||
// AssemblyScript compiles generics to one concrete method or function per set
|
||||
// of unique contextual type arguments, also known as [monomorphisation].
|
||||
// Implications are that a module only includes and exports concrete functions
|
||||
// for sets of type arguments actually used and that concrete functions can be
|
||||
// shortcutted with [static type checks] at compile time, which turned out to
|
||||
// be quite useful.
|
||||
// Classes
|
||||
export class Tuple<T1, T2> {
|
||||
constructor(public item1: T1, public item2: T2) {
|
||||
}
|
||||
}
|
||||
|
||||
export class Pair<T> {
|
||||
item1: T;
|
||||
item2: T;
|
||||
}
|
||||
|
||||
// And functions
|
||||
export function pairToTuple <T>(p: Pair<T>): Tuple<T, T> {
|
||||
return new Tuple(p.item1, p.item2);
|
||||
};
|
||||
|
||||
let tuple = pairToTuple<string>({ item1: "hello", item2: "world" });
|
||||
|
||||
// Including references to a TypeScript-only definition file:
|
||||
/// <reference path="jquery.d.ts" />
|
||||
|
||||
// Template Strings (strings that use backticks)
|
||||
// String Interpolation with Template Strings
|
||||
let name = 'Tyrone';
|
||||
let greeting = `Hi ${name}, how are you?`
|
||||
// Multiline Strings with Template Strings
|
||||
let multiline = `This is an example
|
||||
of a multiline string`;
|
||||
|
||||
let numbers: Array<i8> = [0, 1, 2, 3, 4];
|
||||
let moreNumbers: Array<i8> = numbers;
|
||||
moreNumbers[5] = 5; // Error, elements are read-only
|
||||
moreNumbers.push(5); // Error, no push method (because it mutates array)
|
||||
moreNumbers.length = 3; // Error, length is read-only
|
||||
numbers = moreNumbers; // Error, mutating methods are missing
|
||||
|
||||
// Type inference in Arrays
|
||||
let ints = [0, 1, 2, 3, 4] // will infer as Array<i32>
|
||||
let floats: f32[] = [0, 1, 2, 3, 4] // will infer as Array<f32>
|
||||
let doubles = [0.0, 1.0, 2, 3, 4] // will infer as Array<f64>
|
||||
let bytes1 = [0 as u8, 1, 2, 3, 4] // will infer as Array<u8>
|
||||
let bytes2 = [0, 1, 2, 3, 4] as u8[] // will infer as Array<u8>
|
||||
let bytes3: u8[] = [0, 1, 2, 3, 4] // will infer as Array<u8>
|
||||
|
||||
```
|
||||
|
||||
## Further Reading
|
||||
* [AssemblyScript Official website] (https://www.assemblyscript.org/)
|
||||
* [AssemblyScript source documentation] https://github.com/AssemblyScript/website/tree/main/src)
|
||||
* [Source Code on GitHub] (https://github.com/AssemblyScript/assemblyscript)
|
@ -135,7 +135,7 @@ Let's look at the definition of Big-O.
|
||||
3 * n^2 <= c * n
|
||||
```
|
||||
|
||||
Is there some pair of constants c, n<sub>0</sub> that satisfies this for all n > <sub>0</sub>?
|
||||
Is there some pair of constants c, n<sub>0</sub> that satisfies this for all n > n<sub>0</sub>?
|
||||
No, there isn't. `f(n)` is NOT O(g(n)).
|
||||
|
||||
### Big-Omega
|
||||
|
@ -209,7 +209,7 @@ function string_functions( localvar, arr) {
|
||||
# Both return number of matches replaced
|
||||
localvar = "fooooobar";
|
||||
sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar"
|
||||
gsub("e", ".", localvar); # localvar => "m..t m. at th. bar"
|
||||
gsub("e", ".", localvar); # localvar => "M..t m. at th. bar"
|
||||
|
||||
# Search for a string that matches a regular expression
|
||||
# index() does the same thing, but doesn't allow a regular expression
|
||||
|
432
ballerina.html.markdown
Normal file
432
ballerina.html.markdown
Normal file
@ -0,0 +1,432 @@
|
||||
---
|
||||
language: Ballerina
|
||||
contributors:
|
||||
- ["Anjana Fernando", "https://github.com/lafernando"]
|
||||
filename: learn_ballerina.bal
|
||||
---
|
||||
|
||||
[Ballerina](https://ballerina.io/) is a statically-typed programming language for making development for the cloud an enjoyable experience.
|
||||
|
||||
```java
|
||||
// Single-line comment
|
||||
|
||||
// Import modules into the current source file
|
||||
import ballerina/io;
|
||||
import ballerina/time;
|
||||
import ballerina/http;
|
||||
import ballerinax/java.jdbc;
|
||||
import ballerina/lang.'int as ints;
|
||||
import ballerinax/awslambda;
|
||||
// Module alias "af" used in code in place of the full module name
|
||||
import ballerinax/azure.functions as af;
|
||||
|
||||
http:Client clientEP = new ("https://freegeoip.app/");
|
||||
jdbc:Client accountsDB = new ({url: "jdbc:mysql://localhost:3306/AccountsDB",
|
||||
username: "test", password: "test"});
|
||||
|
||||
// A service is a first-class concept in Ballerina, and is one of the
|
||||
// entrypoints to a Ballerina program.
|
||||
// The Ballerina platform also provides support for easy deployment to
|
||||
// environments such as Kubernetes (https://ballerina.io/learn/deployment/kubernetes/).
|
||||
service geoservice on new http:Listener(8080) {
|
||||
|
||||
@http:ResourceConfig {
|
||||
path: "/geoip/{ip}"
|
||||
}
|
||||
resource function geoip(http:Caller caller, http:Request request,
|
||||
string ip) returns @tainted error? {
|
||||
http:Response resp = check clientEP->get("/json/" + <@untainted>ip);
|
||||
check caller->respond(<@untainted> check resp.getTextPayload());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Serverless Function-as-a-Service support with AWS Lambda.
|
||||
// The Ballerina compiler automatically generates the final deployment
|
||||
// artifact to be deployed.
|
||||
@awslambda:Function
|
||||
public function echo(awslambda:Context ctx, json input) returns json {
|
||||
return input;
|
||||
}
|
||||
|
||||
@awslambda:Function
|
||||
public function notifyS3(awslambda:Context ctx,
|
||||
awslambda:S3Event event) returns json {
|
||||
return event.Records[0].s3.'object.key;
|
||||
}
|
||||
|
||||
// Serverless Function-as-a-Service support with Azure Functions.
|
||||
// Similar to AWS Lambda, the compiler generates the deployment artifacts.
|
||||
@af:Function
|
||||
public function fromQueueToQueue(af:Context ctx,
|
||||
@af:QueueTrigger { queueName: "queue1" } string inMsg,
|
||||
@af:QueueOutput { queueName: "queue2" } af:StringOutputBinding outMsg) {
|
||||
outMsg.value = inMsg;
|
||||
}
|
||||
|
||||
// A custom record type
|
||||
public type Person record {
|
||||
string id; // required field
|
||||
string name;
|
||||
int age?; // optional field
|
||||
string country = "N/A"; // default value
|
||||
};
|
||||
|
||||
@af:Function
|
||||
public function fromHttpTriggerCosmosDBInput(
|
||||
@af:HTTPTrigger { route: "c1/{country}" } af:HTTPRequest httpReq,
|
||||
@af:CosmosDBInput { connectionStringSetting: "CosmosDBConnection",
|
||||
databaseName: "db1", collectionName: "c1",
|
||||
sqlQuery: "select * from c1 where c1.country = {country}" }
|
||||
Person[] dbReq)
|
||||
returns @af:HTTPOutput string|error {
|
||||
return dbReq.toString();
|
||||
}
|
||||
|
||||
public function main() returns @tainted error? {
|
||||
int a = 10; // 64-bit signed integer
|
||||
float b = 1.56; // 64-bit IEEE 754-2008 binary floating point number
|
||||
string c = "hello"; // a unicode string
|
||||
boolean d = true; // true, false
|
||||
decimal e = 15.335; // decimal floating point number
|
||||
|
||||
var f = 20; // type inference with 'var' - 'f' is an int
|
||||
|
||||
int[] intArray = [1, 2, 3, 4, 5, 6];
|
||||
int x = intArray.shift(); // similar to a dequeue operation
|
||||
x = intArray.pop(); // removes the last element
|
||||
intArray.push(10); // add to the end
|
||||
|
||||
// Tuples - similar to a fixed length array with a distinct type for each slot
|
||||
[string, int] p1 = ["Jack", 1990];
|
||||
[string, int] p2 = ["Tom", 1986];
|
||||
io:println("Name: ", p1[0], " Birth Year: ", p1[1]);
|
||||
|
||||
string name1;
|
||||
int birthYear1;
|
||||
[name1, birthYear1] = p1; // tuple destructuring
|
||||
|
||||
var [name2, birthYear2] = p2; // declare and assign values in the same statement
|
||||
|
||||
// If statements
|
||||
int ix = 10;
|
||||
if ix < 10 {
|
||||
io:println("value is less than 10");
|
||||
} else if ix == 10 {
|
||||
io:println("value equals to 10");
|
||||
} else {
|
||||
io:println("value is greater than 10");
|
||||
}
|
||||
|
||||
// Loops
|
||||
int count = 10;
|
||||
int i = 0;
|
||||
while i < 10 {
|
||||
io:println(i);
|
||||
}
|
||||
// Loop from 0 to count (inclusive)
|
||||
foreach var j in 0...count {
|
||||
io:println(j);
|
||||
}
|
||||
// Loop from 0 to count (non-inclusive)
|
||||
foreach var j in 0..<count {
|
||||
io:println(j);
|
||||
}
|
||||
// Loop a list
|
||||
foreach var j in intArray {
|
||||
io:println(j);
|
||||
}
|
||||
|
||||
json j1 = { "name" : name1, "birthYear" : birthYear1, "zipcode" : 90210 };
|
||||
io:println(j1.name, " - ", j1.zipcode);
|
||||
// New fields are added to a JSON value through "mergeJson"
|
||||
var j2 = j1.mergeJson({ "id" : "90400593053"});
|
||||
|
||||
// XML namespace declaration
|
||||
xmlns "http://example.com/ns1" as ns1;
|
||||
xmlns "http://example.com/default";
|
||||
|
||||
// XML variable from a literal value
|
||||
xml x1 = xml `<ns1:entry><name>{{name1}}</name><birthYear>{{birthYear1}}</birthYear></ns1:entry>`;
|
||||
io:println(x1);
|
||||
// Access specific elements in the XML value
|
||||
io:println(x1/<name>);
|
||||
// List all child items in the XML value
|
||||
io:println(x1/*);
|
||||
|
||||
// Function invocations
|
||||
x = add(1, 2);
|
||||
io:println(multiply(2, 4));
|
||||
// Invocation providing value for the defaultable parameter
|
||||
io:println(multiply(3, 4, true));
|
||||
// Invocation with values to a rest parameter (multi-valued)
|
||||
io:println(addAll(1, 2, 3));
|
||||
io:println(addAll(1, 2, 3, 4, 5));
|
||||
|
||||
// Function pointers
|
||||
(function (int, int) returns int) op1 = getOperation("add");
|
||||
(function (int, int) returns int) op2 = getOperation("mod");
|
||||
io:println(op1(5, 10));
|
||||
io:println(op2(13, 10));
|
||||
|
||||
// Closures
|
||||
(function (int x) returns int) add5 = getAdder(5);
|
||||
(function (int x) returns int) add10 = getAdder(10);
|
||||
io:println(add5(10));
|
||||
io:println(add10(10));
|
||||
|
||||
int[] numbers = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||
// Functional iteration
|
||||
int[] evenNumbers = numbers.filter(function (int x) returns boolean { return x % 2 == 0; });
|
||||
|
||||
// Union types - "input" is of type either string or byte[]
|
||||
string|byte[] uval = "XXX";
|
||||
|
||||
// A type test expression ("uval is string") can be used to check the
|
||||
// runtime type of a variable.
|
||||
if uval is string {
|
||||
// In the current scope, "uval" is a string value
|
||||
string data = "data:" + uval;
|
||||
} else {
|
||||
// Since the expression in the "if" statement ruled out that it's not a string,
|
||||
// the only type left is "byte[]"; so in the current scope, "uval" will always
|
||||
// be a "byte[]".
|
||||
int inputLength = uval.length();
|
||||
}
|
||||
|
||||
// Error handling
|
||||
string input = io:readln("Enter number: ");
|
||||
int|error result = ints:fromString(input);
|
||||
if result is int {
|
||||
io:println("Number: ", result);
|
||||
} else {
|
||||
io:println("Invalid number: ", input);
|
||||
}
|
||||
|
||||
// A check expression can be used to directly return the error from
|
||||
// the current function if its subexpression evaluated to an error
|
||||
// value in the runtime.
|
||||
int number = check ints:fromString(input);
|
||||
|
||||
// Concurrent execution using workers in a function
|
||||
doWorkers();
|
||||
|
||||
// Asynchronous execution with futures
|
||||
future<int> f10 = start fib(10);
|
||||
var webresult = clientEP->get("/");
|
||||
int fresult = wait f10;
|
||||
if webresult is http:Response {
|
||||
io:println(webresult.getTextPayload());
|
||||
io:println(fresult);
|
||||
}
|
||||
|
||||
// Mapping types
|
||||
map<int> ageMap = {};
|
||||
ageMap["Peter"] = 25;
|
||||
ageMap["John"] = 30;
|
||||
|
||||
int? agePeter = ageMap["Peter"]; // int? is the union type int|() - int or nill
|
||||
if agePeter is int {
|
||||
io:println("Peter's age is ", agePeter);
|
||||
} else {
|
||||
io:println("Peter's age is not found");
|
||||
}
|
||||
|
||||
Person person1 = { id: "p1", name : "Anne", age: 28, country: "Sri Lanka" };
|
||||
Scores score1 = { physics : 80, mathematics: 95 };
|
||||
score1["chemistry"] = 75;
|
||||
io:println(score1["chemistry"]);
|
||||
|
||||
Student student1 = { id: "s1", name: "Jack", age: 25, country: "Japan" };
|
||||
student1.college = "Stanford";
|
||||
string? jacksCollege = student1?.college; // optional field access
|
||||
if jacksCollege is string {
|
||||
io:println("Jack's college is ", jacksCollege);
|
||||
}
|
||||
|
||||
// Due to the structural type system, "student1" can be assigned to "person2",
|
||||
// since the student1's structure is compatible with person2's,
|
||||
// where we can say, a "Student" is a "Person" as well.
|
||||
Person person2 = student1;
|
||||
|
||||
map<int> grades = {"Jack": 95, "Anne": 90, "John": 80, "Bill": 55};
|
||||
Person px1 = {id: "px1", name: "Jack", age: 30, country: "Canada"};
|
||||
Person px2 = {id: "px2", name: "John", age: 25};
|
||||
Person px3 = {id: "px3", name: "Anne", age: 17, country: "UK"};
|
||||
Person px4 = {id: "px4", name: "Bill", age: 15, country: "USA"};
|
||||
Person[] persons = [];
|
||||
persons.push(px1);
|
||||
persons.push(px2);
|
||||
persons.push(px3);
|
||||
persons.push(px4);
|
||||
|
||||
// Query expressions used to execute complex queries for list data
|
||||
Result[] results = from var person in persons
|
||||
let int lgrade = (grades[person.name] ?: 0)
|
||||
where lgrade > 75
|
||||
let string targetCollege = "Stanford"
|
||||
select {
|
||||
name: person.name,
|
||||
college: targetCollege,
|
||||
grade: lgrade
|
||||
};
|
||||
|
||||
// Compile-time taint checking for handling untrusted data
|
||||
string s1 = "abc";
|
||||
mySecureFunction(s1);
|
||||
// Explicitely make "s2" a tainted value. External input to a Ballerina
|
||||
// program such as command-line arguments and network input are by-default
|
||||
// marked as tainted data.
|
||||
string s2 = <@tainted> s1;
|
||||
// "s2x" is now a tainted value, since its value is derived using a
|
||||
// tainted value (s1).
|
||||
string s2x = s2 + "abc";
|
||||
// The following line uncommented will result in a compilation error,
|
||||
// since we are passing a tainted value (s2x) to a function which
|
||||
// exepects an untainted value.
|
||||
// mySecureFunction(s2x);
|
||||
|
||||
// Instantiating objects
|
||||
Employee emp1 = new("E0001", "Jack Smith", "Sales", 2009);
|
||||
io:println("The company service duration of ", emp1.name,
|
||||
" is ", emp1.serviceDuration());
|
||||
|
||||
// Supported operations can be executed in a transaction by enclosing the actions
|
||||
// in a "transaction" block.
|
||||
transaction {
|
||||
// Executes the below database operations in a single local transactions
|
||||
var r1 = accountsDB->update("UPDATE Employee SET balance = balance + ? WHERE id = ?", 5500.0, "ID001");
|
||||
var r2 = accountsDB->update("UPDATE Employee SET balance = balance + ? WHERE id = ?", 5500.0, "ID001");
|
||||
}
|
||||
}
|
||||
|
||||
// An object is a behavioural type, which encapsulates both data and functionality.
|
||||
type Employee object {
|
||||
|
||||
// Private fields are only visible within the object and its methods
|
||||
private string empId;
|
||||
// Public fields can be accessed by anyone
|
||||
public string name;
|
||||
public string department;
|
||||
// The default qualifier is a "protected" field,
|
||||
// which are accessible only within the module.
|
||||
int yearJoined;
|
||||
|
||||
// The object initialization function; automatically called when an object is instantiated.
|
||||
public function __init(string empId, string name, string department, int yearJoined) {
|
||||
self.empId = empId;
|
||||
self.name = name;
|
||||
self.department = department;
|
||||
self.yearJoined = yearJoined;
|
||||
}
|
||||
|
||||
// An object method
|
||||
public function serviceDuration() returns int {
|
||||
time:Time ct = time:currentTime();
|
||||
return time:getYear(ct) - self.yearJoined;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Student is a subtype of Person
|
||||
type Student record {
|
||||
string id;
|
||||
string name;
|
||||
int age;
|
||||
string college?;
|
||||
string country;
|
||||
};
|
||||
|
||||
type Scores record {
|
||||
int physics;
|
||||
int mathematics;
|
||||
};
|
||||
|
||||
type Result record {
|
||||
string name;
|
||||
string college;
|
||||
int grade;
|
||||
};
|
||||
|
||||
public function getOperation(string op) returns (function (int, int) returns int) {
|
||||
if op == "add" {
|
||||
return add;
|
||||
} else if op == "mod" {
|
||||
return function (int a, int b) returns int { // anonymous function
|
||||
return a % b;
|
||||
};
|
||||
} else {
|
||||
return (x, y) => 0; // single expression anonymous no-op function
|
||||
}
|
||||
}
|
||||
|
||||
// Two required parameters
|
||||
public function add(int a, int b) returns int {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// 'log' is a defaultable parameter
|
||||
public function multiply(int a, int b, boolean log = false) returns int {
|
||||
if log {
|
||||
io:println("Multiplying ", a, " with ", b);
|
||||
}
|
||||
return a * b;
|
||||
}
|
||||
|
||||
// 'numbers' is a rest parameter - it can have multiple values,
|
||||
// similar to an array.
|
||||
public function addAll(int... numbers) returns int {
|
||||
int result = 0;
|
||||
foreach int number in numbers {
|
||||
result += number;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public function getAdder(int n) returns (function (int x) returns int) {
|
||||
return function (int x) returns int { // returns closure
|
||||
return x + n;
|
||||
};
|
||||
}
|
||||
|
||||
function fib(int n) returns int {
|
||||
if n <= 2 {
|
||||
return 1;
|
||||
} else {
|
||||
return fib(n - 1) + fib(n - 2);
|
||||
}
|
||||
}
|
||||
|
||||
// The code in worker blocks "w1" and "w2" are executed concurrency
|
||||
// when this function is invoked. The "wait" expressions waits for
|
||||
// the given workers to finish to retrieve their results.
|
||||
public function doWorkers() {
|
||||
worker w1 returns int {
|
||||
int j = 10;
|
||||
j -> w2;
|
||||
int b;
|
||||
b = <- w2;
|
||||
return b * b;
|
||||
}
|
||||
worker w2 returns int {
|
||||
int a;
|
||||
a = <- w1;
|
||||
a * 2 -> w1;
|
||||
return a + 2;
|
||||
}
|
||||
record {int w1; int w2;} x = wait {w1, w2};
|
||||
io:println(x);
|
||||
}
|
||||
|
||||
// A function which takes in only an untainted string value.
|
||||
public function mySecureFunction(@untainted string input) {
|
||||
io:println(input);
|
||||
}
|
||||
```
|
||||
|
||||
### Further Reading
|
||||
|
||||
* [Ballerina by Example](https://ballerina.io/learn/by-example/)
|
||||
* [User Guide](https://ballerina.io/learn/installing-ballerina/)
|
||||
* [API Documentation](https://ballerina.io/learn/api-docs/ballerina/)
|
||||
* [Language Specification](https://ballerina.io/spec/)
|
@ -5,7 +5,7 @@ contributors:
|
||||
translators:
|
||||
- ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
|
||||
lang: ca-es
|
||||
filename: asciidoc-ca.md
|
||||
filename: asciidoc-ca.adoc
|
||||
---
|
||||
|
||||
AsciiDoc és un llenguatge de marques similar a Markdown i que pot ser usat per qualsevol ús, des de llibres fins a blogs.
|
||||
|
@ -95,7 +95,7 @@ salts de línia.` // El mateix tipus
|
||||
// literals Non-ASCII literal. El tipus de Go és UTF-8.
|
||||
g := 'Σ' // El tipus rune, és un àlies de int32 conté un caràcter unicode.
|
||||
|
||||
f := 3.14195 // float64, un número de 64 bits amb coma flotant IEEE-754.
|
||||
f := 3.14159 // float64, un número de 64 bits amb coma flotant IEEE-754.
|
||||
c := 3 + 4i // complex128, representat internament amb dos float64.
|
||||
|
||||
// Sintaxi amb var i inicialitzadors.
|
||||
@ -433,25 +433,25 @@ func requestServer() {
|
||||
## Més informació
|
||||
|
||||
L'arrel de tot en Go és la web oficial [official Go web site]
|
||||
(http://golang.org/). Allà es pot seguir el tutorial, jugar interactivament
|
||||
(https://go.dev/). Allà es pot seguir el tutorial, jugar interactivament
|
||||
i llegir molt més del que hem vist aquí.En el "tour",
|
||||
[the docs](https://golang.org/doc/) conté informació sobre com escriure codi
|
||||
[the docs](https://go.dev/doc/) conté informació sobre com escriure codi
|
||||
net i efectiu en Go, comandes per empaquetar i generar documentació, i
|
||||
història de les versions.
|
||||
|
||||
És altament recomanable llegir La definició del llenguatge. És fàcil de llegir
|
||||
i sorprenentment curta (com la definició del llenguatge en aquests dies).
|
||||
|
||||
Es pot jugar amb codi a [Go playground](https://play.golang.org/p/tnWMjr16Mm).
|
||||
Es pot jugar amb codi a [Go playground](https://go.dev/play/p/tnWMjr16Mm).
|
||||
Prova de fer canvis en el codi i executar-lo des del navegador! Es pot fer
|
||||
servir [https://play.golang.org](https://play.golang.org) com a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per provar coses i codi
|
||||
servir [https://go.dev/play/](https://go.dev/play/) com a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per provar coses i codi
|
||||
en el navegador sense haver d'instal·lar Go.
|
||||
|
||||
En la llista de lectures pels estudiants de Go hi ha
|
||||
[el codi font de la llibreria estàndard](http://golang.org/src/pkg/).
|
||||
[el codi font de la llibreria estàndard](https://go.dev/src/).
|
||||
Ampliament comentada, que demostra el fàcil que és de llegir i entendre els
|
||||
programes en Go, l'estil de programació, i les formes de treballar-hi. O es
|
||||
pot clicar en un nom de funció en [la documentació](http://golang.org/pkg/)
|
||||
pot clicar en un nom de funció en [la documentació](https://go.dev/pkg/)
|
||||
i veure'n el codi!
|
||||
|
||||
Un altre gran recurs per aprendre Go és
|
||||
|
@ -90,7 +90,7 @@ může obsahovat nové řádky` // Opět typ řetězec.
|
||||
// Můžeme použít ne ASCII znaky, Go používá UTF-8.
|
||||
g := 'Σ' // type runa, což je alias na int32 a ukládá se do něj znak UTF-8
|
||||
|
||||
f := 3.14195 // float64, je IEEE-754 64-bit číslem s plovoucí čárkou.
|
||||
f := 3.14159 // float64, je IEEE-754 64-bit číslem s plovoucí čárkou.
|
||||
c := 3 + 4i // complex128, interně uložené jako dva float64.
|
||||
|
||||
// takhle vypadá var s inicializací
|
||||
@ -408,20 +408,20 @@ func requestServer() {
|
||||
|
||||
## Kam dále
|
||||
|
||||
Vše hlavní o Go se nachází na [oficiálních stránkách go](http://golang.org/).
|
||||
Vše hlavní o Go se nachází na [oficiálních stránkách go](https://go.dev/).
|
||||
Tam najdete tutoriály, interaktivní konzolu a mnoho materiálu ke čtení.
|
||||
Kromě úvodu, [dokumenty](https://golang.org/doc/) tam obsahují jak psát čistý kód v Go
|
||||
Kromě úvodu, [dokumenty](https://go.dev/doc/) tam obsahují jak psát čistý kód v Go
|
||||
popis balíčků (package), dokumentaci příkazové řádky a historii releasů.
|
||||
|
||||
Také doporučujeme přečíst si definici jazyka. Je čtivá a překvapivě krátká. Tedy alespoň proti
|
||||
jiným současným jazyků.
|
||||
|
||||
Pokud si chcete pohrát s Go, tak navštivte [hřiště Go](https://play.golang.org/p/r46YvCu-XX).
|
||||
Můžete tam spouštět programy s prohlížeče. Také můžete [https://play.golang.org](https://play.golang.org) použít jako
|
||||
Pokud si chcete pohrát s Go, tak navštivte [hřiště Go](https://go.dev/play/p/r46YvCu-XX).
|
||||
Můžete tam spouštět programy s prohlížeče. Také můžete [https://go.dev/play/](https://go.dev/play/) použít jako
|
||||
[REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop), kde si v rychlosti vyzkoušíte věci, bez instalace Go.
|
||||
|
||||
Na vašem knižním seznamu, by neměly chybět [zdrojáky stadardní knihovny](http://golang.org/src/pkg/).
|
||||
Důkladně popisuje a dokumentuje Go, styl zápisu Go a Go idiomy. Pokud kliknete na [dokumentaci](http://golang.org/pkg/)
|
||||
Na vašem knižním seznamu, by neměly chybět [zdrojáky stadardní knihovny](https://go.dev/src/).
|
||||
Důkladně popisuje a dokumentuje Go, styl zápisu Go a Go idiomy. Pokud kliknete na [dokumentaci](https://go.dev/pkg/)
|
||||
tak se podíváte na dokumentaci.
|
||||
|
||||
Dalším dobrým zdrojem informací je [Go v ukázkách](https://gobyexample.com/).
|
||||
|
@ -102,19 +102,24 @@ div.some-parent.class-name { }
|
||||
/* There are some selectors called pseudo classes that can be used to select an
|
||||
element only when it is in a particular state */
|
||||
|
||||
/* for example, when the cursor hovers over an element */
|
||||
selector:hover { }
|
||||
/* for example, when a link hasn't been visited */
|
||||
selected:link { }
|
||||
|
||||
/* or a link has been visited */
|
||||
selector:visited { }
|
||||
|
||||
/* or hasn't been visited */
|
||||
selected:link { }
|
||||
|
||||
/* or an element is in focus */
|
||||
selected:focus { }
|
||||
|
||||
/* any element that is the first child of its parent */
|
||||
/* or when the cursor hovers over an element */
|
||||
selector:hover { }
|
||||
|
||||
/* or when a link is clicked on */
|
||||
selector:active { }
|
||||
|
||||
/* These pseudo classes regarding links should always be written in the above order or the code might not work as expected */
|
||||
|
||||
/* Any element that is the first child of its parent */
|
||||
selector:first-child {}
|
||||
|
||||
/* any element that is the last child of its parent */
|
||||
|
551
cue.html.markdown
Normal file
551
cue.html.markdown
Normal file
@ -0,0 +1,551 @@
|
||||
---
|
||||
name: CUE
|
||||
category: language
|
||||
language: cue
|
||||
filename: learncue.cue
|
||||
contributors:
|
||||
- ["Daniel Cox", "https://github.com/danielpcox"]
|
||||
- ["Coleman McFarland", "https://github.com/dontlaugh"]
|
||||
---
|
||||
|
||||
CUE is an expressive (but not Turing-complete) JSON superset, exportable to JSON or YAML. It supports optional types and many other conveniences for working with large configuration sets. The unification engine has roots in logic programming, and as such it provides a ready solution to modern configuration management problems.
|
||||
|
||||
When CUE is exported to JSON, values from every processed file are unified into one giant object. Consider these two files:
|
||||
|
||||
```yaml
|
||||
//name.cue
|
||||
name: "Daniel"
|
||||
```
|
||||
|
||||
```yaml
|
||||
//disposition.cue
|
||||
disposition: "oblivious"
|
||||
```
|
||||
|
||||
Now we can unify and export to JSON:
|
||||
```bash
|
||||
% cue export name.cue disposition.cue
|
||||
{
|
||||
"name": "Daniel",
|
||||
"disposition": "oblivious"
|
||||
}
|
||||
```
|
||||
|
||||
Or YAML:
|
||||
```bash
|
||||
% cue export --out yaml name.cue disposition.cue
|
||||
name: Daniel
|
||||
disposition: oblivious
|
||||
```
|
||||
|
||||
Notice the C-style comments are not in the output. Also notice that the keys in CUE syntax did not require quotes. Some special characters do require quotes:
|
||||
|
||||
```yaml
|
||||
works_fine: true
|
||||
"needs-quotes": true
|
||||
```
|
||||
|
||||
Unification doesn't just unify across files, it is also a *global merge* of all types and values. The following fails, because the *types* are different.
|
||||
|
||||
```yaml
|
||||
//string_value.cue
|
||||
foo: "baz"
|
||||
```
|
||||
|
||||
```yaml
|
||||
//integer_value.cue
|
||||
foo: 100
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue export string_value.cue integer_value.cue
|
||||
foo: conflicting values "baz" and 100 (mismatched types string and int):
|
||||
integer_value.cue:1:6
|
||||
string_value.cue:1:6
|
||||
```
|
||||
|
||||
But even if we quote the integer, it still fails, because the *values* conflict and there is no way to unify everything into a top-level object.
|
||||
|
||||
```yaml
|
||||
//string_value.cue
|
||||
foo: "baz"
|
||||
```
|
||||
|
||||
```yaml
|
||||
//integer_value.cue
|
||||
foo: "100" // a string now
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue export string_value.cue integer_value.cue
|
||||
foo: conflicting values "100" and "baz":
|
||||
integer_value.cue:1:6
|
||||
string_value.cue:1:6
|
||||
```
|
||||
|
||||
Types in CUE *are* values; special ones that the unification engine knows have certain behavior relative to other values. During unification it requires that values match the specified types, and when concrete values are required, you will get an error if there's only a type. So this is fine:
|
||||
|
||||
```yaml
|
||||
street: "1 Infinite Loop"
|
||||
street: string
|
||||
```
|
||||
|
||||
While `cue export` produces YAML or JSON, `cue eval` produces CUE. This is useful for converting YAML or JSON to CUE, or for inspecting the unified output in CUE itself. It's fine to be missing concrete values in CUE (though it prefers concrete values when emitting CUE when both are available and match),
|
||||
|
||||
```yaml
|
||||
//type-only.cue
|
||||
amount: float
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue eval type-only.cue
|
||||
amount: float
|
||||
```
|
||||
|
||||
but you *need* concrete values if you want to export (or if you tell `eval` to require them with `-c`):
|
||||
|
||||
```bash
|
||||
% cue export type-only.cue
|
||||
amount: incomplete value float
|
||||
```
|
||||
|
||||
Give it a value that unifies with the type, and all is well.
|
||||
|
||||
```yaml
|
||||
//concrete-value.cue
|
||||
amount: 3.14
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue export type-only.cue concrete-value.cue
|
||||
{
|
||||
"amount": 3.14
|
||||
}
|
||||
```
|
||||
|
||||
The method of unifying concrete values with types that share a common syntax is very powerful, and much more compact than, e.g., JSON Schema. This way, schema, defaults, and data are all expressible in CUE.
|
||||
|
||||
Default values may be supplied with a type using an asterisk:
|
||||
|
||||
```yaml
|
||||
// default-port.cue
|
||||
port: int | *8080
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue eval default-port.cue
|
||||
port: 8080
|
||||
```
|
||||
|
||||
Enum-style options ("disjunctions" in CUE) may be specified with an `|` separator:
|
||||
|
||||
```yaml
|
||||
//severity-enum.cue
|
||||
severity: "high" | "medium" | "low"
|
||||
severity: "unknown"
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue eval severity-enum.cue
|
||||
severity: 3 errors in empty disjunction:
|
||||
severity: conflicting values "high" and "unknown":
|
||||
./severity-enum.cue:1:11
|
||||
./severity-enum.cue:1:48
|
||||
severity: conflicting values "low" and "unknown":
|
||||
./severity-enum.cue:1:31
|
||||
./severity-enum.cue:1:48
|
||||
severity: conflicting values "medium" and "unknown":
|
||||
./severity-enum.cue:1:20
|
||||
./severity-enum.cue:1:48
|
||||
```
|
||||
|
||||
You can even have disjunctions of structs (not shown, but it works like you'd expect).
|
||||
|
||||
CUE has "definitions", and you can use them like you would variable declarations in other languages. They are also for defining struct types. You can apply a struct of type definitions to some concrete value(s) with `&`. Also notice you can say "a list with type #Whatever" using `[...#Whatever]`.
|
||||
|
||||
```yaml
|
||||
// definitions.cue
|
||||
|
||||
#DashboardPort: 1337
|
||||
|
||||
configs: {
|
||||
host: "localhost"
|
||||
port: #DashboardPort
|
||||
}
|
||||
|
||||
#Address: {
|
||||
street: string
|
||||
city: string
|
||||
zip?: int // ? makes zip optional
|
||||
}
|
||||
|
||||
some_address: #Address & {
|
||||
street: "1 Rocket Rd"
|
||||
city: "Hawthorne"
|
||||
}
|
||||
|
||||
more_addresses: [...#Address] & [
|
||||
{street: "1600 Amphitheatre Parkway", city: "Mountain View", zip: "94043"},
|
||||
{street: "1 Hacker Way", city: "Menlo Park"}
|
||||
]
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue export --out yaml definitions.cue
|
||||
configs:
|
||||
host: localhost
|
||||
port: 1337
|
||||
some_address:
|
||||
street: 1 Rocket Rd
|
||||
city: Hawthorne
|
||||
more_addresses:
|
||||
- street: 1600 Amphitheatre Parkway
|
||||
city: Mountain View
|
||||
zip: "94043"
|
||||
- street: 1 Hacker Way
|
||||
city: Menlo Park
|
||||
```
|
||||
|
||||
CUE supports more complex values and validation:
|
||||
|
||||
```yaml
|
||||
#Country: {
|
||||
name: =~"^\\p{Lu}" // Must start with an upper-case letter
|
||||
pop: >800 & <9_000_000_000 // More than 800, fewer than 9 billion
|
||||
}
|
||||
|
||||
vatican_city: #Country & {
|
||||
name: "Vatican City"
|
||||
pop: 825
|
||||
}
|
||||
```
|
||||
|
||||
CUE may save you quite a bit of time with all the sugar it provides on top of mere JSON. Here we're defining, "modifying", and validating a nested structure in three lines: (Notice the `[]` syntax used around `string` to signal to the engine that `string` is a constraint, not a string in this case.)
|
||||
|
||||
```yaml
|
||||
//paths.cue
|
||||
|
||||
// path-value pairs
|
||||
outer: middle1: inner: 3
|
||||
outer: middle2: inner: 7
|
||||
|
||||
// collection-constraint pair
|
||||
outer: [string]: inner: int
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue export paths.cue
|
||||
{
|
||||
"outer": {
|
||||
"middle1": {
|
||||
"inner": 3
|
||||
},
|
||||
"middle2": {
|
||||
"inner": 7
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the same vein, CUE supports "templates", which are a bit like functions of a single argument. Here `Name` is bound to each string key immediately under `container` while the struct underneath *that* is evaluated.
|
||||
|
||||
```yaml
|
||||
//templates.cue
|
||||
|
||||
container: [Name=_]: {
|
||||
name: Name
|
||||
replicas: uint | *1
|
||||
command: string
|
||||
}
|
||||
|
||||
container: sidecar: command: "envoy"
|
||||
|
||||
container: service: {
|
||||
command: "fibonacci"
|
||||
replicas: 2
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue eval templates.cue
|
||||
container: {
|
||||
sidecar: {
|
||||
name: "sidecar"
|
||||
replicas: 1
|
||||
command: "envoy"
|
||||
}
|
||||
service: {
|
||||
name: "service"
|
||||
command: "fibonacci"
|
||||
replicas: 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And while we're talking about references like that, CUE supports scoped references.
|
||||
|
||||
```yaml
|
||||
//scopes-and-references.cue
|
||||
v: "top-level v"
|
||||
b: v // a reference
|
||||
a: {
|
||||
b: v // matches the top-level v
|
||||
}
|
||||
|
||||
let V = v
|
||||
a: {
|
||||
v: "a's inner v"
|
||||
c: v // matches the inner v
|
||||
d: V // matches the top-level v now shadowed by a.v
|
||||
}
|
||||
av: a.v // matches a's v
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue eval --out yaml scopes-and-references.cue
|
||||
```
|
||||
|
||||
```yaml
|
||||
v: top-level v
|
||||
b: top-level v
|
||||
a:
|
||||
b: top-level v
|
||||
v: a's inner v
|
||||
c: a's inner v
|
||||
d: top-level v
|
||||
av: a's inner v
|
||||
```
|
||||
|
||||
I changed the order of the keys in the output for clarity. Order doesn't actually matter, and notice that duplicate keys at a given level are *all* unified.
|
||||
|
||||
You can hide fields be prefixing them with `_` (quote the field if you need a `_` prefix in an emitted field)
|
||||
|
||||
```yaml
|
||||
//hiddens.cue
|
||||
"_foo": 2
|
||||
_foo: 3
|
||||
foo: 4
|
||||
_#foo: 5
|
||||
#foo : 6
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue eval hiddens.cue
|
||||
"_foo": 2
|
||||
foo: 4
|
||||
#foo: 6
|
||||
|
||||
% cue export hiddens.cue
|
||||
{
|
||||
"_foo": 2,
|
||||
"foo": 4
|
||||
}
|
||||
```
|
||||
|
||||
Notice the difference between `eval` and `export` with respect to definitions. If you want to hide a definition in CUE, you can prefix *that* with `_`.
|
||||
|
||||
Interpolation of values and fields:
|
||||
|
||||
```yaml
|
||||
//interpolation.cue
|
||||
|
||||
#expense: 90
|
||||
#revenue: 100
|
||||
message: "Your profit was $\( #revenue - #expense)"
|
||||
|
||||
cat: {
|
||||
type: "Cuddly"
|
||||
"is\(type)": true
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue export interpolation.cue
|
||||
{
|
||||
"message": "Your profit was $10",
|
||||
"cat": {
|
||||
"type": "Cuddly",
|
||||
"isCuddly": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Operators, list comprehensions, conditionals, imports...:
|
||||
|
||||
```yaml
|
||||
//getting-out-of-hand-now.cue
|
||||
import "strings" // we'll come back to this
|
||||
|
||||
// operators are nice
|
||||
g: 5 / 3 // CUE can do math
|
||||
h: 3 * "blah" // and Python-like string repetition
|
||||
i: 3 * [1, 2, 3] // with lists too
|
||||
j: 8 < 10 // and supports boolean ops
|
||||
|
||||
// conditionals are also nice
|
||||
price: number
|
||||
// Require a justification if price is too high
|
||||
if price > 100 {
|
||||
justification: string
|
||||
}
|
||||
price: 200
|
||||
justification: "impulse buy"
|
||||
|
||||
// list comprehensions are powerful and compact
|
||||
#items: [ 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
comp: [ for x in #items if x rem 2 == 0 {x*x}]
|
||||
|
||||
// and... well you can do this too
|
||||
#a: [ "Apple", "Google", "SpaceX"]
|
||||
for k, v in #a {
|
||||
"\( strings.ToLower(v) )": {
|
||||
pos: k + 1
|
||||
name: v
|
||||
nameLen: len(v)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
% cue export getting-out-of-hand-now.cue
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"g": 1.66666666666666666666667,
|
||||
"h": "blahblahblah",
|
||||
"i": [1, 2, 3, 1, 2, 3, 1, 2, 3],
|
||||
"j": true,
|
||||
"apple": {
|
||||
"pos": 1,
|
||||
"name": "Apple",
|
||||
"nameLen": 5
|
||||
},
|
||||
"google": {
|
||||
"pos": 2,
|
||||
"name": "Google",
|
||||
"nameLen": 6
|
||||
},
|
||||
"price": 200,
|
||||
"justification": "impulse buy",
|
||||
"comp": [
|
||||
4,
|
||||
16,
|
||||
36,
|
||||
64
|
||||
],
|
||||
"spacex": {
|
||||
"pos": 3,
|
||||
"name": "SpaceX",
|
||||
"nameLen": 6
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
At this point it's worth mentioning that CUE may not be Turing-complete, but it *is* powerful enough for you to shoot yourself in the foot, so do try to keep it clear. It's easy to go off the deep end and make your config *harder* to work with if you're not careful. Make use of those comments, at least, and/or...
|
||||
|
||||
To that end, CUE supports packages and modules. CUE files are standalone by default, but if you put a package clause at the top, you're saying that file is unifiable with other files "in" the same package.
|
||||
|
||||
```yaml
|
||||
//a.cue
|
||||
package config
|
||||
|
||||
foo: 100
|
||||
bar: int
|
||||
```
|
||||
|
||||
```yaml
|
||||
//b.cue
|
||||
package config
|
||||
|
||||
bar: 200
|
||||
```
|
||||
|
||||
If you create these two files in a new directory and run `cue eval` (no arguments), it will unify them like you'd expect. It searches the current directory for .cue files, and if they all have the same package, they will be unified.
|
||||
|
||||
Packages are more clear in the context of "modules". Modules are the *largest* unit of organization. Basically every time you have a project that spans multiple files, you should create a module and name it with something that looks like the domain and path of a URL, e.g., `example.com/something`. When you import anything from this module, even from *within* the module, you must do so using the fully-qualified module path which will be prefixed with this module name.
|
||||
|
||||
You can create a new module like so:
|
||||
|
||||
```bash
|
||||
mkdir mymodule && cd mymodule
|
||||
cue mod init example.com/mymodule
|
||||
```
|
||||
|
||||
This creates a `cue.mod/` subdirectory within that `mymodule` directory, and `cue.mod/` contains the following file and subdirectories:
|
||||
|
||||
- `module.cue` (which defines your module name, in this case with `module: "example.com/mymodule"`)
|
||||
- pkg/
|
||||
- gen/
|
||||
- usr/
|
||||
|
||||
For a different perspective on this and details about what's in there, see https://cuelang.org/docs/concepts/packages/. For my purposes here, I'll say you don't need to think about the contents of this directory *at all*, except that your module name will be the prefix for all imports within your module.
|
||||
|
||||
Where will your module file hierarchy go? All files and directories for your module are rooted in `mymodule/`, the directory that also contains `cue.mod/`. If you want to import a package, you'll prefix it with `example.com/mymodule`, followed by a relative path rooted in `mymodule/`.
|
||||
|
||||
To make it concrete, consider the following:
|
||||
|
||||
```
|
||||
mymodule
|
||||
├── config
|
||||
│ ├── a.cue
|
||||
│ └── b.cue
|
||||
├── cue.mod
|
||||
│ ├── module.cue
|
||||
│ ├── pkg
|
||||
│ └── usr
|
||||
└── main.cue
|
||||
```
|
||||
|
||||
`cue.mod/` and the files underneath it were created by `cue mod init example.com/mymodule`. I then created the `config/` subdirectory with `a.cue` and `b.cue` inside. Then I created `main.cue` to act as my top-level file to rule them all.
|
||||
|
||||
Running `eval` (no arguments) checks to see if there's only one package in all .cue files in the current directory, and if so, it unifies them and outputs the result. In this case, there's only main.cue with package `main` (nothing special about "main" there, it just seemed appropriate), so that's the one.
|
||||
|
||||
```bash
|
||||
% cue eval
|
||||
configuredBar: 200
|
||||
```
|
||||
|
||||
The contents of `main.cue` is:
|
||||
|
||||
```yaml
|
||||
//main.cue
|
||||
|
||||
package main
|
||||
import "example.com/mymodule/config"
|
||||
|
||||
configuredBar: config.bar
|
||||
```
|
||||
|
||||
`config/a.cue` and `config/b.cue` are files from earlier, except now they've both got `package config` at the top:
|
||||
|
||||
```yaml
|
||||
//a.cue
|
||||
package config
|
||||
|
||||
foo: 100
|
||||
bar: int
|
||||
```
|
||||
|
||||
```yaml
|
||||
//b.cue
|
||||
package config
|
||||
|
||||
bar: 200
|
||||
```
|
||||
|
||||
So there you go. If you want to verify that it's actually unifying both files under `config/`, you can change `bar: int` to `bar: string` in `a.cue` and re-run `cue eval` to get a nice type error:
|
||||
|
||||
```
|
||||
cue eval 2022-01-06 17:51:24
|
||||
configuredBar: conflicting values string and 200 (mismatched types string and int):
|
||||
./config/a.cue:4:6
|
||||
./config/b.cue:3:6
|
||||
./main.cue:5:16
|
||||
```
|
||||
|
||||
That's it for now. I understand there are more package management features coming in the future and the design decisions around `cue.mod` are looking ahead to that.
|
||||
|
||||
Finally, CUE has built-in modules with powerful functionality. We saw one of these earlier, when we imported "strings" and used `strings.ToLower`. Imports without fully-qualified module names are assumed to be built-ins. The full list and documentation for each is here: https://pkg.go.dev/cuelang.org/go/pkg
|
||||
|
||||
This has been a condensation of the official docs and tutorials, so go give the source material some love: https://cuelang.org/docs/tutorials/
|
@ -45,7 +45,7 @@ const CONSTANT_VALUE = "I CANNOT CHANGE";
|
||||
CONSTANT_VALUE = "DID I?"; //Error
|
||||
/// Final is another variable declaration that cannot be change once it has been instantiated. Commonly used in classes and functions
|
||||
/// `final` can be declared in pascalCase.
|
||||
final finalValue = "value cannot be change once instantiated";
|
||||
final finalValue = "value cannot be changed once instantiated";
|
||||
finalValue = "Seems not"; //Error
|
||||
|
||||
/// `var` is another variable declaration that is mutable and can change its value. Dart will infer types and will not change its data type
|
||||
@ -79,7 +79,8 @@ example1() {
|
||||
|
||||
/// Anonymous functions don't include a name
|
||||
example2() {
|
||||
nested1(fn) {
|
||||
//// Explicit return type.
|
||||
nested1(void Function() fn) {
|
||||
fn();
|
||||
}
|
||||
nested1(() => print("Example2 nested 1"));
|
||||
|
@ -4,7 +4,7 @@ contributors:
|
||||
- ["Ryan Mavilia", "http://unoriginality.rocks/"]
|
||||
translators:
|
||||
- ["Dennis Keller", "https://github.com/denniskeller"]
|
||||
filename: asciidoc-de.md
|
||||
filename: asciidoc-de.adoc
|
||||
lang: de-de
|
||||
---
|
||||
|
||||
|
561
de-de/crystal-de.html.markdown
Normal file
561
de-de/crystal-de.html.markdown
Normal file
@ -0,0 +1,561 @@
|
||||
---
|
||||
language: crystal
|
||||
contributors:
|
||||
- ["Vitalii Elenhaupt", "http://veelenga.com"]
|
||||
- ["Arnaud Fernandés", "https://github.com/TechMagister/"]
|
||||
translators:
|
||||
- ["caminsha", "https://github.com/caminsha"]
|
||||
filename: learncrystal-de.cr
|
||||
lang: de-de
|
||||
---
|
||||
|
||||
```crystal
|
||||
|
||||
# Das ist ein Kommentar
|
||||
|
||||
# Alles ist ein Objekt
|
||||
nil.class # => Nil
|
||||
100.class # => Int32
|
||||
true.class # => Bool
|
||||
|
||||
# Falschwerte sind: nil, false und Nullpointer
|
||||
!nil # => true : Bool
|
||||
!false # => true : Bool
|
||||
!0 # => false : Bool
|
||||
|
||||
# Integer
|
||||
|
||||
1.class # => Int32
|
||||
|
||||
# Fünf vorzeichenbehaftete Ganzzahlen
|
||||
1_i8.class # => Int8
|
||||
1_i16.class # => Int16
|
||||
1_i32.class # => Int32
|
||||
1_i64.class # => Int64
|
||||
1_i128.class # => Int128
|
||||
|
||||
# Fünf vorzeichenlose Ganzzahlen
|
||||
1_u8.class # => UInt8
|
||||
1_u16.class # => UInt16
|
||||
1_u32.class # => UInt32
|
||||
1_u64.class # => UInt64
|
||||
1_u128.class # => UInt128
|
||||
|
||||
|
||||
2147483648.class # => Int64
|
||||
9223372036854775808.class # => UInt64
|
||||
|
||||
# Binäre Zahlen
|
||||
0b1101 # => 13 : Int32
|
||||
|
||||
# Oktalzahlen
|
||||
0o123 # => 83 : Int32
|
||||
|
||||
# Hexadezimalzahlen
|
||||
0xFE012D # => 16646445 : Int32
|
||||
0xfe012d # => 16646445 : Int32
|
||||
|
||||
# Gleitkommazahlen (floats)
|
||||
|
||||
1.0.class # => Float64
|
||||
|
||||
# Es gibt zwei Typen von Gleitkommazahlen
|
||||
|
||||
1.0_f32.class # => Float32
|
||||
1_f32.class # => Float32
|
||||
|
||||
1e10.class # => Float64
|
||||
1.5e10.class # => Float64
|
||||
1.5e-7.class # => Float64
|
||||
|
||||
|
||||
# Chars (einzelne Zeichen)
|
||||
|
||||
'a'.class # => Char
|
||||
|
||||
# Oktale Schreibweise
|
||||
'\101' # => 'A' : Char
|
||||
|
||||
# Unicode Schreibweise
|
||||
'\u0041' # => 'A' : Char
|
||||
|
||||
# Strings (Zeichenketten)
|
||||
"s".class # => String
|
||||
|
||||
# Strings sind unveränderlich
|
||||
s = 'hello, " # => "hello, " : String
|
||||
s.object_id # => 1234667712 : UInt64
|
||||
s += "Crystal" # => "hello, Crystal" : String
|
||||
s.object_id # => 142528472 : UInt64
|
||||
|
||||
# Interpolation wird unterstützt
|
||||
"sum = #{1 + 2}" # => "sum = 3" : String
|
||||
|
||||
# Mehrzeilige Strings
|
||||
" Dies ist ein
|
||||
mehrzeiliger String."
|
||||
|
||||
# String mit doppeltem Anführungszeichen
|
||||
%(hello "world") # => "hello \"world\""
|
||||
|
||||
# Symbole
|
||||
# Unveränderbare, wiederverwendbare Konstanten, welche intern als Int32 Integer
|
||||
# Werte repräsentiert werden.
|
||||
# Symbole werden oft anstelle von Strings verwendet, um bestimmte Werte zu bestimmen.
|
||||
|
||||
:symbol.class # => Symbol
|
||||
|
||||
sentence = :question? # :"question?" : Symbol
|
||||
|
||||
sentence = :question? # => true : Bool
|
||||
sentence = :exclamation! # => false : Bool
|
||||
sentence = "question?" # => false : Bool
|
||||
|
||||
# Arrays
|
||||
[1, 2, 3].class # => Array(Int32)
|
||||
[1, "hello", 'x'].class # => Array(Int32 | String | Char)
|
||||
|
||||
# Leere Arrays sollten einen Typen definieren
|
||||
[] # => Syntaxfehler: für leere Arrays,
|
||||
# verwende `[] of ElementType`
|
||||
[] of Int32 # => [] : Array(Int32)
|
||||
Array(Int32).new # => [] : Array(Int32)
|
||||
|
||||
# Arrays können indiziert werden
|
||||
array = [1, 2, 3, 4, 5] # => [1, 2, 3, 4, 5] : Array(Int32)
|
||||
array[0] # => 1 : Int32
|
||||
array[10] # führt zu einem IndexError
|
||||
array[-6] # führt zu einem IndexError
|
||||
array[10]? # => nil : (Int32 | Nil)
|
||||
array[-6]? # => nil : (Int32 | Nil)
|
||||
|
||||
# Starte am Ende des Arrays
|
||||
array[-1] # => 5
|
||||
|
||||
# Mit einem Startindex und einer Länge
|
||||
array[2, 4] # => [3, 4, 5]
|
||||
|
||||
# oder mit einem Bereich
|
||||
array[1..3] # => [2, 3, 4]
|
||||
|
||||
# Füge etwas zu einem Array hinzu
|
||||
array << 6 # => [1, 2, 3, 4, 5, 6]
|
||||
|
||||
# Entferne Einträge am Ende des Arrays
|
||||
array.pop # => 6
|
||||
array # => [1, 2, 3, 4, 5]
|
||||
|
||||
# Entferne ersten Eintrag im Array
|
||||
array.shift # => 1
|
||||
array # => [2, 3, 4, 5]
|
||||
|
||||
# Überprüfe, ob ein Element in einem Array existiert
|
||||
array.includes? 3 # => true
|
||||
|
||||
# Spezielle Syntax für String-Arrays und Symbol-Arrays
|
||||
%w(one two three) # => ["one", "two", "three"] : Array(String)
|
||||
%i(one two three) # 0> [:one, :two, :three] : Array(Symbol)
|
||||
|
||||
# Es gibt auch für andere Arrays eine spezielle Syntax, wenn die Methoden
|
||||
# `.new` und `#<<` definiert werden.
|
||||
set = Set{1, 2, 3} # => [1, 2, 3]
|
||||
set.class # => Set(Int32)
|
||||
|
||||
# Das obere ist äquivalent zu:
|
||||
set = Set(typeof(1, 2, 3)).new
|
||||
set << 1
|
||||
set << 2
|
||||
set << 3
|
||||
|
||||
# Hashes
|
||||
{1 => 2, 3 => 4}.class # => Hash(Int32, Int32)
|
||||
{1 => 2, 'a' => 3}.class # => Hash (Int32 | Char, Int32)
|
||||
|
||||
# Leere Hashes sollten einen Typen spezifieren
|
||||
{} # Syntaxfehler
|
||||
{} of Int32 => Int32 # {}
|
||||
Hash(Int32, Int32).new # {}
|
||||
|
||||
# Hashes können schnell mit dem Key nachgeschaut werden
|
||||
hash = {"color" => "green", "number" => 5}
|
||||
hash["color"] # => "green"
|
||||
hash["no_such_key"] # => Fehlender hash key: "no_such_key" (KeyError)
|
||||
hash["no_such_key"]? # => nil
|
||||
|
||||
# Überprüfe die Existenz eines Hashkeys
|
||||
hash.has_key? "color" # => true
|
||||
|
||||
# Spezielle Schreibweise für Symbol- und Stringkeys
|
||||
{key1: 'a', key2: 'b'} # {:key1 => 'a', :key2 => 'b'}
|
||||
{"key1": 'a', "key2": 'b'} # {"key1" => 'a', "key2" => 'b'}
|
||||
|
||||
# Die spezielle Syntax für Hash-Literale gibt es auch für andere Typen, sofern
|
||||
# diese die Methoden `.new` und `#[]=` Methoden definieren.
|
||||
class MyType
|
||||
def []=(key, value)
|
||||
puts "do stuff"
|
||||
end
|
||||
end
|
||||
|
||||
MyType{"foo" => "bar"}
|
||||
|
||||
# Das obere ist äquivalent zu:
|
||||
tmp = MyType.new
|
||||
tmp["foo"] = "bar"
|
||||
tmp
|
||||
|
||||
# Ranges (Bereiche)
|
||||
1..10 # => Range(Int32, Int32)
|
||||
Range.new(1,10).class # => Range(Int32, Int32)
|
||||
|
||||
# Ranges können inklusiv oder exklusiv sein.
|
||||
(3..5).to_a # => [3, 4, 5]
|
||||
(3...5).to_a # => [3, 4]
|
||||
|
||||
# Überprüfe, ob ein Range einen Wert enthält oder nicht.
|
||||
(1..8).includes? 2 # => true
|
||||
|
||||
# Tupel sind unveränderliche, Stack-zugewiese Folgen von Werten mit fester
|
||||
# Größe und möglicherweise unterschiedlichen Typen
|
||||
{1, "hello", 'x'}.class # => Tuple(Int32, String, Char)
|
||||
|
||||
# Erhalte den Wert eines Tupels über den Index
|
||||
tuple = {:key1, :key2}
|
||||
tuple[1] # => :key2
|
||||
tuple[2] # syntax error: Index out of bound
|
||||
|
||||
# Können auf mehrere Variablen erweitert werden
|
||||
a, b, c = {:a, 'b', "c"}
|
||||
a # => :a
|
||||
b # => 'b'
|
||||
c # => "c"
|
||||
|
||||
# Procs repräsentieren ein Funktionspointer mit einem optionalen Kontext.
|
||||
# Normalerweise wird ein Proc mit einem proc-Literal erstellt.
|
||||
proc = ->(x : Int32) { x.to_s }
|
||||
proc.class # => Print(Int32, String)
|
||||
# Außerdem kann man auch mit der Methode `new` ein Proc erstellen.
|
||||
Proc(Int32, String).new { |x| x.to_s }
|
||||
|
||||
# Rufe ein Proc auf mit der Methode `call`
|
||||
proc.call 10 # => "10"
|
||||
|
||||
# Kontrollstatements
|
||||
|
||||
if true
|
||||
"if statement"
|
||||
elsif false
|
||||
"else-f, optional"
|
||||
else
|
||||
"else, auch optional"
|
||||
end
|
||||
|
||||
puts "if as a suffix" if true # => if as a suffix
|
||||
|
||||
# If als Ausdruck
|
||||
a = if 2 > 1
|
||||
3
|
||||
else
|
||||
4
|
||||
end
|
||||
|
||||
a # => 3
|
||||
|
||||
# Bedingter ternärer Ausdruck
|
||||
a = 1 > 2 ? 3 : 4 # => 4
|
||||
|
||||
# Case-Statement
|
||||
cmd = "move"
|
||||
|
||||
action = case cmd
|
||||
when "create"
|
||||
"Creating..."
|
||||
when "copy"
|
||||
"Copying..."
|
||||
when "move"
|
||||
"Moving..."
|
||||
when "delete"
|
||||
"Deleting..."
|
||||
end
|
||||
|
||||
action # => "Moving..."
|
||||
|
||||
# Schleifen
|
||||
index = 0
|
||||
while index <= 3
|
||||
puts "Index: #{index}"
|
||||
index += 1
|
||||
end
|
||||
# Index: 0
|
||||
# Index: 1
|
||||
# Index: 2
|
||||
# Index: 3
|
||||
|
||||
index = 0
|
||||
until index > 3
|
||||
puts "Index: #{index}"
|
||||
index += 1
|
||||
end
|
||||
# Index: 0
|
||||
# Index: 1
|
||||
# Index: 2
|
||||
# Index: 3
|
||||
|
||||
# Der bevorzugte Weg, ist `each` zu verwenden.
|
||||
(1..3).each do |index|
|
||||
puts "Index: #{index}"
|
||||
end
|
||||
# Index: 1
|
||||
# Index: 2
|
||||
# Index: 3
|
||||
|
||||
# Der Typ der Variablen hängt vom Typen innerhalb der Kontrollanweisung ab
|
||||
if a < 3
|
||||
a = "hello"
|
||||
else
|
||||
a = true
|
||||
end
|
||||
typeof a # => (Bool | String)
|
||||
|
||||
if a && b
|
||||
# Hier wird garantiert, dass weder a noch b vom Typ Nil sind
|
||||
end
|
||||
|
||||
if a.is_a? String
|
||||
a.class # => String
|
||||
end
|
||||
|
||||
# Funktionen
|
||||
def double(x)
|
||||
x * 2
|
||||
end
|
||||
|
||||
# Funktionen geben implizit den Wert der letzten Anweisung zurück
|
||||
# Dies ist auch bei anderen Blöcken der Fall.
|
||||
double(2) # => 4
|
||||
|
||||
# Klammern müssen nicht gesetzt werden, wenn der Aufruf eindeutig ist
|
||||
double 3 # => 6
|
||||
double double 3 # => 12
|
||||
|
||||
def sum(x, y)
|
||||
x + y
|
||||
end
|
||||
|
||||
# Funktionsargumente werden mit einem Komma separiert.
|
||||
sum 3, 4 # => 7
|
||||
|
||||
sum sum(3, 4), 5 # => 12
|
||||
|
||||
# yield
|
||||
# Alle Methoden haben einen impliziten, optionalen Blockparameter.
|
||||
# Dieser kann mit dem Schlüsselwort `yield` aufgerufen werden.
|
||||
|
||||
def surround
|
||||
puts '{'
|
||||
yield
|
||||
puts '}'
|
||||
end
|
||||
|
||||
surround { puts "Hallo Welt" }
|
||||
|
||||
# {
|
||||
# Hallo Welt
|
||||
# }
|
||||
|
||||
# Du kannst ein Block einer Funktion übergeben.
|
||||
# "&" kennzeichnet eine Referenz zu einem übergebenen Block
|
||||
def guests(&block)
|
||||
block.call "some_argument"
|
||||
end
|
||||
|
||||
# Du kannst eine Liste von Argumenten mitgeben, welche zu einem Array
|
||||
# umgewandelt werden.
|
||||
# Hierfür ist der Splat-Operator ("*")
|
||||
def guests(*array)
|
||||
array.each { |guest| puts guest }
|
||||
end
|
||||
|
||||
# Wenn eine Methode ein Array zurückgibt, kann destrukturiende Zuordnung
|
||||
# verwendet werden.
|
||||
def foods
|
||||
["pancake", "sandwich", "quesadilla"]
|
||||
end
|
||||
breakfast, lunch, dinner = foods
|
||||
breakfast # => "pancake"
|
||||
dinner # => "quesadilla"
|
||||
|
||||
# Gemäß der Konvention enden alle Methoden, welchen einen Boolean zurückgeben
|
||||
# mit einem Fragezeichen.
|
||||
5.even? # false
|
||||
5.odd? # true
|
||||
|
||||
# Und wenn eine Methode mit einem Ausrufezeichen endet, macht sie etwas
|
||||
# destruktives. Zum Beispiel wird der Aufrufer verändert. Einige Methoden haben
|
||||
# eine !-Version, um eine Änderung zu machen und eine Nicht-!-Version, welche
|
||||
# lediglich eine neue veränderte Version zurückgibt.
|
||||
|
||||
company_name = "Dunder Mifflin"
|
||||
company_name.gsub "Dunder", "Donald" # => "Donald Mifflin"
|
||||
company_name # => "Dunder Mifflin"
|
||||
company_name.gsub! "Dunder", "Donald"
|
||||
company_name # => "Donald Mifflin"
|
||||
|
||||
# definiere eine Klasse mit dem Schlüsselwort `class`.
|
||||
class Human
|
||||
|
||||
# eine Klassenvariable. Diese wird mit allen Instanzen dieser Klasse geteilt.
|
||||
@@species = "H. sapiens"
|
||||
|
||||
# type of name is String
|
||||
@name: String
|
||||
|
||||
# Grundlegender Intialisierer
|
||||
# Weise das Argument der Instanz-Variable "name" zu
|
||||
# Wenn kein Alter angegeben wird, wird der Default (hier 0) genommen.
|
||||
def initialize(@name, @age = 0)
|
||||
end
|
||||
|
||||
# Einfache Setter-Methode
|
||||
def name=(name)
|
||||
@name = name
|
||||
end
|
||||
|
||||
# einfache Getter-Methode
|
||||
def name
|
||||
@name
|
||||
end
|
||||
|
||||
# Die obere Funktionalität kann mit der property-Methode gekapselt werden:
|
||||
property :name
|
||||
|
||||
# Getter/Setter-Methoden können auch individuell erstellt werden:
|
||||
getter :name
|
||||
setter :name
|
||||
|
||||
# eine Klassenmethode verwendet `self` um sich von Instanzmethoden zu
|
||||
# unterscheiden. Diese kann lediglich von einer Klasse aufgerufen werden,
|
||||
# nicht von einer Instanz.
|
||||
def self.say(msg)
|
||||
puts msg
|
||||
end
|
||||
|
||||
def species
|
||||
@@species
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Eine Klasse instanzieren
|
||||
jim = Human.new("Jim Halpert")
|
||||
|
||||
dwight = Human.new("Dwight K. Schrute")
|
||||
|
||||
# Lass uns ein paar Methoden aufrufen
|
||||
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"
|
||||
|
||||
# Rufe die Klassenmethode auf
|
||||
Human.say("Hi") # => gibt Hi aus und gibt `nil` zurück
|
||||
|
||||
# Variablen, welche mit @ starten, sind im Scope der Instanz
|
||||
class TestClass
|
||||
@var = "Ich bin eine Instanzvariable"
|
||||
end
|
||||
|
||||
# Variablen, welche mit @@ starten, sind im Scope der Klasse
|
||||
class TestClass
|
||||
@@var = "Ich bin eine Klassenvariable"
|
||||
end
|
||||
|
||||
# Variablen, welche mit einem Großbuchstaben starten, sind Konstanten.
|
||||
Var = "Ich bin eine Konstante"
|
||||
Var = "Ich kann nicht aktualisiert werden." # Die Konstante Var wurde bereits
|
||||
# initialisiert.
|
||||
|
||||
# In Crystal ist Class auch ein Objekt. Dadurch können Klassen Instanzvariablen
|
||||
# haben. Klassenvariablen werden mit der Klasse und allen Subklassen geteilt.
|
||||
|
||||
# Basisklasse
|
||||
class Human
|
||||
@@foo = 0
|
||||
|
||||
def self.foo
|
||||
@@foo
|
||||
end
|
||||
|
||||
def self.foo=(value)
|
||||
@@foo = value
|
||||
end
|
||||
end
|
||||
|
||||
# abgeleitete Klasse
|
||||
class Worker < Human
|
||||
end
|
||||
|
||||
Human.foo # => 0
|
||||
Worker.foo # => 0
|
||||
|
||||
Human.foo = 2 # => 2
|
||||
Worker.foo # => 0
|
||||
|
||||
Worker.foo = 3 # => 3
|
||||
Human.foo # => 2
|
||||
Worker.foo # => 3
|
||||
|
||||
module ModuleExample
|
||||
def foo
|
||||
"foo"
|
||||
end
|
||||
end
|
||||
|
||||
# Wenn ein Modul mit include eingeschlossen wird, so werden die Methoden an die
|
||||
# Instanzen gebunden.
|
||||
# Wenn eine Klasse mit einem Modul erweitert wird, so werden die Methoden an die
|
||||
# Klasse selbst gebunden.
|
||||
|
||||
class Person
|
||||
include ModuleExample
|
||||
end
|
||||
|
||||
class Book
|
||||
extend ModuleExample
|
||||
end
|
||||
|
||||
Person.foo # => undefinierte Methode 'foo' für Person:Class
|
||||
Person.new.foo # => 'foo'
|
||||
Book.foo # => 'foo'
|
||||
Book.new.foo # => undefinierte Methode für Book
|
||||
|
||||
# Ausnahmebehandlung
|
||||
|
||||
# Definiere eine neue Ausnahme
|
||||
class MyException < Exception
|
||||
end
|
||||
|
||||
# Definiere eine weitere Ausnahme
|
||||
class MyAnotherException < Exception; end
|
||||
|
||||
ex = begin
|
||||
raise MyException.new
|
||||
rescue ex1 : IndexError
|
||||
"ex1"
|
||||
rescue ex2 : MyException | MyAnotherException
|
||||
"ex2"
|
||||
rescue ex3 : Exception
|
||||
"ex3"
|
||||
rescue ex4 # fange alle Ausnahmen ab
|
||||
"ex4"
|
||||
end
|
||||
|
||||
ex # => "ex2"
|
||||
```
|
||||
|
||||
|
||||
## Weitere Unterlagen
|
||||
|
||||
- [offizielle Dokumentation, englisch](https://crystal-lang.org/)
|
@ -82,7 +82,7 @@ Zeilenumbrüche beinhalten.` // Selber Zeichenketten-Typ
|
||||
// nicht-ASCII Literal. Go Quelltext ist UTF-8 kompatibel.
|
||||
g := 'Σ' // Ein Runen-Typ, alias int32, gebraucht für unicode code points.
|
||||
|
||||
f := 3.14195 // float64, eine IEEE-754 64-bit Dezimalzahl
|
||||
f := 3.14159 // float64, eine IEEE-754 64-bit Dezimalzahl
|
||||
c := 3 + 4i // complex128, besteht intern aus zwei float64-er
|
||||
|
||||
// "var"-Syntax mit Initalwert
|
||||
@ -308,13 +308,13 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
```
|
||||
|
||||
## Weitere Resourcen
|
||||
Informationen zu Go findet man auf der [offiziellen Go Webseite](http://golang.org/).
|
||||
Informationen zu Go findet man auf der [offiziellen Go Webseite](https://go.dev/).
|
||||
Dort gibt es unter anderem ein Tutorial und interaktive Quelltext-Beispiele, vor
|
||||
allem aber Dokumentation zur Sprache und den Paketen.
|
||||
|
||||
Auch zu empfehlen ist die Spezifikation von Go, die nach heutigen Standards sehr
|
||||
kurz und gut verständlich formuliert ist. Auf der Leseliste von Go-Neulingen
|
||||
ist außerdem der Quelltext der [Go standard Bibliothek](http://golang.org/src/pkg/)
|
||||
ist außerdem der Quelltext der [Go standard Bibliothek](https://go.dev/src/)
|
||||
einzusehen. Dieser kann als Referenz für leicht zu verstehendes und im idiomatischen Stil
|
||||
verfasstes Go dienen. Erreichbar ist der Quelltext auch durch das Klicken der Funktionsnamen
|
||||
in der [offiziellen Dokumentation von Go](http://golang.org/pkg/).
|
||||
in der [offiziellen Dokumentation von Go](https://go.dev/pkg/).
|
||||
|
@ -162,13 +162,13 @@ case bestellungsStatus
|
||||
//- <p class="warn">Deine Bestellung steht noch aus</p>
|
||||
|
||||
//- --INCLUDE--
|
||||
//- File path -> "includes/nav.png"
|
||||
//- File path -> "includes/nav.pug"
|
||||
h1 Firmenname
|
||||
nav
|
||||
a(href="index.html") Home
|
||||
a(href="about.html") Über uns
|
||||
|
||||
//- Dateipfad -> "index.png"
|
||||
//- Dateipfad -> "index.pug"
|
||||
html
|
||||
body
|
||||
include includes/nav.pug
|
||||
|
290
de-de/visualbasic-de.html.markdown
Normal file
290
de-de/visualbasic-de.html.markdown
Normal file
@ -0,0 +1,290 @@
|
||||
---
|
||||
language: Visual Basic
|
||||
contributors:
|
||||
- ["Brian Martin", "http://brianmartin.biz"]
|
||||
translators:
|
||||
- ["Enno Nagel", "https://github.com/konfekt"]
|
||||
filename: learnvisualbasic-de.vb
|
||||
lang: de-de
|
||||
---
|
||||
|
||||
```
|
||||
Module Modul1
|
||||
|
||||
Sub Main()
|
||||
' Ein kurzer Blick auf Visual Basic-Konsolenanwendungen
|
||||
' bevor wir tiefer in das Thema eintauchen.
|
||||
' Das Hochkomma leitet eine Kommentarzeile ein.
|
||||
' Um dieses Tutorial innerhalb des Visual Basic Compilers zu erkunden,
|
||||
' habe ich ein Navigationssystem erstellt.
|
||||
' Dieses System wird im weiteren Verlauf des Tutorials erklärt;
|
||||
' Sie werden nach und nach verstehen, was das alles bedeutet.
|
||||
Console.Title = ("Lerne X in Y Minuten")
|
||||
Console.WriteLine ("NAVIGATION") 'Anzeige
|
||||
Console.WriteLine ("")
|
||||
Console.ForegroundColor = ConsoleColor.Green
|
||||
Console.WriteLine ("1. Ausgabe von 'Hallo, Welt'")
|
||||
Console.WriteLine ("2. Eingabe 'Hallo, Welt'")
|
||||
Console.WriteLine ("3. ganze Zahlen berechnen")
|
||||
Console.WriteLine ("4. Berechne Dezimalzahlen")
|
||||
Console.WriteLine ("5. ein funktionaler Taschenrechner")
|
||||
Console.WriteLine ("6. 'Do While'-Schleifen verwenden")
|
||||
Console.WriteLine ("7. Verwendung von 'For While'-Schleifen")
|
||||
Console.WriteLine ("8. Bedingte Anweisungen")
|
||||
Console.WriteLine ("9. Ein Getränk auswählen")
|
||||
Console.WriteLine ("50. Über")
|
||||
Console.WriteLine ("Wählen Sie eine Zahl aus der obigen Liste")
|
||||
Dim selection As String = Console.Readline()
|
||||
Select Case auswahl
|
||||
Case "1" 'Ausgabe "Hallo, Welt"
|
||||
Console.Clear() 'Löscht die Konsole und öffnet die private Subroutine
|
||||
AusgabeHalloWelt() 'Öffnet die genannte private Subroutine
|
||||
Case "2" 'Eingabe "hallo, Welt"
|
||||
Console.Clear()
|
||||
EingabeHalloWelt()
|
||||
Case "3" 'Berechne ganze Zahlen
|
||||
Console.Clear()
|
||||
BerechneGanzeZahlen()
|
||||
Case "4" 'Dezimalzahlen berechnen
|
||||
Console.Clear()
|
||||
BerechneDezimalZahlen()
|
||||
Case "5" 'Ein funktionaler Taschenrechner
|
||||
Console.Clear()
|
||||
Taschenrechner()
|
||||
Case "6" 'Verwendung von "Do While"-Schleifen
|
||||
Console.Clear()
|
||||
WhileSchleife()
|
||||
Case "7" 'Verwendung von "For While"-Schleifen
|
||||
Console.Clear()
|
||||
ForSchleife()
|
||||
Case "8" 'Bedingte Anweisungen
|
||||
Console.Clear()
|
||||
BedingteAnweisung()
|
||||
Case "9" 'If/Else-Anweisung
|
||||
Console.Clear()
|
||||
IfElseAnweisung() 'Ein Getränk auswählen
|
||||
Case "50" '"Über" Infobox
|
||||
Console.Clear()
|
||||
Console.Title = ("Lernen Sie X in Y Minuten :: Über")
|
||||
MsgBox ("Tutorial geschrieben von Brian Martin (@BrianMartinn)")
|
||||
Console.Clear()
|
||||
Main()
|
||||
Console.ReadLine()
|
||||
|
||||
End Select
|
||||
End Sub
|
||||
|
||||
'Eins - Ich habe Zahlen verwendet, um mich durch das obige Navigationssystem zu
|
||||
'führen auf das ich später zurückkomme, um es zu implementieren.
|
||||
|
||||
'wir verwenden private Unterprogramme, um verschiedene Abschnitte des Programms
|
||||
'zu trennen.
|
||||
Private Sub AusgabeHalloWelt()
|
||||
'Titel der Konsolenanwendung
|
||||
Console.Title = "Ausgabe 'Hallo, Welt' | Lerne X in Y Minuten"
|
||||
'Verwenden Sie Console.Write("") oder Console.WriteLine(""), um die Ausgabe
|
||||
'anzuzeigen, gefolgt von Console.Read(), oder Console.Readline()
|
||||
'Console.ReadLine() zeigt die Ausgabe auf der Konsole an.
|
||||
Console.WriteLine ("Hallo, Welt")
|
||||
Console.ReadLine()
|
||||
End Sub
|
||||
|
||||
'Zwei
|
||||
Private Sub EingabeHalloWelt()
|
||||
Console.Title = "Hallo, Welt, ich bin.. | Lerne X in Y Minuten"
|
||||
'Variablen
|
||||
'Vom Benutzer eingegebene Daten müssen gespeichert werden.
|
||||
'Variablen beginnen ebenfalls mit Dim und enden mit As VariableType.
|
||||
|
||||
'In diesem Lernprogramm wollen wir Ihren Namen wissen und das Programm
|
||||
'auf ihn antworten.
|
||||
Dim nutzername As String
|
||||
' Wir verwenden "String", weil es sich um eine textbasierte Variable handelt.
|
||||
Console.WriteLine ("Hallo, wie ist Ihr Name?") 'Frage nach dem Benutzernamen.
|
||||
nutzername = Console.ReadLine() 'Benutzernamen speichern.
|
||||
Console.WriteLine ("Hallo, " + nutzername) 'Ausgabe ist Hallo, Name
|
||||
Console.ReadLine() 'Die obige Ausgabe anzeigen.
|
||||
'Der obige Code stellt Ihnen eine Frage und zeigt die Antwort an.
|
||||
'Neben anderen Variablentypen gibt es Integer, den wir für ganze Zahlen
|
||||
'verwenden werden.
|
||||
End Sub
|
||||
|
||||
'Drei
|
||||
Private Sub BerechneGanzeZahlen()
|
||||
Console.Title = "Berechne ganze Zahlen | Lerne X in Y Minuten"
|
||||
Console.Write ("Erste Zahl: ") 'Schreiben Sie eine ganze Zahl, 1, 2, 104, usw
|
||||
Dim a As Integer = Console.ReadLine()
|
||||
Console.Write ("Zweite Zahl: ") 'Schreiben Sie eine weitere ganze Zahl.
|
||||
Dim b As Integer = Console.ReadLine()
|
||||
Dim c As Integer = a + b
|
||||
Console.WriteLine (c)
|
||||
Console.ReadLine()
|
||||
'Dies ist ein einfacher Taschenrechner
|
||||
End Sub
|
||||
|
||||
'Vier
|
||||
Private Sub BerechneDezimalZahlen()
|
||||
Console.Title = "Berechne mit dem Typ Double | Lerne X in Y Minuten"
|
||||
'Natürlich würden wir gerne Dezimalzahlen addieren.
|
||||
'Also könnten wir von Integer auf Double umstellen.
|
||||
|
||||
'Schreiben Sie eine Bruchzahl, 1.2, 2.4, 50.1, 104.9 usw
|
||||
Console.Write ("Erste Zahl: ")
|
||||
Dim a As Double = Console.Readline()
|
||||
Console.Write ("Zweite Zahl: ") 'Schreiben Sie die zweite Zahl.
|
||||
Dim b As Double = Console.Readline()
|
||||
Dim c As Double = a + b
|
||||
Console.WriteLine (c)
|
||||
Console.ReadLine()
|
||||
'Dieses Programm kann 1.1 und 2.2 addieren
|
||||
End Sub
|
||||
|
||||
'Fünf
|
||||
Private Sub Taschenrechner()
|
||||
Console.Title = "Der Funktionsrechner | Lerne X in Y Minuten"
|
||||
'Wenn Sie aber wollen, dass der Rechner subtrahiert, dividiert,
|
||||
'multipliziert und addiert.
|
||||
'Kopieren Sie den obigen Text und fügen Sie ihn ein.
|
||||
Console.Write ("Erste Zahl: ")
|
||||
Dim a As Double = Console.Readline()
|
||||
Console.Write ("Zweite Zahl: ")
|
||||
Dim b As Integer = Console.Readline()
|
||||
Dim c As Integer = a + b
|
||||
Dim d As Integer = a * b
|
||||
Dim e As Integer = a - b
|
||||
Dim f As Integer = a / b
|
||||
|
||||
'Mit den folgenden Zeilen können wir die Werte a und b
|
||||
'subtrahieren, multiplizieren und dividieren
|
||||
Console.Write (a.ToString() + " + " + b.ToString())
|
||||
'Wir wollen den Ergebnissen einen linken Rand von 3 Leerzeichen geben.
|
||||
Console.WriteLine (" = " + c.ToString.PadLeft(3))
|
||||
Console.Write (a.ToString() + " * " + b.ToString())
|
||||
Console.WriteLine (" = " + d.ToString.PadLeft(3))
|
||||
Console.Write (a.ToString() + " - " + b.ToString())
|
||||
Console.WriteLine (" = " + e.ToString.PadLeft(3))
|
||||
Console.Write (a.ToString() + " / " + b.ToString())
|
||||
Console.WriteLine (" = " + f.ToString.PadLeft(3))
|
||||
Console.ReadLine()
|
||||
|
||||
End Sub
|
||||
|
||||
'Sechs
|
||||
Private Sub WhileSchleife()
|
||||
'Gleich zur vorherigen privaten Subroutine.
|
||||
'Diesmal fragen wir den Benutzer, ob er fortfahren möchte (ja oder nein?).
|
||||
'Wir verwenden die Do While-Schleife, weil wir nicht wissen, ob der Benutzer
|
||||
'das Programm mehr als einmal verwenden möchte.
|
||||
Console.Title = "Do While-Schleifen verwenden | X in Y Minuten lernen"
|
||||
Dim antwort As String 'Wir verwenden "String", weil die Antwort ein Text ist
|
||||
Do 'Wir beginnen das Programm mit
|
||||
Console.Write ("Erste Zahl: ")
|
||||
Dim a As Double = Console.Readline()
|
||||
Console.Write ("Zweite Zahl: ")
|
||||
Dim b As Integer = Console.Readline()
|
||||
Dim c As Integer = a + b
|
||||
Dim d As Integer = a * b
|
||||
Dim e As Integer = a - b
|
||||
Dim f As Integer = a / b
|
||||
|
||||
Console.Write (a.ToString() + " + " + b.ToString())
|
||||
Console.WriteLine (" = " + c.ToString.PadLeft(3))
|
||||
Console.Write (a.ToString() + " * " + b.ToString())
|
||||
Console.WriteLine (" = " + d.ToString.PadLeft(3))
|
||||
Console.Write (a.ToString() + " - " + b.ToString())
|
||||
Console.WriteLine (" = " + e.ToString.PadLeft(3))
|
||||
Console.Write (a.ToString() + " / " + b.ToString())
|
||||
Console.WriteLine (" = " + f.ToString.PadLeft(3))
|
||||
Console.ReadLine()
|
||||
'Fragen Sie den Benutzer, ob er fortfahren möchte. Unglücklicherweise
|
||||
'werden Groß- und Kleinschreibung unterschieden.
|
||||
Console.Write ("Möchten Sie fortfahren? (j / n)")
|
||||
'Das Programm nimmt die Variable, zeigt sie an und beginnt von vorne.
|
||||
antwort = Console.Readline()
|
||||
'Der Befehl, der diese Variable zum Laufen bringt, ist in diesem Fall "j"
|
||||
Loop While antwort = "j"
|
||||
|
||||
End Sub
|
||||
|
||||
'Sieben
|
||||
Private Sub ForSchleife()
|
||||
'Manchmal muss das Programm nur einmal ausgeführt werden.
|
||||
'In diesem Programm werden wir von 10 loszählen.
|
||||
|
||||
Console.Title = "Mit "For"-Schleifen | X in Y Minuten lernen"
|
||||
'Deklarieren Sie die Variable und ab welcher Zahl in Schritt -1 gezählt
|
||||
'werden soll, Schritt -2, Schritt -3, usw.
|
||||
For i As Integer = 10 To 0 Schritt -1
|
||||
Console.WriteLine (i.ToString) 'Zählerwert anzeigen
|
||||
Next i 'Berechne den neuen Wert
|
||||
Console.WriteLine ("Start") 'Starten wir das Programm, baby!!!!
|
||||
Console.ReadLine() 'BANG!!!! - Vielleicht war ich zu aufgeregt :)
|
||||
End Sub
|
||||
|
||||
'Acht
|
||||
Private Sub BedingteAnweisung()
|
||||
Console.Title = "Bedingte Anweisungen | X in Y Minuten lernen"
|
||||
Dim username As String = Console.Readline()
|
||||
'Aufforderung zur Eingabe des Benutzernamens.
|
||||
Console.WriteLine ("Hallo, wie ist Ihr Name?")
|
||||
username = Console.ReadLine() 'Benutzernamen speichern.
|
||||
If username = "Adam" Then
|
||||
Console.WriteLine ("Hallo, Adam")
|
||||
Console.WriteLine ("Danke, dass Sie diese nützliche Website erstellt haben")
|
||||
Console.ReadLine()
|
||||
Else
|
||||
Console.WriteLine ("Hallo, " + Benutzername)
|
||||
Console.WriteLine ("Haben Sie www.learnxinyminutes.com besucht?")
|
||||
Console.ReadLine() 'Beendet und zeigt die obige Anweisung an.
|
||||
End If
|
||||
End Sub
|
||||
|
||||
'Neun
|
||||
Private Sub IfElseAnweisung()
|
||||
Console.Title = "If / Else-Anweisung | X in Y Minuten lernen"
|
||||
'Manchmal ist es wichtig, mehr als zwei Alternativen in Betracht zu ziehen.
|
||||
'Manchmal sind einige von ihnen besser.
|
||||
'In diesem Fall brauchen wir mehr als eine "if"-Anweisung.
|
||||
'Eine "if"-Anweisung ist für Verkaufsautomaten geeignet.
|
||||
'Der Benutzer gibt einen Code ein (A1, A2, A3), aus dem er wählen kann.
|
||||
'Alle Auswahlmöglichkeiten können in einer einzigen "if"-Anweisung
|
||||
'kombiniert werden.
|
||||
|
||||
Dim auswahl As String = Console.ReadLine 'Der Wert der Auswahl
|
||||
Console.WriteLine ("A1. für 7Up")
|
||||
Console.WriteLine ("A2. für Fanta")
|
||||
Console.WriteLine ("A3. für Dr. Pepper")
|
||||
Console.WriteLine ("A4. für Coca-Cola")
|
||||
Console.ReadLine()
|
||||
If auswahl = "A1" Dann
|
||||
Console.WriteLine ("7up")
|
||||
Console.ReadLine()
|
||||
ElseIf auswahl = "A2" Then
|
||||
Console.WriteLine ("fanta")
|
||||
Console.ReadLine()
|
||||
ElseIf auswahl = "A3" Then
|
||||
Console.WriteLine ("Dr. Pfeffer")
|
||||
Console.ReadLine()
|
||||
ElseIf auswahl = "A4" Then
|
||||
Console.WriteLine ("Coca-Cola")
|
||||
Console.ReadLine()
|
||||
Else
|
||||
Console.WriteLine ("Ein Produkt auswählen")
|
||||
Console.ReadLine()
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
End Module
|
||||
```
|
||||
|
||||
## Referenzen
|
||||
|
||||
Für diejenigen, die mehr wissen wollen, hat Brian Martin ein umfassenderes
|
||||
[Visual Basic Tutorial](http://www.vbbootcamp.co.uk/ "Visual Basic Tutorial")
|
||||
erstellt.
|
||||
|
||||
Die gesamte Syntax sollte gültig sein.
|
||||
Kopieren Sie den Code und fügen Sie ihn in den Visual Basic Compiler ein und
|
||||
führen Sie das Programm aus (F5).
|
||||
|
@ -187,7 +187,7 @@ $ docker exec -it 7b272 bash
|
||||
# directory. Here 7b272 was our ubuntu container and the above command would
|
||||
# help us interact with the container by opening a bash session.
|
||||
|
||||
$docker logs <container-id>
|
||||
$ docker logs <container-id>
|
||||
# Displays the information logged by the specified container
|
||||
# root@7b27222e4bb7:/# whoami
|
||||
# root
|
||||
@ -245,11 +245,11 @@ image to run ( or build) it.
|
||||
|
||||
```bash
|
||||
|
||||
$docker build <path-to-dockerfile>
|
||||
$ docker build <path-to-dockerfile>
|
||||
# used to build an image from the specified Dockerfile
|
||||
# instead of path we could also specify a URL
|
||||
# -t tag is optional and used to name and tag your images for e.g.
|
||||
# `$docker build -t my-image:0.1 ./home/app`
|
||||
# `$ docker build -t my-image:0.1 ./home/app`
|
||||
# rebuild images everytime you make changes in the dockerfile
|
||||
```
|
||||
|
||||
@ -264,15 +264,15 @@ as part of the source image name. We need to create the target image with the
|
||||
tag name of username/image-name much like GitHub repositories.
|
||||
|
||||
```bash
|
||||
$docker login
|
||||
$ docker login
|
||||
# to login to Docker Hub using your username and password
|
||||
|
||||
$docker tag <src-image>[:<src-tag>] <target-image>[:<target-tag>]
|
||||
$ docker tag <src-image>[:<src-tag>] <target-image>[:<target-tag>]
|
||||
# this tags a local src-image to a public target-image
|
||||
# e.g. `docker tag my-sample-app:1.0.0 akshitadixit/my-sample-app`
|
||||
# if tags are not specified, they're defaulted to `latest`
|
||||
|
||||
$docker push <target-image>[:<target-tag>]
|
||||
$ docker push <target-image>[:<target-tag>]
|
||||
# uploads our image to Docker Hub
|
||||
# e.g. `docker push akshitadixit/my-sample-app`
|
||||
# this image will be accessible under your profile's repositories as
|
||||
|
@ -59,5 +59,3 @@ for i=0 to n-1
|
||||
* [Optimal Substructure Property](https://www.geeksforgeeks.org/dynamic-programming-set-2-optimal-substructure-property/)
|
||||
* [How to solve a DP problem](https://www.geeksforgeeks.org/solve-dynamic-programming-problem/)
|
||||
* [How to write DP solutions](https://www.quora.com/Are-there-any-good-resources-or-tutorials-for-dynamic-programming-DP-besides-the-TopCoder-tutorial/answer/Michal-Danilák)
|
||||
|
||||
And a [quiz](https://www.commonlounge.com/discussion/cdbbfe83bcd64281964b788969247253) to test your knowledge.
|
||||
|
@ -62,7 +62,7 @@ fn add2(x: i32, y: i32) -> i32 {
|
||||
fn main() {
|
||||
// Αριθμοί //
|
||||
|
||||
// Αμετάβλητη σύνδεση
|
||||
// Αμετάβλητη δέσμευση (η τιμή που αντιστοιχεί στο όνομα "x" δεν μπορεί να αλλάξει)
|
||||
let x: i32 = 1;
|
||||
|
||||
// Καταλήξεις integer/float
|
||||
@ -80,7 +80,8 @@ fn main() {
|
||||
// Πράξεις
|
||||
let sum = x + y + 13;
|
||||
|
||||
// Μη-αμετάβλητη αξία (με την έννοια ότι μπορεί να αλλάξει)
|
||||
// Μεταβλητές (με την έννοια των προστακτικών γλωσσών προγραμματισμού).
|
||||
// Στη Rust η αμετάβλητη δέσμευση είναι στάνταρ. Το mut δηλώνει μεταβλητότητα.
|
||||
let mut mutable = 1;
|
||||
mutable = 4;
|
||||
mutable += 2;
|
||||
@ -96,7 +97,7 @@ fn main() {
|
||||
// A `String` – a heap-allocated string
|
||||
let s: String = "καλημέρα κόσμε".to_string();
|
||||
|
||||
// Ένα κομμάτι αλφαριθμητικού (string slice) – μια μη-μεταβλητή οπτική γωνία προς ένα άλλο αλφαριθμητικό
|
||||
// Ένα κομμάτι αλφαριθμητικού (string slice) – μια αμετάβλητη οπτική γωνία προς ένα άλλο αλφαριθμητικό
|
||||
// Το αλφαριθμητικό μπορεί να είναι στατικό όπως τα σταθερά αλφαριθμητικά, ή να περιλαμβάνεται σε ένα άλλο,
|
||||
// δυναμικό αντικείμενο (σε αυτή την περίπτωση τη μεταβλητή `s`)
|
||||
let s_slice: &str = &s;
|
||||
@ -112,7 +113,7 @@ fn main() {
|
||||
let mut vector: Vec<i32> = vec![1, 2, 3, 4];
|
||||
vector.push(5);
|
||||
|
||||
// Ένα κομμάτι – μια μη-μεταβλητή οπτική γωνία προς ένα διάνυσμα ή πίνακα
|
||||
// Ένα κομμάτι – μια αμετάβλητη οπτική γωνία προς ένα διάνυσμα ή πίνακα
|
||||
// Είναι παρόμοιο με το κομμάτι αλφαριθμητικού που είδαμε προηγουμένως
|
||||
let slice: &[i32] = &vector;
|
||||
|
||||
@ -121,10 +122,10 @@ fn main() {
|
||||
|
||||
// Tuples (πλειάδες) //
|
||||
|
||||
// Ένα tuple είναι μια σταθερού μεγέθους σειρά από αξίες (πιθανά διαφορετικού τύπου)
|
||||
// Ένα tuple είναι μια σταθερού μεγέθους σειρά από τιμές (πιθανά διαφορετικού τύπου)
|
||||
let x: (i32, &str, f64) = (1, "καλημέρα", 3.4);
|
||||
|
||||
// Μπορούμε να χρησιμοποιήσουμε το `let` και ένα tuple για να δώσουμε πολλές αξίες σε πολλές μεταβλητές ταυτόχρονα
|
||||
// Μπορούμε να χρησιμοποιήσουμε το `let` και ένα tuple για να δώσουμε πολλές τιμές σε πολλές μεταβλητές ταυτόχρονα
|
||||
// (destructuring `let`)
|
||||
let (a, b, c) = x;
|
||||
println!("{} {} {}", a, b, c); // 1 καλημέρα 3.4
|
||||
@ -185,7 +186,7 @@ fn main() {
|
||||
fn bar(&self) -> &T { // Δανειζόμαστε το self
|
||||
&self.bar
|
||||
}
|
||||
fn bar_mut(&mut self) -> &mut T { // Δανειζόμαστε το self ως μη-αμετάβλητη αξία
|
||||
fn bar_mut(&mut self) -> &mut T { // Γίνεται "μεταβλητός δανεισμός" του self (μπορούμε να το τροποποιήσουμε)
|
||||
&mut self.bar
|
||||
}
|
||||
fn into_bar(self) -> T { // Εδώ το self καταναλώνεται
|
||||
@ -240,7 +241,7 @@ fn main() {
|
||||
// 4. Έλεγχος ροής //
|
||||
/////////////////////
|
||||
|
||||
// Βρόγχοι `for`
|
||||
// Βρόχοι `for`
|
||||
let array = [1, 2, 3];
|
||||
for i in array {
|
||||
println!("{}", i);
|
||||
@ -253,7 +254,7 @@ fn main() {
|
||||
println!("");
|
||||
// Τυπώνει `0 1 2 3 4 5 6 7 8 9 `
|
||||
|
||||
// Βρόγχοι `if`
|
||||
// `if` (υπό συνθήκη διακλάδωση)
|
||||
if 1 == 1 {
|
||||
println!("Τα μαθηματικά δουλεύουν!");
|
||||
} else {
|
||||
@ -267,17 +268,17 @@ fn main() {
|
||||
"κακό"
|
||||
};
|
||||
|
||||
// Βρόγχοι `while`
|
||||
// Βρόχοι `while`
|
||||
while 1 == 1 {
|
||||
println!("Το σύμπαν λειτουργεί κανονικά.");
|
||||
// Μπορούμε να βγούμε από το βρόγχο με το `break`
|
||||
// Μπορούμε να βγούμε από το βρόχο με το `break`
|
||||
break
|
||||
}
|
||||
|
||||
// Ατέρμονος βρόχγος
|
||||
// Ατέρμονος βρόχος
|
||||
loop {
|
||||
println!("Καλημέρα!");
|
||||
// Μπορούμε να βγούμε από το βρόγχο με το `break`
|
||||
// Μπορούμε να βγούμε από το βρόχο με το `break`
|
||||
break
|
||||
}
|
||||
|
||||
@ -294,11 +295,11 @@ fn main() {
|
||||
*now_its_mine += 2;
|
||||
|
||||
println!("{}", now_its_mine); // 7
|
||||
// println!("{}", mine); // Αυτό παράγει λάθος κατά τη μεταγλώττιση διότι τώρα ο δείκτης ανοίκει στο `now_its_mine`
|
||||
// println!("{}", mine); // Αυτό παράγει λάθος κατά τη μεταγλώττιση διότι τώρα ο δείκτης ανήκει στο `now_its_mine`
|
||||
|
||||
// Reference (αναφορά) – ένας αμετάβλητος δείκτης που αναφέρεται σε άλλα δεδομένα
|
||||
// Όταν μια αναφορά δίνεται σε μια αξία, λέμε πως η αξία έχει "δανειστεί".
|
||||
// Όταν μια αξία δανείζεται αμετάβλητα, δεν μπορεί να είναι mutated (να μεταβληθεί) ή να μετακινηθεί.
|
||||
// Όταν μια αναφορά δίνεται σε μια τιμή, λέμε πως η τιμή έχει "δανειστεί".
|
||||
// Όταν μια τιμή δανείζεται αμετάβλητα, δεν μπορεί να είναι mutated (να μεταβληθεί) ή να μετακινηθεί.
|
||||
// Ένας "δανεισμός" παραμένει ενεργός μέχρι την τελευταία χρήση της μεταβλητής που δανείζεται.
|
||||
let mut var = 4;
|
||||
var = 3;
|
||||
@ -313,13 +314,13 @@ fn main() {
|
||||
var = 2; // Η `ref_var` δεν χρησιμοποιείται από εδώ και στο εξής, άρα ο "δανεισμός" τελειώνει
|
||||
|
||||
// Μεταβλητή αναφορά
|
||||
// Όσο μια αξία είναι μεταβλητά δανεισμένη, παραμένει τελείως απροσβάσιμη.
|
||||
// Όσο μια τιμή είναι μεταβλητά δανεισμένη, παραμένει τελείως απροσβάσιμη.
|
||||
let mut var2 = 4;
|
||||
let ref_var2: &mut i32 = &mut var2;
|
||||
*ref_var2 += 2; // Ο αστερίσκος (*) χρησιμοποιείται ως δείκτης προς την μεταβλητά δανεισμένη `var2`
|
||||
|
||||
println!("{}", *ref_var2); // 6 , // Αν είχαμε `var2` εδώ θα προκαλούνταν λάθος μεταγλώττισης.
|
||||
// O τύπος της `ref_var2` είναι &mut i32, άρα αποθηκεύει μια αναφορά προς μια αξία i32, όχι την αξία την ίδια.
|
||||
// O τύπος της `ref_var2` είναι &mut i32, άρα αποθηκεύει μια αναφορά προς μια τιμή i32, όχι την τιμή την ίδια.
|
||||
// var2 = 2; // Λάθος μεταγλώττισης, γιατί η `var2` είναι δανεισμένη.
|
||||
ref_var2; // Εντολή no-op (τίποτα δεν εκτελείται από τον επεξεργαστή), η οποία όμως μετράει ως χρήση και κρατά τον
|
||||
// "δανεισμό" ενεργό
|
||||
|
@ -3,6 +3,7 @@ language: elisp
|
||||
contributors:
|
||||
- ["Bastien Guerry", "https://bzg.fr"]
|
||||
- ["Saurabh Sandav", "http://github.com/SaurabhSandav"]
|
||||
- ["rilysh", "https://github.com/rilysh"]
|
||||
filename: learn-emacs-lisp.el
|
||||
---
|
||||
|
||||
@ -12,11 +13,11 @@ filename: learn-emacs-lisp.el
|
||||
;; First make sure you read this text by Peter Norvig:
|
||||
;; http://norvig.com/21-days.html
|
||||
;;
|
||||
;; Then install GNU Emacs 24.3:
|
||||
;; Then install latest version of GNU Emacs:
|
||||
;;
|
||||
;; Debian: apt-get install emacs (or see your distro instructions)
|
||||
;; OSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg
|
||||
;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip
|
||||
;; OSX: https://emacsformacosx.com/
|
||||
;; Windows: https://ftp.gnu.org/gnu/emacs/windows/
|
||||
;;
|
||||
;; More general information can be found at:
|
||||
;; http://www.gnu.org/software/emacs/#Obtaining
|
||||
@ -76,12 +77,12 @@ filename: learn-emacs-lisp.el
|
||||
;; `C-j' inserts the result of the evaluation in the buffer.
|
||||
|
||||
;; `C-xC-e' displays the same result in Emacs bottom line,
|
||||
;; called the "minibuffer". We will generally use `C-xC-e',
|
||||
;; called the "echo area". We will generally use `C-xC-e',
|
||||
;; as we don't want to clutter the buffer with useless text.
|
||||
|
||||
;; `setq' stores a value into a variable:
|
||||
(setq my-name "Bastien")
|
||||
;; `C-xC-e' => "Bastien" (displayed in the mini-buffer)
|
||||
;; `C-xC-e' => "Bastien" (displayed in the echo area)
|
||||
|
||||
;; `insert' will insert "Hello!" where the cursor is:
|
||||
(insert "Hello!")
|
||||
@ -343,3 +344,9 @@ filename: learn-emacs-lisp.el
|
||||
;; To read an online introduction to Emacs Lisp:
|
||||
;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
|
||||
```
|
||||
|
||||
### Further Reading
|
||||
- [GNU Elisp Manual](https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html)
|
||||
- [Emacs Wiki](https://www.emacswiki.org/emacs/LearningEmacs)
|
||||
- [Emacs Docs](https://emacsdocs.org/docs/elisp/Emacs-Lisp)
|
||||
- [Mpre Elisp Docs](https://www.math.utah.edu/docs/info/elisp_22.html)
|
||||
|
@ -224,7 +224,7 @@ List.map : (a -> b) -> List a -> List b
|
||||
-- Comparable allows you to order numbers and strings, like a < b.
|
||||
-- Appendable things can be combined with a ++ b.
|
||||
|
||||
{-- Type Aliases and Union Types --}
|
||||
{-- Type Aliases and Custom Types --}
|
||||
|
||||
-- When you write a record or tuple, its type already exists.
|
||||
-- (Notice that record types use colon and record values use equals.)
|
||||
@ -244,28 +244,28 @@ otherOrigin =
|
||||
-- But it's still the same type, so you can equate them.
|
||||
origin == otherOrigin -- True
|
||||
|
||||
-- By contrast, defining a union type creates a type that didn't exist before.
|
||||
-- A union type is so called because it can be one of many possibilities.
|
||||
-- Each of the possibilities is represented as a "tag".
|
||||
-- By contrast, defining a custom type creates a type that didn't exist before.
|
||||
-- A custom type is so called because it can be one of many possibilities.
|
||||
-- Each of the possibilities is represented as a "type variant".
|
||||
type Direction =
|
||||
North | South | East | West
|
||||
|
||||
-- Tags can carry other values of known type. This can work recursively.
|
||||
-- Type variants can carry other values of known type. This can work recursively.
|
||||
type IntTree =
|
||||
Leaf | Node Int IntTree IntTree
|
||||
-- "Leaf" and "Node" are the tags. Everything following a tag is a type.
|
||||
-- "Leaf" and "Node" are the type variants. Everything following a type variant is a type.
|
||||
|
||||
-- Tags can be used as values or functions.
|
||||
-- Type variants can be used as values or functions.
|
||||
root : IntTree
|
||||
root =
|
||||
Node 7 Leaf Leaf
|
||||
|
||||
-- Union types (and type aliases) can use type variables.
|
||||
-- Custom types (and type aliases) can use type variables.
|
||||
type Tree a =
|
||||
Leaf | Node a (Tree a) (Tree a)
|
||||
-- "The type tree-of-a is a leaf, or a node of a, tree-of-a, and tree-of-a."
|
||||
|
||||
-- Pattern match union tags. The uppercase tags will be matched exactly. The
|
||||
-- Pattern match variants in a custom type. The uppercase variants will be matched exactly. The
|
||||
-- lowercase variables will match anything. Underscore also matches anything,
|
||||
-- but signifies that you aren't using it.
|
||||
leftmostElement : Tree a -> Maybe a
|
||||
@ -289,7 +289,7 @@ module Name where
|
||||
-- By default, everything is exported. You can specify exports explicitly.
|
||||
module Name (MyType, myValue) where
|
||||
|
||||
-- One common pattern is to export a union type but not its tags. This is known
|
||||
-- One common pattern is to export a custom type but not its type variants. This is known
|
||||
-- as an "opaque type", and is frequently used in libraries.
|
||||
|
||||
-- Import code from other modules to use it in this one.
|
||||
|
@ -5,7 +5,7 @@ contributors:
|
||||
translators:
|
||||
- ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
|
||||
lang: es-es
|
||||
filename: asciidoc-es.md
|
||||
filename: asciidoc-es.adoc
|
||||
---
|
||||
|
||||
AsciiDoc es un lenguaje de marcas similar a Markdown que puede ser usado para cualquier uso, desde libros a blogs.
|
||||
|
@ -196,7 +196,7 @@ function string_functions( localvar, arr) {
|
||||
# Ambas regresan el número de matches remplazados.
|
||||
localvar = "fooooobar"
|
||||
sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar"
|
||||
gsub("e", ".", localvar) # localvar => "m..t m. at th. bar"
|
||||
gsub("e", ".", localvar) # localvar => "M..t m. at th. bar"
|
||||
|
||||
# Buscar una cadena que haga match con una expresión regular
|
||||
# index() hace lo mismo, pero no permite expresiones regulares
|
||||
|
1219
es-es/chapel-es.html.markdown
Normal file
1219
es-es/chapel-es.html.markdown
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,327 +0,0 @@
|
||||
---
|
||||
language: css
|
||||
contributors:
|
||||
- ["Mohammad Valipour", "https://github.com/mvalipour"]
|
||||
- ["Marco Scannadinari", "https://github.com/marcoms"]
|
||||
- ["Geoffrey Liu", "https://github.com/g-liu"]
|
||||
- ["Connor Shea", "https://github.com/connorshea"]
|
||||
- ["Deepanshu Utkarsh", "https://github.com/duci9y"]
|
||||
- ["Brett Taylor", "https://github.com/glutnix"]
|
||||
- ["Tyler Mumford", "https://tylermumford.com"]
|
||||
translators:
|
||||
- ["miky ackerman", "https://github.com/mikyackerman"]
|
||||
lang: es-es
|
||||
filename: learncss-es.css
|
||||
---
|
||||
|
||||
Paginas web estan contruidas en HTML, lo cual especifica el contenido de una pagina
|
||||
CSS(Hoja de Estilos en Cascada) es un lenguaje separado el cual especifica
|
||||
la **apariencia** de una pagina.
|
||||
|
||||
codigo CSS esta hecho de *reglas* estaticas. Cada regla toma uno o mas *selectores* y da *valores* especificos a un numero de *propiedades* visuales. Esas propiedades estan entonces aplicadas a los elementos indicados en una pagina por los selectores
|
||||
|
||||
Esta guia ha sido escrita con CSS 2 en mente, la cual es extendida por una nueva caracterica de CSS 3.
|
||||
|
||||
**NOTA:** Debido a que CSS produce resultados visuales, para aprenderlo, necesitas
|
||||
Probar todo en un patio de juegos CSS como [dabblet] (http://dabblet.com/).
|
||||
El objetivo principal de este artículo es la sintaxis y algunos consejos generales.
|
||||
|
||||
## Sintaxis
|
||||
|
||||
```css
|
||||
/* Los comentarios aparecen dentro de un diagonal-asterisco, justo como esta linea
|
||||
no hay "comentarios en una linea"; este es el unico estilo de comentario.*/
|
||||
|
||||
|
||||
/* ####################
|
||||
## SELECTORS
|
||||
#################### */
|
||||
|
||||
/* el selector es usado para apuntar a un elemento de la pagina. */
|
||||
selector { property: value; /* more properties...*/ }
|
||||
|
||||
/*
|
||||
Here is an example element:
|
||||
|
||||
<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' />
|
||||
*/
|
||||
|
||||
/* You can target it using one of its CSS classes */
|
||||
.class1 { }
|
||||
|
||||
/* or both classes! */
|
||||
.class1.class2 { }
|
||||
|
||||
/* or its name */
|
||||
div { }
|
||||
|
||||
/* or its id */
|
||||
#anID { }
|
||||
|
||||
/* or using the fact that it has an attribute! */
|
||||
[attr] { font-size:smaller; }
|
||||
|
||||
/* or that the attribute has a specific value */
|
||||
[attr='value'] { font-size:smaller; }
|
||||
|
||||
/* starts with a value (CSS 3) */
|
||||
[attr^='val'] { font-size:smaller; }
|
||||
|
||||
/* or ends with a value (CSS 3) */
|
||||
[attr$='ue'] { font-size:smaller; }
|
||||
|
||||
/* or contains a value in a space-separated list */
|
||||
[otherAttr~='foo'] { }
|
||||
[otherAttr~='bar'] { }
|
||||
|
||||
/* or contains a value in a dash-separated list, e.g., "-" (U+002D) */
|
||||
[otherAttr|='en'] { font-size:smaller; }
|
||||
|
||||
|
||||
/* You can combine different selectors to create a more focused selector. Don't
|
||||
put spaces between them. */
|
||||
div.some-class[attr$='ue'] { }
|
||||
|
||||
/* You can select an element which is a child of another element */
|
||||
div.some-parent > .class-name { }
|
||||
|
||||
/* or a descendant of another element. Children are the direct descendants of
|
||||
their parent element, only one level down the tree. Descendants can be any
|
||||
level down the tree. */
|
||||
div.some-parent .class-name { }
|
||||
|
||||
/* Warning: the same selector without a space has another meaning.
|
||||
Can you guess what? */
|
||||
div.some-parent.class-name { }
|
||||
|
||||
/* You may also select an element based on its adjacent sibling */
|
||||
.i-am-just-before + .this-element { }
|
||||
|
||||
/* or any sibling preceding it */
|
||||
.i-am-any-element-before ~ .this-element { }
|
||||
|
||||
/* There are some selectors called pseudo classes that can be used to select an
|
||||
element only when it is in a particular state */
|
||||
|
||||
/* for example, when the cursor hovers over an element */
|
||||
selector:hover { }
|
||||
|
||||
/* or a link has been visited */
|
||||
selector:visited { }
|
||||
|
||||
/* or hasn't been visited */
|
||||
selected:link { }
|
||||
|
||||
/* or an element is in focus */
|
||||
selected:focus { }
|
||||
|
||||
/* any element that is the first child of its parent */
|
||||
selector:first-child {}
|
||||
|
||||
/* any element that is the last child of its parent */
|
||||
selector:last-child {}
|
||||
|
||||
/* Just like pseudo classes, pseudo elements allow you to style certain parts of
|
||||
a document */
|
||||
|
||||
/* matches a virtual first child of the selected element */
|
||||
selector::before {}
|
||||
|
||||
/* matches a virtual last child of the selected element */
|
||||
selector::after {}
|
||||
|
||||
/* At appropriate places, an asterisk may be used as a wildcard to select every
|
||||
element */
|
||||
* { } /* all elements */
|
||||
.parent * { } /* all descendants */
|
||||
.parent > * { } /* all children */
|
||||
|
||||
/* ####################
|
||||
## PROPERTIES
|
||||
#################### */
|
||||
|
||||
selector {
|
||||
|
||||
/* Units of length can be absolute or relative. */
|
||||
|
||||
/* Relative units */
|
||||
width: 50%; /* percentage of parent element width */
|
||||
font-size: 2em; /* multiples of element's original font-size */
|
||||
font-size: 2rem; /* or the root element's font-size */
|
||||
font-size: 2vw; /* multiples of 1% of the viewport's width (CSS 3) */
|
||||
font-size: 2vh; /* or its height */
|
||||
font-size: 2vmin; /* whichever of a vh or a vw is smaller */
|
||||
font-size: 2vmax; /* or greater */
|
||||
|
||||
/* Absolute units */
|
||||
width: 200px; /* pixels */
|
||||
font-size: 20pt; /* points */
|
||||
width: 5cm; /* centimeters */
|
||||
min-width: 50mm; /* millimeters */
|
||||
max-width: 5in; /* inches */
|
||||
|
||||
/* Colors */
|
||||
color: #F6E; /* short hex format */
|
||||
color: #FF66EE; /* long hex format */
|
||||
color: tomato; /* a named color */
|
||||
color: rgb(255, 255, 255); /* as rgb values */
|
||||
color: rgb(10%, 20%, 50%); /* as rgb percentages */
|
||||
color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */
|
||||
color: transparent; /* equivalent to setting the alpha to 0 */
|
||||
color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */
|
||||
color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */
|
||||
|
||||
/* Borders */
|
||||
border-width:5px;
|
||||
border-style:solid;
|
||||
border-color:red; /* similar to how background-color is set */
|
||||
border: 5px solid red; /* this is a short hand approach for the same */
|
||||
border-radius:20px; /* this is a CSS3 property */
|
||||
|
||||
/* Images as backgrounds of elements */
|
||||
background-image: url(/img-path/img.jpg); /* quotes inside url() optional */
|
||||
|
||||
/* Fonts */
|
||||
font-family: Arial;
|
||||
/* if the font family name has a space, it must be quoted */
|
||||
font-family: "Courier New";
|
||||
/* if the first one is not found, the browser uses the next, and so on */
|
||||
font-family: "Courier New", Trebuchet, Arial, sans-serif;
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Save a CSS stylesheet with the extension `.css`.
|
||||
|
||||
```html
|
||||
<!-- You need to include the css file in your page's <head>. This is the
|
||||
recommended method. Refer to http://stackoverflow.com/questions/8284365 -->
|
||||
<link rel='stylesheet' type='text/css' href='path/to/style.css'>
|
||||
|
||||
<!-- You can also include some CSS inline in your markup. -->
|
||||
<style>
|
||||
a { color: purple; }
|
||||
</style>
|
||||
|
||||
<!-- Or directly set CSS properties on the element. -->
|
||||
<div style="border: 1px solid red;">
|
||||
</div>
|
||||
```
|
||||
|
||||
## Precedence or Cascade
|
||||
|
||||
An element may be targeted by multiple selectors and may have a property set on
|
||||
it in more than once. In these cases, one of the rules takes precedence over
|
||||
others. Rules with a more specific selector take precedence over a less specific
|
||||
one, and a rule occurring later in the stylesheet overwrites a previous one
|
||||
(which also means that if two different linked stylesheets contain rules for an
|
||||
element and if the rules are of the same specificity, then order of linking
|
||||
would take precedence and the sheet linked latest would govern styling) .
|
||||
|
||||
This process is called cascading, hence the name Cascading Style Sheets.
|
||||
|
||||
Given the following CSS:
|
||||
|
||||
```css
|
||||
/* A */
|
||||
p.class1[attr='value']
|
||||
|
||||
/* B */
|
||||
p.class1 { }
|
||||
|
||||
/* C */
|
||||
p.class2 { }
|
||||
|
||||
/* D */
|
||||
p { }
|
||||
|
||||
/* E */
|
||||
p { property: value !important; }
|
||||
```
|
||||
|
||||
and the following markup:
|
||||
|
||||
```html
|
||||
<p style='/*F*/ property:value;' class='class1 class2' attr='value'>
|
||||
```
|
||||
|
||||
The precedence of style is as follows. Remember, the precedence is for each
|
||||
**property**, not for the entire block.
|
||||
|
||||
* `E` has the highest precedence because of the keyword `!important`. It is
|
||||
recommended that you avoid its usage.
|
||||
* `F` is next, because it is an inline style.
|
||||
* `A` is next, because it is more "specific" than anything else. It has 3
|
||||
specifiers: The name of the element `p`, its class `class1`, an attribute
|
||||
`attr='value'`.
|
||||
* `C` is next, even though it has the same specificity as `B`.
|
||||
This is because it appears after `B`.
|
||||
* `B` is next.
|
||||
* `D` is the last one.
|
||||
|
||||
## Media Queries
|
||||
|
||||
CSS Media Queries are a feature in CSS 3 which allows you to specify when certain CSS rules should be applied, such as when printed, or when on a screen with certain dimensions or pixel density. They do not add to the selector's specificity.
|
||||
|
||||
```css
|
||||
/* A rule that will be used on all devices */
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
color: white;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
/* change the h1 to use less ink on a printer */
|
||||
@media print {
|
||||
h1 {
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
|
||||
/* make the font bigger when shown on a screen at least 480px wide */
|
||||
@media screen and (min-width: 480px) {
|
||||
h1 {
|
||||
font-size: 3em;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Media queries can include these features:
|
||||
`width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. Most of these features can be prefixed with `min-` or `max-`.
|
||||
|
||||
The `resolution` feature is not supported by older devices, instead use `device-pixel-ratio`.
|
||||
|
||||
Many smartphones and tablets will attempt to render the page as if it were on a desktop unless you provide a `viewport` meta-tag.
|
||||
|
||||
```html
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width; initial-scale=1.0">
|
||||
</head>
|
||||
```
|
||||
|
||||
## Compatibility
|
||||
|
||||
Most of the features in CSS 2 (and many in CSS 3) are available across all
|
||||
browsers and devices. But it's always good practice to check before using
|
||||
a new feature.
|
||||
|
||||
## Resources
|
||||
|
||||
* [CanIUse](http://caniuse.com) (Detailed compatibility info)
|
||||
* [Dabblet](http://dabblet.com/) (CSS playground)
|
||||
* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS) (Tutorials and reference)
|
||||
* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/) (Reference)
|
||||
|
||||
## Further Reading
|
||||
|
||||
* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/)
|
||||
* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/)
|
||||
* [QuirksMode CSS](http://www.quirksmode.org/css/)
|
||||
* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context)
|
||||
* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing
|
||||
* [CSS-Tricks](https://css-tricks.com)
|
||||
|
||||
|
@ -1,253 +1,327 @@
|
||||
---
|
||||
language: css
|
||||
filename: learncss-es.css
|
||||
contributors:
|
||||
- ["Mohammad Valipour", "https://github.com/mvalipour"]
|
||||
- ["Marco Scannadinari", "https://github.com/marcoms"]
|
||||
- ["Geoffrey Liu", "https://github.com/g-liu"]
|
||||
- ["Connor Shea", "https://github.com/connorshea"]
|
||||
- ["Deepanshu Utkarsh", "https://github.com/duci9y"]
|
||||
- ["Brett Taylor", "https://github.com/glutnix"]
|
||||
- ["Tyler Mumford", "https://tylermumford.com"]
|
||||
translators:
|
||||
- ["Daniel Zendejas","https://github.com/DanielZendejas"]
|
||||
- ["miky ackerman", "https://github.com/mikyackerman"]
|
||||
lang: es-es
|
||||
filename: learncss-es.css
|
||||
---
|
||||
|
||||
Tutorial de CSS en español
|
||||
Paginas web estan contruidas en HTML, lo cual especifica el contenido de una pagina
|
||||
CSS(Hoja de Estilos en Cascada) es un lenguaje separado el cual especifica
|
||||
la **apariencia** de una pagina.
|
||||
|
||||
En los primeros días de la web no había elementos visuales, todo
|
||||
era texto plano. Pero después, con el desarrollo de los navegadores,
|
||||
las páginas con contenido visual empezaron a ser más comunes.
|
||||
CSS es el lenguaje estándar que existe para separar el contenido
|
||||
(HTML) y el aspecto visual de las páginas web.
|
||||
codigo CSS esta hecho de *reglas* estaticas. Cada regla toma uno o mas *selectores* y da *valores* especificos a un numero de *propiedades* visuales. Esas propiedades estan entonces aplicadas a los elementos indicados en una pagina por los selectores
|
||||
|
||||
Lo que CSS hace es proveer con una sintaxis que te permite apuntar a distintos
|
||||
elementos HTML y asignarles diferentes propiedades visuales.
|
||||
Esta guia ha sido escrita con CSS 2 en mente, la cual es extendida por una nueva caracterica de CSS 3.
|
||||
|
||||
CSS, como cualquier otro lenguaje, tiene múltiples versiones. Aquí nos enfocamos
|
||||
en CSS 2.0. No es la versión más reciente pero sí la más soportada y compatible.
|
||||
**NOTA:** Debido a que CSS produce resultados visuales, para aprenderlo, necesitas
|
||||
Probar todo en un patio de juegos CSS como [dabblet] (http://dabblet.com/).
|
||||
El objetivo principal de este artículo es la sintaxis y algunos consejos generales.
|
||||
|
||||
**NOTA:** Como los resultados de CSS son efectos visuales, para aprenderlo,
|
||||
necesitarás probar todo tipo de cosas en ambientes como
|
||||
[dabblet](http://dabblet.com/). Este artículo se enfoca, principalmente, en
|
||||
la sintaxis y consejos generales.
|
||||
## Sintaxis
|
||||
|
||||
```css
|
||||
/* ¡Los comentarios aparecen dentro de diagonal-asterisco, justo como esta línea! */
|
||||
/* Los comentarios aparecen dentro de un diagonal-asterisco, justo como esta linea
|
||||
no hay "comentarios en una linea"; este es el unico estilo de comentario.*/
|
||||
|
||||
|
||||
/* ####################
|
||||
## SELECTORES
|
||||
####################*/
|
||||
## SELECTORS
|
||||
#################### */
|
||||
|
||||
/* Generalmente, la sentencia principal en CSS es muy simple. */
|
||||
selector { propiedad: valor; /* más propiedades separados por punto y coma...*/ }
|
||||
|
||||
/* El selector es usado para apuntar a (seleccionar) un elemento en la página.
|
||||
|
||||
¡Puedes apuntar a todos los elementos en la página con el asterisco! */
|
||||
* { color:red; }
|
||||
/* el selector es usado para apuntar a un elemento de la pagina. */
|
||||
selector { property: value; /* more properties...*/ }
|
||||
|
||||
/*
|
||||
Dado un elemento como este en la página:
|
||||
Here is an example element:
|
||||
|
||||
<div class='una-clase clase2' id='unaId' attr='valor' />
|
||||
<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' />
|
||||
*/
|
||||
|
||||
/* puedes seleccionar el <div> por el nombre de su clase */
|
||||
.una-clase { }
|
||||
/* You can target it using one of its CSS classes */
|
||||
.class1 { }
|
||||
|
||||
/*¡O por sus dos clases! */
|
||||
.una-clase.clase2 { }
|
||||
/* or both classes! */
|
||||
.class1.class2 { }
|
||||
|
||||
/* O por el nombre de su elemento */
|
||||
/* or its name */
|
||||
div { }
|
||||
|
||||
/* O por su Id */
|
||||
#unaId { }
|
||||
/* or its id */
|
||||
#anID { }
|
||||
|
||||
/* ¡O por el hecho de que tiene un atributo! */
|
||||
/* or using the fact that it has an attribute! */
|
||||
[attr] { font-size:smaller; }
|
||||
|
||||
/* O por el hecho de que el atributo tiene un valor determinado */
|
||||
[attr='valor'] { font-size:smaller; }
|
||||
/* or that the attribute has a specific value */
|
||||
[attr='value'] { font-size:smaller; }
|
||||
|
||||
/* Empieza con un valor ('val' en este caso)*/
|
||||
/* starts with a value (CSS 3) */
|
||||
[attr^='val'] { font-size:smaller; }
|
||||
|
||||
/* O termina con un valor ('or' en este caso) */
|
||||
[attr$='or'] { font-size:smaller; }
|
||||
/* or ends with a value (CSS 3) */
|
||||
[attr$='ue'] { font-size:smaller; }
|
||||
|
||||
/* O incluso contiene un valor ('lo' en este caso) */
|
||||
[attr~='lo'] { font-size:smaller; }
|
||||
/* or contains a value in a space-separated list */
|
||||
[otherAttr~='foo'] { }
|
||||
[otherAttr~='bar'] { }
|
||||
|
||||
/*Más importante, puedes combinar estos criterios de búsqueda entre sí.
|
||||
No debe existir ningún espacio entre estas partes porque hace que el
|
||||
significado cambie.*/
|
||||
div.una-clase[attr$='or'] { }
|
||||
/* or contains a value in a dash-separated list, e.g., "-" (U+002D) */
|
||||
[otherAttr|='en'] { font-size:smaller; }
|
||||
|
||||
/* También puedes seleccionar un elemento HTML basándote en sus padres*/
|
||||
|
||||
/* Un elemento que es hijo directo de otro elemento (Seleccionado de la forma que
|
||||
vimos anteriormente) */
|
||||
/* You can combine different selectors to create a more focused selector. Don't
|
||||
put spaces between them. */
|
||||
div.some-class[attr$='ue'] { }
|
||||
|
||||
div.un-padre > .nombre-clase {}
|
||||
/* You can select an element which is a child of another element */
|
||||
div.some-parent > .class-name { }
|
||||
|
||||
/* O cualquiera de sus ancestros en la jerarquía*/
|
||||
/* La siguiente sentencia selecciona a cualquier elemento que tenga una clase
|
||||
"nombre-clase" y sea hijo de un div con clase "un-padre" EN CUALQUIER PROFUNDIDAD*/
|
||||
div.un-padre .nombre-clase {}
|
||||
/* or a descendant of another element. Children are the direct descendants of
|
||||
their parent element, only one level down the tree. Descendants can be any
|
||||
level down the tree. */
|
||||
div.some-parent .class-name { }
|
||||
|
||||
/* advertencia: el mismo selector sin espacio tiene otro significado. ¿Puedes
|
||||
identificar la diferencia?*/
|
||||
/* Warning: the same selector without a space has another meaning.
|
||||
Can you guess what? */
|
||||
div.some-parent.class-name { }
|
||||
|
||||
/* También puedes seleccionar un elemento basado en su hermano inmediato previo*/
|
||||
.yo-estoy-antes + .este-elemento { }
|
||||
/* You may also select an element based on its adjacent sibling */
|
||||
.i-am-just-before + .this-element { }
|
||||
|
||||
/*o cualquier hermano previo */
|
||||
.yo-soy-cualquiera-antes ~ .estes-elemento {}
|
||||
/* or any sibling preceding it */
|
||||
.i-am-any-element-before ~ .this-element { }
|
||||
|
||||
/* Existen algunas pseudo-clases que permiten seleccionar un elemento
|
||||
basado en el comportamiendo de la página (a diferencia de la estructura de
|
||||
la página) */
|
||||
/* There are some selectors called pseudo classes that can be used to select an
|
||||
element only when it is in a particular state */
|
||||
|
||||
/* Por ejemplo, para cuando pasas el mouse por encima de un elemento */
|
||||
:hover {}
|
||||
/* for example, when the cursor hovers over an element */
|
||||
selector:hover { }
|
||||
|
||||
/* o una liga visitada*/
|
||||
:visited {}
|
||||
/* or a link has been visited */
|
||||
selector:visited { }
|
||||
|
||||
/* o una liga no visitada aún*/
|
||||
:link {}
|
||||
/* or hasn't been visited */
|
||||
selected:link { }
|
||||
|
||||
/* o un elemento de un formulario que esté seleccionado */
|
||||
:focus {}
|
||||
/* or an element is in focus */
|
||||
selected:focus { }
|
||||
|
||||
/* any element that is the first child of its parent */
|
||||
selector:first-child {}
|
||||
|
||||
/* any element that is the last child of its parent */
|
||||
selector:last-child {}
|
||||
|
||||
/* Just like pseudo classes, pseudo elements allow you to style certain parts of
|
||||
a document */
|
||||
|
||||
/* matches a virtual first child of the selected element */
|
||||
selector::before {}
|
||||
|
||||
/* matches a virtual last child of the selected element */
|
||||
selector::after {}
|
||||
|
||||
/* At appropriate places, an asterisk may be used as a wildcard to select every
|
||||
element */
|
||||
* { } /* all elements */
|
||||
.parent * { } /* all descendants */
|
||||
.parent > * { } /* all children */
|
||||
|
||||
/* ####################
|
||||
## PROPIEDADES
|
||||
####################*/
|
||||
## PROPERTIES
|
||||
#################### */
|
||||
|
||||
selector {
|
||||
|
||||
/* Unidades */
|
||||
width: 50%; /* en porcentaje */
|
||||
font-size: 2em; /* dos veces el tamaño de la fuente actual */
|
||||
width: 200px; /* en pixeles */
|
||||
font-size: 20pt; /* en puntos */
|
||||
width: 5cm; /* en centimetros */
|
||||
width: 50mm; /* en milimetros */
|
||||
width: 5in; /* en pulgadas */
|
||||
|
||||
/* Colores */
|
||||
background-color: #F6E; /* en hexadecimal corto */
|
||||
background-color: #F262E2; /* en hexadecimal largo */
|
||||
background-color: tomato; /* puede ser un color con nombre */
|
||||
background-color: rgb(255, 255, 255); /* en rgb */
|
||||
background-color: rgb(10%, 20%, 50%); /* en rgb percent */
|
||||
background-color: rgba(255, 0, 0, 0.3); /* en rgb semi-transparente (con valor alfa)*/
|
||||
|
||||
/* Imagenes */
|
||||
background-image: url(/ruta-a-la-imagen/imagen.jpg);
|
||||
|
||||
/* Fuentes */
|
||||
font-family: Arial;
|
||||
font-family: "Courier New"; /* si el nombre contiene espacios, debe ir entre comillas */
|
||||
font-family: "Courier New", Trebuchet, Arial; /* si la primera fuente no se encontró
|
||||
entonces se busca la seguna, o la tercera, así recursivamente*/
|
||||
}
|
||||
|
||||
/* Units of length can be absolute or relative. */
|
||||
|
||||
/* Relative units */
|
||||
width: 50%; /* percentage of parent element width */
|
||||
font-size: 2em; /* multiples of element's original font-size */
|
||||
font-size: 2rem; /* or the root element's font-size */
|
||||
font-size: 2vw; /* multiples of 1% of the viewport's width (CSS 3) */
|
||||
font-size: 2vh; /* or its height */
|
||||
font-size: 2vmin; /* whichever of a vh or a vw is smaller */
|
||||
font-size: 2vmax; /* or greater */
|
||||
|
||||
/* Absolute units */
|
||||
width: 200px; /* pixels */
|
||||
font-size: 20pt; /* points */
|
||||
width: 5cm; /* centimeters */
|
||||
min-width: 50mm; /* millimeters */
|
||||
max-width: 5in; /* inches */
|
||||
|
||||
/* Colors */
|
||||
color: #F6E; /* short hex format */
|
||||
color: #FF66EE; /* long hex format */
|
||||
color: tomato; /* a named color */
|
||||
color: rgb(255, 255, 255); /* as rgb values */
|
||||
color: rgb(10%, 20%, 50%); /* as rgb percentages */
|
||||
color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */
|
||||
color: transparent; /* equivalent to setting the alpha to 0 */
|
||||
color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */
|
||||
color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */
|
||||
|
||||
/* Borders */
|
||||
border-width:5px;
|
||||
border-style:solid;
|
||||
border-color:red; /* similar to how background-color is set */
|
||||
border: 5px solid red; /* this is a short hand approach for the same */
|
||||
border-radius:20px; /* this is a CSS3 property */
|
||||
|
||||
/* Images as backgrounds of elements */
|
||||
background-image: url(/img-path/img.jpg); /* quotes inside url() optional */
|
||||
|
||||
/* Fonts */
|
||||
font-family: Arial;
|
||||
/* if the font family name has a space, it must be quoted */
|
||||
font-family: "Courier New";
|
||||
/* if the first one is not found, the browser uses the next, and so on */
|
||||
font-family: "Courier New", Trebuchet, Arial, sans-serif;
|
||||
}
|
||||
```
|
||||
|
||||
## Uso
|
||||
## Usage
|
||||
|
||||
Guarda cualquier CSS que quieras en un archivo con extensión `.css`.
|
||||
Save a CSS stylesheet with the extension `.css`.
|
||||
|
||||
```xml
|
||||
<!-- Necesitas incluir tu archivo CSS en el elemento <head> de tu HTML: -->
|
||||
<link rel='stylesheet' type='text/css' href='ruta/archivoDeEstilos.css' />
|
||||
```html
|
||||
<!-- You need to include the css file in your page's <head>. This is the
|
||||
recommended method. Refer to http://stackoverflow.com/questions/8284365 -->
|
||||
<link rel='stylesheet' type='text/css' href='path/to/style.css'>
|
||||
|
||||
<!--
|
||||
también puedes incluir CSS dentro del archivo HTML. Esta no es una buena práctica
|
||||
y debe ser evitada.
|
||||
-->
|
||||
<!-- You can also include some CSS inline in your markup. -->
|
||||
<style>
|
||||
selector { propiedad:valor; }
|
||||
a { color: purple; }
|
||||
</style>
|
||||
|
||||
<!--
|
||||
También se pueden aplicar propiedades al elemento directamente.
|
||||
Esta práctica también debe ser evitada a toda costa
|
||||
-->
|
||||
<div style='propiedad:valor;'>
|
||||
<!-- Or directly set CSS properties on the element. -->
|
||||
<div style="border: 1px solid red;">
|
||||
</div>
|
||||
|
||||
```
|
||||
|
||||
## Preferencia y orden
|
||||
## Precedence or Cascade
|
||||
|
||||
Como te habrás dado cuenta un elemento puede ser seleccionado por más
|
||||
de un selector. En este caso alguna de las reglas cobra preferencia
|
||||
sobre las otras:
|
||||
An element may be targeted by multiple selectors and may have a property set on
|
||||
it in more than once. In these cases, one of the rules takes precedence over
|
||||
others. Rules with a more specific selector take precedence over a less specific
|
||||
one, and a rule occurring later in the stylesheet overwrites a previous one
|
||||
(which also means that if two different linked stylesheets contain rules for an
|
||||
element and if the rules are of the same specificity, then order of linking
|
||||
would take precedence and the sheet linked latest would govern styling) .
|
||||
|
||||
Dado el siguiente CSS:
|
||||
This process is called cascading, hence the name Cascading Style Sheets.
|
||||
|
||||
Given the following CSS:
|
||||
|
||||
```css
|
||||
/*A*/
|
||||
p.clase1[attr='valor']
|
||||
/* A */
|
||||
p.class1[attr='value']
|
||||
|
||||
/*B*/
|
||||
p.clase1 {}
|
||||
/* B */
|
||||
p.class1 { }
|
||||
|
||||
/*C*/
|
||||
p.clase2 {}
|
||||
/* C */
|
||||
p.class2 { }
|
||||
|
||||
/*D*/
|
||||
p {}
|
||||
|
||||
/*E*/
|
||||
p { propiedad: valor !important; }
|
||||
/* D */
|
||||
p { }
|
||||
|
||||
/* E */
|
||||
p { property: value !important; }
|
||||
```
|
||||
|
||||
Y el siguiente HTML:
|
||||
and the following markup:
|
||||
|
||||
```xml
|
||||
<p style='/*F*/ propiedad:valor;' class='clase1 clase2' attr='valor'>
|
||||
</p>
|
||||
```html
|
||||
<p style='/*F*/ property:value;' class='class1 class2' attr='value'>
|
||||
```
|
||||
|
||||
El orden respetado es el siguiente:
|
||||
Recuerda, la preferencia es por cada **property**, no para el bloque completo.
|
||||
The precedence of style is as follows. Remember, the precedence is for each
|
||||
**property**, not for the entire block.
|
||||
|
||||
* `E` tiene la preferencia más elevada gracias a la palabra `!important`.
|
||||
Es recomendado evitar esto a menos que sea estrictamente necesario incluirlo.
|
||||
* `F` le sigue, porque es estilo incrustado directamente en el HTML.
|
||||
* `A` le sigue, porque es más específico que cualquier otra opción.
|
||||
más específico = más especificadores. Aquí hay tres especificadores: elemento `p` +
|
||||
nombre de la clase `clase1` + un atributo `attr='valor'`
|
||||
* `C` le sigue. Aunque tiene el mismo número de especificadores como `B`
|
||||
pero aparece después.
|
||||
* Luego va `B`
|
||||
* y al final `D`.
|
||||
* `E` has the highest precedence because of the keyword `!important`. It is
|
||||
recommended that you avoid its usage.
|
||||
* `F` is next, because it is an inline style.
|
||||
* `A` is next, because it is more "specific" than anything else. It has 3
|
||||
specifiers: The name of the element `p`, its class `class1`, an attribute
|
||||
`attr='value'`.
|
||||
* `C` is next, even though it has the same specificity as `B`.
|
||||
This is because it appears after `B`.
|
||||
* `B` is next.
|
||||
* `D` is the last one.
|
||||
|
||||
## Compatibilidad
|
||||
## Media Queries
|
||||
|
||||
La mayoría de las funcionalidades de CSS2 (y gradualmente de CSS3) son compatibles
|
||||
en todos los navegadores y dispositivos. Pero siempre es vital tener en mente la
|
||||
compatibilidad y disponibilidad del CSS que uses con respecto a los navegadores
|
||||
y dispositivos para los que desarrolles.
|
||||
CSS Media Queries are a feature in CSS 3 which allows you to specify when certain CSS rules should be applied, such as when printed, or when on a screen with certain dimensions or pixel density. They do not add to the selector's specificity.
|
||||
|
||||
[QuirksMode CSS](http://www.quirksmode.org/css/) es una excelente referencia para esto.
|
||||
```css
|
||||
/* A rule that will be used on all devices */
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
color: white;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
## Recursos
|
||||
/* change the h1 to use less ink on a printer */
|
||||
@media print {
|
||||
h1 {
|
||||
color: black;
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
|
||||
* Para ejecutar un test de compatibilidad, revisa [CanIUse](http://caniuse.com).
|
||||
* CSS Playground [Dabblet](http://dabblet.com/).
|
||||
* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS).
|
||||
* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/).
|
||||
/* make the font bigger when shown on a screen at least 480px wide */
|
||||
@media screen and (min-width: 480px) {
|
||||
h1 {
|
||||
font-size: 3em;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Otras lecturas
|
||||
Media queries can include these features:
|
||||
`width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. Most of these features can be prefixed with `min-` or `max-`.
|
||||
|
||||
* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/).
|
||||
* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/).
|
||||
* [QuirksMode CSS](http://www.quirksmode.org/css/).
|
||||
The `resolution` feature is not supported by older devices, instead use `device-pixel-ratio`.
|
||||
|
||||
Many smartphones and tablets will attempt to render the page as if it were on a desktop unless you provide a `viewport` meta-tag.
|
||||
|
||||
```html
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width; initial-scale=1.0">
|
||||
</head>
|
||||
```
|
||||
|
||||
## Compatibility
|
||||
|
||||
Most of the features in CSS 2 (and many in CSS 3) are available across all
|
||||
browsers and devices. But it's always good practice to check before using
|
||||
a new feature.
|
||||
|
||||
## Resources
|
||||
|
||||
* [CanIUse](http://caniuse.com) (Detailed compatibility info)
|
||||
* [Dabblet](http://dabblet.com/) (CSS playground)
|
||||
* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS) (Tutorials and reference)
|
||||
* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/) (Reference)
|
||||
|
||||
## Further Reading
|
||||
|
||||
* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/)
|
||||
* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/)
|
||||
* [QuirksMode CSS](http://www.quirksmode.org/css/)
|
||||
* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context)
|
||||
* [SASS](http://sass-lang.com/) y [LESS](http://lesscss.org/) para preprocesamiento CSS.
|
||||
* [CSS-Tricks](https://css-tricks.com).
|
||||
* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing
|
||||
* [CSS-Tricks](https://css-tricks.com)
|
||||
|
||||
|
||||
|
@ -88,7 +88,7 @@ saltos de línea.` // mismo tipo cadena
|
||||
|
||||
// Literal no ASCII. Los ficheros fuente de Go son UTF-8.
|
||||
g := 'Σ' // Tipo rune, un alias de int32, alberga un carácter unicode.
|
||||
f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit.
|
||||
f := 3.14159 // float64, el estándar IEEE-754 de coma flotante 64-bit.
|
||||
c := 3 + 4i // complex128, representado internamente por dos float64.
|
||||
// Sintaxis var con iniciadores.
|
||||
var u uint = 7 // Sin signo, pero la implementación depende del tamaño
|
||||
@ -425,7 +425,7 @@ func consultaAlServidor() {
|
||||
## Más información
|
||||
|
||||
La raíz de todas las cosas sobre Go es el
|
||||
[sitio web oficial de Go](http://golang.org/).
|
||||
[sitio web oficial de Go](https://go.dev/).
|
||||
Allí puedes seguir el tutorial, jugar interactivamente y leer mucho más.
|
||||
|
||||
La definición del lenguaje es altamente recomendada. Es fácil de leer y
|
||||
@ -433,17 +433,17 @@ sorprendentemente corta (como la definición del lenguaje Go en estos
|
||||
días).
|
||||
|
||||
Puedes jugar con el código en el
|
||||
[parque de diversiones Go](https://play.golang.org/p/ncRC2Zevag). ¡Trata
|
||||
[parque de diversiones Go](https://go.dev/play/p/ncRC2Zevag). ¡Trata
|
||||
de cambiarlo y ejecutarlo desde tu navegador! Ten en cuenta que puedes
|
||||
utilizar [https://play.golang.org]( https://play.golang.org) como un
|
||||
utilizar [https://go.dev/play/]( https://go.dev/play/) como un
|
||||
[REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) para probar
|
||||
cosas y el código en el navegador, sin ni siquiera instalar Go.
|
||||
|
||||
En la lista de lecturas para estudiantes de Go está el
|
||||
[código fuente de la biblioteca estándar](http://golang.org/src/pkg/).
|
||||
[código fuente de la biblioteca estándar](https://go.dev/src/).
|
||||
Ampliamente documentado, que demuestra lo mejor del legible y comprensible
|
||||
Go, con su característico estilo y modismos. ¡O puedes hacer clic en un
|
||||
nombre de función en [la documentación](http://golang.org/pkg/) y
|
||||
nombre de función en [la documentación](https://go.dev/pkg/) y
|
||||
aparecerá el código fuente!
|
||||
|
||||
Otro gran recurso para aprender Go está en
|
||||
|
@ -16,7 +16,7 @@ LaTeX.
|
||||
|
||||
```r
|
||||
|
||||
# Los comentariso inician con símbolos numéricos.
|
||||
# Los comentarios inician con símbolos numéricos.
|
||||
|
||||
# No puedes hacer comentarios de múltiples líneas
|
||||
# pero puedes agrupar múltiples comentarios de esta manera.
|
||||
|
469
fa-ir/vim-fa.html.markdown
Normal file
469
fa-ir/vim-fa.html.markdown
Normal file
@ -0,0 +1,469 @@
|
||||
---
|
||||
category: tool
|
||||
tool: vim
|
||||
contributors:
|
||||
- ["RadhikaG", "https://github.com/RadhikaG"]
|
||||
translators:
|
||||
- ["Moein Halvaei", "https://github.com/mo1ein"]
|
||||
lang: fa-ir
|
||||
filename: LearnVim-fa.txt
|
||||
---
|
||||
|
||||
<p dir="rtl">
|
||||
[Vim](http://www.vim.org) (Vi رشدیافته) یک کلون از ادیتور مشهور vi است برای unix. ادیتورمتنیست که برای سرعت و افزایش بهرهوری طراحی شده و در همه جا به ویژه در سیستم های unix-based دیده میشود. شورتکات کلید های بیشماری برای سرعت جهتیابی به نقاط ویژهي فایل ها و تغییر سریع، دارد.
|
||||
<br />
|
||||
`vimtutor` یک برنامهي عالیست که به شما چگونگی استفاده از `vim` را آموزش میدهد.
|
||||
این به همراه پکیج های vim هنگام نصب کردن، نصب میشود. شما باید بتوانید با ران کردن `vimtutor` در کامندلاین از آموزش ها استفاده کنید. این همهی ویژگی های عمدهی `vim` را به شما راهنمایی میکند.
|
||||
</p>
|
||||
<h3>
|
||||
<p dir="rtl">
|
||||
مکانیابی اولیه vim
|
||||
</p>
|
||||
</h3>
|
||||
|
||||
|
||||
<p dir="rtl">
|
||||
باز کردن `<filename>` در ویم
|
||||
</p>
|
||||
|
||||
```
|
||||
vim <filename> # Open <filename> in vim
|
||||
```
|
||||
<p dir="rtl">
|
||||
باز کردن help docs های `<topic>` اگر وجود داشته باشد
|
||||
</p>
|
||||
|
||||
```
|
||||
:help <topic> # Open up built-in help docs about <topic> if any exists
|
||||
```
|
||||
```
|
||||
:q # خروج از ویم
|
||||
|
||||
:w # ذخیره کردن فایل فعلی
|
||||
|
||||
:wq # ذخیره کردن و خارج شدن از ویم
|
||||
|
||||
ZZ # ذخیره کردن و خارج شدن از ویم
|
||||
|
||||
:q! # خارج شدن بدون ذخیره کردن فایل
|
||||
|
||||
! *forces* :q to execute, hence quiting vim without saving
|
||||
|
||||
ZQ # خارج شدن بدون ذخیره کردن فایل
|
||||
```
|
||||
|
||||
<p dir="rtl">ذخیره کردن و خارج شدن از vim ورژن خلاصه شدهی wq:</p>
|
||||
|
||||
```
|
||||
:x # Save file and quit vim, shorter version of :wq
|
||||
```
|
||||
|
||||
<p dir="rtl">برگشت به عقب</p>
|
||||
|
||||
```
|
||||
u # Undo
|
||||
```
|
||||
|
||||
<p dir="rtl">رفتن به جلو</p>
|
||||
|
||||
```
|
||||
CTRL+R # Redo
|
||||
```
|
||||
|
||||
<p dir="rtl">راه رفتن در صفحه</p>
|
||||
|
||||
```
|
||||
h # رفتن یک کاراکتر به چپ
|
||||
|
||||
j # رفتن یک کاراکتر به پایین
|
||||
|
||||
k # رفتن یک کاراکتر به بالا
|
||||
|
||||
l # رفتن یک کاراکتر به راست
|
||||
|
||||
Ctrl+B # جابهجا شدن به عقب به اندازه یک صفحه
|
||||
|
||||
Ctrl+F # جابهجا شدن به جلو به اندازه یک صفحه
|
||||
|
||||
Ctrl+D # جابهجا شدن به جلو به اندازه نصف صفحه
|
||||
|
||||
Ctrl+U # جابهجا شدن به عقب به اندازه نصف صفحه
|
||||
```
|
||||
|
||||
<p dir="rtl"><strong>جابهجا شدن در خط</strong></p>
|
||||
|
||||
```
|
||||
0 # رفتن به اول خط
|
||||
$ # رفتن به آخر خط
|
||||
^ # رفتن به اولین کاراکتر غیرخالی در خط
|
||||
```
|
||||
|
||||
<p dir="rtl"><strong>جست و جو در متن</strong></p>
|
||||
|
||||
```
|
||||
/word # هایلایت کردن همهی کلمه های بعد کِرسر
|
||||
|
||||
?word # هایلایت کردن همهی کلمه های قبل کِرسر
|
||||
|
||||
n # جابهجایی کِرسر به کلمه های بعدی پیدا شده
|
||||
|
||||
N # جابهجایی کِرسر به کلمه های قبلی پیدا شده
|
||||
```
|
||||
|
||||
<p dir="rtl">عوض کردن 'foo' به 'bar' در هر خط از فایل</p>
|
||||
|
||||
```
|
||||
:%s/foo/bar/g # Change 'foo' to 'bar' on every line in the file
|
||||
```
|
||||
|
||||
<p dir="rtl">عوض کردن 'foo' به 'bar' در خط فعلی</p>
|
||||
|
||||
```
|
||||
:s/foo/bar/g # Change 'foo' to 'bar' on the current line
|
||||
```
|
||||
|
||||
<p dir="rtl">جایگزینی کاراکتر های خط جدید با کاراکتر های خط جدید</p>
|
||||
|
||||
```
|
||||
:%s/\n/\r/g # Replace new line characters with new line characters
|
||||
```
|
||||
|
||||
<p dir="rtl"><strong>پرش به کاراکتر ها</strong></p>
|
||||
<p dir="rtl">پرش به جلو و قرار گرفتن روی کاراکتر مورد نظر</p>
|
||||
|
||||
```
|
||||
f<character> # Jump forward and land on <character>
|
||||
```
|
||||
|
||||
<p dir="rtl">پرش به جلو و قرار گرفتن قبل کاراکتر مورد نظر</p>
|
||||
|
||||
```
|
||||
t<character> # Jump forward and land right before <character>
|
||||
```
|
||||
|
||||
<p dir="rtl"><strong>برای مثال:</strong></p>
|
||||
|
||||
<p dir="rtl">پرش به جلو و قرار گرفتن روی ></p>
|
||||
|
||||
```
|
||||
f< # Jump forward and land on <
|
||||
```
|
||||
|
||||
<p dir="rtl">پرش به جلو و قرار گرفتن قبل از ></p>
|
||||
|
||||
```
|
||||
t< # Jump forward and land right before <
|
||||
```
|
||||
<p dir="rtl"><strong>جابهجا شدن با کلمه ها</strong></p>
|
||||
|
||||
```
|
||||
w # رفتن به جلو به اندازهی یک کلمه
|
||||
b # رفتن به عقب به اندازهی یک کلم
|
||||
e # رفتن به آخر کلمهی فعلی
|
||||
```
|
||||
<p dir="rtl"><strong>سایر کاراکتر ها برای جابهجایی</strong></p>
|
||||
<p dir="rtl">رفتن به اول فایل</p>
|
||||
|
||||
```
|
||||
gg # Go to the top of the file
|
||||
```
|
||||
<p dir="rtl">رفتن به آخر فایل</p>
|
||||
|
||||
```
|
||||
G # Go to the bottom of the file
|
||||
```
|
||||
<p dir="rtl">رفتن به شمارهی خط مورد نظر (NUM شماره است)</p>
|
||||
|
||||
```
|
||||
:NUM # Go to line number NUM (NUM is any number)
|
||||
```
|
||||
<p dir="rtl">رفتن به اول صفحه</p>
|
||||
|
||||
```
|
||||
H # Move to the top of the screen
|
||||
```
|
||||
<p dir="rtl">رفتن به وسط صفحه</p>
|
||||
|
||||
```
|
||||
M # Move to the middle of the screen
|
||||
```
|
||||
<p dir="rtl">رفتن به آخر صفحه</p>
|
||||
|
||||
```
|
||||
L # Move to the bottom of the screen
|
||||
```
|
||||
|
||||
<h3>
|
||||
<p dir="rtl"><strong>
|
||||
داک های help
|
||||
</strong></p>
|
||||
</h3>
|
||||
|
||||
<p dir="rtl">
|
||||
Vim دارای یک help doc داخلی است که میتوان با help: <topic> به آن دسترسی داشت. برای مثال help navigation: داک مربوط به مکانیابی در فضای کار را به شما نشان میدهد! <br /><br />
|
||||
help: همچنین میتواند بدون option مورد استفاده قرار گیرد.
|
||||
این یه صورت یک help پیشفرض بالا میآید که شروع vim را قابل دسترس تر میکند!
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
<p dir="rtl"><strong>Modes:</strong></p>
|
||||
</h3>
|
||||
|
||||
<div dir="rtl">
|
||||
Vim بر پایهی مفهومیست به نام <strong>modes</strong>
|
||||
<br /><br />
|
||||
<ul>
|
||||
<li>
|
||||
Command Mode - ویم در این حالت بالا میآید، برای مکانیابی و نوشتن دستورات استفاده میشود
|
||||
</li>
|
||||
<li>
|
||||
Insert Mode - برای ایجاد تغییر در فایل شما استفاده میشود
|
||||
</li>
|
||||
<li>
|
||||
Visual Mode - برای هایلایت کردن متن و انجام عملی روی آن ها استفاده میشود
|
||||
</li>
|
||||
<li>
|
||||
Ex Mode - برای وارد کردن دستورات توسط ":" در قسمت پایین استفاده میشود
|
||||
</li>
|
||||
</ul>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<p dir="rtl">رفتن به حالت insert, پیش از جایگاه cursor</p>
|
||||
|
||||
```
|
||||
i # Puts vim into insert mode, before the cursor position
|
||||
```
|
||||
<p dir="rtl">رفتن به حالت insert, پس از جایگاه cursor</p>
|
||||
|
||||
```
|
||||
a # Puts vim into insert mode, after the cursor position
|
||||
```
|
||||
|
||||
<p dir="rtl">رفتن به حالت visual</p>
|
||||
|
||||
```
|
||||
v # Puts vim into visual mode
|
||||
```
|
||||
<p dir="rtl">رفتن به حالت ex</p>
|
||||
|
||||
```
|
||||
: # Puts vim into ex mode
|
||||
```
|
||||
<p dir="rtl">خروج از همهی حالت ها و رفتن به حالت command</p>
|
||||
|
||||
```
|
||||
<esc> # 'Escapes' from whichever mode you're in, into Command mode
|
||||
```
|
||||
<p dir="rtl">کپی و پیست در متن</p>
|
||||
|
||||
```
|
||||
y # کپی کردن متن انتخاب شده
|
||||
|
||||
yy # کپی کردن خط فعلی
|
||||
|
||||
d # حذف کردن متن انتخاب شده
|
||||
|
||||
dd # حذف کردن خط فعلی
|
||||
|
||||
p # پیست کردن متن کپی شده پس از جایگاه فعلی کِرسر
|
||||
|
||||
P # پیست کردن متن کپی شده پیش از جایگاه فعلی کِرسر
|
||||
|
||||
x # حذف کردن یک کاراکتر از جایگاه کِرسر
|
||||
```
|
||||
|
||||
<h3>
|
||||
<p dir="rtl"><strong>گرامر (Grammer) </strong></p>
|
||||
</h3>
|
||||
|
||||
<div dir="rtl">
|
||||
Vim را می توان به عنوان مجموعه ای از دستورات در قالب (Verb - Modifier - Noun) تصور کرد ، جایی که:
|
||||
<br /><br />
|
||||
<ul>
|
||||
<li>
|
||||
Verb - عمل شما
|
||||
</li>
|
||||
<li>
|
||||
Modifier - چگونگی انجام عمل شما
|
||||
</li>
|
||||
<li>
|
||||
Noun - شیئی که عمل شما بر اساس آن عمل می کند
|
||||
</li>
|
||||
</ul>
|
||||
اندکی از مثال های مهم Verbs ,Modifiers, Nouns:
|
||||
<br /><br />
|
||||
</div>
|
||||
|
||||
<p dir="rtl"><strong>فعل ها (Verbs)</strong></p>
|
||||
|
||||
```
|
||||
d # حذف
|
||||
c # تغییر
|
||||
y # کپی
|
||||
v # انتخاب
|
||||
```
|
||||
<p dir="rtl"><strong>تغییردهنده ها (Modifiers)</strong></p>
|
||||
|
||||
```
|
||||
i # داخل
|
||||
a # اطراف
|
||||
NUM # شماره (NUM هر شمارهای است)
|
||||
f # جست و جو کردن چیزی و متوقف شدن روی آن
|
||||
t # جست و جو کردن چیزی و متوقف شدن قبل از آن
|
||||
/ # جست و جو کردن رشتهای پس از کِرسر
|
||||
? # جست و جو کردن رشتهای پیش از کِرسر
|
||||
```
|
||||
<p dir="rtl"><strong>اسم ها (Nouns)</strong></p>
|
||||
|
||||
```
|
||||
w # کلمه
|
||||
s # جمله
|
||||
p # پاراگراف
|
||||
b # بلوک
|
||||
```
|
||||
<p dir="rtl"><strong>جمله ها و کامند های نمونه</strong></p>
|
||||
|
||||
```
|
||||
d2w # حذف دو کلمه
|
||||
cis # تغییر داخل جمله
|
||||
yip # کپی داخل پاراگراف (از پاراگرافی که داخل آن هستید کپی کنید)
|
||||
ct< # متن را از جایی که قرار دارید به براکت باز بعدی تغییر دهید
|
||||
d$ # حذف تا پایان
|
||||
```
|
||||
|
||||
<h3>
|
||||
<p dir="rtl">بعضی از شورتکات ها و ترفند ها</p>
|
||||
</h3>
|
||||
|
||||
```
|
||||
<!--TODO: Add more!-->
|
||||
|
||||
> # ایجاد دندانه به اندازه یک بلوک
|
||||
|
||||
< # حذف دندانه به اندازه یک بلوک
|
||||
|
||||
:earlier 15m # برگرداندن همه چیز به ۱۵ دقیقه قبل
|
||||
|
||||
:later 15m # برعکس کامند قبلی
|
||||
|
||||
ddp # تغییر مکان خطوط متوالی(dd, then p)
|
||||
|
||||
. # تکرار دستور قبلی
|
||||
|
||||
:w !sudo tee % # ذخیره کردن فایل فعلی به عنوان روت
|
||||
|
||||
:set syntax=c # تنظیم سینتکس هایلایتینگ روی 'c'
|
||||
|
||||
:sort # مرتب کردن همهی خطوط
|
||||
|
||||
:sort! # مرتب کردن همهی خطوط به صورت برعکس
|
||||
|
||||
:sort u # مرتب کردن همهی خطوط و پاک کردن تکراری ها
|
||||
|
||||
~ # تبدیل متن انتخاب شده به حروف (اگر بزرگ است، کوچک و اگر کوچک است، بزرگ)
|
||||
|
||||
u # تبدیل متن انتخاب شده به حروف کوچک
|
||||
|
||||
U # تبدیل متن انتخاب شده به حروف بزرگ
|
||||
|
||||
J # اتصال خط فعلی به خط بعدی
|
||||
```
|
||||
<h4>
|
||||
<p dir="rtl">
|
||||
فولد (Fold)
|
||||
</p>
|
||||
</h4>
|
||||
|
||||
```
|
||||
zf # ایجاد فولد برای متن انتخاب شده
|
||||
zo # باز کردن فولد فعلی
|
||||
zc # بستن فولد فعلی
|
||||
zR # باز کردن همهی فولد ها
|
||||
zM # بستن همهی فولد ها
|
||||
```
|
||||
|
||||
<h3>
|
||||
<p dir="rtl">
|
||||
ماکرو ها (Macros)
|
||||
</p>
|
||||
</h3>
|
||||
|
||||
<p dir="rtl">
|
||||
ماکرو ها اساسا عمل های قابل ضبط هستند. زمانی که شما شروع میکنید به ضبط ماکرو، هر عمل و دستوری را که استفاده میکنید، تا زمانی که ضبط را متوقف کنید، ضبط میشود. با فراخوانی ماکرو، دقیقاً همان توالی اعمال و دستورات، دوباره روی متن انتخاب شده اعمال میشود.
|
||||
</p>
|
||||
|
||||
```
|
||||
qa # Start recording a macro named 'a'
|
||||
q # Stop recording
|
||||
@a # Play back the macro
|
||||
```
|
||||
<h3>
|
||||
<p dir="rtl">
|
||||
کانفیگ vimrc./~
|
||||
<p>
|
||||
</h3>
|
||||
|
||||
<p dir="rtl">
|
||||
vimrc. فایلیست که استفاده میشود برای کانفیگ vim هنگام بالا آمدن
|
||||
<br />
|
||||
اینجا یک نمونه فایل vimrc. آورده شده:
|
||||
</p>
|
||||
|
||||
```
|
||||
" Example ~/.vimrc
|
||||
" 2015.10
|
||||
|
||||
" Required for vim to be iMproved
|
||||
set nocompatible
|
||||
|
||||
" Determines filetype from name to allow intelligent auto-indenting, etc.
|
||||
filetype indent plugin on
|
||||
|
||||
" Enable syntax highlighting
|
||||
syntax on
|
||||
|
||||
" Better command-line completion
|
||||
set wildmenu
|
||||
|
||||
" Use case insensitive search except when using capital letters
|
||||
set ignorecase
|
||||
set smartcase
|
||||
|
||||
" When opening a new line and no file-specific indenting is enabled,
|
||||
" keep same indent as the line you're currently on
|
||||
set autoindent
|
||||
|
||||
" Display line numbers on the left
|
||||
set number
|
||||
|
||||
" Indentation options, change according to personal preference
|
||||
|
||||
" Number of visual spaces per TAB
|
||||
set tabstop=4
|
||||
|
||||
" Number of spaces in TAB when editing
|
||||
set softtabstop=4
|
||||
|
||||
" Number of spaces indented when reindent operations (>> and <<) are used
|
||||
set shiftwidth=4
|
||||
" Convert TABs to spaces
|
||||
set expandtab
|
||||
|
||||
" Enable intelligent tabbing and spacing for indentation and alignment
|
||||
set smarttab
|
||||
```
|
||||
|
||||
<h3>
|
||||
<p dir="rtl">رفرنس ها</p>
|
||||
</h3>
|
||||
|
||||
[Vim | Home](http://www.vim.org/index.php)
|
||||
|
||||
`$ vimtutor`
|
||||
|
||||
[A vim Tutorial and Primer](https://danielmiessler.com/study/vim/)
|
||||
|
||||
[What are the dark corners of Vim your mom never told you about? (St
|
||||
|
||||
[Arch Linux Wiki](https://wiki.archlinux.org/index.php/Vim)
|
@ -90,7 +90,7 @@ voi sisältää rivinvaihtoja.` // Sama merkkijonotyyppi.
|
||||
// Ei-ASCII todellisarvo. Go-lähdekoodi on UTF-8.
|
||||
g := 'Σ' // riimutyyppi, lempinimi int32:lle, sisältää unicode-koodipisteen.
|
||||
|
||||
f := 3.14195 //float64, IEEE-754 64-bittinen liukuluku.
|
||||
f := 3.14159 //float64, IEEE-754 64-bittinen liukuluku.
|
||||
c := 3 + 4i // complex128, sisäisesti ilmaistu kahdella float64:lla.
|
||||
|
||||
// var -syntaksi alkuarvoilla.
|
||||
@ -418,21 +418,21 @@ func requestServer() {
|
||||
|
||||
## Lisää luettavaa
|
||||
|
||||
Go-tietämyksen alku ja juuri on sen [virallinen verkkosivu]()(http://golang.org/).
|
||||
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://golang.org/doc/) pitää sisällään tietoa
|
||||
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://play.golang.org/p/tnWMjr16Mm).
|
||||
Muuttele sitä ja aja se selaimestasi! Huomaa, että voit käyttää [https://play.golang.org](https://play.golang.org)
|
||||
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](http://golang.org/src/pkg/).
|
||||
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](http://golang.org/pkg/) ja
|
||||
-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/).
|
||||
|
@ -3,6 +3,7 @@ category: tool
|
||||
tool: fish
|
||||
contributors:
|
||||
- ["MySurmise", "https://github.com/MySurmise"]
|
||||
- ["Geo Maciolek", "https://github.com/GeoffMaciolek"]
|
||||
filename: learn.fish
|
||||
---
|
||||
|
||||
@ -14,45 +15,64 @@ Examples of these features are autosuggestions, 24-bit colors, Man Page Completi
|
||||
|
||||
It was released in February 2005.
|
||||
|
||||
[Read more](https://fishshell.com/docs/current/language.html)
|
||||
|
||||
[Installation guide](https://github.com/fish-shell/fish-shell#getting-fish)
|
||||
- [Read more](https://fishshell.com/docs/current/language.html)
|
||||
- [Installation guide](https://github.com/fish-shell/fish-shell#getting-fish)
|
||||
|
||||
|
||||
# Guide
|
||||
## Guide
|
||||
|
||||
Be sure you have the newest fish shell. This was made with version 3.3.0. To test, type:
|
||||
|
||||
```
|
||||
> fish -v
|
||||
```
|
||||
|
||||
To start the fish shell, type:
|
||||
|
||||
```
|
||||
> fish
|
||||
```
|
||||
|
||||
to exit, type:
|
||||
|
||||
```
|
||||
> exit
|
||||
```
|
||||
|
||||
or press <kbd>Ctrl + D</kbd>
|
||||
|
||||
Now, right out of the gate, there's one annoying thing in fish. It's the welcome message. Who needs that, right? When your shell is started, just type:
|
||||
|
||||
```
|
||||
> set -U fish_greeting ""
|
||||
|
||||
To set that to the wanted value, .
|
||||
|
||||
```
|
||||
|
||||
If you want to execute a single command written in bash, without switching to that shell, you can type:
|
||||
|
||||
```
|
||||
> bash -c 'echo "fish is better than bash"'
|
||||
```
|
||||
|
||||
In fish, you can use single or double quotes.
|
||||
The escape character is a `\`
|
||||
|
||||
You can change your configuration of fish either by editing the config file
|
||||
|
||||
```
|
||||
> vim ~/.config/fish/config.fish
|
||||
```
|
||||
|
||||
or by opening the aforementioned web settings:
|
||||
|
||||
>fish_config
|
||||
```
|
||||
> fish_config
|
||||
```
|
||||
|
||||
Adding something to your fish PATH Variable is easy:
|
||||
|
||||
```
|
||||
> fish_path_add ~/cowsay
|
||||
```
|
||||
|
||||
Can you do that with bash, huh? No, you always have to look it up... It's just that easy!
|
||||
|
||||
@ -60,21 +80,28 @@ But there's more. Most fish-specific commands start, you guessed it, with 'fish'
|
||||
Now you can navigate with <kbd>TAB</kbd>, <kbd>Shift + TAB</kbd> and your Arrow-Keys <kbd>←</kbd><kbd>↑</kbd><kbd>→</kbd><kbd>↓</kbd>.
|
||||
|
||||
To get help, contact your local psychiatrist or type `man`. That will bring up the manual for that command, for example:
|
||||
|
||||
```
|
||||
> man set
|
||||
```
|
||||
|
||||
If you finally tried fish, you can see something other in fish that's really cool. Everything has cool colors, if you type in something wrong, it is red, without even executing, if you put something in quotes, you see where it ends and why that quote doesn't work, because there's another qoutation mark in the quote at position 26.
|
||||
|
||||
fish has even more cool things, like wildcards.
|
||||
For example, type
|
||||
|
||||
```
|
||||
> ls *.fish
|
||||
```
|
||||
|
||||
That will list all fish files in your current directory.
|
||||
|
||||
You can have multiple wildcards per command or even a recursive wildcard, `**`, which basically means it includes files and directories, that fit.
|
||||
For example the following command would return (in your case):
|
||||
> ls ~/images/**.jpg
|
||||
|
||||
```
|
||||
> ls ~/images/**.jpg
|
||||
|
||||
~/images/nudes/pewdiepie.jpg
|
||||
~/images/nudes/peppa.jpg
|
||||
~/images/screenshots/2020-42-69.jpg
|
||||
@ -83,72 +110,77 @@ For example the following command would return (in your case):
|
||||
|
||||
Of course, you can also pipe the output of a command to another command
|
||||
|
||||
```
|
||||
>echo sick egg, nadia. no u do really goofy shit. | grep [udense]
|
||||
```
|
||||
|
||||
write to a file:
|
||||
|
||||
```
|
||||
>echo This\ is\ text > file.txt
|
||||
```
|
||||
|
||||
(noticed the escape character?)
|
||||
Add to a file:
|
||||
|
||||
```
|
||||
>echo This\ is\ a\ line >> file.txt
|
||||
|
||||
>echo This\ is\ a\ second\ line >> file.txt
|
||||
```
|
||||
|
||||
For Autocompletion, just always press <kbd>TAB</kbd>. You will be surprised how many things fish knows.
|
||||
|
||||
To use variables, just type `$VAR`, like in bash.
|
||||
|
||||
```
|
||||
> echo "My home is $HOME"
|
||||
|
||||
> My home is /home/myuser
|
||||
My home is /home/myuser
|
||||
```
|
||||
|
||||
Here comes a difference between single and double quotes. If you use a variable in single quotes, it will not substitute it.
|
||||
|
||||
```
|
||||
> echo 'My home is $HOME'
|
||||
|
||||
> My home is $HOME
|
||||
My home is $HOME
|
||||
```
|
||||
|
||||
More on variables later.
|
||||
|
||||
To execute two commands, separate them with `;`
|
||||
|
||||
```
|
||||
> echo Lol; echo this is fun
|
||||
```
|
||||
|
||||
The status code of the last command is stored in `$status`
|
||||
|
||||
You can use && for two commands that depend on each other.
|
||||
|
||||
```
|
||||
> set var lol && echo $var
|
||||
```
|
||||
|
||||
You can also use and,
|
||||
which executes if the previous command was successful
|
||||
|
||||
or
|
||||
which executes if the previous command was not successful
|
||||
|
||||
and not
|
||||
You can also use `and` which executes if the previous command was successful,
|
||||
`or` which executes if the previous command was not successful, and `not`
|
||||
which inverts the exit status of a command.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
> if not echo It's very late I should not waste my time with this
|
||||
|
||||
>> echo Nobody heard you
|
||||
|
||||
>end
|
||||
```
|
||||
> if not echo It's very late I should not waste my time with this
|
||||
echo Nobody heard you
|
||||
end
|
||||
```
|
||||
|
||||
(You can of course do all of that in the shell)
|
||||
|
||||
|
||||
---
|
||||
Now let's start with the scripting part of fish.
|
||||
Now let's start with the scripting part of fish.
|
||||
|
||||
As with every shell, you can not only execute commands in the shell, but also as files, saved as a `.fish` file.
|
||||
(You can also execute `.sh` files with fish syntax, but I always use `.fish` for fish-syntax scripts to distinguish them from bash script files)
|
||||
|
||||
```bash
|
||||
```fish
|
||||
# This is a comment in fish.
|
||||
#
|
||||
# If you execute a file without specifying an interpreter,
|
||||
@ -165,10 +197,9 @@ As with every shell, you can not only execute commands in the shell, but also as
|
||||
# for use inside a program, you can use the syntax
|
||||
set name = 'My Variable'
|
||||
|
||||
|
||||
# use
|
||||
# Use...
|
||||
set -x name value
|
||||
# to eXport
|
||||
# to eXport, or
|
||||
set -e name
|
||||
# to Erase
|
||||
|
||||
@ -188,20 +219,21 @@ count $PATH
|
||||
# So $PWD for example is a list of length 1.
|
||||
# To make a list, just give the set command multiple arguments:
|
||||
set list entry1 entry2 entry3
|
||||
|
||||
# that way you can also append something to an existing variable:
|
||||
set PATH $PATH ~/cowsay/
|
||||
|
||||
# But, as previously mentioned, we also have a simpler way to do that specifically in fish.
|
||||
# As with every Array/List, you can access it with
|
||||
$listvar[2]
|
||||
|
||||
# there's also ranges with
|
||||
$listvar[1..5]
|
||||
$listvar[1..5]
|
||||
|
||||
# and you can use negative numbers like
|
||||
$listvar[-1]
|
||||
# e.g to access the last element.
|
||||
|
||||
|
||||
|
||||
# You can also do fancy cartesian products when you combine two list variables:
|
||||
set a 1 2 3
|
||||
set 1 a b c
|
||||
@ -239,7 +271,7 @@ else
|
||||
echo Got nothing
|
||||
end
|
||||
|
||||
# A little weird is that you compare stuff with one = sign , of course because we don't need it to set variables, but still... and the keyword "test":
|
||||
# A little weird is that you compare stuff with one = sign, of course because we don't need it to set variables, but still... and the keyword "test":
|
||||
if test $var = "test"
|
||||
echo yes
|
||||
else
|
||||
@ -304,10 +336,7 @@ end
|
||||
# Cool!
|
||||
|
||||
# The bashrc equivalent is not fishrc, but the previously mentioned config.fish file in ~/.config/fish/
|
||||
|
||||
# To add a function to fish, though, you should create a simple .fish file in that directory. Don't just paste that function in the config.fish. That's ugly.
|
||||
|
||||
# If you have more, just add it, but those are the most important basics.
|
||||
|
||||
```
|
||||
|
||||
|
@ -93,8 +93,8 @@ see square \ : square dup * ; ok
|
||||
|
||||
\ ------------------------------------ Loops -----------------------------------
|
||||
|
||||
\ `do` is also a compile-only word.
|
||||
: myloop ( -- ) 5 0 do cr ." Hello!" loop ; \ ok
|
||||
\ `?do` is also a compile-only word.
|
||||
: myloop ( -- ) 5 0 ?do cr ." Hello!" loop ; \ ok
|
||||
myloop
|
||||
\ Hello!
|
||||
\ Hello!
|
||||
@ -102,16 +102,17 @@ myloop
|
||||
\ Hello!
|
||||
\ Hello! ok
|
||||
|
||||
\ `do` expects two numbers on the stack: the end number and the start number.
|
||||
\ `?do` expects two numbers on the stack: the end number (exclusive) and the
|
||||
\ start number (inclusive).
|
||||
|
||||
\ We can get the value of the index as we loop with `i`:
|
||||
: one-to-12 ( -- ) 12 0 do i . loop ; \ ok
|
||||
one-to-12 \ 0 1 2 3 4 5 6 7 8 9 10 11 12 ok
|
||||
one-to-12 \ 0 1 2 3 4 5 6 7 8 9 10 11 ok
|
||||
|
||||
\ `?do` works similarly, except it will skip the loop if the end and start
|
||||
\ numbers are equal.
|
||||
: squares ( n -- ) 0 ?do i square . loop ; \ ok
|
||||
10 squares \ 0 1 4 9 16 25 36 49 64 81 ok
|
||||
\ `do` works similarly, except if start and end are exactly the same it will
|
||||
\ loop forever (until arithmetic underflow).
|
||||
: loop-forever 1 1 do i square . loop ; \ ok
|
||||
loop-forever \ 1 4 9 16 25 36 49 64 81 100 ...
|
||||
|
||||
\ Change the "step" with `+loop`:
|
||||
: threes ( n n -- ) ?do i . 3 +loop ; \ ok
|
||||
|
@ -11,9 +11,9 @@ Translation"). Despite its age, it is still used for high-performance computing
|
||||
such as weather prediction. However, the language has changed considerably over
|
||||
the years, although mostly maintaining backwards compatibility; well known
|
||||
versions are FORTRAN 77, Fortran 90, Fortran 95, Fortran 2003, Fortran 2008,
|
||||
Fortran 2015, and Fortran 2018.
|
||||
Fortran 2018 and Fortran 2023.
|
||||
|
||||
This overview will discuss the features of Fortran 95 since it is the most
|
||||
This overview will discuss the features of Fortran 2008 since it is the most
|
||||
widely implemented of the more recent specifications and the later versions are
|
||||
largely similar (by comparison FORTRAN 77 is a very different language).
|
||||
|
||||
@ -21,158 +21,147 @@ largely similar (by comparison FORTRAN 77 is a very different language).
|
||||
|
||||
! This is a comment.
|
||||
|
||||
|
||||
program example !declare a program called example.
|
||||
program example ! declare a program called example.
|
||||
|
||||
! Code can only exist inside programs, functions, subroutines or modules.
|
||||
! Using indentation is not required but it is recommended.
|
||||
|
||||
|
||||
! Declaring Variables
|
||||
! ===================
|
||||
|
||||
! All declarations must come before statements and expressions.
|
||||
|
||||
implicit none !prevents dynamic declaration of variables (recommended!)
|
||||
implicit none ! prevents dynamic declaration of variables (recommended!)
|
||||
! Implicit none must be redeclared in every function/program/module...
|
||||
|
||||
! IMPORTANT - Fortran is case insensitive.
|
||||
real z
|
||||
REAL Z2
|
||||
|
||||
real :: v,x ! WARNING: default initial values are compiler dependent!
|
||||
real :: a = 3, b=2E12, c = 0.01
|
||||
integer :: i, j, k=1, m
|
||||
real, parameter :: PI = 3.1415926535897931 !declare a constant.
|
||||
logical :: y = .TRUE. , n = .FALSE. !boolean type.
|
||||
complex :: w = (0,1) !sqrt(-1)
|
||||
character (len=3) :: month !string of 3 characters.
|
||||
real :: v, x ! WARNING: default initial values are compiler dependent!
|
||||
real :: a = 3, b = 2E12, c = 0.01
|
||||
integer :: i, j, k = 1, m
|
||||
real, parameter :: PI = 3.1415926535897931 ! declare a constant.
|
||||
logical :: y = .TRUE., n = .FALSE. ! boolean type.
|
||||
complex :: w = (0, 1) ! sqrt(-1)
|
||||
character(len=3) :: month ! string of 3 characters.
|
||||
|
||||
real :: array(6) !declare an array of 6 reals.
|
||||
real, dimension(4) :: arrayb !another way to declare an array.
|
||||
integer :: arrayc(-10:10) !an array with a custom index.
|
||||
real :: array2d(3,2) !multidimensional array.
|
||||
real :: array(6) ! declare an array of 6 reals.
|
||||
real, dimension(4) :: arrayb ! another way to declare an array.
|
||||
integer :: arrayc(-10:10) ! an array with a custom index.
|
||||
real :: array2d(3, 2) ! multidimensional array.
|
||||
|
||||
! The '::' separators are not always necessary but are recommended.
|
||||
|
||||
! many other variable attributes also exist:
|
||||
real, pointer :: p !declare a pointer.
|
||||
real, pointer :: p ! declare a pointer.
|
||||
|
||||
integer, parameter :: LP = selected_real_kind(20)
|
||||
real (kind = LP) :: d !long precision variable.
|
||||
real(kind=LP) :: d ! long precision variable.
|
||||
|
||||
! WARNING: initialising variables during declaration causes problems
|
||||
! in functions since this automatically implies the 'save' attribute
|
||||
! whereby values are saved between function calls. In general, separate
|
||||
! declaration and initialisation code except for constants!
|
||||
|
||||
|
||||
! Strings
|
||||
! =======
|
||||
|
||||
character :: a_char = 'i'
|
||||
character (len = 6) :: a_str = "qwerty"
|
||||
character (len = 30) :: str_b
|
||||
character (len = *), parameter :: a_long_str = "This is a long string."
|
||||
character(len=6) :: a_str = "qwerty"
|
||||
character(len=30) :: str_b
|
||||
character(len=*), parameter :: a_long_str = "This is a long string."
|
||||
!can have automatic counting of length using (len=*) but only for constants.
|
||||
|
||||
str_b = a_str // " keyboard" !concatenate strings using // operator.
|
||||
|
||||
str_b = a_str//" keyboard" ! concatenate strings using // operator.
|
||||
|
||||
! Assignment & Arithmetic
|
||||
! =======================
|
||||
|
||||
Z = 1 !assign to variable z declared above (case insensitive).
|
||||
Z = 1 ! assign to variable z declared above (case insensitive).
|
||||
j = 10 + 2 - 3
|
||||
a = 11.54 / (2.3 * 3.1)
|
||||
b = 2**3 !exponentiation
|
||||
|
||||
a = 11.54/(2.3*3.1)
|
||||
b = 2**3 ! exponentiation
|
||||
|
||||
! Control Flow Statements & Operators
|
||||
! ===================================
|
||||
|
||||
! Single-line if statement
|
||||
if (z == a) b = 4 !condition always need surrounding parentheses.
|
||||
if (z == a) b = 4 ! condition always need surrounding parentheses.
|
||||
|
||||
if (z /= a) then !z not equal to a
|
||||
! Other symbolic comparisons are < > <= >= == /=
|
||||
b = 4
|
||||
else if (z .GT. a) then !z greater than a
|
||||
! Text equivalents to symbol operators are .LT. .GT. .LE. .GE. .EQ. .NE.
|
||||
b = 6
|
||||
else if (z < a) then !'then' must be on this line.
|
||||
b = 5 !execution block must be on a new line.
|
||||
if (z /= a) then ! z not equal to a
|
||||
! Other symbolic comparisons are < > <= >= == /=
|
||||
b = 4
|
||||
else if (z .GT. a) then ! z greater than a
|
||||
! Text equivalents to symbol operators are .LT. .GT. .LE. .GE. .EQ. .NE.
|
||||
b = 6
|
||||
else if (z < a) then ! 'then' must be on this line.
|
||||
b = 5 ! execution block must be on a new line.
|
||||
else
|
||||
b = 10
|
||||
end if !end statement needs the 'if' (or can use 'endif').
|
||||
|
||||
|
||||
if (.NOT. (x < c .AND. v >= a .OR. z == z)) then !boolean operators.
|
||||
inner: if (.TRUE.) then !can name if-construct.
|
||||
b = 1
|
||||
endif inner !then must name endif statement.
|
||||
endif
|
||||
b = 10
|
||||
end if ! end statement needs the 'if' (or can use 'endif').
|
||||
|
||||
if (.NOT. (x < c .AND. v >= a .OR. z == z)) then ! boolean operators.
|
||||
inner: if (.TRUE.) then ! can name if-construct.
|
||||
b = 1
|
||||
end if inner ! then must name endif statement.
|
||||
end if
|
||||
|
||||
i = 20
|
||||
select case (i)
|
||||
case (0) !case i == 0
|
||||
j=0
|
||||
case (1:10) !cases i is 1 to 10 inclusive.
|
||||
j=1
|
||||
case (11:) !all cases where i>=11
|
||||
j=2
|
||||
case default
|
||||
j=3
|
||||
case (0, 1) ! cases i == 0 or i == 1
|
||||
j = 0
|
||||
case (2:10) ! cases i is 2 to 10 inclusive.
|
||||
j = 1
|
||||
case (11:) ! all cases where i>=11
|
||||
j = 2
|
||||
case default
|
||||
j = 3
|
||||
end select
|
||||
|
||||
|
||||
month = 'jan'
|
||||
! Condition can be integer, logical or character type.
|
||||
! Select constructions can also be named.
|
||||
monthly: select case (month)
|
||||
case ("jan")
|
||||
j = 0
|
||||
case default
|
||||
j = -1
|
||||
monthly:select case(month)
|
||||
case ("jan")
|
||||
j = 0
|
||||
case default
|
||||
j = -1
|
||||
end select monthly
|
||||
|
||||
|
||||
do i=2,10,2 !loops from 2 to 10 (inclusive) in increments of 2.
|
||||
innerloop: do j=1,3 !loops can be named too.
|
||||
exit !quits the loop.
|
||||
end do innerloop
|
||||
cycle !jump to next loop iteration.
|
||||
enddo
|
||||
|
||||
do i = 2, 10, 2 ! loops from 2 to 10 (inclusive) in increments of 2.
|
||||
innerloop: do j = 1, 3 ! loops can be named too.
|
||||
exit ! quits the loop.
|
||||
end do innerloop
|
||||
cycle ! jump to next loop iteration.
|
||||
end do
|
||||
|
||||
! Goto statement exists but it is heavily discouraged though.
|
||||
goto 10
|
||||
stop 1 !stops code immediately (returning specified condition code).
|
||||
10 j = 201 !this line is labeled as line 10
|
||||
|
||||
stop 1 ! stops code immediately (returning specified condition code).
|
||||
10 j = 201 ! this line is labeled as line 10
|
||||
|
||||
! Arrays
|
||||
! ======
|
||||
array = (/1,2,3,4,5,6/)
|
||||
array = [1,2,3,4,5,6] !using Fortran 2003 notation.
|
||||
arrayb = [10.2,3e3,0.41,4e-5]
|
||||
array2d = reshape([1.0,2.0,3.0,4.0,5.0,6.0], [3,2])
|
||||
array = (/1, 2, 3, 4, 5, 6/)
|
||||
array = [1, 2, 3, 4, 5, 6] ! using Fortran 2003 notation.
|
||||
arrayb = [10.2, 3e3, 0.41, 4e-5]
|
||||
array2d = reshape([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], [3, 2])
|
||||
|
||||
! Fortran array indexing starts from 1.
|
||||
! (by default but can be defined differently for specific arrays).
|
||||
v = array(1) !take first element of array.
|
||||
v = array2d(2,2)
|
||||
v = array(1) ! take first element of array.
|
||||
v = array2d(2, 2)
|
||||
|
||||
print *, array(3:5) !print all elements from 3rd to 5th (inclusive).
|
||||
print *, array2d(1,:) !print first column of 2d array.
|
||||
print *, array(3:5) ! print all elements from 3rd to 5th (inclusive).
|
||||
print *, array2d(1, :) ! print first column of 2d array.
|
||||
|
||||
array = array*3 + 2 !can apply mathematical expressions to arrays.
|
||||
array = array*array !array operations occur element-wise.
|
||||
!array = array*array2d !these arrays would not be compatible.
|
||||
array = array*3 + 2 ! can apply mathematical expressions to arrays.
|
||||
array = array*array ! array operations occur element-wise.
|
||||
! array = array*array2d ! these arrays would not be compatible.
|
||||
|
||||
! There are many built-in functions that operate on arrays.
|
||||
c = dot_product(array,array) !this is the dot product.
|
||||
c = dot_product(array, array) ! this is the dot product.
|
||||
! Use matmul() for matrix maths.
|
||||
c = sum(array)
|
||||
c = maxval(array)
|
||||
@ -188,74 +177,73 @@ program example !declare a program called example.
|
||||
end do
|
||||
|
||||
! Conditionally execute element-wise assignments.
|
||||
array = [1,2,3,4,5,6]
|
||||
array = [1, 2, 3, 4, 5, 6]
|
||||
where (array > 3)
|
||||
array = array + 1
|
||||
elsewhere (array == 2)
|
||||
elsewhere(array == 2)
|
||||
array = 1
|
||||
elsewhere
|
||||
array = 0
|
||||
end where
|
||||
|
||||
! Implied-DO loops are a compact way to create arrays.
|
||||
array = [ (i, i = 1,6) ] !creates an array of [1,2,3,4,5,6]
|
||||
array = [ (i, i = 1,12,2) ] !creates an array of [1,3,5,7,9,11]
|
||||
array = [ (i**2, i = 1,6) ] !creates an array of [1,4,9,16,25,36]
|
||||
array = [ (4,5, i = 1,3) ] !creates an array of [4,5,4,5,4,5]
|
||||
|
||||
array = [(i, i=1, 6)] ! creates an array of [1,2,3,4,5,6]
|
||||
array = [(i, i=1, 12, 2)] ! creates an array of [1,3,5,7,9,11]
|
||||
array = [(i**2, i=1, 6)] ! creates an array of [1,4,9,16,25,36]
|
||||
array = [(4, 5, i=1, 3)] ! creates an array of [4,5,4,5,4,5]
|
||||
|
||||
! Input/Output
|
||||
! ============
|
||||
|
||||
print *, b !print the variable 'b' to the command line
|
||||
print *, b ! print the variable 'b' to the command line
|
||||
|
||||
! We can format our printed output.
|
||||
print "(I6)", 320 !prints ' 320'
|
||||
print "(I6.4)", 3 !prints ' 0003'
|
||||
print "(F6.3)", 4.32 !prints ' 4.320'
|
||||
print "(I6)", 320 ! prints ' 320'
|
||||
print "(I6.4)", 3 ! prints ' 0003'
|
||||
print "(F6.3)", 4.32 ! prints ' 4.320'
|
||||
|
||||
! The letter indicates the expected type and the number afterwards gives
|
||||
! the number of characters to use for printing the value.
|
||||
! Letters can be I (integer), F (real), E (engineering format),
|
||||
! L (logical), A (characters) ...
|
||||
print "(I3)", 3200 !print '***' since the number doesn't fit.
|
||||
print "(I3)", 3200 ! print '***' since the number doesn't fit.
|
||||
|
||||
! we can have multiple format specifications.
|
||||
print "(I5,F6.2,E6.2)", 120, 43.41, 43.41
|
||||
print "(3I5)", 10, 20, 30 !3 repeats of integers (field width = 5).
|
||||
print "(2(I5,F6.2))", 120, 43.42, 340, 65.3 !repeated grouping of formats.
|
||||
print "(3I5)", 10, 20, 30 ! 3 repeats of integers (field width = 5).
|
||||
print "(2(I5,F6.2))", 120, 43.42, 340, 65.3 ! repeated grouping of formats.
|
||||
|
||||
! We can also read input from the terminal.
|
||||
read *, v
|
||||
read "(2F6.2)", v, x !read two numbers
|
||||
|
||||
! To read a file.
|
||||
open(unit=11, file="records.txt", status="old")
|
||||
! The file is referred to by a 'unit number', an integer that you pick in
|
||||
! the range 9:99. Status can be one of {'old','replace','new'}.
|
||||
read(unit=11, fmt="(3F10.2)") a, b, c
|
||||
close(11)
|
||||
read (*, *) v
|
||||
read (*, "(2F6.2)") v, x ! read two numbers
|
||||
|
||||
! To write a file.
|
||||
open(unit=12, file="records.txt", status="replace")
|
||||
write(12, "(F10.2,F10.2,F10.2)") c, b, a
|
||||
close(12)
|
||||
open (unit=12, file="records.txt", status="replace")
|
||||
! The file is referred to by a 'unit number', an integer that you pick in
|
||||
! the range 9:99. Status can be one of {'old','replace','new'}.
|
||||
write (12, "(F10.2,F10.2,F10.2)") c, b, a
|
||||
close (12)
|
||||
|
||||
! To read a file.
|
||||
open (newunit=m, file="records.txt", status="old")
|
||||
! The file is referred to by a 'new unit number', an integer that the compiler
|
||||
! picks for you.
|
||||
read (unit=m, fmt="(3F10.2)") a, b, c
|
||||
close (m)
|
||||
|
||||
! There are more features available than discussed here and alternative
|
||||
! variants due to backwards compatibility with older Fortran versions.
|
||||
|
||||
|
||||
! Built-in Functions
|
||||
! ==================
|
||||
|
||||
! Fortran has around 200 functions/subroutines intrinsic to the language.
|
||||
! Examples -
|
||||
call cpu_time(v) !sets 'v' to a time in seconds.
|
||||
k = ior(i,j) !bitwise OR of 2 integers.
|
||||
v = log10(x) !log base 10.
|
||||
i = floor(b) !returns the closest integer less than or equal to x.
|
||||
v = aimag(w) !imaginary part of a complex number.
|
||||
|
||||
call cpu_time(v) ! sets 'v' to a time in seconds.
|
||||
k = ior(i, j) ! bitwise OR of 2 integers.
|
||||
v = log10(x) ! log base 10.
|
||||
i = floor(b) ! returns the closest integer less than or equal to x.
|
||||
v = aimag(w) ! imaginary part of a complex number.
|
||||
|
||||
! Functions & Subroutines
|
||||
! =======================
|
||||
@ -263,70 +251,69 @@ program example !declare a program called example.
|
||||
! A subroutine runs some code on some input values and can cause
|
||||
! side-effects or modify the input values.
|
||||
|
||||
call routine(a,c,v) !subroutine call.
|
||||
call routine(a, c, v) ! subroutine call.
|
||||
|
||||
! A function takes a list of input parameters and returns a single value.
|
||||
! However the input parameters may still be modified and side effects
|
||||
! executed.
|
||||
|
||||
m = func(3,2,k) !function call.
|
||||
m = func(3, 2, k) ! function call.
|
||||
|
||||
! Function calls can also be evoked within expressions.
|
||||
Print *, func2(3,2,k)
|
||||
print *, func2(3, 2, k)
|
||||
|
||||
! A pure function is a function that doesn't modify its input parameters
|
||||
! or cause any side-effects.
|
||||
m = func3(3,2,k)
|
||||
m = func3(3, 2, k)
|
||||
|
||||
|
||||
contains ! Zone for defining sub-programs internal to the program.
|
||||
contains ! Zone for defining sub-programs internal to the program.
|
||||
|
||||
! Fortran has a couple of slightly different ways to define functions.
|
||||
|
||||
integer function func(a,b,c) !a function returning an integer value.
|
||||
implicit none !best to use implicit none in function definitions too.
|
||||
integer :: a,b,c !type of input parameters defined inside the function.
|
||||
integer function func(a, b, c) ! a function returning an integer value.
|
||||
! implicit none ! subvariable fields can no longer declare implicit none
|
||||
integer, intent(in) :: a, b, c ! type of input parameters defined inside the function.
|
||||
|
||||
if (a >= 2) then
|
||||
func = a + b + c !the return variable defaults to the function name.
|
||||
return !can return the current value from the function at any time.
|
||||
endif
|
||||
func = a + b + c ! the return variable defaults to the function name.
|
||||
return ! can return the current value from the function at any time.
|
||||
end if
|
||||
func = a + c
|
||||
|
||||
! Don't need a return statement at the end of a function.
|
||||
end function func
|
||||
|
||||
|
||||
function func2(a,b,c) result(f) !return variable declared to be 'f'.
|
||||
implicit none
|
||||
integer, intent(in) :: a,b !can declare and enforce that variables
|
||||
!are not modified by the function.
|
||||
function func2(a, b, c) result(f) ! return variable declared to be 'f'.
|
||||
integer, intent(in) :: a, b ! can declare and enforce that variables
|
||||
!are not modified by the function.
|
||||
integer, intent(inout) :: c
|
||||
integer :: f !function return type declared inside the function.
|
||||
integer :: cnt = 0 !GOTCHA - initialisation implies variable is
|
||||
!saved between function calls.
|
||||
integer :: f ! function return type declared inside the function.
|
||||
integer :: cnt = 0 ! GOTCHA - initialisation implies variable is
|
||||
!saved between function calls.
|
||||
|
||||
f = a + b - c
|
||||
c = 4 !altering the value of an input variable.
|
||||
cnt = cnt + 1 !count number of function calls.
|
||||
c = 4 ! altering the value of an input variable.
|
||||
cnt = cnt + 1 ! count number of function calls.
|
||||
|
||||
end function func2
|
||||
|
||||
|
||||
pure function func3(a,b,c) !a pure function can have no side-effects.
|
||||
implicit none
|
||||
integer, intent(in) :: a,b,c
|
||||
pure function func3(a, b, c) ! a pure function can have no side-effects.
|
||||
integer, intent(in) :: a, b, c
|
||||
integer :: func3
|
||||
|
||||
func3 = a*b*c
|
||||
|
||||
end function func3
|
||||
|
||||
|
||||
subroutine routine(d,e,f)
|
||||
implicit none
|
||||
subroutine routine(d, e, f)
|
||||
real, intent(inout) :: f
|
||||
real, intent(in) :: d,e
|
||||
real, intent(in) :: d, e
|
||||
|
||||
f = 2*d + 3*e + f
|
||||
|
||||
end subroutine routine
|
||||
|
||||
|
||||
end program example ! End of Program Definition -----------------------
|
||||
|
||||
end program example ! End of Program Definition -----------------------
|
||||
|
||||
! Functions and Subroutines declared externally to the program listing need
|
||||
! to be declared to the program using an Interface declaration (even if they
|
||||
@ -338,9 +325,10 @@ elemental real function func4(a) result(res)
|
||||
! but can also be used on an array where it will be separately applied to all
|
||||
! of the elements of an array and return a new array.
|
||||
real, intent(in) :: a
|
||||
res = a**2 + 1.0
|
||||
end function func4
|
||||
|
||||
res = a**2 + 1.0
|
||||
|
||||
end function func4
|
||||
|
||||
! Modules
|
||||
! =======
|
||||
@ -349,22 +337,23 @@ end function func4
|
||||
! subroutines together for reusability.
|
||||
|
||||
module fruit
|
||||
|
||||
real :: apple
|
||||
real :: pear
|
||||
real :: orange
|
||||
end module fruit
|
||||
|
||||
end module fruit
|
||||
|
||||
module fruity
|
||||
! Declarations must be in the order: modules, interfaces, variables.
|
||||
! (can declare modules and interfaces in programs too).
|
||||
|
||||
use fruit, only: apple, pear ! use apple and pear from fruit module.
|
||||
implicit none !comes after module imports.
|
||||
implicit none ! comes after module imports.
|
||||
|
||||
private !make things private to the module (default is public).
|
||||
private ! make things private to the module (default is public).
|
||||
! Declare some variables/functions explicitly public.
|
||||
public :: apple,mycar,create_mycar
|
||||
public :: apple, mycar, create_mycar
|
||||
! Declare some variables/functions private to the module (redundant here).
|
||||
private :: func4
|
||||
|
||||
@ -389,13 +378,15 @@ module fruity
|
||||
! ==================
|
||||
! Can create custom structured data collections.
|
||||
type car
|
||||
character (len=100) :: model
|
||||
real :: weight !(kg)
|
||||
real :: dimensions(3) !i.e. length-width-height (metres).
|
||||
character(len=100) :: model
|
||||
real :: weight ! (kg)
|
||||
real :: dimensions(3) ! i.e. length-width-height (metres).
|
||||
character :: colour
|
||||
contains
|
||||
procedure :: info ! bind a procedure to a type.
|
||||
end type car
|
||||
|
||||
type(car) :: mycar !declare a variable of your custom type.
|
||||
type(car) :: mycar ! declare a variable of your custom type.
|
||||
! See create_mycar() routine for usage.
|
||||
|
||||
! Note: There are no executable statements in modules.
|
||||
@ -404,35 +395,48 @@ contains
|
||||
|
||||
subroutine create_mycar(mycar)
|
||||
! Demonstrates usage of a derived data type.
|
||||
implicit none
|
||||
type(car),intent(out) :: mycar
|
||||
type(car), intent(out) :: mycar
|
||||
|
||||
! Access type elements using '%' operator.
|
||||
mycar%model = "Ford Prefect"
|
||||
mycar%colour = 'r'
|
||||
mycar%weight = 1400
|
||||
mycar%dimensions(1) = 5.0 !default indexing starts from 1!
|
||||
mycar%dimensions(1) = 5.0 ! default indexing starts from 1!
|
||||
mycar%dimensions(2) = 3.0
|
||||
mycar%dimensions(3) = 1.5
|
||||
|
||||
end subroutine
|
||||
end subroutine create_mycar
|
||||
|
||||
real function real_abs(x)
|
||||
real :: x
|
||||
if (x<0) then
|
||||
subroutine info(self)
|
||||
class(car), intent(in) :: self
|
||||
! 'class' keyword used to bind a procedure to a type here.
|
||||
|
||||
print *, "Model : ", self%model
|
||||
print *, "Colour : ", self%colour
|
||||
print *, "Weight : ", self%weight
|
||||
print *, "Dimensions: ", self%dimensions
|
||||
|
||||
end subroutine info
|
||||
|
||||
real pure function real_abs(x)
|
||||
real, intent(in) :: x
|
||||
|
||||
if (x < 0) then
|
||||
real_abs = -x
|
||||
else
|
||||
real_abs = x
|
||||
end if
|
||||
|
||||
end function real_abs
|
||||
|
||||
real function complex_abs(z)
|
||||
complex :: z
|
||||
real pure function complex_abs(z)
|
||||
complex, intent(in) :: z
|
||||
! long lines can be continued using the continuation character '&'
|
||||
complex_abs = sqrt(real(z)**2 + &
|
||||
aimag(z)**2)
|
||||
end function complex_abs
|
||||
|
||||
complex_abs = sqrt(real(z)**2 + &
|
||||
aimag(z)**2)
|
||||
|
||||
end function complex_abs
|
||||
|
||||
end module fruity
|
||||
|
@ -217,7 +217,7 @@ function string_functions( localvar, arr) {
|
||||
# Les deux renvoient le nombre de correspondances remplacées
|
||||
localvar = "fooooobar";
|
||||
sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar"
|
||||
gsub("e", ".", localvar); # localvar => "m..t m. at th. bar"
|
||||
gsub("e", ".", localvar); # localvar => "M..t m. at th. bar"
|
||||
|
||||
# Rechercher une chaîne de caractères qui correspond à une expression
|
||||
# régulière index() fait la même chose, mais n'autorise pas les expressions
|
||||
|
@ -87,7 +87,7 @@ sauts de ligne.` // Chaîne de caractère.
|
||||
g := 'Σ' // type rune, un alias pour le type int32, contenant un caractère
|
||||
// unicode.
|
||||
|
||||
f := 3.14195 // float64, un nombre flottant IEEE-754 de 64-bit.
|
||||
f := 3.14159 // float64, un nombre flottant IEEE-754 de 64-bit.
|
||||
c := 3 + 4i // complex128, considéré comme deux float64 par le compilateur.
|
||||
|
||||
// Syntaxe "var" avec une valeur d'initialisation.
|
||||
@ -422,18 +422,18 @@ func requestServer() {
|
||||
|
||||
## En savoir plus
|
||||
|
||||
La référence Go se trouve sur [le site officiel de Go](http://golang.org/).
|
||||
La référence Go se trouve sur [le site officiel de Go](https://go.dev/).
|
||||
Vous pourrez y suivre le tutoriel interactif et en apprendre beaucoup plus.
|
||||
|
||||
Une lecture de la documentation du langage est grandement conseillée. C'est
|
||||
facile à lire et très court (comparé aux autres langages).
|
||||
|
||||
Vous pouvez exécuter et modifier le code sur [Go playground](https://play.golang.org/p/tnWMjr16Mm). Essayez de le modifier et de l'exécuter à partir de votre navigateur! Prennez en note que vous pouvez utiliser [https://play.golang.org](https://play.golang.org) comme un [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) pour tester et coder dans votre navigateur, sans même avoir à installer Go.
|
||||
Vous pouvez exécuter et modifier le code sur [Go playground](https://go.dev/play/p/tnWMjr16Mm). Essayez de le modifier et de l'exécuter à partir de votre navigateur! Prennez en note que vous pouvez utiliser [https://go.dev/play/](https://go.dev/play/) comme un [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) pour tester et coder dans votre navigateur, sans même avoir à installer Go.
|
||||
|
||||
Sur la liste de lecteur des étudiants de Go se trouve le [code source de la
|
||||
librairie standard](http://golang.org/src/pkg/). Bien documentée, elle démontre
|
||||
librairie standard](https://go.dev/src/). Bien documentée, elle démontre
|
||||
le meilleur de la clarté de Go, le style ainsi que ses expressions. Sinon, vous
|
||||
pouvez cliquer sur le nom d'une fonction dans [la
|
||||
documentation](http://golang.org/pkg/) et le code source apparaît!
|
||||
documentation](https://go.dev/pkg/) et le code source apparaît!
|
||||
|
||||
Une autre excellente ressource pour apprendre est [Go par l'exemple](https://gobyexample.com/).
|
||||
|
@ -33,6 +33,21 @@ let myInt = 5
|
||||
let myFloat = 3.14
|
||||
let myString = "hello" // note that no types needed
|
||||
|
||||
// Mutable variables
|
||||
let mutable a=3
|
||||
a <- 4 // a is now 4.
|
||||
|
||||
// Somewhat mutable variables
|
||||
// Reference cells are storage locations that enable you to create mutable values with reference semantics.
|
||||
// See https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/reference-cells
|
||||
let xRef = ref 10
|
||||
printfn "%d" xRef.Value // 10
|
||||
xRef.Value <- 11
|
||||
printfn "%d" xRef.Value // 11
|
||||
|
||||
let a=[ref 0; ref 1] // somewhat mutable list
|
||||
a[0].Value <- 2
|
||||
|
||||
// ------ Lists ------
|
||||
let twoToFive = [2; 3; 4; 5] // Square brackets create a list with
|
||||
// semicolon delimiters.
|
||||
|
@ -583,7 +583,8 @@ $ git rm /pather/to/the/file/HelloWorld.c
|
||||
```
|
||||
|
||||
### blame
|
||||
Examine specific parts of the code's history and find out who was the last author to modify that line
|
||||
Examine specific parts of the code's history and find out who was the last author to modify that line.
|
||||
|
||||
```bash
|
||||
# find the authors on the latest modified lines
|
||||
$ git blame google_python_style.vim
|
||||
|
@ -46,7 +46,7 @@ package main
|
||||
import (
|
||||
"fmt" // A package in the Go standard library.
|
||||
"io/ioutil" // Implements some I/O utility functions.
|
||||
"math" // Math library with local alias m.
|
||||
m "math" // Math library with local alias m.
|
||||
"net/http" // Yes, a web server!
|
||||
"os" // OS functions like working with the file system
|
||||
"strconv" // String conversions.
|
||||
@ -95,7 +95,7 @@ can include line breaks.` // Same string type.
|
||||
// Non-ASCII literal. Go source is UTF-8.
|
||||
g := 'Σ' // rune type, an alias for int32, holds a unicode code point.
|
||||
|
||||
f := 3.14195 // float64, an IEEE-754 64-bit floating point number.
|
||||
f := 3.14159 // float64, an IEEE-754 64-bit floating point number.
|
||||
c := 3 + 4i // complex128, represented internally with two float64's.
|
||||
|
||||
// var syntax with initializers.
|
||||
@ -130,7 +130,7 @@ can include line breaks.` // Same string type.
|
||||
// Because they are dynamic, slices can be appended to on-demand.
|
||||
// To append elements to a slice, the built-in append() function is used.
|
||||
// First argument is a slice to which we are appending. Commonly,
|
||||
// the array variable is updated in place, as in example below.
|
||||
// the slice variable is updated in place, as in example below.
|
||||
s := []int{1, 2, 3} // Result is a slice of length 3.
|
||||
s = append(s, 4, 5, 6) // Added 3 elements. Slice now has length of 6.
|
||||
fmt.Println(s) // Updated slice is now [1 2 3 4 5 6]
|
||||
@ -357,7 +357,7 @@ func learnInterfaces() {
|
||||
// Functions can have variadic parameters.
|
||||
func learnVariadicParams(myStrings ...interface{}) {
|
||||
// Iterate each value of the variadic.
|
||||
// The underbar here is ignoring the index argument of the array.
|
||||
// The underscore here is ignoring the index argument of the array.
|
||||
for _, param := range myStrings {
|
||||
fmt.Println("param:", param)
|
||||
}
|
||||
@ -456,21 +456,21 @@ func requestServer() {
|
||||
|
||||
## Further Reading
|
||||
|
||||
The root of all things Go is the [official Go web site](http://golang.org/).
|
||||
The root of all things Go is the [official Go web site](https://go.dev/).
|
||||
There you can follow the tutorial, play interactively, and read lots.
|
||||
Aside from a tour, [the docs](https://golang.org/doc/) contain information on
|
||||
Aside from a tour, [the docs](https://go.dev/doc/) contain information on
|
||||
how to write clean and effective Go code, package and command docs, and release history.
|
||||
|
||||
The [Go language specification](https://golang.org/ref/spec) itself is highly recommended. It's easy to read
|
||||
The [Go language specification](https://go.dev/ref/spec) itself is highly recommended. It's easy to read
|
||||
and amazingly short (as language definitions go these days.)
|
||||
|
||||
You can play around with the code on [Go playground](https://play.golang.org/p/tnWMjr16Mm). Try to change it and run it from your browser! Note that you can use [https://play.golang.org](https://play.golang.org) as a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) to test things and code in your browser, without even installing Go.
|
||||
You can play around with the code on [Go playground](https://go.dev/play/p/tnWMjr16Mm). Try to change it and run it from your browser! Note that you can use [https://go.dev/play/](https://go.dev/play/) as a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) to test things and code in your browser, without even installing Go.
|
||||
|
||||
On the reading list for students of Go is the [source code to the standard
|
||||
library](http://golang.org/src/pkg/). Comprehensively documented, it
|
||||
library](https://go.dev/src/). Comprehensively documented, it
|
||||
demonstrates the best of readable and understandable Go, Go style, and Go
|
||||
idioms. Or you can click on a function name in [the
|
||||
documentation](http://golang.org/pkg/) and the source code comes up!
|
||||
documentation](https://go.dev/pkg/) and the source code comes up!
|
||||
|
||||
Another great resource to learn Go is [Go by example](https://gobyexample.com/).
|
||||
|
||||
|
@ -3,6 +3,7 @@ language: Haskell
|
||||
filename: learnhaskell.hs
|
||||
contributors:
|
||||
- ["Adit Bhargava", "http://adit.io"]
|
||||
- ["Stanislav Modrak", "https://stanislav.gq"]
|
||||
---
|
||||
|
||||
Haskell was designed as a practical, purely functional programming
|
||||
@ -602,6 +603,6 @@ qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
|
||||
There are two popular ways to install Haskell: The traditional [Cabal-based installation](http://www.haskell.org/platform/), and the newer [Stack-based process](https://www.stackage.org/install).
|
||||
|
||||
You can find a much gentler introduction from the excellent
|
||||
[Learn you a Haskell](http://learnyouahaskell.com/),
|
||||
[Learn you a Haskell](http://learnyouahaskell.com/) (or [up-to-date community version](https://learnyouahaskell.github.io/)),
|
||||
[Happy Learn Haskell Tutorial](http://www.happylearnhaskelltutorial.com/) or
|
||||
[Real World Haskell](http://book.realworldhaskell.org/).
|
||||
|
574
hocon.html.markdown
Normal file
574
hocon.html.markdown
Normal file
@ -0,0 +1,574 @@
|
||||
---
|
||||
language: hocon
|
||||
filename: learnhocon.conf
|
||||
contributors:
|
||||
- [TehBrian, 'https://tehbrian.xyz']
|
||||
---
|
||||
|
||||
Human-Optimized Configuration Object Notation, or HOCON, is a configuration and
|
||||
data serialization format designed to be easily editable by humans.
|
||||
|
||||
It's a superset of JSON, meaning that any valid JSON is valid HOCON, but it
|
||||
differs in being much less pedantic and opinionated. With its flexible yet
|
||||
easily determinable syntax, resulting configuration files are often much less
|
||||
noisy than some other formats.
|
||||
|
||||
Additionally, its support for comments makes it much better suited for
|
||||
user-facing configurations than JSON.
|
||||
|
||||
```hocon
|
||||
// Comments can either look like this,
|
||||
# or they can look like this.
|
||||
// Anything after // or # is a comment.
|
||||
|
||||
##################
|
||||
### THE BASICS ###
|
||||
##################
|
||||
|
||||
# Everything in HOCON is either a key, a value, or a separator.
|
||||
# : and = are separators. They separate the key from the value.
|
||||
key: value
|
||||
another_key = another_value
|
||||
|
||||
# You can use either separator with or without whitespace on either side.
|
||||
colon1:value
|
||||
colon2: value
|
||||
colon3 : value
|
||||
equals1=value
|
||||
equals2= value
|
||||
equals3 = value
|
||||
# As you'll see, HOCON is very nonrestrictive regarding its syntax style.
|
||||
|
||||
# HOCON also isn't opinionated on how keys look.
|
||||
THIS_IS_A_VALID_KEY: value
|
||||
this-is-also-a-valid-key: value
|
||||
keys can have spaces too: value
|
||||
or even numbers like 12345: value
|
||||
"you can even quote keys if you'd like!": value
|
||||
|
||||
# A key, followed by any separator, and then finally a value, is called a field.
|
||||
this_entire_line_is: a field
|
||||
|
||||
###################
|
||||
### VALUE TYPES ###
|
||||
###################
|
||||
|
||||
# The types that a value can be are string, number, object, array, boolean, and
|
||||
# null. Every value type except for array and object are called simple values.
|
||||
|
||||
## SIMPLE VALUES ##
|
||||
|
||||
quoted_string: "I like quoting my strings."
|
||||
unquoted_string: I don't like quoting my strings.
|
||||
# Special characters that cannot be used in unquoted strings are:
|
||||
# $ " { } [ ] : = , + # ` ^ ? ! @ * &
|
||||
# Unquoted strings do not support any kind of escaping. If using one of those
|
||||
# special characters is desired, use a quoted string.
|
||||
multi-line_string: """
|
||||
This entire thing is a string!
|
||||
One giant, multi-line string.
|
||||
You can put 'single' and "double" quotes without it being invalid.
|
||||
"""
|
||||
|
||||
number: 123
|
||||
negative: -123
|
||||
fraction: 3.1415926536
|
||||
scientific_notation: 1.2e6 // same as 1.2 * (10^6)
|
||||
|
||||
boolean: true # or false
|
||||
empty: null
|
||||
|
||||
## ARRAYS ##
|
||||
|
||||
# Arrays hold lists of values.
|
||||
# Values in arrays can be separated with commas..
|
||||
array: [ 1, 2, 3, 4, 5 ]
|
||||
fibonacci: [1,1,2,3,5,8,13]
|
||||
multiples_of_5: [5, 10, 15, 20,] # Notice the trailing comma. That's okay here.
|
||||
# or newlines..
|
||||
friends: [
|
||||
"Brian"
|
||||
"Sophie"
|
||||
"Maya"
|
||||
"Sabina"
|
||||
]
|
||||
# or both!
|
||||
ingredients: [
|
||||
"Egg",
|
||||
"Sugar",
|
||||
"Oil",
|
||||
"Flour", # Notice the trailing comma. That's okay here too.
|
||||
]
|
||||
# Once again, HOCON has a very loose syntax. Use whichever style you prefer.
|
||||
no newline before or after bracket: ["This"
|
||||
"is"
|
||||
"an"
|
||||
"array!"]
|
||||
|
||||
# Just like any other value, arrays can hold other arrays.
|
||||
array in array: [ [1, 2, 3], ["a", "b", "c"] ]
|
||||
array in array in array: [ [ [1, 2], [8, 9] ], [ ["a", "b" ], ["y", "z"] ] ]
|
||||
|
||||
## OBJECTS ##
|
||||
|
||||
# Objects hold fields.
|
||||
# Just like arrays, fields in objects can be separated with commas..
|
||||
object: { key: value, another_key: another_value }
|
||||
server_connection: {ip: "127.0.0.1", port: 80}
|
||||
first: {letter: a, number: 1,} # Notice the trailing comma.
|
||||
# or newlines..
|
||||
power_grid: {
|
||||
max_capacity: 15000
|
||||
current_power: 1200
|
||||
}
|
||||
# or both!
|
||||
food_colors: {
|
||||
carrot: orange,
|
||||
pear: green,
|
||||
apple: red,
|
||||
plum: purple,
|
||||
banana: yellow, # Trailing commas are okay here too!
|
||||
}
|
||||
|
||||
# Arrays can hold objects just like any other value type.
|
||||
coworkers: [
|
||||
{
|
||||
name: Jeff
|
||||
age: 27
|
||||
},
|
||||
{
|
||||
name: Henry
|
||||
age: 35
|
||||
},
|
||||
{
|
||||
name: Timmy
|
||||
age: 12
|
||||
}
|
||||
]
|
||||
|
||||
# The field separator may be omitted if the key is followed by {
|
||||
no_separator {
|
||||
key: value
|
||||
speed_of_light: very fast
|
||||
ten: 10
|
||||
|
||||
# Objects can go inside other objects just like any other value.
|
||||
another_object {
|
||||
twenty: 20
|
||||
speed_of_sound: also pretty fast
|
||||
}
|
||||
}
|
||||
|
||||
# In fact, the entirety of any HOCON document is an actually just an object.
|
||||
# That object is called the root object. The only difference between it and any
|
||||
# other object is that the curly brackets at the top and bottom of the document
|
||||
# may be omitted.
|
||||
|
||||
# This means that HOCON documents can be formatted in the same way that
|
||||
# regular objects can be formatted, including separating fields with commas
|
||||
# rather than with newlines.
|
||||
|
||||
# Additionally, while the entirety of a HOCON document can be and is usually an
|
||||
# object, it can also be an array. If it is an array, the opening and closing
|
||||
# brackets at the top and bottom of the document must be explicitly written.
|
||||
|
||||
######################
|
||||
### DUPLICATE KEYS ###
|
||||
######################
|
||||
|
||||
is_happy: false
|
||||
# If there is a duplicate key, the new value overrides the previous value.
|
||||
is_happy: true
|
||||
online_users: [Jacob, Mike]
|
||||
# Same with arrays.
|
||||
online_users: [Jacob, Mike, Henry]
|
||||
|
||||
# For objects, it's a bit different.
|
||||
my_car: {
|
||||
color: blue
|
||||
speed: 9001
|
||||
passengers: null
|
||||
|
||||
engine: {
|
||||
running: true
|
||||
temperature: 137
|
||||
}
|
||||
}
|
||||
# If there is a duplicate key and both values are objects,
|
||||
# then the objects are merged.
|
||||
my_car: {
|
||||
// These fields are added to the old, previous object.
|
||||
nickname: "My Favorite Car"
|
||||
type: 2-door sedan
|
||||
|
||||
// Since the value of this duplicate key is NOT an object,
|
||||
// it simply overrides the previous value.
|
||||
speed: 60
|
||||
// Same with arrays. They override, not merge.
|
||||
passengers: ["Nate", "Ty"]
|
||||
|
||||
// This object is recursively merged with the other object.
|
||||
engine: {
|
||||
// These two fields are added to the previous object.
|
||||
type: gas
|
||||
oil_level: 10
|
||||
// This field overrides the previous value.
|
||||
temperature: 179
|
||||
}
|
||||
}
|
||||
|
||||
# Object merging is done two at a time. That is to say, the first two objects
|
||||
# merge into one, then that object merges with the next object, and so on.
|
||||
|
||||
# Because of this, if you set a field with an object value to a non-object value
|
||||
# and then back to an object value, the new object will completely override any
|
||||
# previous value.
|
||||
|
||||
// Null, a non-object value, completely overrides the object value.
|
||||
my_car: null
|
||||
|
||||
// Then, this object completely overrides null.
|
||||
my_car: {
|
||||
nickname: "My New Car"
|
||||
type: 4-door minivan
|
||||
color: gray
|
||||
speed: 90
|
||||
passengers: ["Ayden", "Liz"]
|
||||
}
|
||||
|
||||
###########################
|
||||
### VALUE CONCATENATION ###
|
||||
###########################
|
||||
|
||||
## SIMPLE VALUE CONCATENATION ##
|
||||
|
||||
# Simple values (all value types except objects and arrays) separated by
|
||||
# whitespace are concatenated into a single string. The whitespace between
|
||||
# values is preserved.
|
||||
number_concatenation: 1 2 3 12.5 -3 2e5 // same as: "1 2 3 12.5 -3 2e5"
|
||||
boolean_concat: true false true // "true false true"
|
||||
null_concat: null null null // "null null null"
|
||||
mixed_concat: 1 true null // "1 true null"
|
||||
|
||||
# String value concatenation can appear anywhere that a quoted string can.
|
||||
number_concat_in_array: [1 2, 3 4, 5 6] // same as: ["1 2", "3 4", "5 6"]
|
||||
|
||||
# In fact, unquoted strings are actually just string value concatenations.
|
||||
unquoted_string_concat: his name is jeff // same as: "his name is jeff"
|
||||
|
||||
# Going further, even keys that are unquoted strings are actually just string
|
||||
# value concatenations.
|
||||
this is a key: value // the KEY is the same as: "this is a key"
|
||||
# The following field is identical to the field above.
|
||||
"this is a key": value
|
||||
|
||||
# Quoted strings can also be concatenated. This will be useful later,
|
||||
# when we cover substitutions.
|
||||
quoted_string_concat: "her"" name" "is ""jenna" // same as: "her name is jenna"
|
||||
# Notice that the whitespace (or lack thereof) between values is preserved.
|
||||
|
||||
## ARRAY CONCATENATION ##
|
||||
|
||||
# Arrays separated by whitespace are merged into a single array.
|
||||
array_concat: [1, 2, 3] [4, 5, 6] // same as: [1, 2, 3, 4, 5, 6]
|
||||
|
||||
# Arrays cannot be concatenated with a non-array value.
|
||||
//array_concat: true [false] results in an error
|
||||
//array_concat: 1 [2] results in an error
|
||||
|
||||
## OBJECT CONCATENATION ##
|
||||
|
||||
# Objects separated by whitespace are merged into a single object.
|
||||
# The merge functionality is identical to that of duplicate key object merging.
|
||||
lamp: {on: true} {color: tan} // same as: {on: true, color: tan}
|
||||
|
||||
# Similarly to arrays, objects cannot be concatenated with a non-object value.
|
||||
//object_concat: true {on: false} results in an error
|
||||
//object_concat: 1 {number: 2} results in an error
|
||||
|
||||
########################
|
||||
### PATH EXPRESSIONS ###
|
||||
########################
|
||||
|
||||
# Path expressions are used to write out a path through the object graph.
|
||||
# Think of it as navigating through objects to a specific field.
|
||||
# Each object to traverse through is called an element, and each element is
|
||||
# separated with a period.
|
||||
|
||||
country: {
|
||||
city: {
|
||||
neighborhood: {
|
||||
house: {
|
||||
name: "My House"
|
||||
address: 123 Example Dr.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# For example, the path to the address of the house could be written as:
|
||||
# country.city.neighborhood.house.address
|
||||
# Country, city, neighborhood, house, and address are all elements.
|
||||
|
||||
# Path expressions are used in two places: substitutions (which will be
|
||||
# covered in a moment), and as keys.
|
||||
# That's right: keys themselves can also be path expressions.
|
||||
foo: {
|
||||
bar: {
|
||||
baz: {
|
||||
number: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
# Rather than tediously specifying each object, a path expression can be used.
|
||||
# The following field represents the same object found above.
|
||||
foo.bar.baz.number: 12
|
||||
|
||||
# Fields and objects specified with path expressions are merged in the same way
|
||||
# that any object is usually merged.
|
||||
foo.bar.baz.bool: true
|
||||
// the object foo's value is: foo { bar { baz { number: 12, bool: true } } }
|
||||
|
||||
#####################
|
||||
### SUBSTITUTIONS ###
|
||||
#####################
|
||||
|
||||
# Substitutions refer to a specific value from some path expression.
|
||||
# They're only allowed in values, not keys or nested inside other substitutions.
|
||||
|
||||
me: {
|
||||
favorite_animal: parrots
|
||||
favorite_food: cookies
|
||||
}
|
||||
# The syntax for a substitution is either ${path_expression} or
|
||||
# ${?path_expression}. The latter syntax will be discussed in a moment.
|
||||
my_fav_animal: ${me.favorite_animal}
|
||||
my_fav_food: ${me.favorite_food}
|
||||
|
||||
# Substitutions are not parsed inside quoted strings. To get around this,
|
||||
# either use an unquoted string or value concatenation.
|
||||
animal_announcement: My favorite animal is ${my_fav_animal}
|
||||
// the value is: My favorite animal is parrots
|
||||
food_announcement: "My favorite food is "${my_fav_food}"!"
|
||||
// the value is: "My favorite food is cookies!"
|
||||
|
||||
# Substitutions are parsed last in the document. Because of this, you can
|
||||
# reference a key that hasn't been defined yet.
|
||||
color_announcement: "My favorite color is" ${my_fav_color}"!"
|
||||
// the value is: "My favorite color is blue!"
|
||||
my_fav_color: blue
|
||||
|
||||
# Another effect of substitutions being parsed last is that substitutions will
|
||||
# always use the latest, as in last, value assigned in the entire document,
|
||||
# which includes merged objects.
|
||||
color: green
|
||||
their_favorite_color: ${color} // the value is: orange
|
||||
color: orange
|
||||
|
||||
random_object: {
|
||||
number: 12
|
||||
}
|
||||
the_number: ${random_object.number} // the value is: 15
|
||||
random_object: {
|
||||
number: 15
|
||||
}
|
||||
|
||||
###############################
|
||||
### UNDEFINED SUBSTITUTIONS ###
|
||||
###############################
|
||||
|
||||
# A substitution using the ${path_expression} syntax with an undefined path
|
||||
# expression, meaning a path expression that does not point to a defined value,
|
||||
# is invalid and will therefore generate an error.
|
||||
//${does.not.exist} will throw an error
|
||||
|
||||
# However, an undefined substitution using the ${?path_expression} syntax
|
||||
# has different behavior depending on what it is the value of.
|
||||
request: {
|
||||
# If it is the value of a field, then the field will not be created.
|
||||
response: ${?does.not.exist} // this field won't be created and does not exist
|
||||
type: HTTP
|
||||
}
|
||||
|
||||
request: {
|
||||
# Additionally, if it would have overridden a previous value, then the
|
||||
# previous value remains unchanged.
|
||||
type: ${?does.not.exist} // request.type is still HTTP
|
||||
}
|
||||
|
||||
# If it is a value in an array, then it is simply not added.
|
||||
values: [ 172, "Brian", ${?does.not.exist}, null, true, ]
|
||||
// the value is: [ 172, "Brian", null, true ]
|
||||
|
||||
# If it is part of simple value concatenation, it acts as an empty string.
|
||||
final_string: "String One"${?does.not.exist}"String Two"
|
||||
// the value is: "String OneString Two"
|
||||
|
||||
# If it is part of array concatenation, it acts as an empty array.
|
||||
final_array: [ 1, 2, 3 ] ${?does.not.exist} [ 7, 8, 9 ]
|
||||
// the value is: [ 1, 2, 3, 7, 8, 9 ]
|
||||
|
||||
# If it is part of object concatenation, it acts as an empty object.
|
||||
final_array: { a: 1 } ${?does.not.exist} { c: 3 }
|
||||
// the value is: { a: 1, c: 3 }
|
||||
|
||||
######################################
|
||||
### SELF-REFERENTIAL SUBSTITUTIONS ###
|
||||
######################################
|
||||
|
||||
# Substitutions normally "look forward" and use the final value defined in the
|
||||
# document. However, in cases when this would create a cycle, the substitution
|
||||
# looks only backwards.
|
||||
|
||||
# A field which contains a substitution that points to itself or points to
|
||||
# other fields that eventually point back to itself is called a
|
||||
# self-referential field.
|
||||
letters: "a b c" // the value is: "a b c"
|
||||
letters: ${letters}" d" // "a b c d"
|
||||
letters: ${letters}" e" // "a b c d e"
|
||||
|
||||
PATH: [/bin] // the value is: [/bin]
|
||||
PATH: ${PATH} [/usr/bin] // [/bin, /usr/bin]
|
||||
PATH: ${PATH} [/usr/local/bin] // [/bin, /usr/bin, /usr/local/bin]
|
||||
|
||||
x: "x" // the value is: "x"
|
||||
y: ${x}"y" // "xy"
|
||||
x: ${y}"z" // "xyz"
|
||||
|
||||
##########################
|
||||
### += FIELD SEPARATOR ###
|
||||
##########################
|
||||
|
||||
# In addition to : and =, there actually exists another separator: +=
|
||||
# A field separated with += acts as a self-referential array concatenation.
|
||||
# In short, it appends an element to a previously defined array.
|
||||
|
||||
a: [1]
|
||||
b: [1]
|
||||
# This field:
|
||||
a += 2 // the value is: [1, 2]
|
||||
# functions the same as:
|
||||
b: ${?b} [2] // the value is: [1, 2]
|
||||
|
||||
USERS: [/usr/luke] // the value is: [/usr/luke]
|
||||
USERS += /usr/devon // [/usr/luke, /usr/devon]
|
||||
USERS += /usr/michael // [/usr/luke, /usr/devon, /usr/michael]
|
||||
|
||||
# Since += only appends elements to a previously existing array, if the previous
|
||||
# value was not an array, an error will be generated.
|
||||
OTHER_USERS: /usr/luke
|
||||
//OTHER_USERS += /usr/devon results in an error
|
||||
|
||||
# Notice that the underlying substitution syntax used is ${?path}, not ${path}.
|
||||
# Recall that, using the ${?} syntax, an undefined substitution in array
|
||||
# concatenation acts as an empty array. Because of this, it is perfectly
|
||||
# acceptable if the field that is being set is initially undefined.
|
||||
//z: [] not necessary
|
||||
z += 3 // the value is: [3]
|
||||
z += 4 // the value is: [3, 4]
|
||||
|
||||
NEW_USERS += /usr/sandra // the value is: [/usr/sandra]
|
||||
NEW_USERS += /usr/kennedy // [/usr/sandra, /usr/kennedy]
|
||||
NEW_USERS += /usr/robin // [/usr/sandra, /usr/kennedy, /usr/robin]
|
||||
|
||||
################
|
||||
### INCLUDES ###
|
||||
################
|
||||
|
||||
# Includes allow you to "import" one HOCON document into another.
|
||||
|
||||
# An include statement consists of the unquoted string "include" followed by
|
||||
# whitespace and then a resource name, which is one of the following:
|
||||
# - a single quoted string which is heuristically interpreted as a URL,
|
||||
# filename, or a Java classpath resource.
|
||||
# - url(), file(), or classpath(), with the parentheses surrounding a quoted
|
||||
# string which is either a URL, filename, or classpath resource respectively.
|
||||
# - required(), with the parentheses surrounding one of the above.
|
||||
include "https://example.com/config.conf"
|
||||
include "/foo/bar/config.conf"
|
||||
include "config.conf"
|
||||
|
||||
include url("https://example.com/config.conf")
|
||||
include file("/foo/bar/config.conf")
|
||||
include classpath("config.conf")
|
||||
|
||||
# If the included file does not exist, it will be silently ignored and act as if
|
||||
# it were an empty object. However, if it is wrapped around required(), then
|
||||
# parsing will explicitly error if the file cannot be resolved.
|
||||
//include required("doesnt_exist.conf") will error
|
||||
//include required(url("https://example.com/doesnt_exist.conf")) will error
|
||||
//include required(file("doesnt_exist.conf")) will error
|
||||
//include required(classpath("doesnt_exist.conf")) will error
|
||||
|
||||
# The file specified by the include statement is called the included file, and
|
||||
# the file which contains the include statement is called the including file.
|
||||
|
||||
# Including a file functions as if you directly replaced the include statement,
|
||||
# wherever it may be, with the contents of the included file's root object.
|
||||
|
||||
# An included file must have an object as its root value and not an array.
|
||||
# If the included file has an array as its root value, then it is invalid and
|
||||
# an error will be generated.
|
||||
|
||||
# Pretend that the following is in a file called user_config.conf:
|
||||
username: RandomUser1337
|
||||
auto_login: true
|
||||
color_theme: dark
|
||||
screensaver: {
|
||||
image: usr/images/screensaver.jpg
|
||||
turn_on_after: 1m
|
||||
}
|
||||
|
||||
# And then we include that file.
|
||||
include file("user_config.conf")
|
||||
|
||||
# We can now reference values from that file!
|
||||
path_to_user_screensaver: ${screensaver.image} //
|
||||
greeting: "Welcome, "${username}"!" // the value is: "Welcome, RandomUser1337!"
|
||||
|
||||
# Duplicate keys override as they normally do.
|
||||
status: "Auto Login: "${auto_login} // the value is: "Auto Login: true"
|
||||
auto_login: false
|
||||
status: "Auto Login: "${auto_login} // the value is: "Auto Login: false"
|
||||
|
||||
# Object merging is also the same as usual.
|
||||
screensaver: {
|
||||
// This gets added to the screensaver object.
|
||||
enable_during_day: false
|
||||
// This overrides the previous value.
|
||||
turn_on_after: 30s
|
||||
}
|
||||
|
||||
# Include statements can appear in place of a field. Anywhere that a field
|
||||
# could appear, an include statement could appear as well.
|
||||
|
||||
# Pretend that the following is in a file called server_settings.conf:
|
||||
max_connections: 10
|
||||
url: example.com
|
||||
port: 80
|
||||
admin_page: {
|
||||
username: admin
|
||||
password: pass12345
|
||||
}
|
||||
|
||||
# And then we include that file nested inside another object.
|
||||
websites: {
|
||||
my_epic_website: {
|
||||
include file("server_settings.conf")
|
||||
}
|
||||
}
|
||||
|
||||
# Now, we can reference the contents of server_settings.conf as if they
|
||||
# had been written directly into the object my_epic_website.
|
||||
server_port: ${websites.my_epic_website.port}
|
||||
|
||||
the_password: "The password is: "${websites.my_epic_website.admin_page.password}
|
||||
// the value is: The password is: pass12345
|
||||
|
||||
max_conn: "Max Connections: "${websites.my_epic_website.max_connections}
|
||||
// the value is: Max Connections: 10
|
||||
```
|
||||
|
||||
### More Resources
|
||||
|
||||
+ [Official HOCON Specification](https://github.com/lightbend/config/blob/master/HOCON.md)
|
||||
+ [HOCON Playground](https://hocon-playground.herokuapp.com)
|
120
httpie.html.markdown
Normal file
120
httpie.html.markdown
Normal file
@ -0,0 +1,120 @@
|
||||
---
|
||||
category: tool
|
||||
tool: httpie
|
||||
contributors:
|
||||
- ["Adaías Magdiel", "https://github.com/AdaiasMagdiel"]
|
||||
filename: learn-httpie.sh
|
||||
---
|
||||
|
||||
HTTPie is a powerful command-line HTTP client designed for easy interaction
|
||||
with HTTP servers. It provides a simple and intuitive interface, making it an
|
||||
excellent tool for developers, testers, and system administrators.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
HTTPie follows a simple syntax: http [flags] [METHOD] URL [items].
|
||||
|
||||
```bash
|
||||
http GET https://api.example.com/posts
|
||||
```
|
||||
|
||||
You can print the request without sending it by using the `--offline` flag.
|
||||
|
||||
```bash
|
||||
http --offline https://api.example.com/posts
|
||||
```
|
||||
|
||||
### URL shortcuts for `localhost`
|
||||
|
||||
HTTPie supports a curl-like shorthand for localhost. For instance, ":3000"
|
||||
expands to "http://localhost:3000". If the port is omitted, it assumes port 80.
|
||||
|
||||
```bash
|
||||
http :/users # http://localhost/users
|
||||
http :5000/rss # http://localhost:5000/rss
|
||||
```
|
||||
|
||||
### Optional GET and POST
|
||||
|
||||
If you don't specify the METHOD, the HTTPie will use:
|
||||
|
||||
- GET for requests without body
|
||||
- POST for requests with body
|
||||
|
||||
```bash
|
||||
http https://api.example.com/tags # GET tags
|
||||
http https://api.example.com/tags title="Tutorial" slug="tutorial" # POST a new tag
|
||||
```
|
||||
|
||||
## Querystring Parameters
|
||||
|
||||
|
||||
If you're manually adding query string parameters in the terminal, try the
|
||||
`param==value` syntax. It avoids shell escaping for & separators and
|
||||
automatically URL-escapes special characters in parameter names and values.
|
||||
This differs from parameters in the full URL, which HTTPie doesn't modify.
|
||||
|
||||
```bash
|
||||
http https://api.example.com/search q==httpie per_page==20
|
||||
```
|
||||
|
||||
## Sending Data
|
||||
|
||||
You can send data in various formats such as JSON, form data, or files.
|
||||
|
||||
### JSON Data
|
||||
|
||||
```bash
|
||||
http POST https://api.example.com/posts title="Hello" body="World"
|
||||
```
|
||||
|
||||
### Form Data
|
||||
|
||||
```bash
|
||||
http -f POST https://api.example.com/submit name=John email=john@example.com
|
||||
```
|
||||
|
||||
### Files
|
||||
|
||||
```bash
|
||||
http --form POST https://api.example.com/upload file@/path/to/file.txt
|
||||
```
|
||||
|
||||
## Headers and Authentication
|
||||
|
||||
HTTPie allows you to set headers and handle authentication easily.
|
||||
|
||||
### Headers
|
||||
|
||||
```bash
|
||||
http GET https://api.example.com/posts Authorization:"Bearer Token" User-Agent:"HTTPie"
|
||||
```
|
||||
|
||||
### Basic Authentication
|
||||
|
||||
```bash
|
||||
http -a username:password GET https://api.example.com/protected
|
||||
```
|
||||
|
||||
### Bearer Authentication
|
||||
|
||||
```bash
|
||||
https -A bearer -a token https://api.example.com/admin
|
||||
```
|
||||
|
||||
## Response Handling
|
||||
|
||||
HTTPie provides various options for handling responses.
|
||||
|
||||
```bash
|
||||
http GET https://api.example.com/data Accept:application/json # Pretty Print JSON
|
||||
|
||||
http GET https://api.example.com/image --output image.png # Save Response to File
|
||||
|
||||
http --follow GET https://example.com # Follow Redirects
|
||||
```
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Official Documentation](https://httpie.io/docs/cli).
|
||||
- [Github](https://github.com/httpie).
|
@ -89,7 +89,7 @@ func learnTypes() {
|
||||
g := 'Σ' // rúna(rune) típus, megegyezik az uint32-vel, egy UTF-8 karaktert
|
||||
// tárol
|
||||
|
||||
f := 3.14195 // float64, az IEEE-754 szabványnak megfelelő 64-bites
|
||||
f := 3.14159 // float64, az IEEE-754 szabványnak megfelelő 64-bites
|
||||
// lebegőpontos szám
|
||||
c := 3 + 4i // complex128, belsőleg két float64-gyel tárolva
|
||||
|
||||
@ -325,7 +325,7 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
## További olvasmányok
|
||||
|
||||
Minden Go-val kapcsolatos megtaláható a [hivatalos Go weboldalon](http://golang.org/).
|
||||
Minden Go-val kapcsolatos megtaláható a [hivatalos Go weboldalon](https://go.dev/).
|
||||
Ott követhetsz egy tutorialt, játszhatsz a nyelvvel az interneten, és sok érdekességet olvashatsz.
|
||||
|
||||
A nyelv specifikációját kifejezetten érdemes olvasni, viszonylag rövid és sokat tanul belőle az ember.
|
||||
|
@ -174,10 +174,10 @@ True ; => True
|
||||
|
||||
; create lexical bindings with `let', all variables defined thusly
|
||||
; have local scope
|
||||
(let [[nemesis {"superman" "lex luther"
|
||||
(let [nemesis {"superman" "lex luther"
|
||||
"sherlock" "moriarty"
|
||||
"seinfeld" "newman"}]]
|
||||
(for [(, h v) (.items nemesis)]
|
||||
"seinfeld" "newman"}]
|
||||
(for [[h v] (.items nemesis)]
|
||||
(print (.format "{0}'s nemesis was {1}" h v))))
|
||||
|
||||
;; classes
|
||||
|
@ -4,7 +4,7 @@ contributors:
|
||||
- ["Ryan Mavilia", "http://unoriginality.rocks/"]
|
||||
translators:
|
||||
- ["Rizky Luthfianto", "http://github.com/rilut"]
|
||||
filename: asciidoc-id.md
|
||||
filename: asciidoc-id.adoc
|
||||
lang: id-id
|
||||
---
|
||||
|
||||
|
@ -6,7 +6,7 @@ contributors:
|
||||
translators:
|
||||
- ["Ale46", "https://github.com/ale46"]
|
||||
lang: it-it
|
||||
filename: asciidoc-it.md
|
||||
filename: asciidoc-it.adoc
|
||||
---
|
||||
|
||||
AsciiDoc è un linguaggio di markup simile a Markdown e può essere usato per qualsiasi cosa, dai libri ai blog. Creato nel 2002 da Stuart Rackman, questo linguaggio è semplice ma permette un buon numero di personalizzazioni.
|
||||
|
@ -91,7 +91,7 @@ può includere andata a capo.` // Sempre di tipo stringa.
|
||||
// Stringa letterale non ASCII. I sorgenti Go sono in UTF-8.
|
||||
g := 'Σ' // Il tipo runa, alias per int32, è costituito da un code point unicode.
|
||||
|
||||
f := 3.14195 // float64, un numero in virgola mobile a 64-bit (IEEE-754)
|
||||
f := 3.14159 // float64, un numero in virgola mobile a 64-bit (IEEE-754)
|
||||
|
||||
c := 3 + 4i // complex128, rappresentato internamente con due float64.
|
||||
|
||||
@ -422,9 +422,9 @@ func richiediServer() {
|
||||
|
||||
## Letture consigliate
|
||||
|
||||
La risorsa più importante per imparare il Go è il [sito ufficiale di Go](http://golang.org/).
|
||||
La risorsa più importante per imparare il Go è il [sito ufficiale di Go](https://go.dev/).
|
||||
Qui puoi seguire i tutorial, scrivere codice in modo interattivo, e leggere tutti i dettagli.
|
||||
Oltre al tour, [la documentazione](https://golang.org/doc/) contiene informazioni su
|
||||
Oltre al tour, [la documentazione](https://go.dev/doc/) contiene informazioni su
|
||||
come scrivere ottimo codice in Go, documentazione sui package e sui comandi, e
|
||||
la cronologia delle release.
|
||||
|
||||
@ -432,17 +432,17 @@ Anche il documento che definisce il linguaggio è un'ottima lettura. E' semplice
|
||||
da leggere e incredibilmente corto (rispetto ad altri documenti riguardanti
|
||||
la creazione di linguaggi).
|
||||
|
||||
Puoi giocare con il codice visto finora nel [Go playground](https://play.golang.org/p/Am120Xe7qf).
|
||||
Puoi giocare con il codice visto finora nel [Go playground](https://go.dev/play/p/Am120Xe7qf).
|
||||
Prova a cambiarlo e ad eseguirlo dal browser!
|
||||
Osserva che puoi usare [https://play.golang.org](https://play.golang.org) come
|
||||
Osserva che puoi usare [https://go.dev/play/](https://go.dev/play/) come
|
||||
una [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per scrivere
|
||||
codice all'interno del browser, senza neanche installare Go!
|
||||
|
||||
Una lettura importante per capire Go in modo più profondo è il [codice
|
||||
sorgente della libreria standard](http://golang.org/src/pkg/). Infatti è
|
||||
sorgente della libreria standard](https://go.dev/src/). Infatti è
|
||||
molto ben documentato e costituisce quanto più chiaro e conciso ci sia riguardo
|
||||
gli idiomi e le buone pratiche del Go. Inoltre, clickando sul nome di una
|
||||
funzione [nella documentazione](http://golang.org/pkg/) compare il relativo
|
||||
funzione [nella documentazione](https://go.dev/pkg/) compare il relativo
|
||||
codice sorgente!
|
||||
|
||||
Un'altra ottima risorsa per imparare è [Go by example](https://gobyexample.com/).
|
||||
|
@ -253,7 +253,7 @@ Ma non è comunemente usato.
|
||||
Le immagini sono inserite come i link ma con un punto esclamativo inserito prima delle parentesi quadre!
|
||||
|
||||
```md
|
||||
![Qeusto è il testo alternativo per l'immagine](http://imgur.com/myimage.jpg "Il titolo opzionale")
|
||||
![Questo è il testo alternativo per l'immagine](http://imgur.com/myimage.jpg "Il titolo opzionale")
|
||||
```
|
||||
|
||||
E la modalità a riferimento funziona esattamente come ci si aspetta
|
||||
@ -307,4 +307,4 @@ Col 1 | Col2 | Col3
|
||||
```
|
||||
|
||||
---
|
||||
Per altre informazioni, leggete il post ufficiale di John Gruber sulla sintassi [qui](http://daringfireball.net/projects/markdown/syntax) e il magnifico cheatsheet di Adam Pritchard [qui](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
|
||||
Per altre informazioni, leggete il post ufficiale di John Gruber sulla sintassi [qui](https://daringfireball.net/projects/markdown/syntax) e il magnifico cheatsheet di Adam Pritchard [qui](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
|
||||
|
193
it-it/php-composer-it.html.markdown
Normal file
193
it-it/php-composer-it.html.markdown
Normal file
@ -0,0 +1,193 @@
|
||||
---
|
||||
category: tool
|
||||
tool: composer
|
||||
contributors:
|
||||
- ["Brett Taylor", "https://github.com/glutnix"]
|
||||
translator:
|
||||
- ["Agostino Fiscale", "https://github.com/agostinofiscale"]
|
||||
lang: it-it
|
||||
filename: LearnComposer-it.sh
|
||||
---
|
||||
|
||||
[Composer](https://getcomposer.org/) è uno strumento che ti aiuta a gestire le
|
||||
dipendenze in PHP. Ti permette di dichiarare le librerie utilizzate dal tuo
|
||||
progetto e di installarle/aggiornarle per te.
|
||||
|
||||
# Installazione
|
||||
|
||||
```sh
|
||||
# Se installi l'eseguibile in una cartella...
|
||||
curl -sS https://getcomposer.org/installer | php
|
||||
# ...dovrai utilizzare questo approccio, invocando Composer in questo modo:
|
||||
php composer.phar about
|
||||
|
||||
# Se installi l'eseguibile nella directory ~/bin/composer
|
||||
# Nota: assicurati che ~/bin si trovi nella variabile di ambiente PATH
|
||||
curl -sS https://getcomposer.org/installer | php -- --install-dir=~/bin --filename=composer
|
||||
```
|
||||
|
||||
Gli utenti Windows possono seguire le istruzioni per [installarlo su Windows](https://getcomposer.org/doc/00-intro.md#installation-windows).
|
||||
|
||||
## Assicuriamoci che il tutto abbia funzionato correttamente
|
||||
|
||||
```sh
|
||||
# Controlla la versione e la lista delle opzioni disponibili
|
||||
composer
|
||||
|
||||
# Ottieni ulteriori informazioni riguardanti le opzioni
|
||||
composer help require
|
||||
|
||||
# Controlla se Composer ha tutto il necessario per funzionare come si deve
|
||||
# e se è aggiornato correttamente all'ultima versione disponibile.
|
||||
composer diagnose
|
||||
composer diag # alias
|
||||
|
||||
# Aggiorna Composer all'ultima versione disponibile
|
||||
composer self-update
|
||||
composer self # alias
|
||||
```
|
||||
|
||||
# Cominciamo ad usare Composer
|
||||
|
||||
Composer memorizza le dipendenze necessarie nel file `composer.json`.
|
||||
Puoi editare questo file manualmente, ma è meglio che lasci che Composer se ne
|
||||
occupi per te.
|
||||
|
||||
```sh
|
||||
# Crea un nuovo progetto nella cartella attuale
|
||||
composer init
|
||||
# ti verranno chieste delle domande interrative riguardanti il tuo progetto.
|
||||
# Puoi evitare di rispondere almeno che tu non stia sviluppando altri progetti
|
||||
# che che possano dipendere da questo.
|
||||
|
||||
# Se il file composer.json esiste già, scarichera' le dipendenze necessarie
|
||||
composer install
|
||||
|
||||
# Scarica le dipendenze necessarie per l'ambiente di produzione
|
||||
composer install --no-dev
|
||||
|
||||
# Aggiunge una dipendenza per l'ambiente di produzione
|
||||
composer require guzzlehttp/guzzle
|
||||
# automaticamente selezionera' l'ultima versione, la scarichera' e la aggiungera'
|
||||
# come dipendenza nell'apposito campo del file composer.json.
|
||||
|
||||
composer require guzzlehttp/guzzle:6.0.*
|
||||
# scarichera' l'ultima versione disponibile corrispondente al pattern (es. 6.0.2)
|
||||
# e lo aggiungera' come dipendenza nell'apposito campo del file composer.json.
|
||||
|
||||
composer require --dev phpunit/phpunit:~4.5.0
|
||||
# aggiungera' la dipendenza nell'ambiente di sviluppo utilizzando l'ultima versione
|
||||
# disponibile nel range >=4.5.0 e < 4.6.0.
|
||||
|
||||
composer require-dev phpunit/phpunit:^4.5.0
|
||||
# aggiungera' la dipendenza nell'ambiente di sviluppo utilizzando l'ultima versione
|
||||
# disponibile nel range >=4.5.0 and < 5.0.
|
||||
|
||||
# Per ulteriori dettagli riguardo le versioni, vedi [la documentazione di Composer sulle versioni](https://getcomposer.org/doc/articles/versions.md) per ulteriori dettagli
|
||||
|
||||
# Per vedere quali pacchetti sono installabili e quali sono gia' stati installati
|
||||
composer show
|
||||
|
||||
# Per vedere solo quali pacchetti sono gia' stati installati
|
||||
composer show --installed
|
||||
|
||||
# Per trovare una dipendenza con 'mailgun' nel suo nome o nella descrizione.
|
||||
composer search mailgun
|
||||
```
|
||||
|
||||
[Packagist.org](https://packagist.org/) è il repository principale per i pacchetti
|
||||
di Composer. Cerca qui pacchetti di terze-parti utili per il tuo progetto.
|
||||
|
||||
## `composer.json` vs `composer.lock`
|
||||
|
||||
Il file `composer.json` memorizza la versione che si preferisce per ogni dipendenza,
|
||||
insieme ad altre informazioni.
|
||||
|
||||
Il file `composer.lock` memorizza quale versione è stata scaricata per ogni
|
||||
dipendenza. Non editare mai questo file.
|
||||
|
||||
Se includi il file `composer.lock` nella tua repository git, ogni sviluppatore
|
||||
andra' a installare la versione attualmente utilizzata dal tuo progetto per
|
||||
ogni dipendenza. Anche quando una nuova versione è stata rilasciata, Composer
|
||||
andra' a installare la versione registrata nel file lock.
|
||||
|
||||
```sh
|
||||
# Se vuoi aggiornare tutte le dipendenze all'ultima versione che corrisponde al pattern descritto
|
||||
composer update
|
||||
|
||||
# Se vuoi scaricare l'ultima versione di una particolare dipendenza:
|
||||
composer update phpunit/phpunit
|
||||
|
||||
# Se vuoi cambiare la versione di una una dipendenza, potresti dover rimuovere
|
||||
# quello attualmente selezionato, per poi richiedere quello corretto successivamente,
|
||||
# attraverso i seguenti comandi:
|
||||
composer remove --dev phpunit/phpunit
|
||||
composer require --dev phpunit/phpunit:^5.0
|
||||
|
||||
```
|
||||
|
||||
## Autoloader
|
||||
|
||||
Composer crea una classe autoloader che puoi richiamare nella tua applicazione.
|
||||
Puoi creare instanze delle classi tramite il loro namespace.
|
||||
|
||||
```php
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$mailgun = new Mailgun\Mailgun("key");
|
||||
```
|
||||
|
||||
### PSR-4 Autoloader
|
||||
|
||||
Puoi aggiungere i tuoi namespace all'autoloader.
|
||||
|
||||
Nel file `composer.json`, aggiungi il campo "autoload":
|
||||
|
||||
```json
|
||||
{
|
||||
"autoload": {
|
||||
"psr-4": {"Acme\\": "src/"}
|
||||
}
|
||||
}
|
||||
```
|
||||
Questo dira' all'autoloader di controllare ogni risorsa che corrisponde al
|
||||
namespace `\Acme\` all'interno della cartella `src`.
|
||||
|
||||
In alternativa puoi usare [PSR-0, una Classmap o una lista di file da includere](https://getcomposer.org/doc/04-schema.md#autoload).
|
||||
Inoltre e' possibile anche utilizzare `autoload-dev` dedicato all'ambiente di sviluppo.
|
||||
|
||||
Quando aggiungi o modifichi una chiave, dovrai ricompilare l'autoload attraverso:
|
||||
|
||||
```sh
|
||||
composer dump-autoload
|
||||
composer dump # alias
|
||||
|
||||
# Ottimizza i pacchetti PSR0 e PSR4 per essere caricati anche con le classmap.
|
||||
# Sara' lento, ma migliorera' le performance in produzione.
|
||||
composer dump-autoload --optimize --no-dev
|
||||
```
|
||||
|
||||
# La cache di Composer
|
||||
|
||||
```sh
|
||||
# Composer utilizzera i pacchetti scaricati anche per i progetti futuri. Per evitare che accada:
|
||||
composer clear-cache
|
||||
```
|
||||
|
||||
# Problemi?
|
||||
|
||||
```sh
|
||||
composer diagnose
|
||||
composer self-update
|
||||
composer clear-cache
|
||||
```
|
||||
|
||||
## Argomenti che non sono stati (ancora) discussi in questo tutorial
|
||||
|
||||
* Creare e distribuire pacchetti personali su Packagist.org o altrove
|
||||
* Pre- e post- script hooks: eseguire operazioni quando vengono eseguiti degli eventi
|
||||
|
||||
### References
|
||||
|
||||
* [Composer - Dependency Manager for PHP](https://getcomposer.org/)
|
||||
* [Packagist.org](https://packagist.org/)
|
@ -5,7 +5,7 @@ contributors:
|
||||
- ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
|
||||
translators:
|
||||
- ["Ryota Kayanuma", "https://github.com/PicoSushi"]
|
||||
filename: asciidoc-ja.md
|
||||
filename: asciidoc-ja.adoc
|
||||
lang: ja-jp
|
||||
---
|
||||
|
||||
|
193
ja-jp/yaml-jp.html.markdown
Normal file
193
ja-jp/yaml-jp.html.markdown
Normal file
@ -0,0 +1,193 @@
|
||||
---
|
||||
language: yaml
|
||||
filename: learnyaml-jp.yaml
|
||||
contributors:
|
||||
- [Leigh Brenecki, 'https://leigh.net.au']
|
||||
- [Suhas SG, 'https://github.com/jargnar']
|
||||
translators:
|
||||
- [haru, 'https://haru52.com/']
|
||||
lang: ja-jp
|
||||
---
|
||||
|
||||
YAMLはデータのシリアライズ用言語で、
|
||||
人間が直接読み書きしやすいようにデザインされています。
|
||||
|
||||
YAMLはJSONの厳格なスーパーセットで、
|
||||
改行とインデントが構文的に意味を持つというPythonに似た仕様を追加しています。
|
||||
しかしPythonとは異なりYAMLではインデントにタブ文字を使うことはできません。
|
||||
|
||||
```yaml
|
||||
--- # ドキュメント開始
|
||||
|
||||
# YAMLのコメントはこんな感じです。
|
||||
|
||||
##############
|
||||
# スカラー型 #
|
||||
##############
|
||||
|
||||
# (ドキュメント全体を含む)ルートオブジェクトはマップになります。
|
||||
# これは他言語における辞書型、ハッシュ、オブジェクトなどと等価です。
|
||||
キー: 値
|
||||
別のキー: 別の値。
|
||||
数値: 100
|
||||
指数表記: 1e+12
|
||||
# 1 はbooleanでなく数値として解釈されます。
|
||||
# もしbooleanとして解釈してほしい場合はtrueを使います
|
||||
boolean: true
|
||||
null値: null
|
||||
スペースを 含む キー: 値
|
||||
# 文字列をクォートで囲う必要がないことに注意してください。
|
||||
# しかし囲うこともできます。
|
||||
しかし: 'クォートで囲まれた文字列。'
|
||||
'キーもクォートで囲えます。': "keyの中で ':' を使いたいときに有用です。"
|
||||
シングルクォート: 'には ''1つの'' エスケープパターンがあります'
|
||||
ダブルクォート: "には多くのエスケープパターンがあります:\", \0, \t, \u263A,
|
||||
\x0d\x0a == \r\n, など、他にもあります。"
|
||||
# UTF-8/16/32文字はエンコードされている必要があります
|
||||
上付き2: \u00B2
|
||||
|
||||
# 複数行の文字列は(| を使う)「リテラルブロック」、
|
||||
# または、('>' を使う)「折り畳みブロック」として書くことができます
|
||||
リテラルブロック: |
|
||||
この文章のブロック全体が「リテラルブロック」キーの値になり、
|
||||
改行は保持されます。
|
||||
|
||||
リテラルはインデントを解除するまで続き、先頭行のインデント文字数分を
|
||||
各行のテキストの先頭から取り除きます。
|
||||
|
||||
「よりインデントの深い」行はその分のインデントを保持します -
|
||||
この2行はスペース4個分インデントされます。
|
||||
折り畳みスタイル: >
|
||||
この文章のブロック全体が「折り畳みスタイル」の値になります。
|
||||
しかしこちらの場合、全ての改行がスペース1個に置き換わります。
|
||||
|
||||
直前のような空行は改行文字に変換されます。
|
||||
|
||||
「よりインデントの深い」行も改行を保持します -
|
||||
このテキストは2行にわたって表示されます。
|
||||
|
||||
##################
|
||||
# コレクション型 #
|
||||
##################
|
||||
|
||||
# 入れ子を表現するにはインデントを使います。
|
||||
# スペース2個のインデントが好まれます(が必須ではありません)。
|
||||
入れ子のマップ:
|
||||
キー: 値
|
||||
別のキー: 別の値
|
||||
別の入れ子のマップ:
|
||||
こんにちは: こんにちは
|
||||
|
||||
# マップのキーは文字列である必要はありません。
|
||||
0.25: 小数のキー
|
||||
|
||||
# 複数行オブジェクトのような複雑なキーも使用可能です。
|
||||
# ? の後にスペースを入れることで複雑なキーの開始を宣言できます。
|
||||
? |
|
||||
これはキーです
|
||||
複数行あります
|
||||
: そしてこれがその値です
|
||||
|
||||
# YAMLではシーケンスを複雑なキー構文で使うこともできます
|
||||
# しかし、言語パーサーによってはエラーになるかもしれません
|
||||
# 例
|
||||
? - マンチェスター・ユナイテッド
|
||||
- レアル・マドリード
|
||||
: [2001-01-01, 2002-02-02]
|
||||
|
||||
# シーケンス(リストや配列と等価)はこんな感じです
|
||||
# ('-' はインデントとしてカウントしてください):
|
||||
シーケンス:
|
||||
- アイテム1
|
||||
- アイテム2
|
||||
- 0.5 # シーケンスには異なる型の値を混在させられます
|
||||
- アイテム4
|
||||
- キー: 値
|
||||
別のキー: 別の値
|
||||
-
|
||||
- これはシーケンスです
|
||||
- 別のシーケンス内部
|
||||
- - - 入れ子のシーケンス表記は
|
||||
- 折り畳めます
|
||||
|
||||
# YAMLはJSONのスーパーセットなので、
|
||||
# JSON形式のマップとシーケンスを書くこともできます:
|
||||
jsonマップ: {"キー": "値"}
|
||||
jsonシーケンス: [3, 2, 1, "発進"]
|
||||
クォートは任意: {キー: [3, 2, 1, 発進]}
|
||||
|
||||
######################
|
||||
# その他のYAMLの機能 #
|
||||
######################
|
||||
|
||||
# YAMLには「アンカー」と呼ばれる便利な機能もあります。これによりコンテンツを
|
||||
# ドキュメント内で簡単に複製できます。これらのキーはどちらも同じ値を持ちます:
|
||||
アンカーされたコンテンツ: &anchor_name この文字列は2つのキーの値になります。
|
||||
他のアンカー: *anchor_name
|
||||
|
||||
# アンカーは複製/継承プロパティとして使えます
|
||||
ベース: &base
|
||||
名前: みんな同じ名前を持ちます
|
||||
|
||||
# 記号 << はマージキー言語非依存型(Merge Key Language-Independent Type)
|
||||
# と呼ばれます。これは指定された1つ以上のマップの全てのキーを現在のマップに
|
||||
# 挿入することを示すために使われます。
|
||||
|
||||
foo:
|
||||
<<: *base
|
||||
年齢: 10
|
||||
|
||||
bar:
|
||||
<<: *base
|
||||
年齢: 20
|
||||
|
||||
# fooとbarも「名前: みんな同じ名前を持ちます」を持ちます
|
||||
|
||||
# YAMLにはタグもあり、明示的に型を宣言できます。
|
||||
明示的な文字列: !!str 0.5
|
||||
# 言語特有のタグを実装したパーサーもあり、例えばPythonの複素数型が使えます。
|
||||
pythonの複素数型: !!python/complex 1+2j
|
||||
|
||||
# YAMLの複雑なキーでは言語特有のタグも使えます
|
||||
? !!python/tuple [5, 7]
|
||||
: 五十七
|
||||
# Python上で {(5, 7): '五十七'} として扱われます
|
||||
|
||||
####################
|
||||
# その他のYAMLの型 #
|
||||
####################
|
||||
|
||||
# 文字列と数値がYAMLの理解できる唯一のスカラーではありません。
|
||||
# ISO形式の日付や日時リテラルもパースされます。
|
||||
日時: 2001-12-15T02:59:43.1Z
|
||||
スペースを含む日時: 2001-12-14 21:59:43.10 -5
|
||||
日付: 2002-12-14
|
||||
|
||||
# !!binaryタグは文字列の実体がバイナリblobのbase64エンコード表現であることを
|
||||
# 示します。
|
||||
gifファイル: !!binary |
|
||||
R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
|
||||
OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
|
||||
+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
|
||||
AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
|
||||
|
||||
# YAMLにはセット型もあり、それはこんな感じです:
|
||||
セット:
|
||||
? アイテム1
|
||||
? アイテム2
|
||||
? アイテム3
|
||||
または: {アイテム1, アイテム2, アイテム3}
|
||||
|
||||
# セットは値がnullのただのマップで、直前のセットは以下と等価です:
|
||||
セット2:
|
||||
アイテム1: null
|
||||
アイテム2: null
|
||||
アイテム3: null
|
||||
|
||||
... # ドキュメント終了
|
||||
```
|
||||
|
||||
### 補足資料
|
||||
|
||||
+ [YAML公式ウェブサイト](https://yaml.org/)
|
||||
+ [オンラインYAMLバリデーター](http://www.yamllint.com/)
|
@ -29,9 +29,9 @@ nil
|
||||
# Typical style for symbols (identifiers-for / names-of things).
|
||||
do-stuff
|
||||
pants-on-fire!
|
||||
foo->bar # Evidently for converting foos to bars.
|
||||
foo->bar # Evidently for converting foos to bars.
|
||||
fully-charged?
|
||||
_ # Usually used as a dummy variable.
|
||||
_ # Usually used as a dummy variable.
|
||||
|
||||
# Keywords are like symbols that start with a colon, are treated like
|
||||
# constants, and are typically used as map keys or pieces of syntax in
|
||||
@ -58,10 +58,11 @@ math/e # => 2.71828
|
||||
"hello"
|
||||
"hey\tthere" # contains a tab
|
||||
|
||||
# For multi-line strings, use one or more backticks. No escapes allowed.
|
||||
# For multi-line strings, use one or more backticks. Backslash-escapes not
|
||||
# recognized in these (bytes will be parsed literally).
|
||||
``a long
|
||||
multi-line
|
||||
string`` # => "a long\nmulti-line\nstring"
|
||||
string`` # => "a long\nmulti-line\nstring"
|
||||
|
||||
# Strings and data structures in Janet come in two varieties: mutable and
|
||||
# immutable. The literal for the mutable variety is written with a `@` in
|
||||
@ -72,7 +73,7 @@ string`` # => "a long\nmulti-line\nstring"
|
||||
@`a multi-line
|
||||
one here`
|
||||
|
||||
(string "con" "cat" "enate") # => "concatenate"
|
||||
(string "con" "cat" "enate") # => "concatenate"
|
||||
|
||||
# To get a substring:
|
||||
(string/slice "abcdefgh" 2 5) # => "cde"
|
||||
@ -81,7 +82,8 @@ one here`
|
||||
|
||||
# See the string library for more (splitting, replacement, etc.)
|
||||
|
||||
# Arrays and Tuples ###########################################################
|
||||
# Data Structures #############################################################
|
||||
# Arrays and Tuples
|
||||
# Arrays are mutable, tuples are immutable.
|
||||
|
||||
# Arrays (mutable)
|
||||
@ -91,18 +93,19 @@ one here`
|
||||
# Tuples (immutable)
|
||||
# Note that an open paren usually indicates a function call, so if you want a
|
||||
# literal tuple with parens, you need to "quote" it (with a starting single
|
||||
# quote mark).
|
||||
# quote mark)...
|
||||
'(4 5 6)
|
||||
[4 5 6] # ... or just use square brackets.
|
||||
|
||||
# Tables and Structs (AKA: "maps", "hashmaps", "dictionaries")
|
||||
# Tables and Structs (associative data structures)
|
||||
@{:a 1 :b 2 :c 3} # table (mutable)
|
||||
{:a 1 :b 2 :c 3} # struct (immutable)
|
||||
|
||||
# To "pretty-print" these out, use `pp` instead of `print`.
|
||||
# More about how to work with arrays/tuples and tables/structs below.
|
||||
|
||||
# Bindings ####################################################################
|
||||
# ... or "Name Some Things!" (that is, bind a value to a symbol)
|
||||
# Bind a value to a symbol.
|
||||
(def x 4.7) # Define a constant, `x`.
|
||||
x # => 4.7
|
||||
(quote x) # => x (the symbol x)
|
||||
@ -113,7 +116,7 @@ x # => 4.7
|
||||
(set x 5.6) # Error, `x` is a constant.
|
||||
|
||||
(var y 10)
|
||||
(set y 12) # Works, since `y` was made var.
|
||||
(set y 12) # Works, since `y` was defined using `var`.
|
||||
|
||||
# Note that bindings are local to the scope they're called in. `let`
|
||||
# creates a local scope and makes some bindings all in one shot:
|
||||
@ -151,29 +154,29 @@ insect-friend # => bee
|
||||
(% 5 3) # => 2 (remainder)
|
||||
(- 5) # => -5 (or you can just write `-5`)
|
||||
|
||||
(++ i) # increments
|
||||
(++ i) # increments (modifies `i`)
|
||||
(-- i) # decrements
|
||||
(+= i 3) # add 3 to `i`
|
||||
(*= i 3) # triple `i`
|
||||
# ... and so on for the other operations on numbers.
|
||||
|
||||
# If you don't want to mutate `i`, use `(inc i)` and `(dec i)`.
|
||||
|
||||
# Comparison
|
||||
# = < > not= <= >=
|
||||
(< 2 7 12) # => true
|
||||
|
||||
# Functions ###################################################################
|
||||
# Call them:
|
||||
(- 5 3) # => 2 (Yes, operators and functions work the same.)
|
||||
(- 5 3) # => 2 (Operators and functions work the same way.)
|
||||
(math/sin (/ math/pi 2)) # => 1
|
||||
(range 5) # => @[0 1 2 3 4]
|
||||
(range 5) # => @[0 1 2 3 4]
|
||||
|
||||
# Create them:
|
||||
(defn mult-by-2
|
||||
``First line of docstring.
|
||||
|
||||
Some more of the docstring.
|
||||
|
||||
Possibly more!``
|
||||
Some more of the docstring.``
|
||||
[x]
|
||||
(print "Hi.")
|
||||
(print "Will compute using: " x)
|
||||
@ -206,7 +209,7 @@ n # => 3
|
||||
# You might say that function bodies provide an "implicit do".
|
||||
|
||||
# Operations on data structures ###############################################
|
||||
# (Making all these mutable so we can ... mutate them.)
|
||||
# (Making all of these mutable so we can ... mutate them.)
|
||||
(def s @"Hello, World!")
|
||||
(def a @[:a :b :c :d :e])
|
||||
(def t @{:a 1 :b 2})
|
||||
@ -216,9 +219,9 @@ n # => 3
|
||||
(length t) # => 2
|
||||
|
||||
# Getting values:
|
||||
(s 7) # => 87 (which is the code point for "W")
|
||||
(a 1) # => :b
|
||||
(t :a) # => 1
|
||||
(s 7) # => 87 (which is the code point for "W")
|
||||
(a 1) # => :b
|
||||
(t :a) # => 1
|
||||
(keys t) # => @[:a :b]
|
||||
(values t) # => @[1 2]
|
||||
|
||||
@ -227,14 +230,14 @@ n # => 3
|
||||
(put a 2 :x) # @[:a :b :x :d :e]
|
||||
(put t :b 42) # @{:a 1 :b 42}
|
||||
|
||||
# Adding & removing values (again, for mutable data structures):
|
||||
# Adding and removing values (again, for mutable data structures):
|
||||
(buffer/push-string s "??") # @"HeWlo, World!??"
|
||||
(array/push a :f) # @[:a :b :x :d :e :f]
|
||||
(array/pop a) # => :f, and it's also removed from `a`.
|
||||
(put t :x 88) # @{:a 1 :b 42 :x 88}
|
||||
|
||||
# See the manual for a wide variety of functions for working with
|
||||
# buffers/strings, arrays/tuples, and tables/struct.
|
||||
# buffers/strings, arrays/tuples, and tables/structs.
|
||||
|
||||
# Flow control ################################################################
|
||||
(if some-condition
|
||||
@ -282,7 +285,7 @@ n # => 3
|
||||
{:yar v} (print "matches key :yar! " v)
|
||||
{:moo v} (print "matches key :moo! " v)
|
||||
{:c v} (print "matches key :c! " v)
|
||||
_ (print "no match")) # => prints "matches key :c! 3"
|
||||
_ (print "no match")) # => prints "matches key :c! 3"
|
||||
|
||||
# Iterating ###################################################################
|
||||
# Iterate over an integer range:
|
||||
@ -312,7 +315,7 @@ n # => 3
|
||||
(* x x))
|
||||
(range 10))) # => @[0 4 16 36 64]
|
||||
|
||||
(reduce + 0 (range 5)) # => 10
|
||||
(reduce + 0 (range 5)) # => 10
|
||||
|
||||
# ...and lots more (see the API docs).
|
||||
|
||||
|
@ -91,6 +91,9 @@ public class LearnJava {
|
||||
int numInt = scanner.nextInt();
|
||||
|
||||
// read long input
|
||||
long numLong = scanner.nextLong();
|
||||
|
||||
// read float input
|
||||
float numFloat = scanner.nextFloat();
|
||||
|
||||
// read double input
|
||||
@ -123,6 +126,9 @@ public class LearnJava {
|
||||
// <name1> = <name2> = <name3> = <val>
|
||||
int barInt1, barInt2, barInt3;
|
||||
barInt1 = barInt2 = barInt3 = 1;
|
||||
// Shorthand for multiple declarations
|
||||
int barInt4 = 1, barInt5 = 2;
|
||||
|
||||
|
||||
/*
|
||||
* Variable types
|
||||
@ -182,7 +188,7 @@ public class LearnJava {
|
||||
//
|
||||
// BigInteger is a data type that allows programmers to manipulate
|
||||
// integers longer than 64-bits. Integers are stored as an array of
|
||||
// of bytes and are manipulated using functions built into BigInteger
|
||||
// bytes and are manipulated using functions built into BigInteger
|
||||
//
|
||||
// BigInteger can be initialized using an array of bytes or a string.
|
||||
BigInteger fooBigInteger = new BigInteger(fooByteArray);
|
||||
@ -304,8 +310,8 @@ public class LearnJava {
|
||||
///////////////////////////////////////
|
||||
System.out.println("\n->Operators");
|
||||
|
||||
int i1 = 1, i2 = 2; // Shorthand for multiple declarations
|
||||
|
||||
int i1 = 1, i2 = 2;
|
||||
|
||||
// Arithmetic is straightforward
|
||||
System.out.println("1+2 = " + (i1 + i2)); // => 3
|
||||
System.out.println("2-1 = " + (i2 - i1)); // => 1
|
||||
@ -314,7 +320,7 @@ public class LearnJava {
|
||||
System.out.println("1/2.0 = " + (i1 / (double)i2)); // => 0.5
|
||||
|
||||
// Modulo
|
||||
System.out.println("11%3 = "+(11 % 3)); // => 2
|
||||
System.out.println("11%3 = " + (11 % 3)); // => 2
|
||||
|
||||
// Comparison operators
|
||||
System.out.println("3 == 2? " + (3 == 2)); // => false
|
||||
@ -368,7 +374,7 @@ public class LearnJava {
|
||||
|
||||
// While loop
|
||||
int fooWhile = 0;
|
||||
while(fooWhile < 100) {
|
||||
while (fooWhile < 100) {
|
||||
System.out.println(fooWhile);
|
||||
// Increment the counter
|
||||
// Iterated 100 times, fooWhile 0,1,2...99
|
||||
@ -383,7 +389,7 @@ public class LearnJava {
|
||||
// Increment the counter
|
||||
// Iterated 100 times, fooDoWhile 0->99
|
||||
fooDoWhile++;
|
||||
} while(fooDoWhile < 100);
|
||||
} while (fooDoWhile < 100);
|
||||
System.out.println("fooDoWhile Value: " + fooDoWhile);
|
||||
|
||||
// For Loop
|
||||
|
@ -105,6 +105,10 @@ false;
|
||||
"1, 2, " + 3; // = "1, 2, 3"
|
||||
"Hello " + ["world", "!"]; // = "Hello world,!"
|
||||
|
||||
// ...which can result in some weird behaviour...
|
||||
13 + !0; // 14
|
||||
"13" + !0; // '13true'
|
||||
|
||||
// and are compared with < and >
|
||||
"a" < "b"; // = true
|
||||
|
||||
@ -116,10 +120,6 @@ null == undefined; // = true
|
||||
"5" === 5; // = false
|
||||
null === undefined; // = false
|
||||
|
||||
// ...which can result in some weird behaviour...
|
||||
13 + !0; // 14
|
||||
"13" + !0; // '13true'
|
||||
|
||||
// You can access characters in a string with `charAt`
|
||||
"This is a string".charAt(0); // = 'T'
|
||||
|
||||
@ -405,7 +405,7 @@ myObj = {
|
||||
};
|
||||
myObj.myFunc(); // = "Hello world!"
|
||||
|
||||
// What this is set to has to do with how the function is called, not where
|
||||
// What `this` is set to has to do with how the function is called, not where
|
||||
// it's defined. So, our function doesn't work if it isn't called in the
|
||||
// context of the object.
|
||||
var myFunc = myObj.myFunc;
|
||||
@ -655,7 +655,7 @@ attached terminal
|
||||
[Javascript: The Right Way][10] is a guide intended to introduce new developers
|
||||
to JavaScript and help experienced developers learn more about its best practices.
|
||||
|
||||
[Javascript:Info][11] is a modern javascript tutorial covering the basics (core language and working with a browser)
|
||||
[javascript.info][11] is a modern javascript tutorial covering the basics (core language and working with a browser)
|
||||
as well as advanced topics with concise explanations.
|
||||
|
||||
|
||||
@ -671,6 +671,7 @@ Mozilla Developer Network.
|
||||
[5]: http://bonsaiden.github.io/JavaScript-Garden/
|
||||
[6]: http://www.amazon.com/gp/product/0596805527/
|
||||
[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
|
||||
[8]: https://www.javascripttutorial.net/
|
||||
[8]: http://eloquentjavascript.net/
|
||||
[10]: http://jstherightway.org/
|
||||
[11]: https://javascript.info/
|
||||
|
270
jinja.html.markdown
Normal file
270
jinja.html.markdown
Normal file
@ -0,0 +1,270 @@
|
||||
---
|
||||
language: Jinja
|
||||
contributors:
|
||||
- ["Adaías Magdiel", "https://github.com/AdaiasMagdiel"]
|
||||
filename: learn-jinja.j2
|
||||
---
|
||||
|
||||
## Getting Started with Jinja
|
||||
|
||||
Jinja is a fast, expressive, and extensible templating engine for Python
|
||||
applications.
|
||||
|
||||
Jinja includes a lot of functionalities, such as:
|
||||
- Template inheritance and inclusion;
|
||||
- Defining and importing macros within templates;
|
||||
- Security mechanisms to prevent XSS attacks;
|
||||
- A sandboxed environment that can safely render untrusted templates;
|
||||
- Extensible filters, tests, functions, and even syntax.
|
||||
|
||||
A Jinja template is simply a text file. Jinja doesn't require a specific
|
||||
extension, but it's common to use `.j2` or `.jinja` to make it easier for
|
||||
some IDEs.
|
||||
|
||||
There are a few kinds of delimiters. The default Jinja delimiters are configured
|
||||
as follows:
|
||||
|
||||
- `{% ... %}` for Statements
|
||||
- `{{ ... }}` for Expressions to print to the template output
|
||||
- `{# ... #}` for Comments not included in the template output
|
||||
|
||||
```jinja
|
||||
{# This is an example of a comment. #}
|
||||
|
||||
{#
|
||||
You can use this syntax
|
||||
to write multiline comments
|
||||
as well.
|
||||
#}
|
||||
```
|
||||
|
||||
|
||||
## VARIABLES
|
||||
|
||||
```jinja
|
||||
{# You have the option to access variables from the context passed to the template #}
|
||||
|
||||
{{ foo }}
|
||||
|
||||
{#
|
||||
Additionally, you can use a dot (.) to access attributes of a variable or
|
||||
use Python syntax, using []
|
||||
#}
|
||||
|
||||
{{ foo.bar }}
|
||||
{{ foo['bar'] }}
|
||||
|
||||
{# Within the template, you can define variables as well #}
|
||||
|
||||
{% set name = "Magdiel" %}
|
||||
{{ name }}
|
||||
```
|
||||
|
||||
## Loops
|
||||
|
||||
```html
|
||||
<h1>Members</h1>
|
||||
<ul>
|
||||
{% for user in users %}
|
||||
<li>{{ user.username }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
||||
<div>
|
||||
{% for key, value in my_dict.items() %}
|
||||
<p>{{ key }}</p> - <p>{{ value }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
{% for idx, url in enumerate(urls) %}
|
||||
<a href="{{ url }}">Go to url {{ idx + 1 }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
```
|
||||
|
||||
## Conditionals
|
||||
|
||||
The if statement in Jinja is similar to the if statement in Python. It is
|
||||
commonly used to check if a variable is defined, not empty, and not false in
|
||||
its most basic form.
|
||||
|
||||
```html
|
||||
{% if users %}
|
||||
<ul>
|
||||
{% for user in users %}
|
||||
<li>{{ user.username }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{# For multiple branches, elif and else can be used like in Python. #}
|
||||
|
||||
|
||||
{% if message.status == "error" %}
|
||||
<p class="text-red-400">{{ message.content }}</p>
|
||||
{% elif message.status == "success" %}
|
||||
<p class="text-green-400">{{ message.content }}</p>
|
||||
{% else %}
|
||||
<p class="text-blue-400">{{ message.content }}</p>
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
## Template Inheritance
|
||||
|
||||
One of the most powerful features of Jinja is template inheritance. You can
|
||||
create a base layout with predefined blocks that you can extend in another file
|
||||
and override with your own content.
|
||||
|
||||
```html
|
||||
{# file: base.html.j2 #}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{% block head %}
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}{% endblock title %} - Learning Jinja</title>
|
||||
{% endblock head %}
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
{% block content %}{% endblock %}
|
||||
{# the endblock tag doesn't need the name of the block #}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
{# file: child.html.j2 #}
|
||||
|
||||
{% extends "base.html.j2" %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
console.log("There's a console.log here")
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}Home{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Index</h1>
|
||||
<p>Welcome to my home homepage.</p>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
{# RESULT #}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Home - Learning Jinja</title>
|
||||
<script>
|
||||
console.log("There's a console.log here")
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Index</h1>
|
||||
<p>Welcome to my home homepage.</p>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
```
|
||||
|
||||
### Including Content
|
||||
|
||||
You can include content from another template on your current template using
|
||||
the `{% include "template/path" %}` tag.
|
||||
|
||||
```html
|
||||
|
||||
{# file: footer.html.j2 #}
|
||||
|
||||
<footer>
|
||||
<p>© 2024 - John Doe</p>
|
||||
</footer>
|
||||
|
||||
|
||||
|
||||
{# file: index.html.j2 #}
|
||||
...
|
||||
<body>
|
||||
<main>
|
||||
<h1>Hi! I'm John Doe!</h1>
|
||||
</main>
|
||||
{% include "footer.html.j2" %}
|
||||
</body>
|
||||
...
|
||||
|
||||
|
||||
|
||||
{# RESULT #}
|
||||
|
||||
...
|
||||
<body>
|
||||
<main>
|
||||
<h1>Hi! I'm John Doe!</h1>
|
||||
</main>
|
||||
<footer>
|
||||
<p>© 2024 - John Doe</p>
|
||||
</footer>
|
||||
</body>
|
||||
...
|
||||
```
|
||||
|
||||
Variables passed to the main template can also be used in the include, as the
|
||||
included template has access to the context of the main template.
|
||||
|
||||
```html
|
||||
{# file: greetings.html.j2 #}
|
||||
|
||||
<p>I'm the {{ name }} and i like to {{ hobby }}.</p>
|
||||
|
||||
|
||||
|
||||
{# file: index.html.j2 #}
|
||||
|
||||
{% set name = "Captain Nemo" %}
|
||||
{% set hobby = "navigate through the depths of the ocean" %}
|
||||
|
||||
<div>
|
||||
{% include "greetings.html.j2" %}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{# RESULT #}
|
||||
|
||||
<div>
|
||||
<p>I'm the Captain Nemo and i like to navigate through the depths of the ocean.</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Macros
|
||||
|
||||
Macros are basically like functions in another languages. You can define macros with or without arguments and reuse them in various parts of your template.
|
||||
|
||||
```html
|
||||
{% macro input(value="", type="text", placeholder="") -%}
|
||||
<input type="{{ type }}" value="{{ value }}" placeholder="{{ placeholder }}">
|
||||
{%- endmacro %}
|
||||
|
||||
<p>{{ input(placeholder="Your username") }}</p>
|
||||
<p>{{ input(type="password") }}</p>
|
||||
```
|
||||
|
||||
## Official Documentation
|
||||
|
||||
To learn more, access the [official documentation](https://jinja.palletsprojects.com/en/).
|
910
jq.html.markdown
Normal file
910
jq.html.markdown
Normal file
@ -0,0 +1,910 @@
|
||||
---
|
||||
category: tool
|
||||
tool: jq
|
||||
contributors:
|
||||
- ["Jack Kuan", "https://github.com/kjkuan"]
|
||||
filename: learnjq.sh
|
||||
---
|
||||
|
||||
`jq` is a tool for transforming JSON inputs and generating JSON outputs. As a
|
||||
programming language, jq supports boolean and arithmetic expressions, object
|
||||
and array indexing; it has conditionals, functions, and even exception
|
||||
handling... etc. Knowing jq enables you to easily write small programs that
|
||||
can perform complex queries on JSON documents to find answers, make reports, or
|
||||
to produce another JSON document for further processing by other programs.
|
||||
|
||||
> **NOTE**: This guide demonstrates the use of jq from the command line,
|
||||
> specifically, under an environment running the Bash shell.
|
||||
|
||||
```bash
|
||||
# When running jq from the command line, jq program code can be specified as the
|
||||
# first argument after any options to `jq`. We often quote such jq program with
|
||||
# single quotes (`'`) to prevent any special interpretation from the command line
|
||||
# shell.
|
||||
#
|
||||
jq -n '# Comments start with # until the end of line.
|
||||
# The -n option sets the input to the value, `null`, and prevents `jq`
|
||||
# from reading inputs from external sources.
|
||||
'
|
||||
|
||||
# Output:
|
||||
# null
|
||||
|
||||
|
||||
# By default jq reads from *STDIN* a stream of JSON inputs (values). It
|
||||
# processes each input with the jq program (filters) specified at the command
|
||||
# line, and prints the outputs of processing each input with the program to
|
||||
# *STDOUT*.
|
||||
#
|
||||
echo '
|
||||
"hello" 123 [
|
||||
"one",
|
||||
"two",
|
||||
"three"
|
||||
]
|
||||
{ "name": "jq" }
|
||||
' |
|
||||
jq '. # <-- the jq program here is the single dot (.), called the identity
|
||||
# operator, which stands for the current input.
|
||||
'
|
||||
|
||||
# Output:
|
||||
# "hello"
|
||||
# 123
|
||||
# [
|
||||
# "one",
|
||||
# "two",
|
||||
# "three"
|
||||
# ]
|
||||
# {
|
||||
# "name": "jq"
|
||||
# }
|
||||
|
||||
|
||||
# Notice that jq pretty-prints the outputs by default, therefore, piping
|
||||
# to `jq` is a simple way to format a response from some REST API endpoint
|
||||
# that returns JSON. E.g., `curl -s https://freegeoip.app/json/ | jq`
|
||||
|
||||
|
||||
# Instead of processing each JSON input with a jq program, you can also
|
||||
# ask jq to slurp them up as an array.
|
||||
#
|
||||
echo '1 "two" 3' | jq -s .
|
||||
|
||||
# Output:
|
||||
# [
|
||||
# 1,
|
||||
# "two",
|
||||
# 3
|
||||
# ]
|
||||
|
||||
|
||||
# Or, treat each line as a string.
|
||||
#
|
||||
(echo line 1; echo line 2) | jq -R .
|
||||
|
||||
# Output:
|
||||
# "line 1"
|
||||
# "line 2"
|
||||
|
||||
|
||||
# Or, combine -s and -R to slurp the input lines into a single string.
|
||||
#
|
||||
(echo line 1; echo line 2) | jq -sR .
|
||||
|
||||
# Output:
|
||||
# "line 1\nline2\n"
|
||||
|
||||
|
||||
# Inputs can also come from a JSON file specified at the command line:
|
||||
#
|
||||
echo '"hello"' > hello.json
|
||||
jq . hello.json
|
||||
|
||||
# Output:
|
||||
# "hello"
|
||||
|
||||
|
||||
# Passing a value into a jq program can be done with the `--arg` option.
|
||||
# Below, `val` is the variable name to bind the value, `123`, to.
|
||||
# The variable is then referenced as `$val`.
|
||||
#
|
||||
jq -n --arg val 123 '$val' # $val is the string "123" here
|
||||
|
||||
# Output:
|
||||
# "123"
|
||||
|
||||
|
||||
# If you need to pass a JSON value, use `--argjson`
|
||||
#
|
||||
jq -n --argjson val 123 '$val' # $val is a number
|
||||
|
||||
# Output:
|
||||
# 123
|
||||
|
||||
|
||||
# Using `--arg` or `--argjson` is an useful way of building JSON output from
|
||||
# existing input.
|
||||
#
|
||||
jq --arg text "$(date; echo "Have a nice day!")" -n '{ "today": $text }'
|
||||
|
||||
# Output:
|
||||
# {
|
||||
# "today": "Sun Apr 10 09:53:07 PM EDT 2022\nHave a nice day!"
|
||||
# }
|
||||
|
||||
|
||||
# Instead of outputting values as JSON, you can use the `-r` option to print
|
||||
# string values unquoted / unescaped. Non-string values are still printed as
|
||||
# JSON.
|
||||
#
|
||||
echo '"hello" 2 [1, "two", null] {}' | jq -r .
|
||||
|
||||
# Output:
|
||||
# hello
|
||||
# 2
|
||||
# [
|
||||
# 1,
|
||||
# "two",
|
||||
# null
|
||||
# ]
|
||||
# {}
|
||||
|
||||
|
||||
# Inside a string in jq, `\(expr)` can be used to substitute the output of
|
||||
# `expr` into the surrounding string context.
|
||||
#
|
||||
jq -rn '"1 + 2 = \(1+2)"'
|
||||
|
||||
# Output:
|
||||
# 1 + 2 = 3
|
||||
|
||||
|
||||
# The `-r` option is most useful for generating text outputs to be processed
|
||||
# down in a shell pipeline, especially when combined with an intepolated
|
||||
# string that is prefixed the `@sh` prefix operator.
|
||||
#
|
||||
# The `@sh` operator escapes the outputs of `\(...)` inside a string with
|
||||
# single quotes so that each resulting string of `\(...)` can be evaluated
|
||||
# by the shell as a single word / token / argument without special
|
||||
# interpretations.
|
||||
#
|
||||
env_vars=$(
|
||||
echo '{"var1": "value one", "var2": "value\ntwo"}' \
|
||||
|
|
||||
jq -r '
|
||||
"export " + @sh "var1=\(.var1) var2=\(.var2)"
|
||||
# ^^^^^^^^ ^^^^^^^^
|
||||
# "'value one'" "'value\ntwo'"
|
||||
#
|
||||
# NOTE: The + (plus) operator here concatenates strings.
|
||||
'
|
||||
)
|
||||
echo "$env_vars"
|
||||
eval "$env_vars"
|
||||
declare -p var1 var2
|
||||
|
||||
# Output:
|
||||
# export var1='value one' var2='value
|
||||
# two'
|
||||
# declare -- var1="value one"
|
||||
# declare -- var2="value
|
||||
# two"
|
||||
|
||||
# There are other string `@prefix` operators (e.g., @base64, @uri, @csv, ...)
|
||||
# that might be useful to you. See `man jq` for details.
|
||||
|
||||
|
||||
# The comma (`,`) operator in jq evaluates each operand and generates multiple
|
||||
# outputs:
|
||||
#
|
||||
jq -n '"one", 2, ["three"], {"four": 4}'
|
||||
|
||||
# Output:
|
||||
# "one"
|
||||
# 2
|
||||
# [
|
||||
# "three"
|
||||
# ]
|
||||
# {
|
||||
# "four": 4
|
||||
# }
|
||||
|
||||
|
||||
# Any JSON value is a valid jq expression that evaluates to the JSON value
|
||||
# itself.
|
||||
#
|
||||
jq -n '1, "one", [1, 2], {"one": 1}, null, true, false'
|
||||
|
||||
# Output:
|
||||
# 1
|
||||
# "one"
|
||||
# [
|
||||
# 1,
|
||||
# 2
|
||||
# ]
|
||||
# {
|
||||
# "one": 1
|
||||
# }
|
||||
# null
|
||||
# true
|
||||
# false
|
||||
|
||||
|
||||
# Any jq expression can be used where a JSON value is expected, even as object
|
||||
# keys. (though parenthesis might be required for object keys or values)
|
||||
#
|
||||
jq -n '[2*3, 8-1, 16/2], {("tw" + "o"): (1 + 1)}'
|
||||
|
||||
# Output:
|
||||
# [
|
||||
# 6,
|
||||
# 7,
|
||||
# 8
|
||||
# ]
|
||||
# {
|
||||
# "two": 2
|
||||
# }
|
||||
|
||||
|
||||
# As a shortcut, if a JSON object key looks like a valid identifier (matching
|
||||
# the regex `^[a-zA-Z_][a-zA-Z_0-9]*$`), quotes can be omitted.
|
||||
#
|
||||
jq -n '{ key_1: "value1" }'
|
||||
|
||||
# If a JSON object's key's value is ommited, it is looked up in the current
|
||||
# input using the key: (see next example for the meaning of `... | ...`)
|
||||
#
|
||||
jq -n '{c: 3} | {a: 1, "b", c}'
|
||||
|
||||
# Output:
|
||||
# {
|
||||
# "a": 1,
|
||||
# "b": null,
|
||||
# "c": 3
|
||||
# }
|
||||
|
||||
|
||||
# jq programs are more commonly written as a series of expressions (filters)
|
||||
# connected by the pipe (`|`) operator, which makes the output of its left
|
||||
# filter the input to its right filter.
|
||||
#
|
||||
jq -n '1 | . + 2 | . + 3' # first dot is 1; second dot is 3
|
||||
|
||||
# Output:
|
||||
# 6
|
||||
|
||||
# If an expression evaluates to multiple outputs, then jq will iterate through
|
||||
# them and propagate each output down the pipeline, and generate multiple
|
||||
# outputs in the end.
|
||||
#
|
||||
jq -n '1, 2, 3 | ., 4 | .'
|
||||
|
||||
# Output:
|
||||
# 1
|
||||
# 4
|
||||
# 2
|
||||
# 4
|
||||
# 3
|
||||
# 4
|
||||
|
||||
# The flows of the data in the last example can be visualized like this:
|
||||
# (number prefixed with `*` indicates the current output)
|
||||
#
|
||||
# *1, 2, 3 | *1, 4 | *1
|
||||
# 1, 2, 3 | 1, *4 | *4
|
||||
# 1, *2, 3 | *2, 4 | *2
|
||||
# 1, 2, 3 | 2, *4 | *4
|
||||
# 1, 2, *3 | *3, 4 | *3
|
||||
# 1, 2, 3 | 3, *4 | *4
|
||||
#
|
||||
#
|
||||
# To put it another way, the evaluation of the above example is very similar
|
||||
# to the following pieces of code in other programming languages:
|
||||
#
|
||||
# In Python:
|
||||
#
|
||||
# for first_dot in 1, 2, 3:
|
||||
# for second_dot in first_dot, 4:
|
||||
# print(second_dot)
|
||||
#
|
||||
# In Ruby:
|
||||
#
|
||||
# [1, 2, 3].each do |dot|
|
||||
# [dot, 4].each { |dot| puts dot }
|
||||
# end
|
||||
#
|
||||
# In Javascript:
|
||||
#
|
||||
# [1, 2, 3].forEach(dot => {
|
||||
# [dot, 4].forEach(dot => console.log(dot))
|
||||
# })
|
||||
#
|
||||
|
||||
|
||||
# Below are some examples of array index and object attribute lookups using
|
||||
# the `[expr]` operator after an expression. If `expr` is a number then it's
|
||||
# an array index lookup; otherwise, it should be a string, in which case it's
|
||||
# an object attribute lookup:
|
||||
|
||||
# Array index lookup
|
||||
#
|
||||
jq -n '[2, {"four": 4}, 6][1 - 1]' # => 2
|
||||
jq -n '[2, {"four": 4}, 6][0]' # => 2
|
||||
jq -n '[2, {"four": 4}, 6] | .[0]' # => 2
|
||||
|
||||
# You can chain the lookups since they are just expressions.
|
||||
#
|
||||
jq -n '[2, {"four": 4}, 6][1]["fo" + "ur"]' # => 4
|
||||
|
||||
# For object attributes, you can also use the `.key` shortcut.
|
||||
#
|
||||
jq -n '[2, {"four": 4}, 6][1].four' # => 4
|
||||
|
||||
# Use `."key"` if the key is not a valid identifier.
|
||||
#
|
||||
jq -n '[2, {"f o u r": 4}, 6][1]."f o u r"' # => 4
|
||||
|
||||
# Array index lookup returns null if the index is not found.
|
||||
#
|
||||
jq -n '[2, {"four": 4}, 6][99]' # => null
|
||||
|
||||
# Object attribute lookup returns null if the key is not found.
|
||||
#
|
||||
jq -n '[2, {"four": 4}, 6][1].whatever' # => null
|
||||
|
||||
# The alternative operator `//` can be used to provide a default
|
||||
# value when the result of the left operand is either `null` or `false`.
|
||||
#
|
||||
jq -n '.unknown_key // 7' # => 7
|
||||
|
||||
# If the thing before the lookup operator (`[expr]`) is neither an array
|
||||
# or an object, then you will get an error:
|
||||
#
|
||||
jq -n '123 | .[0]' # => jq: error (at <unknown>): Cannot index number with number
|
||||
jq -n '"abc" | .name' # => jq: error (at <unknown>): Cannot index string with string "name"
|
||||
jq -n '{"a": 97} | .[0]' # => jq: error (at <unknown>): Cannot index object with number
|
||||
jq -n '[89, 64] | .["key"]' # => jq: error (at <unknown>): Cannot index array with string "key"
|
||||
|
||||
# You can, however, append a `?` to a lookup to make jq return `empty`
|
||||
# instead when such error happens.
|
||||
#
|
||||
jq -n '123 | .[0]?' # no output since it's empty.
|
||||
jq -n '"abc" | .name?' # no output since it's empty.
|
||||
|
||||
# The alternative operator (`//`) also works with `empty`:
|
||||
#
|
||||
jq -n '123 | .[0]? // 99' # => 99
|
||||
jq -n '"abc" | .name? // "unknown"' # => "unknown"
|
||||
|
||||
# NOTE: `empty` is actually a built-in function in jq.
|
||||
# With the nested loop explanation we illustrated earlier before,
|
||||
# `empty` is like the `continue` or the `next` keyword that skips
|
||||
# the current iteration of the loop in some programming languages.
|
||||
|
||||
|
||||
# Strings and arrays can be sliced with the same syntax (`[i:j]`, but no
|
||||
# steppings) and semantic as found in the Python programming language:
|
||||
#
|
||||
# 0 1 2 3 4 5 ... infinite
|
||||
# array = ["a", "b", "c", "d"]
|
||||
# -infinite ... -4 -3 -2 -1
|
||||
#
|
||||
jq -n '["Peter", "Jerry"][1]' # => "Jerry"
|
||||
jq -n '["Peter", "Jerry"][-1]' # => "Jerry"
|
||||
jq -n '["Peter", "Jerry", "Tom"][1:]' # => ["Jerry", "Tom"]
|
||||
jq -n '["Peter", "Jerry", "Tom"][:1+1]' # => ["Peter", "Jerry"]
|
||||
jq -n '["Peter", "Jerry", "Tom"][1:99]' # => ["Jerry", "Tom"]
|
||||
|
||||
|
||||
# If the lookup index or key is ommited then jq iterates through
|
||||
# the collection, generating one output value from each iteration.
|
||||
#
|
||||
# These examples produce the same outputs.
|
||||
#
|
||||
echo 1 2 3 | jq .
|
||||
jq -n '1, 2, 3'
|
||||
jq -n '[1, 2, 3][]'
|
||||
jq -n '{a: 1, b: 2, c: 3}[]'
|
||||
|
||||
# Output:
|
||||
# 1
|
||||
# 2
|
||||
# 3
|
||||
|
||||
|
||||
# You can build an array out of multiple outputs.
|
||||
#
|
||||
jq -n '{values: [{a: 1, b: 2, c: 3}[] | . * 2]}'
|
||||
|
||||
# Output:
|
||||
# {
|
||||
# "values": [
|
||||
# 2,
|
||||
# 4,
|
||||
# 6
|
||||
# ]
|
||||
# }
|
||||
|
||||
|
||||
# If multiple outputs are not contained, then we'd get multiple outputs
|
||||
# in the end.
|
||||
#
|
||||
jq -n '{values: ({a: 1, b: 2, c: 3}[] | . * 2)}'
|
||||
|
||||
# Output:
|
||||
# {
|
||||
# "values": 2
|
||||
# }
|
||||
# {
|
||||
# "values": 4
|
||||
# }
|
||||
# {
|
||||
# "values": 6
|
||||
# }
|
||||
|
||||
|
||||
# Conditional `if ... then ... else ... end` in jq is an expression, so
|
||||
# both the `then` part and the `else` part are required. In jq, only
|
||||
# two values, `null` and `false`, are false; all other values are true.
|
||||
#
|
||||
jq -n 'if 1 > 2 | not and 1 <= 2 then "Makes sense" else "WAT?!" end'
|
||||
|
||||
# Output
|
||||
# "Makes sense"
|
||||
|
||||
# Notice that `not` is a built-in function that takes zero arguments,
|
||||
# that's why it's used as a filter to negate its input value.
|
||||
# We'll talk about functions soon.
|
||||
|
||||
# Another example using a conditional:
|
||||
#
|
||||
jq -n '1, 2, 3, 4, 5 | if . % 2 != 0 then . else empty end'
|
||||
|
||||
# Output
|
||||
# 1
|
||||
# 3
|
||||
# 5
|
||||
|
||||
# The `empty` above is a built-in function that takes 0 arguments and
|
||||
# generates no outputs. Let's see more examples of built-in functions.
|
||||
|
||||
# The above conditional example can be written using the `select/1` built-in
|
||||
# function (`/1` indicates the number of arguments expected by the function).
|
||||
#
|
||||
jq -n '1, 2, 3, 4, 5 | select(. % 2 != 0)' # NOTE: % gives the remainder.
|
||||
|
||||
# Output
|
||||
# 1
|
||||
# 3
|
||||
# 5
|
||||
|
||||
|
||||
# Function arguments in jq are passed with call-by-name semantic, which
|
||||
# means, an argument is not evaulated at call site, but instead, is
|
||||
# treated as a lambda expression with the calling context of the call
|
||||
# site as its scope for variable and function references used in the
|
||||
# expression.
|
||||
#
|
||||
# In the above example, the expression `. % 2 != 0` is what's passed to
|
||||
# `select/1` as the argument, not `true` or `false`, which is what would
|
||||
# have been the case had the (boolean) expression was evaluated before it's
|
||||
# passed to the function.
|
||||
|
||||
|
||||
# The `range/1`, `range/2`, and `range/3` built-in functions generate
|
||||
# integers within a given range.
|
||||
#
|
||||
jq -n '[range(3)]' # => [0, 1, 2]
|
||||
jq -n '[range(0; 4)]' # => [0, 1, 2, 3]
|
||||
jq -n '[range(2; 10; 2)]' # => [2, 4, 6, 8]
|
||||
|
||||
# Notice that `;` (semicolon) is used to separate function arguments.
|
||||
|
||||
|
||||
# The `map/1` function applies a given expression to each element of
|
||||
# the current input (array) and outputs a new array.
|
||||
#
|
||||
jq -n '[range(1; 6) | select(. % 2 != 0)] | map(. * 2)'
|
||||
|
||||
# Output:
|
||||
# [
|
||||
# 2,
|
||||
# 6,
|
||||
# 10
|
||||
# ]
|
||||
|
||||
# Without using `select/1` and `map/1`, we could have also written the
|
||||
# above example like this:
|
||||
#
|
||||
jq -n '[range(1; 6) | if . % 2 != 0 then . else empty end | . * 2]'
|
||||
|
||||
|
||||
# `keys/0` returns an array of keys of the current input. For an object,
|
||||
# these are the object's attribute names; for an array, these are the
|
||||
# array indices.
|
||||
#
|
||||
jq -n '[range(2; 10; 2)] | keys' # => [0, 1, 2, 3]
|
||||
jq -n '{a: 1, b: 2, c: 3} | keys' # => ["a", "b", "c"]
|
||||
|
||||
# `values/0` returns an array of values of the current input. For an object,
|
||||
# these are the object's attribute values; for an array, these are the
|
||||
# elements of the array.
|
||||
#
|
||||
jq -n '[range(2; 10; 2)] | values' # => [2, 4, 6, 8]
|
||||
jq -n '{a: 1, b: 2, c: 3} | values' # => [1, 2, 3]
|
||||
|
||||
|
||||
# `to_entries/0` returns an array of key-value objects of the current input
|
||||
# object.
|
||||
#
|
||||
jq -n '{a: 1, b: 2, c: 3} | to_entries'
|
||||
|
||||
# Output:
|
||||
# [
|
||||
# {
|
||||
# "key": "a",
|
||||
# "value": 1
|
||||
# },
|
||||
# {
|
||||
# "key": "b",
|
||||
# "value": 2
|
||||
# },
|
||||
# {
|
||||
# "key": "c",
|
||||
# "value": 3
|
||||
# }
|
||||
# ]
|
||||
|
||||
|
||||
# Here's how you can turn an object's attribute into environment variables
|
||||
# using what we have learned so far.
|
||||
#
|
||||
env_vars=$(
|
||||
jq -rn '{var1: "1 2 3 4", var2: "line1\nline2\n"}
|
||||
| to_entries[]
|
||||
| "export " + @sh "\(.key)=\(.value)"
|
||||
'
|
||||
)
|
||||
eval "$env_vars"
|
||||
declare -p var1 var2
|
||||
|
||||
# Output:
|
||||
# declare -x var1="1 2 3 4"
|
||||
# declare -x var2="line1
|
||||
# line2
|
||||
# "
|
||||
|
||||
|
||||
# `from_entries/0` is the opposite of `to_entries/0` in that it takes an
|
||||
# an array of key-value objects and turn that into an object with keys
|
||||
# and values from the `key` and `value` attributes of the objects.
|
||||
#
|
||||
# It's useful together with `to_entries/0` when you need to iterate and
|
||||
# do something to each attribute of an object.
|
||||
#
|
||||
jq -n '{a: 1, b: 2, c: 3} | to_entries | map(.value *= 2) | from_entries'
|
||||
|
||||
# Output:
|
||||
# {
|
||||
# "a": 2,
|
||||
# "b": 4,
|
||||
# "c": 6
|
||||
# }
|
||||
|
||||
|
||||
# The example above can be further shortened with the `with_entries/1` built-in:
|
||||
#
|
||||
jq -n '{a: 1, b: 2, c: 3} | with_entries(.value *= 2)'
|
||||
|
||||
|
||||
# The `group_by/1` generates an array of groups (arrays) from the current
|
||||
# input (array). The classification is done by applying the expression argument
|
||||
# to each member of the input array.
|
||||
#
|
||||
# Let's look at a contrived example (Note that `tostring`, `tonumber`,
|
||||
# `length` and `max` are all built-in jq functions. Feel free to look
|
||||
# them up in the jq manual):
|
||||
#
|
||||
# Generate some random numbers.
|
||||
numbers=$(echo $RANDOM{,,,,,,,,,,,,,,,,,,,,})
|
||||
#
|
||||
# Feed the numbers to jq, classifying them into groups and calculating their
|
||||
# averages, and finally generate a report.
|
||||
#
|
||||
echo $numbers | jq -rs ' # Slurp the numbers into an array.
|
||||
[
|
||||
[ map(tostring) # Turn it into an array of strings.
|
||||
| group_by(.[0:1]) # Group the numbers by their first digits.
|
||||
| .[] # Iterate through the array of arrays (groups).
|
||||
| map(tonumber) # Turn each group back to an array of numbers.
|
||||
] # Finally, contain all groups in an array.
|
||||
|
||||
| sort_by([length, max]) # Sort the groups by their sizes.
|
||||
# If two groups have the same size then the one with the largest
|
||||
# number wins (is bigger).
|
||||
|
||||
| to_entries[] # Enumerate the array, generating key-value objects.
|
||||
| # For each object, generate two lines:
|
||||
"Group \(.key): \(.value | sort | join(" "))" + "\n" +
|
||||
"Average: \( .value | (add / length) )"
|
||||
|
||||
] # Contain the group+average lines in an array.
|
||||
# Join the array elements by separator lines (dashes) to produce the report.
|
||||
| join("\n" + "-"*78 + "\n")
|
||||
'
|
||||
|
||||
# Output:
|
||||
#
|
||||
# Group 0: 3267
|
||||
# Average: 3267
|
||||
# ------------------------------------------------------------------------------
|
||||
# Group 1: 7854
|
||||
# Average: 7854
|
||||
# ------------------------------------------------------------------------------
|
||||
# Group 2: 4415 4447
|
||||
# Average: 4431
|
||||
# ------------------------------------------------------------------------------
|
||||
# Group 3: 681 6426
|
||||
# Average: 3553.5
|
||||
# ------------------------------------------------------------------------------
|
||||
# Group 4: 21263 21361 21801 21832 22947 23523 29174
|
||||
# Average: 23128.714285714286
|
||||
# ------------------------------------------------------------------------------
|
||||
# Group 5: 10373 12698 13132 13924 17444 17963 18934 18979
|
||||
# Average: 15430.875
|
||||
|
||||
|
||||
# The `add/1` built-in "reduces" an array of values to a single value.
|
||||
# You can think of it as sticking the `+` operator in between each value of
|
||||
# the collection. Here are some examples:
|
||||
#
|
||||
jq -n '[1, 2, 3, 4, 5] | add' # => 15
|
||||
jq -n '["a", "b", "c"] | add' # => "abc"
|
||||
|
||||
# `+` concatenates arrays
|
||||
jq -n '[["a"], ["b"], ["c"]] | add'
|
||||
|
||||
# Output:
|
||||
# [
|
||||
# "a",
|
||||
# "b",
|
||||
# "c"
|
||||
# ]
|
||||
|
||||
# `+` merges objects non-recursively.
|
||||
jq -n '[{a: 1, b: {c: 3}}, {b: 2, c: 4}] | add'
|
||||
|
||||
# Output:
|
||||
# {
|
||||
# "a": 1,
|
||||
# "b": 2,
|
||||
# "c": 4
|
||||
# }
|
||||
|
||||
|
||||
# jq provides a special syntax for writing an expression that reduces
|
||||
# the outputs generated by a given expresion to a single value.
|
||||
# It has this form:
|
||||
#
|
||||
# reduce outputs_expr as $var (initial_value; reduction_expr)
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
jq -n 'reduce range(1; 6) as $i (0; . + $i)' # => 15
|
||||
jq -n 'reduce (1, 2, 3, 4, 5) as $i (0; . + $i)' # => 15
|
||||
jq -n '[1, 2, 3, 4, 5] | reduce .[] as $i (0; . + $i)' # => 15
|
||||
jq -n '["a", "b", "c"] | reduce .[] as $i (""; . + $i)' # => "abc"
|
||||
|
||||
# Notice the `.` in the `reduction_expr` is the `initial_value` at first,
|
||||
# and then it becomes the result of applying the `reduction_expr` as
|
||||
# we iterate through the values of `outputs_expr`. The expression:
|
||||
#
|
||||
# reduce (1, 2, 3, 4, 5) as $i (0; . + $i)
|
||||
#
|
||||
# can be thought of as doing:
|
||||
#
|
||||
# 0 + 1 | . + 2 | . + 3 | . + 4 | . + 5
|
||||
#
|
||||
|
||||
|
||||
# The `*` operator when used on two objects, merges both recursively.
|
||||
# Therefore, to merge JSON objects recursively, you can use `reduce`
|
||||
# with the `*` operator. For example:
|
||||
#
|
||||
echo '
|
||||
{"a": 1, "b": {"c": 3}}
|
||||
{ "b": {"d": 4}}
|
||||
{"a": 99, "e": 5 }
|
||||
' | jq -s 'reduce .[] as $m ({}; . * $m)'
|
||||
|
||||
# Output:
|
||||
# {
|
||||
# "a": 99,
|
||||
# "b": {
|
||||
# "c": 3,
|
||||
# "d": 4
|
||||
# },
|
||||
# "e": 5
|
||||
# }
|
||||
|
||||
|
||||
# jq has variable assignment in the form of `expr as $var`, which binds
|
||||
# the value of `expr` to `$var`, and `$var` is immutable. Further more,
|
||||
# `... as ...` doesn't change the input of the next filter; its introduction
|
||||
# in a filter pipeline is only for establishing the binding of a value to a
|
||||
# variable, and its scope extends to the filters following its definition.
|
||||
# (i.e., to look up a variable's definition, scan to the left of the filter
|
||||
# chain from the expression using it until you find the definition)
|
||||
#
|
||||
jq -rn '[1, 2, 3, 4, 5]
|
||||
| (.[0] + .[-1]) as $sum # Always put ( ) around the binding `expr` to avoid surprises.
|
||||
| ($sum * length / 2) as $result # The current input at this step is still the initial array.
|
||||
| "The result is: \($result)" # Same.
|
||||
'
|
||||
|
||||
# Output:
|
||||
# The result is: 15
|
||||
|
||||
|
||||
# With the `expr as $var` form, if multiple values are generated by `expr`
|
||||
# then jq will iterate through them and bind each value to `$var` in turn
|
||||
# for the rest of the pipeline.
|
||||
#
|
||||
jq -rn 'range(2; 4) as $i
|
||||
| range(1; 6) as $j
|
||||
| "\($i) * \($j) = \($i * $j)"
|
||||
'
|
||||
|
||||
# Output:
|
||||
# 2 * 1 = 2
|
||||
# 2 * 2 = 4
|
||||
# 2 * 3 = 6
|
||||
# 2 * 4 = 8
|
||||
# 2 * 5 = 10
|
||||
# 3 * 1 = 3
|
||||
# 3 * 2 = 6
|
||||
# 3 * 3 = 9
|
||||
# 3 * 4 = 12
|
||||
# 3 * 5 = 15
|
||||
|
||||
|
||||
# It's sometimes useful to bind the initial input to a variable at the
|
||||
# start of a program, so that you can refer to it later down the pipeline.
|
||||
#
|
||||
jq -rn "$(cat <<'EOF'
|
||||
{lookup: {a: 1, b: 2, c: 3},
|
||||
bonuses: {a: 5, b: 2, c: 9}
|
||||
}
|
||||
| . as $doc
|
||||
| .bonuses
|
||||
| to_entries[]
|
||||
| "\(.key)'s total is \($doc.lookup[.key] + .value)"
|
||||
EOF
|
||||
)"
|
||||
|
||||
# Output:
|
||||
# a's total is 6
|
||||
# b's total is 4
|
||||
# c's total is 12
|
||||
|
||||
|
||||
# jq supports destructing during varible binding. This lets you extract values
|
||||
# from an array or an object and bind them to variables.
|
||||
#
|
||||
jq -n '[range(5)] | . as [$first, $second] | $second'
|
||||
|
||||
# Output:
|
||||
# 1
|
||||
|
||||
jq -n '{ name: "Tom", numbers: [1, 2, 3], age: 32}
|
||||
| . as {
|
||||
name: $who, # bind .name to $who
|
||||
$name, # shorthand for `name: $name`
|
||||
numbers: [$first, $second],
|
||||
}
|
||||
| $name, $second, $first, $who
|
||||
'
|
||||
|
||||
# Output:
|
||||
# "Tom"
|
||||
# 2
|
||||
# 1
|
||||
# "Tom"
|
||||
|
||||
|
||||
# In jq, values can be assigned to an array index or object key via the
|
||||
# assignment operator, `=`. The same current input is given to both sides
|
||||
# of the assignment operator, and the assignment itself evaluates to the
|
||||
# current input. In other words, the assignment expression is evaluated
|
||||
# for its side effect, and doesn't generate a new output.
|
||||
#
|
||||
jq -n '.a = 1 | .b = .a + 1' # => {"a": 1, "b": 2}
|
||||
|
||||
# Note that input is `null` due to `jq -n`, so `.` is `null` in the first
|
||||
# filter, and assiging to a key under `null` turns it into an object with
|
||||
# the key. The same input (now an object) then gets piped to the next filter,
|
||||
# which then sets the `b` key to the value of the `a` key plus `1`, which is `2`.
|
||||
#
|
||||
|
||||
# Another example:
|
||||
#
|
||||
jq -n '.a=1, .a.b=2' # => {"a": 1} {"a": {"b": 2}}
|
||||
|
||||
# In the above example, two objects are generated because both assignments
|
||||
# received `null` as their inputs, and each operand of the comma operator
|
||||
# is evaluated independently. Notice also how you can easily generate
|
||||
# nested objects.
|
||||
|
||||
|
||||
# In addition to the assignment operator, jq also has operators like:
|
||||
# `+=`, `-=`, `*=`, and '/=', ... etc. Basically, `a op= b` is a shorthand
|
||||
# for `a = a op b`, and they are handy for updating an object attribute or
|
||||
# an item in an array based on its current value. Examples:
|
||||
#
|
||||
jq -n '.a.b.c = 3 | .a.b.c = .a.b.c + 1' # => {"a": {"b": {"c": 4}}}
|
||||
jq -n '.a.b.c = 3 | .a.b.c += 1' # => {"a": {"b": {"c": 4}}}
|
||||
|
||||
|
||||
# To delete a value, use `del/1`, which takes a path expression that specifies
|
||||
# the locations of the things to be deleted. Example:
|
||||
#
|
||||
jq -n '{a: 1, b: {c: 2}, d: [3, 4, 5]} | del(.b.c, .d[1]) | .b.x = 6'
|
||||
|
||||
# Output:
|
||||
# {
|
||||
# "a": 1,
|
||||
# "b": {
|
||||
# "x": 6
|
||||
# },
|
||||
# "d": [
|
||||
# 3,
|
||||
# 5
|
||||
# ]
|
||||
# }
|
||||
|
||||
|
||||
# Other than using jq's built-in functions, you can define your own.
|
||||
# In fact, many built-in functions are defined using jq (see the link
|
||||
# to jq's built-in functions at the end of the doc).
|
||||
#
|
||||
jq -n '
|
||||
def my_select(expr): if expr then . else empty end;
|
||||
def my_map(expr): [.[] | expr];
|
||||
def sum: reduce .[] as $x (0; . + $x);
|
||||
def my_range($from; $to):
|
||||
if $from >= $to then
|
||||
empty
|
||||
else
|
||||
$from, my_range($from + 1; $to)
|
||||
end
|
||||
;
|
||||
[my_range(1; 6)] | my_map(my_select(. % 2 != 0)) | sum
|
||||
'
|
||||
|
||||
# Output:
|
||||
# 9
|
||||
|
||||
# Some notes about function definitons:
|
||||
#
|
||||
# - Functions are usually defined at the beginning, so that they are available
|
||||
# to the rest of the jq program.
|
||||
#
|
||||
# - Each function definion should end with a `;` (semicolon).
|
||||
#
|
||||
# - It's also possible to define a function within another, though it's not shown here.
|
||||
#
|
||||
# - Function parameters are separated by `;` (semicolor). This is consistent with
|
||||
# passing multiple arguments when calling a function.
|
||||
#
|
||||
# - A function can call itself; in fact, jq has TCO (Tail Call Optimization).
|
||||
#
|
||||
# - `def f($a; $b): ...;` is a shorthand for: `def f(a; b): a as $a | b as $b | ...`
|
||||
```
|
||||
|
||||
|
||||
## Further Reading
|
||||
- https://stedolan.github.io/jq/manual/
|
||||
- https://github.com/stedolan/jq/wiki/jq-Language-Description
|
||||
- https://github.com/stedolan/jq/wiki/Cookbook
|
||||
- https://github.com/stedolan/jq/blob/master/src/builtin.jq
|
@ -12,8 +12,8 @@ jQuery is a JavaScript library that helps you "do more, write less". It makes ma
|
||||
Because jQuery is a JavaScript library you should [learn JavaScript first](https://learnxinyminutes.com/docs/javascript/)
|
||||
|
||||
**NOTE**: jQuery has fallen out of the limelight in recent years, since you can achieve the same thing with the vanilla DOM (Document Object Model) API. So the only thing it is used for is a couple of handy features, such as the [jQuery date picker](https://api.jqueryui.com/datepicker) (which actually has a standard, unlike the `<input type="date">` HTML element), and the obvious decrease in the code length.
|
||||
```js
|
||||
|
||||
```js
|
||||
|
||||
///////////////////////////////////
|
||||
// 1. Selectors
|
||||
|
@ -11,7 +11,7 @@ contributors:
|
||||
|
||||
JSON is an extremely simple data-interchange format. As [json.org](https://json.org) says, it is easy for humans to read and write and for machines to parse and generate.
|
||||
|
||||
A piece of JSON must represent either:
|
||||
A piece of JSON can be any value of the types listed later, but in practice almost always represents either:
|
||||
|
||||
* A collection of name/value pairs (`{ }`). In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
|
||||
* An ordered list of values (`[ ]`). In various languages, this is realized as an array, vector, list, or sequence.
|
||||
|
@ -81,7 +81,7 @@ func learnTypes() {
|
||||
// non-ASCII 리터럴. Go 소스는 UTF-8로 작성해야 한다.
|
||||
g := 'Σ' // 유니코드 코드 포인트를 담고 있고, int32 타입의 가칭(alias)인 rune 타입
|
||||
|
||||
f := 3.14195 // float64, an IEEE-754 64-bit 부동소수 타입
|
||||
f := 3.14159 // float64, an IEEE-754 64-bit 부동소수 타입
|
||||
c := 3 + 4i // complex128, 내부적으로는 두 개의 float64 타입으로 표현됨
|
||||
|
||||
// 초기값과 함께 사용하는 var 키워드.
|
||||
@ -332,15 +332,15 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
## 더 읽어볼 것들
|
||||
|
||||
Go에 대한 모든 것들은 [Go 공식 웹 사이트](http://golang.org/)를 참고하자.
|
||||
Go에 대한 모든 것들은 [Go 공식 웹 사이트](https://go.dev/)를 참고하자.
|
||||
여기에는 따라해볼 튜토리얼, 웹 기반의 인터랙티브 실행환경과 많은 읽을거리들이 있다.
|
||||
|
||||
Go 언어 자체에 대한 스펙도 읽어보기를 적극 추천한다. 읽기 쉽게 되어있고
|
||||
그리 길지는 않다.
|
||||
|
||||
Go 소스코드에 대해 좀더 알아보고 싶다면 [Go 표준 라이브러리](http://golang.org/src/pkg/)를
|
||||
Go 소스코드에 대해 좀더 알아보고 싶다면 [Go 표준 라이브러리](https://go.dev/src/)를
|
||||
분석해보기 바란다. 이해하기 쉽게 문서화되어 있고, Go 스타일 그리고 Go에서의
|
||||
관례 배우기에 가장 좋은 방법일 것이다. 또는 [문서](http://golang.org/pkg/) 안에서
|
||||
관례 배우기에 가장 좋은 방법일 것이다. 또는 [문서](https://go.dev/pkg/) 안에서
|
||||
함수 이름 하나를 클릭해보면 소스코드를 브라우저에서 살펴볼 수도 있다.
|
||||
|
||||
Go를 배울수 있는 또하나의 좋은 방법은 [Go by example](https://gobyexample.com/).
|
||||
|
@ -26,7 +26,7 @@ any parameters.
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
/*
|
||||
Declaring values is done using either "var" or "val".
|
||||
Declaring variables is done using either "var" or "val".
|
||||
"val" declarations cannot be reassigned, whereas "vars" can.
|
||||
*/
|
||||
val fooVal = 10 // we cannot later reassign fooVal to something else
|
||||
@ -297,7 +297,7 @@ fun helloWorld(val name : String) {
|
||||
else -> println("none of the above")
|
||||
}
|
||||
|
||||
// "when" can be used as a function that returns a value.
|
||||
// "when" can be used as an expression that returns a value.
|
||||
var result = when (i) {
|
||||
0, 21 -> "0 or 21"
|
||||
in 1..20 -> "in the range 1 to 20"
|
||||
|
@ -17,10 +17,7 @@ filename: learnlua.lua
|
||||
-- 1. Variables and flow control.
|
||||
----------------------------------------------------
|
||||
|
||||
num = 42 -- All numbers are doubles.
|
||||
-- Don't freak out, 64-bit doubles have 52 bits for
|
||||
-- storing exact int values; machine precision is
|
||||
-- not a problem for ints that need < 52 bits.
|
||||
num = 42 -- Numbers can be integer or floating point.
|
||||
|
||||
s = 'walternate' -- Immutable strings like Python.
|
||||
t = "double-quotes are also fine"
|
||||
@ -402,7 +399,7 @@ If you need support join the official Lua [mailing list](https://www.lua.org/lua
|
||||
I was excited to learn Lua so I could make games
|
||||
with the <a href="http://love2d.org/">Love 2D game engine</a>. That's the why.
|
||||
|
||||
I started with <a href="https://ebens.me/post/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>.
|
||||
I started with <a href="https://ebens.me/posts/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>.
|
||||
Next I read the official <a href="http://www.lua.org/pil/contents.html">Programming in Lua</a> book.
|
||||
That's the how.
|
||||
|
||||
|
101
m.html.markdown
101
m.html.markdown
@ -17,8 +17,8 @@ more fits on one screen without scrolling.
|
||||
|
||||
The M database is a hierarchical key-value store designed for high-throughput
|
||||
transaction processing. The database is organized into tree structures called
|
||||
"globals", which are sparse data structures with parallels to modern formats
|
||||
like JSON.
|
||||
"globals", (for global variables) which are sparse data structures with parallels
|
||||
to modern formats like JSON.
|
||||
|
||||
Originally designed in 1966 for the healthcare applications, M continues to be
|
||||
used widely by healthcare systems and financial institutions for high-throughput
|
||||
@ -26,7 +26,7 @@ real-time applications.
|
||||
|
||||
### Example
|
||||
|
||||
Here's an example M program to calculate the Fibonacci series:
|
||||
Here's an example M program using expanded syntax to calculate the Fibonacci series:
|
||||
|
||||
```
|
||||
fib ; compute the first few Fibonacci terms
|
||||
@ -39,28 +39,38 @@ fib ; compute the first few Fibonacci terms
|
||||
```
|
||||
|
||||
### Comments
|
||||
Comments in M need at least one space before the comment marker of semicolon.
|
||||
Comments that start with at least two semicolons (;;) are guaranteed to be accessible
|
||||
within a running program.
|
||||
|
||||
```
|
||||
; Comments start with a semicolon (;)
|
||||
; Comments start with a semicolon (;)
|
||||
```
|
||||
### Data Types
|
||||
|
||||
M has two data types:
|
||||
M has one data type (String) and three interpretations of that string.:
|
||||
|
||||
```
|
||||
; Numbers - no commas, leading and trailing 0 removed.
|
||||
; Scientific notation with 'E'.
|
||||
; Floats with IEEE 754 double-precision values (15 digits of precision)
|
||||
; Examples: 20, 1e3 (stored as 1000), 0500.20 (stored as 500.2)
|
||||
; Strings - Characters enclosed in double quotes.
|
||||
; "" is the null string. Use "" within a string for "
|
||||
; Examples: "hello", "Scrooge said, ""Bah, Humbug!"""
|
||||
;
|
||||
; Numbers - no commas, leading and trailing 0 removed.
|
||||
; Scientific notation with 'E'. (not 'e')
|
||||
; Numbers with at least with IEEE 754 double-precision values (guaranteed 15 digits of precision)
|
||||
; Examples: 20 (stored as 20) , 1e3 (stored as 1000), 0500.20 (stored as 500.2),
|
||||
; the US National Debt AT sometime on 12-OCT-2020 retrieved from http://www.usdebt.org is 27041423576201.15)
|
||||
; (required to be stored as at least 27041422576201.10 but most implementations store as 27041432576201.15)
|
||||
;
|
||||
; Truthvalues - String interpreted as 0 is used for false and any string interpreted as non-zero (such as 1) for true.
|
||||
```
|
||||
### Commands
|
||||
|
||||
Commands are case insensitive, and have a shortened abbreviation, often the first letter. Commands have zero or more arguments,depending on the command. M is whitespace-aware. Spaces are treated as a delimiter between commands and arguments. Each command is separated from its arguments by 1 space. Commands with zero arguments are followed by 2 spaces.
|
||||
Commands are case insensitive, and have full form, and a shortened abbreviation, often the first letter. Commands have zero or more arguments,depending on the command. This page includes programs written in this terse syntax. M is whitespace-aware. Spaces are treated as a delimiter between commands and arguments. Each command is separated from its arguments by 1 space. Commands with zero arguments are followed by 2 spaces. (technically these are called argumentless commands)
|
||||
|
||||
#### W(rite)
|
||||
#### Common Commands from all National and International Standards of M
|
||||
|
||||
#### Write (abbreviated as W)
|
||||
|
||||
Print data to the current device.
|
||||
|
||||
@ -68,13 +78,19 @@ Print data to the current device.
|
||||
WRITE !,"hello world"
|
||||
```
|
||||
|
||||
! is syntax for a new line. Multiple statements can be provided as additional arguments:
|
||||
Output Formatting characters:
|
||||
|
||||
The ! character is syntax for a new line.
|
||||
The # character is syntax for a new page.
|
||||
The sequence of the ? character and then a numeric expression is syntax for output of spaces until the number'th colum is printed.
|
||||
|
||||
Multiple statements can be provided as additional arguments before the space separators to the next command:
|
||||
|
||||
```
|
||||
w !,"foo bar"," ","baz"
|
||||
```
|
||||
|
||||
#### R(ead)
|
||||
#### Read (abbreviated as R)
|
||||
|
||||
Retrieve input from the user
|
||||
|
||||
@ -82,13 +98,13 @@ Retrieve input from the user
|
||||
READ var
|
||||
r !,"Wherefore art thou Romeo? ",why
|
||||
```
|
||||
Multiple arguments can be passed to a read command. Constants are outputted. Variables are retrieved from the user. The terminal waits for the user to enter the first variable before displaying the second prompt.
|
||||
As with all M commands, multiple arguments can be passed to a read command. Constants like quoted strings, numbers, and formatting characters are output directly. Values for both global variables and local variables are retrieved from the user. The terminal waits for the user to enter the first variable before displaying the second prompt.
|
||||
|
||||
```
|
||||
r !,"Better one, or two? ",lorem," Better two, or three? ",ipsum
|
||||
```
|
||||
|
||||
#### S(et)
|
||||
#### Set (abbreviated as S)
|
||||
|
||||
Assign a value to a variable
|
||||
|
||||
@ -100,19 +116,21 @@ w !,centi,!,micro
|
||||
;.01
|
||||
;.00001
|
||||
```
|
||||
#### K(ill)
|
||||
#### Kill (abbreviated as K)
|
||||
|
||||
Remove a variable from memory or remove a database entry from disk.
|
||||
|
||||
A database node (global variable) is killed depending on the variable name being prefixed by the caret character (^).
|
||||
If it is not, then the local variable is removed from memory.
|
||||
If KILLed, automatic garbage collection occurs.
|
||||
```
|
||||
KILL centi
|
||||
k micro
|
||||
```
|
||||
### Globals and Arrays
|
||||
|
||||
In addition to local variables, M has persistent variables stored to disk called _globals_. Global names must start with a __caret__ (__^__). Globals are the built-in database of M.
|
||||
In addition to local variables, M has persistent, shared variables that are the built-in database of M. They are stored to disk and called _globals_. Global names must start with a __caret__ (__^__).
|
||||
|
||||
Any variable can be an array with the assignment of a _subscript_. Arrays are sparse and do not have a predefined size. Arrays should be visualized like trees, where subscripts are branches and assigned values are leaves. Not all nodes in an array need to have a value.
|
||||
Any variable (local or global) can be an array with the assignment of a _subscript_. Arrays are sparse and do not have a predefined size. Only if data is stored will a value use memory. Arrays should be visualized like trees, where subscripts are branches and assigned values are leaves. Not all nodes in an array need to have a value.
|
||||
|
||||
```
|
||||
s ^cars=20
|
||||
@ -128,7 +146,7 @@ w !,^cars("Tesla",1,"Name")
|
||||
; Model 3
|
||||
```
|
||||
|
||||
Arrays are automatically sorted in order. Take advantage of the built-in sorting by setting your value of interest as the last child subscript of an array rather than its value.
|
||||
The index values of Arrays are automatically sorted in order. There is a catchphrase of "MUMPS means never having to say you are sorting". Take advantage of the built-in sorting by setting your value of interest as the last child subscript of an array rather than its value, and then storing an empty string for that node.
|
||||
|
||||
```
|
||||
; A log of temperatures by date and time
|
||||
@ -171,13 +189,14 @@ s ^TEMPS("11/12","1700",43)=""
|
||||
#### Order of operations
|
||||
|
||||
Operations in M are _strictly_ evaluated left to right. No operator has precedence over any other.
|
||||
You should use parentheses to group expressions.
|
||||
For example, there is NO order of operations where multiply is evaluated before addition.
|
||||
To change this order, just use parentheses to group expressions to be evaluated first.
|
||||
|
||||
```
|
||||
w 5+3*20
|
||||
;160
|
||||
;You probably wanted 65
|
||||
w 5+(3*20)
|
||||
write 5+(3*20)
|
||||
```
|
||||
|
||||
### Flow Control, Blocks, & Code Structure
|
||||
@ -193,7 +212,7 @@ w !,$$tag^routine(a,b)
|
||||
|
||||
M has an execution stack. When all levels of the stack have returned, the program ends. Levels are added to the stack with _do_ commands and removed with _quit_ commands.
|
||||
|
||||
#### D(o)
|
||||
#### Do (abbreviated as D)
|
||||
|
||||
With an argument: execute a block of code & add a level to the stack.
|
||||
|
||||
@ -216,12 +235,14 @@ if a=1 do
|
||||
w "hello"
|
||||
```
|
||||
|
||||
#### Q(uit)
|
||||
#### Quit (abbreviated as Q)
|
||||
Stop executing this block and return to the previous stack level.
|
||||
Quit can return a value.
|
||||
Quit can return a value, following the comamnd with a single space.
|
||||
Quit can stop a loop. remember to follow with two spaces.
|
||||
Quit outside a loop will return from the current subroutine followed by two spaces or a linefeed
|
||||
|
||||
#### N(ew)
|
||||
Clear a given variable's value _for just this stack level_. Useful for preventing side effects.
|
||||
#### New (abbreviated as N)
|
||||
Hide with a cleared value a given variable's value _for just this stack level_. Useful for preventing side effects.
|
||||
|
||||
Putting all this together, we can create a full example of an M routine:
|
||||
|
||||
@ -233,20 +254,22 @@ main
|
||||
n length,width ; New length and width so any previous value doesn't persist
|
||||
w !,"Welcome to RECTANGLE. Enter the dimensions of your rectangle."
|
||||
r !,"Length? ",length,!,"Width? ",width
|
||||
d area(length,width) ;Do a tag
|
||||
s per=$$perimeter(length,width) ;Get the value of a function
|
||||
d area(length,width) ;Do/Call subroutine using a tag
|
||||
s per=$$perimeter(length,width) ;Get the value of a function
|
||||
w !,"Perimeter: ",per
|
||||
q
|
||||
quit
|
||||
|
||||
area(length,width) ; This is a tag that accepts parameters.
|
||||
; It's not a function since it quits with no value.
|
||||
w !, "Area: ",length*width
|
||||
q ; Quit: return to the previous level of the stack.
|
||||
q ; Quit: return to the previous level of the stack.
|
||||
|
||||
perimeter(length,width)
|
||||
q 2*(length+width) ; Quits with a value; thus a function
|
||||
q 2*(length+width) ; Returns a value using Quit ; this is a function
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Conditionals, Looping and $Order()
|
||||
|
||||
F(or) loops can follow a few different patterns:
|
||||
@ -255,13 +278,15 @@ F(or) loops can follow a few different patterns:
|
||||
;Finite loop with counter
|
||||
;f var=start:increment:stop
|
||||
|
||||
f i=0:5:25 w i," " ;0 5 10 15 20 25
|
||||
f i=0:5:25 w i," "
|
||||
;0 5 10 15 20 25
|
||||
|
||||
; Infinite loop with counter
|
||||
; The counter will keep incrementing forever. Use a conditional with Quit to get out of the loop.
|
||||
;f var=start:increment
|
||||
|
||||
f j=1:1 w j," " i j>1E3 q ; Print 1-1000 separated by a space
|
||||
f j=1:1 w j," " i j>1E3 q
|
||||
; Print 1-1000 separated by a space
|
||||
|
||||
;Argumentless for - infinite loop. Use a conditional with Quit.
|
||||
; Also read as "forever" - f or for followed by two spaces.
|
||||
@ -355,7 +380,11 @@ f s date=$ORDER(^TEMPS(date)) q:date="" d
|
||||
|
||||
## Further Reading
|
||||
|
||||
There's lots more to learn about M. A great short tutorial comes from the University of Northern Iowa and Professor Kevin O'Kane's [Introduction to the MUMPS Language][1] presentation.
|
||||
There's lots more to learn about M. A great short tutorial comes from the University of Northern Iowa and Professor Kevin O'Kane's [Introduction to the MUMPS Language][1] presentation. More about M using VistA is at
|
||||
|
||||
Intersystems has some products which are a super-set of the M programming language.
|
||||
* [Iris Description Page][5]
|
||||
* [Cache Description Page][6]
|
||||
|
||||
To install an M interpreter / database on your computer, try a [YottaDB Docker image][2].
|
||||
|
||||
@ -368,3 +397,5 @@ YottaDB and its precursor, GT.M, have thorough documentation on all the language
|
||||
[2]: https://yottadb.com/product/get-started/
|
||||
[3]: https://docs.yottadb.com/ProgrammersGuide/langfeat.html
|
||||
[4]: http://tinco.pair.com/bhaskar/gtm/doc/books/pg/UNIX_manual/index.html
|
||||
[5]: https://www.intersystems.com/products/intersystems-iris/
|
||||
[6]: https://en.wikipedia.org/wiki/InterSystems_Caché
|
||||
|
@ -228,7 +228,7 @@ db.engineers.update({ name: 'Foo Baz' },
|
||||
)
|
||||
|
||||
/////////////////////// Delete /////////////////////////
|
||||
// Queries are in the form of db.collectionName.find(<filter>)
|
||||
// Queries are in the form of db.collectionName.delete(<filter>)
|
||||
|
||||
// Delete first document matching query, always returns deletedCount
|
||||
db.engineers.deleteOne({ name: 'Foo Baz' })
|
||||
@ -252,20 +252,21 @@ db.engineers.deleteMany({ gender: 'Male' })
|
||||
//////////////// Comparison Operators ///////////////////
|
||||
|
||||
// Find all greater than or greater than equal to some condition
|
||||
db.engineers.find({ $gt: { age: 25 }})
|
||||
db.engineers.find({ $gte: { age: 25 }})
|
||||
db.engineers.find({ age: { $gt: 25 }})
|
||||
db.engineers.find({ age: { $gte: 25 }})
|
||||
|
||||
// Find all less than or less than equal to some condition
|
||||
db.engineers.find({ $lt: { age: 25 }})
|
||||
db.engineers.find({ $lte: { age: 25 }})
|
||||
db.engineers.find({ age: { $lt: 25 }})
|
||||
db.engineers.find({ age: { $lte: 25 }})
|
||||
|
||||
// Find all equal or not equal to
|
||||
// Note: the $eq operator is added implicitly in most queries
|
||||
db.engineers.find({ $eq: { age: 25 }})
|
||||
db.engineers.find({ $ne: { age: 25 }})
|
||||
db.engineers.find({ age: { $eq: 25 }})
|
||||
db.engineers.find({ age: { $ne: 25 }})
|
||||
|
||||
// Find all that match any element in the array
|
||||
db.engineers.find({ age: ${ in: [ 20, 23, 24, 25 ]}})
|
||||
// Find all that match any element in the array, or not in the array
|
||||
db.engineers.find({ age: { $in: [ 20, 23, 24, 25 ]}})
|
||||
db.engineers.find({ age: { $nin: [ 20, 23, 24, 25 ]}})
|
||||
|
||||
//////////////// Logical Operators ///////////////////
|
||||
|
||||
|
@ -3,7 +3,7 @@ language: Nim
|
||||
filename: learnNim.nim
|
||||
contributors:
|
||||
- ["Jason J. Ayala P.", "http://JasonAyala.com"]
|
||||
- ["Dennis Felsing", "http://felsin9.de/nnis/"]
|
||||
- ["Dennis Felsing", "https://dennis.felsing.org"]
|
||||
---
|
||||
|
||||
Nim (formerly Nimrod) is a statically typed, imperative programming language
|
||||
|
@ -305,6 +305,9 @@ with builtins; [
|
||||
({x, y, ...}: x + "-" + y) { x = "a"; y = "b"; z = "c"; }
|
||||
#=> "a-b"
|
||||
|
||||
# The entire set can be bound to a variable using `@`
|
||||
(args@{x, y}: args.x + "-" + args.y) { x = "a"; y = "b"; }
|
||||
#=> "a-b"
|
||||
|
||||
# Errors
|
||||
#=========================================
|
||||
@ -355,7 +358,7 @@ with builtins; [
|
||||
# its contents. You can read files from anywhere. In this example,
|
||||
# we write a file into the store, and then read it back out.
|
||||
(let filename = toFile "foo.txt" "hello!"; in
|
||||
[filename (builtins.readFile filename)])
|
||||
[filename (readFile filename)])
|
||||
#=> [ "/nix/store/ayh05aay2anx135prqp0cy34h891247x-foo.txt" "hello!" ]
|
||||
|
||||
# We can also download files into the Nix store.
|
||||
|
@ -387,7 +387,7 @@ if ([myClass respondsToSelector:selectorVar]) { // Checks if class contains meth
|
||||
// Implement the methods in an implementation (MyClass.m) file:
|
||||
@implementation MyClass {
|
||||
long distance; // Private access instance variable
|
||||
NSNumber height;
|
||||
NSNumber *height;
|
||||
}
|
||||
|
||||
// To access a public variable from the interface file, use '_' followed by variable name:
|
||||
|
@ -3,26 +3,31 @@ language: OCaml
|
||||
filename: learnocaml.ml
|
||||
contributors:
|
||||
- ["Daniil Baturin", "http://baturin.org/"]
|
||||
- ["Stanislav Modrak", "https://stanislav.gq/"]
|
||||
- ["Luke Tong", "https://lukert.me/"]
|
||||
---
|
||||
|
||||
OCaml is a strictly evaluated functional language with some imperative
|
||||
features.
|
||||
|
||||
Along with StandardML and its dialects it belongs to ML language family.
|
||||
Along with Standard ML and its dialects it belongs to ML language family.
|
||||
F# is also heavily influenced by OCaml.
|
||||
|
||||
Just like StandardML, OCaml features both an interpreter, that can be
|
||||
Just like Standard ML, OCaml features both an interpreter, that can be
|
||||
used interactively, and a compiler.
|
||||
The interpreter binary is normally called "ocaml" and the compiler is "ocamlopt".
|
||||
There is also a bytecode compiler, "ocamlc", but there are few reasons to use it.
|
||||
The interpreter binary is normally called `ocaml` and the compiler is `ocamlopt`.
|
||||
There is also a bytecode compiler, `ocamlc`, but there are few reasons to use it.
|
||||
|
||||
It also includes a package manager, `opam`, and a build system, `dune`.
|
||||
|
||||
It is strongly and statically typed, but instead of using manually written
|
||||
type annotations, it infers types of expressions using Hindley-Milner algorithm.
|
||||
type annotations, it infers types of expressions using the
|
||||
[Hindley-Milner](https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system)
|
||||
algorithm.
|
||||
It makes type annotations unnecessary in most cases, but can be a major
|
||||
source of confusion for beginners.
|
||||
|
||||
When you are in the top level loop, OCaml will print the inferred type
|
||||
after you enter an expression.
|
||||
after you enter an expression
|
||||
|
||||
```
|
||||
# let inc x = x + 1 ;;
|
||||
@ -31,8 +36,8 @@ val inc : int -> int = <fun>
|
||||
val a : int = 99
|
||||
```
|
||||
|
||||
For a source file you can use "ocamlc -i /path/to/file.ml" command
|
||||
to print all names and type signatures.
|
||||
For a source file you can use the `ocamlc -i /path/to/file.ml` command
|
||||
to print all names and type signatures
|
||||
|
||||
```
|
||||
$ cat sigtest.ml
|
||||
@ -48,12 +53,12 @@ val a : int
|
||||
```
|
||||
|
||||
Note that type signatures of functions of multiple arguments are
|
||||
written in curried form. A function that takes multiple arguments can be
|
||||
written in [curried](https://en.wikipedia.org/wiki/Currying) form.
|
||||
A function that takes multiple arguments can be
|
||||
represented as a composition of functions that take only one argument.
|
||||
The "f(x,y) = x + y" function from the example above applied to
|
||||
arguments 2 and 3 is equivalent to the "f0(y) = 2 + y" function applied to 3.
|
||||
Hence the "int -> int -> int" signature.
|
||||
|
||||
The `f(x,y) = x + y` function from the example above applied to
|
||||
arguments 2 and 3 is equivalent to the `f0(y) = 2 + y` function applied to 3.
|
||||
Hence the `int -> int -> int` signature.
|
||||
|
||||
```ocaml
|
||||
(*** Comments ***)
|
||||
@ -65,13 +70,14 @@ Hence the "int -> int -> int" signature.
|
||||
|
||||
(*** Variables and functions ***)
|
||||
|
||||
(* Expressions can be separated by a double semicolon symbol, ";;".
|
||||
(* Expressions can be separated by a double semicolon ";;".
|
||||
In many cases it's redundant, but in this tutorial we use it after
|
||||
every expression for easy pasting into the interpreter shell.
|
||||
Unnecessary use of expression separators in source code files
|
||||
is often considered to be a bad style. *)
|
||||
|
||||
(* Variable and function declarations use "let" keyword. *)
|
||||
(* Variable and function declarations use the "let" keyword. *)
|
||||
(* Variables are immutable by default in OCaml *)
|
||||
let x = 10 ;;
|
||||
|
||||
(* OCaml allows single quote characters in identifiers.
|
||||
@ -109,42 +115,42 @@ let sqr2 = sqr (-2) ;;
|
||||
"unit" type for it that has the only one value written as "()" *)
|
||||
let print_hello () = print_endline "hello world" ;;
|
||||
|
||||
(* Note that you must specify "()" as argument when calling it. *)
|
||||
(* Note that you must specify "()" as the argument when calling it. *)
|
||||
print_hello () ;;
|
||||
|
||||
(* Calling a function with insufficient number of arguments
|
||||
(* Calling a function with an insufficient number of arguments
|
||||
does not cause an error, it produces a new function. *)
|
||||
let make_inc x y = x + y ;; (* make_inc is int -> int -> int *)
|
||||
let inc_2 = make_inc 2 ;; (* inc_2 is int -> int *)
|
||||
inc_2 3 ;; (* Evaluates to 5 *)
|
||||
|
||||
(* You can use multiple expressions in function body.
|
||||
(* You can use multiple expressions in the function body.
|
||||
The last expression becomes the return value. All other
|
||||
expressions must be of the "unit" type.
|
||||
This is useful when writing in imperative style, the simplest
|
||||
form of it is inserting a debug print. *)
|
||||
form of which is inserting a debug print. *)
|
||||
let print_and_return x =
|
||||
print_endline (string_of_int x);
|
||||
x
|
||||
;;
|
||||
|
||||
(* Since OCaml is a functional language, it lacks "procedures".
|
||||
Every function must return something. So functions that
|
||||
do not really return anything and are called solely for their
|
||||
side effects, like print_endline, return value of "unit" type. *)
|
||||
Every function must return something. So functions that do not
|
||||
really return anything and are called solely for their side
|
||||
effects, like print_endline, return a value of "unit" type. *)
|
||||
|
||||
|
||||
(* Definitions can be chained with "let ... in" construct.
|
||||
This is roughly the same to assigning values to multiple
|
||||
(* Definitions can be chained with the "let ... in" construct.
|
||||
This is roughly the same as assigning values to multiple
|
||||
variables before using them in expressions in imperative
|
||||
languages. *)
|
||||
let x = 10 in
|
||||
let y = 20 in
|
||||
x + y ;;
|
||||
|
||||
(* Alternatively you can use "let ... and ... in" construct.
|
||||
(* Alternatively you can use the "let ... and ... in" construct.
|
||||
This is especially useful for mutually recursive functions,
|
||||
with ordinary "let .. in" the compiler will complain about
|
||||
with ordinary "let ... in" the compiler will complain about
|
||||
unbound values. *)
|
||||
let rec
|
||||
is_even = function
|
||||
@ -186,9 +192,9 @@ let my_lambda = fun x -> x * x ;;
|
||||
~-. 3.4 (* Float only *)
|
||||
|
||||
(* You can define your own operators or redefine existing ones.
|
||||
Unlike SML or Haskell, only selected symbols can be used
|
||||
for operator names and first symbol defines associativity
|
||||
and precedence rules. *)
|
||||
Unlike Standard ML or Haskell, only certain symbols can be
|
||||
used for operator names and the operator's first symbol determines
|
||||
its associativity and precedence rules. *)
|
||||
let (+) a b = a - b ;; (* Surprise maintenance programmers. *)
|
||||
|
||||
(* More useful: a reciprocal operator for floats.
|
||||
@ -223,6 +229,10 @@ List.filter (fun x -> x mod 2 = 0) [1; 2; 3; 4] ;;
|
||||
often referred to as "cons". *)
|
||||
1 :: [2; 3] ;; (* Gives [1; 2; 3] *)
|
||||
|
||||
(* Remember that the cons :: constructor can only cons a single item to the front
|
||||
of a list. To combine two lists use the append @ operator *)
|
||||
[1; 2] @ [3; 4] ;; (* Gives [1; 2; 3; 4] *)
|
||||
|
||||
(* Arrays are enclosed in [| |] *)
|
||||
let my_array = [| 1; 2; 3 |] ;;
|
||||
|
||||
@ -258,7 +268,7 @@ let ocaml = (String.make 1 'O') ^ "Caml" ;;
|
||||
(* There is a printf function. *)
|
||||
Printf.printf "%d %s" 99 "bottles of beer" ;;
|
||||
|
||||
(* Unformatted read and write functions are there too. *)
|
||||
(* There's also unformatted read and write functions. *)
|
||||
print_string "hello world\n" ;;
|
||||
print_endline "hello world" ;;
|
||||
let line = read_line () ;;
|
||||
@ -291,15 +301,59 @@ let my_point = Point (2.0, 3.0) ;;
|
||||
type 'a list_of_lists = 'a list list ;;
|
||||
type int_list_list = int list_of_lists ;;
|
||||
|
||||
(* These features allow for useful optional types *)
|
||||
type 'a option = Some of 'a | None ;;
|
||||
let x = Some x ;;
|
||||
let y = None ;;
|
||||
|
||||
(* Types can also be recursive. Like in this type analogous to
|
||||
built-in list of integers. *)
|
||||
a built-in list of integers. *)
|
||||
type my_int_list = EmptyList | IntList of int * my_int_list ;;
|
||||
let l = IntList (1, EmptyList) ;;
|
||||
|
||||
(* or Trees *)
|
||||
type 'a tree =
|
||||
| Empty
|
||||
| Node of 'a tree * 'a * 'a tree
|
||||
|
||||
let example_tree: int tree =
|
||||
Node (
|
||||
Node (Empty, 7, Empty),
|
||||
5,
|
||||
Node (Empty, 9, Empty)
|
||||
)
|
||||
(*
|
||||
5
|
||||
/ \
|
||||
7 9
|
||||
*)
|
||||
|
||||
(*** Records ***)
|
||||
|
||||
(* A collection of values with named fields *)
|
||||
|
||||
type animal =
|
||||
{
|
||||
name: string;
|
||||
color: string;
|
||||
legs: int;
|
||||
}
|
||||
;;
|
||||
|
||||
let cow =
|
||||
{ name: "cow";
|
||||
color: "black and white";
|
||||
legs: 4;
|
||||
}
|
||||
;;
|
||||
val cow : animal
|
||||
|
||||
cow.name ;;
|
||||
- : string = "cow"
|
||||
|
||||
(*** Pattern matching ***)
|
||||
|
||||
(* Pattern matching is somewhat similar to switch statement in imperative
|
||||
(* Pattern matching is somewhat similar to the switch statement in imperative
|
||||
languages, but offers a lot more expressive power.
|
||||
|
||||
Even though it may look complicated, it really boils down to matching
|
||||
@ -311,7 +365,7 @@ let l = IntList (1, EmptyList) ;;
|
||||
let is_zero x =
|
||||
match x with
|
||||
| 0 -> true
|
||||
| _ -> false (* The "_" pattern means "anything else". *)
|
||||
| _ -> false (* The "_" means "anything else". *)
|
||||
;;
|
||||
|
||||
(* Alternatively, you can use the "function" keyword. *)
|
||||
@ -342,6 +396,19 @@ let say x =
|
||||
|
||||
say (Cat "Fluffy") ;; (* "Fluffy says meow". *)
|
||||
|
||||
(* However, pattern matching must be exhaustive *)
|
||||
type color = Red | Blue | Green ;;
|
||||
let what_color x =
|
||||
match x with
|
||||
| Red -> "color is red"
|
||||
| Blue -> "color is blue"
|
||||
(* Won't compile! You have to add a _ case or a Green case
|
||||
to ensure all possibilities are accounted for *)
|
||||
;;
|
||||
(* Also, the match statement checks each case in order.
|
||||
So, if a _ case appears first, none of the
|
||||
following cases will be reached! *)
|
||||
|
||||
(** Traversing data structures with pattern matching **)
|
||||
|
||||
(* Recursive types can be traversed with pattern matching easily.
|
||||
@ -369,9 +436,75 @@ let rec sum_int_list l =
|
||||
let t = Cons (1, Cons (2, Cons (3, Nil))) ;;
|
||||
sum_int_list t ;;
|
||||
|
||||
(* Heres a function to tell if a list is sorted *)
|
||||
let rec is_sorted l =
|
||||
match l with
|
||||
| x :: y :: tail -> x <= y && is_sorted (y :: tail)
|
||||
| _ -> true
|
||||
;;
|
||||
|
||||
is_sorted [1; 2; 3] ;; (* True *)
|
||||
(* OCaml's powerful type inference guesses that l is of type int list
|
||||
since the <= operator is used on elements of l *)
|
||||
|
||||
(* And another to reverse a list *)
|
||||
let rec rev (l: 'a list) : 'a list =
|
||||
match l with
|
||||
| [] -> []
|
||||
| x::tl -> (rev tl) @ [x]
|
||||
;;
|
||||
|
||||
rev [1; 2; 3] ;; (* Gives [3; 2; 1] *)
|
||||
(* This function works on lists of any element type *)
|
||||
|
||||
(*** Higher Order Functions ***)
|
||||
|
||||
(* Functions are first class in OCaml *)
|
||||
|
||||
let rec transform (f: 'a -> 'b) (l: 'a list) : 'b list =
|
||||
match l with
|
||||
| [] -> []
|
||||
| head :: tail -> (f head) :: transform f tail
|
||||
;;
|
||||
|
||||
transform (fun x -> x + 1) [1; 2; 3] ;; (* Gives [2; 3; 4] *)
|
||||
|
||||
(** Lets combine everything we learned! **)
|
||||
let rec filter (pred: 'a -> bool) (l: 'a list) : 'a list =
|
||||
begin match l with
|
||||
| [] -> []
|
||||
| x :: xs ->
|
||||
let rest = filter pred xs in
|
||||
if pred x then x :: rest else rest
|
||||
end
|
||||
;;
|
||||
|
||||
filter (fun x -> x < 4) [3; 1; 4; 1; 5] ;; (* Gives [3; 1; 1]) *)
|
||||
|
||||
(*** Mutability ***)
|
||||
|
||||
(* Records and variables are immutable: you cannot change where a variable points to *)
|
||||
|
||||
(* However, you can create mutable polymorphic fields *)
|
||||
type counter = { mutable num : int } ;;
|
||||
|
||||
let c = { num: 0 } ;;
|
||||
c.num ;; (* Gives 0 *)
|
||||
c.num <- 1 ;; (* <- operator can set mutable record fields *)
|
||||
c.num ;; (* Gives 1 *)
|
||||
|
||||
(* OCaml's standard library provides a ref type to make single field mutability easier *)
|
||||
type 'a ref = { mutable contents : 'a } ;;
|
||||
let counter = ref 0 ;;
|
||||
!counter ;; (* ! operator returns x.contents *)
|
||||
counter := !counter + 1 ;; (* := can be used to set contents *)
|
||||
```
|
||||
|
||||
## Further reading
|
||||
|
||||
* Visit the official website to get the compiler and read the docs: <http://ocaml.org/>
|
||||
* Try interactive tutorials and a web-based interpreter by OCaml Pro: <http://try.ocamlpro.com/>
|
||||
* Visit the official website to get the compiler and read the docs: [http://ocaml.org/](http://ocaml.org/)
|
||||
* Quick tutorial on OCaml: [https://ocaml.org/docs/up-and-running](https://ocaml.org/docs/up-and-running)
|
||||
* Complete online OCaml v5 playground: [https://ocaml.org/play](https://ocaml.org/play)
|
||||
* An up-to-date (2022) book (with free online version) "Real World OCaml": [https://www.cambridge.org/core/books/real-world-ocaml-functional-programming-for-the-masses/052E4BCCB09D56A0FE875DD81B1ED571](https://www.cambridge.org/core/books/real-world-ocaml-functional-programming-for-the-masses/052E4BCCB09D56A0FE875DD81B1ED571)
|
||||
* Online interactive textbook "OCaml Programming: Correct + Efficient + Beautiful" from Cornell University: [https://cs3110.github.io/textbook/cover.html](https://cs3110.github.io/textbook/cover.html)
|
||||
* Try interactive tutorials and a web-based interpreter by OCaml Pro: [http://try.ocamlpro.com/](http://try.ocamlpro.com/)
|
||||
|
@ -114,13 +114,15 @@ eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
|
||||
img = cv2.imread('human.jpg')
|
||||
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
aces = face_cascade.detectMultiScale(gray, 1.3, 5)
|
||||
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
|
||||
for (x,y,w,h) in faces:
|
||||
# Draw a rectangle around detected face
|
||||
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
|
||||
roi_gray = gray[y:y+h, x:x+w]
|
||||
roi_color = img[y:y+h, x:x+w]
|
||||
eyes = eye_cascade.detectMultiScale(roi_gray)
|
||||
for (ex,ey,ew,eh) in eyes:
|
||||
# Draw a rectangle around detected eyes
|
||||
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
|
||||
|
||||
cv2.imshow('img',img)
|
||||
|
751
osl.html.markdown
Normal file
751
osl.html.markdown
Normal file
@ -0,0 +1,751 @@
|
||||
---
|
||||
language: osl
|
||||
filename: learnosl.osl
|
||||
contributors:
|
||||
- ["Preetham Pemmasani", "https://github.com/Preetham-ai"]
|
||||
---
|
||||
|
||||
OSL (Open Shading Language) is a programming language designed by Sony for Arnold Renderer used for creating shaders.
|
||||
|
||||
[Read more here.](https://raw.githubusercontent.com/imageworks/OpenShadingLanguage/master/src/doc/osl-languagespec.pdf)
|
||||
|
||||
```c
|
||||
|
||||
|
||||
// Single-line comments start with //
|
||||
|
||||
/* Multi line comments are preserved. */
|
||||
|
||||
// Statements can be terminated by ;
|
||||
divide(1,2);
|
||||
|
||||
///////////////
|
||||
// 1. Basics //
|
||||
///////////////
|
||||
|
||||
// Declating variables
|
||||
color Blue; // Initializing a variable
|
||||
int _num = 3;
|
||||
float Num = 3.00;
|
||||
float c[3] = {0.1, 0.2, 3.14}; // Array
|
||||
|
||||
// Math works as you would expect
|
||||
3 + 1; // 4
|
||||
74 - 3; // 71
|
||||
20 * 2; // 40
|
||||
75/3; // 25.0
|
||||
|
||||
// And modulo division only works with integers
|
||||
10 % 2; // 0
|
||||
31 % 4; // 1
|
||||
|
||||
// Bitwise operations only works with integers
|
||||
- 0 // 1 (Unary Negation)
|
||||
~ 00100011 // 11011100 (bitwise Compliment)
|
||||
1 << 2; // 4 (shift Left)
|
||||
12 >> 1; // 3 (shift Right)
|
||||
1 & 0; // 0 (bitwise AND)
|
||||
1 | 0; // 1 (bitwise OR)
|
||||
1 ^ 1; // 0 (bitwise XOR)
|
||||
|
||||
// We also have booleans
|
||||
true;
|
||||
false;
|
||||
|
||||
// Booleans can't be compared to integers
|
||||
true == 1 // Error
|
||||
false == 0 // Error
|
||||
|
||||
// Negation uses the ! symbol
|
||||
!0; // 1
|
||||
!1; // 0
|
||||
!2; // 0
|
||||
//... and so on
|
||||
|
||||
// Relation Operators are defined like:
|
||||
0 == 0 // true (equal to)
|
||||
0 != 1 // true (not equal to)
|
||||
5 < 3 // false (less then)
|
||||
3 <= 3 // true (less than or equal to)
|
||||
69 > 69 // false (greater than)
|
||||
99 >= 52 // true (greater than or equal)
|
||||
|
||||
|
||||
// Functions are same as C and C++
|
||||
float sum(float a, float b){
|
||||
return a+b;
|
||||
}
|
||||
|
||||
int subtract(int a, int b){
|
||||
return a-b;
|
||||
}
|
||||
|
||||
sum(2,3); // 5
|
||||
|
||||
////////////////
|
||||
// 2. Shaders //
|
||||
////////////////
|
||||
|
||||
// Shaders explain the custom behavior of materials and light
|
||||
// Shader's syntax is similar to the main function in C
|
||||
// The inputs and the outputs should be initialized to default types
|
||||
shader multiply(float a = 0.0,
|
||||
float b = 0.0,
|
||||
output float c = 0.0){
|
||||
c = a*b;
|
||||
}
|
||||
|
||||
// Double brackets[[ ]] is used to classify metadata of a shader
|
||||
surface plastic
|
||||
[[ string help = "Realistic wood shader" ]]
|
||||
(
|
||||
color Plastic = color (0.7, 0.5, 0.3) [[ string help = "Base color" ]],
|
||||
float Reflectivity = 0.5 [[ float min = 0, float max = 1 ]],
|
||||
){...}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Metadata Types
|
||||
///////////////////////////////////////
|
||||
|
||||
[[ string label = "IOR" ]] // Display-name in UI of the parameter
|
||||
[[ string help = "Change Refractive Index" ]] // Info about the parameter
|
||||
[[ string help = "widget" // Gives widgets to input the parameter
|
||||
string widget = "number" ]] // input float or int
|
||||
string widget = "string" ]] // String input
|
||||
string widget = "boolean" ]] // yes/no (or) 1/0
|
||||
string widget = "popup", options = "smooth|rough" ]] // Drop-down list
|
||||
// enum Drop-down list can also be made
|
||||
string widget = "mapper", options = "smooth:0|rough:1" ]]
|
||||
string widget = "filename" ]] // Input files externally
|
||||
string widget = "null" ]] // null input
|
||||
|
||||
[[ float min = 0.0 ]] // Minimum value of parameter
|
||||
[[ float max = 0.5 ]] // Maximum value of parameter
|
||||
[[ int slider = 3.0 // Adds a slider as an input
|
||||
int slidermin = -1]] // minimum value of the slider
|
||||
int slidermax = 3]] // maximum value of the slider
|
||||
int slidercenter = 2]] // origin value of the slider
|
||||
|
||||
[[ float sensitivity = 0.5 ]] // step size for incrementing the parameter
|
||||
[[ string URL = www.example.com/ ]] // URL of shader's documentation
|
||||
|
||||
|
||||
|
||||
// There are different types of shaders
|
||||
|
||||
/* Surface shaders determine the basic material properties of a surface and
|
||||
how it reacts to light */
|
||||
// Light shaders are a type of SURFACE shaders used for emissive objects.
|
||||
// Displacement shaders alter the geometry using position and normals.
|
||||
// Volume shaders adds a medium like air/smoke/dust into the scene.
|
||||
|
||||
volume multiply(float a = 0.0, float b = 0.0, output float c = 0.0){
|
||||
c = 2*a+b;
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
// 3. Data Types and Global Variables //
|
||||
////////////////////////////////////////
|
||||
|
||||
// Data Types
|
||||
|
||||
// 1. The void type indicates a function that doesn't return any value
|
||||
|
||||
// 2. int (Integer)
|
||||
int x = -12; // Minimum size of 32-bits
|
||||
int new2 = 0x01cf; // Hexadecimal can also be specified
|
||||
|
||||
///////////////////////////////////////
|
||||
// Order of Evaluation
|
||||
///////////////////////////////////////
|
||||
|
||||
// From top to bottom, top has higher precedence
|
||||
//--------------------------//
|
||||
// Operators //
|
||||
//--------------------------//
|
||||
// int++, int-- //
|
||||
// ++ int --int - ~ ! //
|
||||
// * / % //
|
||||
// + - //
|
||||
// << >> //
|
||||
// < <= > >= //
|
||||
// == != //
|
||||
// & //
|
||||
// ^ //
|
||||
// | //
|
||||
// && //
|
||||
// || //
|
||||
// ?: //
|
||||
// = += -= *= /= //
|
||||
//--------------------------//
|
||||
|
||||
// 3. float (Floating-point number)
|
||||
float A = 2.3; // minimum IEEE 32-bit float
|
||||
float Z = -4.1e2; // Z = -4.1 * 10^2
|
||||
|
||||
// Order of evaluation is similar to int.
|
||||
// Operations like ( ~ ! % << >> ^ | & && || ) aren't available in float
|
||||
|
||||
// 4. string
|
||||
// The syntax is similar to C
|
||||
string new = "Hello World";
|
||||
// some Special characters:
|
||||
/*
|
||||
'\"'; // double quote
|
||||
'\n'; // newline character
|
||||
'\t'; // tab character (left justifies text)
|
||||
'\v'; // vertical tab
|
||||
'\\'; // back slash
|
||||
'\r'; // carriage return
|
||||
'\b'; // backspace character
|
||||
*/
|
||||
|
||||
// Strings are concatenated with whitespace
|
||||
"Hello " "world!"; // "Hello world!"
|
||||
// concat function can also be used
|
||||
string concat ("Hello ","World!"); // "Hello world!"
|
||||
|
||||
// printf function is same as C
|
||||
int i = 18;
|
||||
printf("I am %d years old",i); // I am 18 years old
|
||||
|
||||
// String functions can alse be used
|
||||
int strlen (string s); // gives the length of the string
|
||||
int len = strlen("Hello, World!"); // len = 13
|
||||
|
||||
// startswith returns 1 if string starts with prefix, else returns 0
|
||||
int starts = startswith("The quick brown fox", "The"); // starts = 1
|
||||
|
||||
// endswith returns 1 if string starts with suffix, else returns 0
|
||||
int ends = endswith("The quick brown fox", "fox"); // ends will be 1
|
||||
|
||||
// 5. color (Red, Green, Blue)
|
||||
color p = color(0,1,2); // black
|
||||
color q = color(1); // white ( same as color(1,1,1) )
|
||||
color r = color("rgb", 0.23, 0.1, 0.8); // explicitly specify in RGB
|
||||
color s = color("hsv", 0.23, 0.1, 0.8); // specify in HSV
|
||||
// HSV stands for (Hue, Saturation, Luminance)
|
||||
// HSL stands for (Hue, Saturation, Lightness)
|
||||
// YIQ, XYZ and xyY formats can also be used
|
||||
// We can also access the indivudual values of (R,G,B)
|
||||
float Red = p[0]; // 0 (access the red component)
|
||||
float Green = p[1]; // 1 (access the green component)
|
||||
float Blue = p[2]; // 2 (access the blue component)
|
||||
|
||||
// They can also be accessed like this
|
||||
float Red = p.r; // 0 (access the red component)
|
||||
float Green = p.g; // 1 (access the green component)
|
||||
float Blue = p.b; // 2 (access the blue component)
|
||||
|
||||
// Math operators work like this with decreasing precedence
|
||||
color C = (3,2,3) * (1,0,0); // (3, 0, 0)
|
||||
color D = (1,1,1) * 255; // (255, 255, 255)
|
||||
color E = (25,5,125) / 5; // (5, 1, 25)
|
||||
color F = (30,40,50) / (3,4,5); // (10, 10, 10)
|
||||
color A = (1,2,3) + (1,0,0); // (2, 2, 3)
|
||||
color B = (1,2,3) - (1,0,0); // (0, 2, 3)
|
||||
// Operators like ( - == != ) are also used
|
||||
|
||||
// Color Functions
|
||||
color blackbody (1500) // Gives color based on temperature (in Kelvin)
|
||||
float luminance (0.5, 0.3, 0.8) // 0.37 gives luminance cd/m^2
|
||||
// Luminance is calculated by 0.2126R+0.7152G+0.0722B
|
||||
color wavelength color (700) // (1, 0, 0) Gives color based on wavelength
|
||||
color transformc ("hsl", "rgb") // converts one system to another
|
||||
|
||||
// 6. point (x,y,z) is position of a point in the 3D space
|
||||
// 7. vector (x,y,z) has length and direction but no position
|
||||
// 8. normal (x,y,z) is a special vector perpendicular to a surface
|
||||
// These Operators are the same as color and have the same precedence
|
||||
L = point(0.5, 0.6, 0.7);
|
||||
M = vector(30, 100, 70);
|
||||
N = normal(0, 0, 1);
|
||||
|
||||
// These 3 types can be assigned to a coordinate system
|
||||
L = point("object", 0.5, 0.6, 0.7); // relative to local space
|
||||
M = vector("common", 30, 100, 70); // relative to world space
|
||||
// There's also ("shader", "world", "camera", "screen", "raster", "NDC")
|
||||
|
||||
float x = L[0]; // 0.5 (access the x-component)
|
||||
float y = L[1]; // 0.6 (access the y-component)
|
||||
float z = L[2]; // 0.7 (access the z-component)
|
||||
|
||||
// They can also be accessed like this
|
||||
float x = M.x; // 30 (access the x-component)
|
||||
float y = M.y; // 100 (access the y-component)
|
||||
float z = M.z; // 70 (access the z-component)
|
||||
|
||||
float a = dot ((1,2,3), (1,2,3)); // 14 (Dot Product)
|
||||
vector b = cross ((1,2,3), (1,2,3)); // (0,0,0) (Cross Product)
|
||||
float l = length(L); // 1.085 (length of vector)
|
||||
vector normalize (vector L); // (0.460, 0.552, 0.644) Normalizes the vector
|
||||
|
||||
point p0 = point(1, 2, 3);
|
||||
point p1 = point(4, 5, 6);
|
||||
point Q = point(0, 0, 0);
|
||||
|
||||
// Finding distance between two points
|
||||
float len = distance(point(1, 2, 3), point(4, 5, 6)); // 5.196
|
||||
// Perpendicular distance from Q to line joining P0 and P1
|
||||
float distance (point P0, point P1, point Q); // 2.45
|
||||
|
||||
|
||||
// 9. matrix
|
||||
// Used for transforming vectors between different coordinate systems.
|
||||
// They are usually 4x4 (or) 16 floats
|
||||
matrix zero = 0; // makes a 4x4 zero matrix
|
||||
/* 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0 */
|
||||
|
||||
matrix ident = 1; // makes a 4x4 identity matrix
|
||||
/* 1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0 */
|
||||
|
||||
matrix m = 7; // Maked a 4x4 scalar matrix with scaling factor of 7
|
||||
/* 7.0, 0.0, 0.0, 0.0,
|
||||
0.0, 7.0, 0.0, 0.0,
|
||||
0.0, 0.0, 7.0, 0.0,
|
||||
0.0, 0.0, 0.0, 7.0 */
|
||||
|
||||
float x = m[1][1]; // 7
|
||||
|
||||
// matrices can be constructed using floats in row-major order
|
||||
// matrices are usually 4x4 with 16 elements
|
||||
matrix myMatrix = matrix(1.0, 0.0, 0.0, 0.0, // Row 1
|
||||
0.0, 2.0, 0.0, 0.0, // Row 2
|
||||
0.0, 0.0, 3.0, 0.0, // Row 3
|
||||
0.0, 0.0, 0.0, 4.0); // Row 4
|
||||
|
||||
// matrix transformations are easy to implement
|
||||
matrix a = matrix ("shader", 1); // converted shader to common
|
||||
matrix m = matrix ("object", "world"); // converted object to world
|
||||
|
||||
// Operations that can be used with decreasing precedence are:
|
||||
// ( - * / == !=)
|
||||
|
||||
float determinant (matrix M) // 24 (returns the determinant of the matrix)
|
||||
float transpose (matrix M) // returns the transpose of the matrix
|
||||
/* 1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 2.0, 0.0, 0.0,
|
||||
0.0, 0.0, 3.0, 0.0,
|
||||
0.0, 0.0, 0.0, 4.0 */
|
||||
|
||||
// 10. array
|
||||
// Arrays in OSL are similar to C
|
||||
float a[5]; // initialize array a with size 5
|
||||
int b[3] = {90,80,70}; // declare array with size 3
|
||||
int len = arraylength(b); // 3
|
||||
int f = b[1]; // 80
|
||||
float anotherarray[3] = b; // arrays can be copied if same type
|
||||
|
||||
// 11. struct (Structures)
|
||||
// Structures in OSL are similar to C and C++.
|
||||
struct RGBA { // Defining a structure
|
||||
color rgb;
|
||||
float alpha;
|
||||
};
|
||||
|
||||
|
||||
RGBA col; // Declaring a structure
|
||||
RGBA b = { color(0.1, 0.2, 0.3), 1 }; // Can also be declared like this
|
||||
|
||||
r.rgb = color (1, 0, 0); // Assign to one field
|
||||
color c = r.rgb; // Read from a structure field
|
||||
|
||||
// 12. closure
|
||||
// Closure is used to store data that aren't considered when it executes.
|
||||
// It cannot be manipulated or read.
|
||||
// A null closure can always be assigned.
|
||||
// OSL currently only supports color as their closure.
|
||||
|
||||
// A few examples of closures are:
|
||||
|
||||
// Diffuse BSDF closures:
|
||||
closure color oren_nayar_diffuse_bsdf(normal N, color alb, float roughness)
|
||||
closure color burley_diffuse_bsdf(normal N, color alb, float roughness);
|
||||
|
||||
// Dielectric BSDF closure:
|
||||
closure color dielectric_bsdf(normal N, vector U, color reflection_tint,
|
||||
color transmission_tint, float roughness_x, float roughness_y,
|
||||
float ior, string distribution);
|
||||
|
||||
// Conductor BSDF closure:
|
||||
closure color conductor_bsdf(normal N, vector U, float roughness_x,
|
||||
float roughness_y, color ior, color extinction, string distribution);
|
||||
|
||||
// Generalized Schlick BSDF closure:
|
||||
closure color generalized_schlick_bsdf(normal N, vector U,
|
||||
color reflection_tint, color transmission_tint,
|
||||
float roughness_x, float roughness_y, color f0, color f90,
|
||||
float exponent, string distribution);
|
||||
|
||||
// Translucent BSDF closure:
|
||||
closure color translucent_bsdf(normal N, color albedo);
|
||||
|
||||
// Transparent BSDF closure:
|
||||
closure color transparent_bsdf();
|
||||
|
||||
// Subsurface BSSRDF closure:
|
||||
closure color subsurface_bssrdf();
|
||||
|
||||
// Sheen BSDF closure:
|
||||
closure color sheen_bsdf(normal N, color albedo, float roughness);
|
||||
|
||||
// Anisotropic VDF closure: (Volumetric)
|
||||
closure color anisotropic_vdf(color albedo, color extinction,
|
||||
float anisotropy);
|
||||
|
||||
// Medium VDF closure: (Volumetric)
|
||||
closure color medium_vdf(color albedo, float transmission_depth,
|
||||
color transmission_color, float anisotropy, float ior, int priority);
|
||||
|
||||
closure color uniform edf(color emittance); // Emission closure
|
||||
closure color holdout(); // Holdout Hides objects beneath it
|
||||
|
||||
// BSDFs can be layered using this closure
|
||||
closure color layer (closure color top, closure color base);
|
||||
|
||||
|
||||
|
||||
// Global Variables
|
||||
// Contains info that the renderer knows
|
||||
// These variables need not be declared
|
||||
|
||||
point P // Position of the point you are shading
|
||||
vector I // Incident ray direction from viewing position to shading position
|
||||
normal N // Normal of the surface at P
|
||||
normal Ng // Normal of the surface at P irrespective of bump mapping
|
||||
float u // UV 2D x - parametric coordinate of geometry
|
||||
float v // UV 2D y - parametric coordinate of geometry
|
||||
vector dPdu // change of P with respect to u tangent to the surface
|
||||
vector dPdv // change of P with respect to v tangent to the surface
|
||||
float time // Current time
|
||||
float dtime // Time covered
|
||||
vector dPdtime // change of P with respect to time
|
||||
|
||||
/////////////////////
|
||||
// 4. Control flow //
|
||||
/////////////////////
|
||||
|
||||
// Conditionals in OSL are just like in C or C++.
|
||||
|
||||
// If/Else
|
||||
if (5>2){
|
||||
int x = s;
|
||||
int l = x;
|
||||
}
|
||||
else{
|
||||
int x = s + l;
|
||||
}
|
||||
|
||||
// 'while' loop
|
||||
int i = 0;
|
||||
while (i < 5) {
|
||||
i += 1;
|
||||
printf("Current value of i: %d\n", i);
|
||||
}
|
||||
|
||||
// 'do-while' loop is where test happens after the body of the loop
|
||||
int i = 0;
|
||||
do {
|
||||
printf("Current value of i: %d\n", i);
|
||||
i += 1;
|
||||
} while (i < 5);
|
||||
|
||||
// 'for' loop
|
||||
for (int i = 0; i < 5; i += 1) {
|
||||
printf("Current value of i: %d\n", i);
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// 5. Functions //
|
||||
/////////////////////
|
||||
|
||||
// Math Constants
|
||||
M_PI // π
|
||||
M_PI_35 // π/35
|
||||
m_E // e
|
||||
M_LN2 // ln 2
|
||||
M_SQRT2 // √2
|
||||
M_SQRT1_2 // √(1/2)
|
||||
|
||||
// Geometry Functions
|
||||
vector N = vector(0.1, 1, 0.2); // Normal vector
|
||||
vector I = vector(-0.5, 0.2, 0.8); // Incident vector
|
||||
|
||||
// Faceforward tells the direction of vector
|
||||
vector facing_dir = faceforward(N, I); // facing_dir = (-0.5, 0.2, 0.8)
|
||||
|
||||
// faceforward with three arguments
|
||||
vector ref = vector(0.3, -0.7, 0.6); // Reference normal
|
||||
facing_dir = faceforward(N, I, ref); // facing_dir = (0.5, -0.2, -0.8)
|
||||
|
||||
// reflect gives the reflected vector along normal
|
||||
vector refl = reflect(I, N); // refl = (-0.7, -0.4, 1.4)\
|
||||
|
||||
// refract gives the refracted vector along normal
|
||||
float ior = 1.5; // Index of refraction
|
||||
vector refr = refract(I, N, ior); // refr = (-0.25861, 0.32814, 0.96143)
|
||||
|
||||
/* Fresnel computes the Reflection (R) and Transmission (T) vectors, along
|
||||
with the scaling factors for reflected (Kr) and transmitted (Kt) light. */
|
||||
float Kr, Kt;
|
||||
vector R, T;
|
||||
fresnel(I, N, ior, Kr, Kt, R, T);
|
||||
/* Kr = 0.03958, Kt = 0.96042
|
||||
R = (-0.19278, -0.07711, 0.33854)
|
||||
T = (-0.25861, 0.32814, 0.96143) */
|
||||
|
||||
// Rotating a point along a given axis
|
||||
point Q = point(1, 0, 0);
|
||||
float angle = radians(90); // 90 degrees
|
||||
vector axis = vector(0, 0, 1);
|
||||
point rotated_point = rotate(Q, angle, axis);
|
||||
// rotated_point = point(0, 1, 0)
|
||||
|
||||
// Rotating a point along a line made by 2 points
|
||||
point P0 = point(0, 0, 0);
|
||||
point P1 = point(1, 1, 0);
|
||||
angle = radians(45); // 45 degrees
|
||||
Q = point(1, 0, 0);
|
||||
rotated_point = rotate(Q, angle, P0, P1);
|
||||
// rotated_point = point(0.707107, 0.707107, 0)
|
||||
|
||||
// Calculating normal of surface at point p
|
||||
point p1 = point(1, 0, 0); // Point on the sphere of radius 1
|
||||
vector normal1 = calculatenormal(p1);
|
||||
// normal1 = vector(1, 0, 0)
|
||||
|
||||
// Transforming units is easy
|
||||
float transformu ("cm", float x) // converts to cm
|
||||
float transformu ("cm", "m", float y) // converts cm to m
|
||||
|
||||
// Displacement Functions
|
||||
void displace (float 5); // Displace by 5 amp units
|
||||
void bump (float 10); // Bump by 10 amp units
|
||||
|
||||
|
||||
// Noise Generation
|
||||
|
||||
type noise (type noise (string noisetype, float u, float v, ...)); // noise
|
||||
type noise (string noisetype, point p,...); // point instead of coordinates
|
||||
/* some noises are ("perlin", "snoise", "uperlin", "noise", "cell", "hash"
|
||||
"simplex", "usimplex", "gabor", etc) */
|
||||
|
||||
// Noise Names
|
||||
|
||||
// 1. Perlin Noise (perlin, snoise):
|
||||
// Creates smooth, swirling noise often used for textures.
|
||||
// Range: [-1, 1] (signed)
|
||||
color cloud_texture = noise("perlin", P);
|
||||
|
||||
// 2. Simplex Noise (simplex, usimplex):
|
||||
// Similar to Perlin noise but faster.
|
||||
// Range: [-1, 1] (signed) for simplex, [0, 1] (unsigned) for usimplex
|
||||
float bump_amount = 0.2 * noise("simplex", P * 5.0);
|
||||
|
||||
// 3. UPerlin Noise (uperlin, noise):
|
||||
// Similar to peril
|
||||
// Range: [0, 1] (unsigned)
|
||||
color new_texture = noise("uperlin", P);
|
||||
|
||||
// 4. Cell Noise (cell):
|
||||
// Creates a blocky, cellular and constant values within each unit block
|
||||
// Range: [0, 1] (unsigned)
|
||||
color new_texture = noise("cell", P);
|
||||
|
||||
// 5. Hash Noise (hash):
|
||||
// Generates random, uncorrelated values at each point.
|
||||
// Range: [0, 1] (unsigned)
|
||||
color new_texture = noise("hash", P);
|
||||
|
||||
// Gabor Noise (gabor)
|
||||
// Gabor Noise is advanced version of Perin noies and gives more control
|
||||
// Range: [-1, 1] (signed)
|
||||
// Gabor Noise Parameters
|
||||
|
||||
// Anisotropic (default: 0)
|
||||
// Controls anisotropy:
|
||||
// 0: Isotropic (equal frequency in all directions)
|
||||
// 1: Anisotropic with user-defined direction vector (defaults to (1,0,0))
|
||||
/* 2: Hybrid mode,anisotropic along direction vector but radially isotropic
|
||||
perpendicularly. */
|
||||
|
||||
// Direction (default: (1,0,0))
|
||||
// Specifies the direction of anisotropy (used only if anisotropic is 1).
|
||||
|
||||
// bandwidth (default: 1.0)
|
||||
// Controls the frequency range of the noise.
|
||||
|
||||
// impulses (default: 16)
|
||||
// Controls the number of impulses used per cell, affecting detail level.
|
||||
|
||||
// do_filter (default: 1)
|
||||
// Enables/disables antialiasing (filtering).
|
||||
|
||||
result = noise(
|
||||
"gabor",
|
||||
P,
|
||||
"anisotropic", anisotropic,
|
||||
"direction", direction,
|
||||
"bandwidth", bandwidth,
|
||||
"impulses", impulses,
|
||||
"do_filter", do_filter
|
||||
);
|
||||
|
||||
// Specific noises can also be used instead of passing them as types
|
||||
// pnoise is periodic noise
|
||||
float n1 = pnoise("perlin", 0.5, 1.0);
|
||||
// 2D periodic noise with Gabor type
|
||||
float n2 = pnoise("gabor", 0.2, 0.3, 2.0, 3.0);
|
||||
// 2D non-periodic simplex noise
|
||||
float n3 = snoise(0.1, 0.7);
|
||||
// 2D periodic simplex noise
|
||||
type psnoise (float u, float v, float uperiod, float vperiod);
|
||||
float n4 = psnoise(0.4, 0.6, 0.5, 0.25);
|
||||
// 2D cellular noise
|
||||
float n5 = cellnoise(0.2, 0.8);
|
||||
// 2D hash noise
|
||||
int n6 = hash(0.7, 0.3);
|
||||
|
||||
// Step Function
|
||||
// Step Functions are used to compare input and threshold
|
||||
|
||||
// The type may be of float, color, point, vector, or normal.
|
||||
type step (type edge, type x); // Returns 1 if x ≥ edge, else 0
|
||||
color checker = step(0.5, P); // P is a point on the surface
|
||||
/* Pixels with P values below 0.5 will be black, those above or equal will
|
||||
be white */
|
||||
float visibility = step(10, distance(P, light_position));
|
||||
// Light is fully visible within 10 units, completely invisible beyond
|
||||
|
||||
type linearstep (type edge0, type edge1, type x); /* Linearstep Returns 0
|
||||
if x ≤ edge0, and 1 if x ≥ edge1, with linear interpolation */
|
||||
color gradient = linearstep(0, 1, P);
|
||||
// P is a point on the surface between 0 and 1
|
||||
// Color will graduate smoothly from black to white as P moves from 0 to 1
|
||||
float fade = linearstep(0.85, 1, N.z); // N.z is the z-component
|
||||
// Object edges with normals close to vertical (N.z near 1) will fade out
|
||||
|
||||
type smoothstep (type edge0, type edge1, type x); /* smoothstep Returns 0
|
||||
if x ≤ edge0, and 1 if x ≥ edge1, with Hermite interpolation */
|
||||
float soft_mask = smoothstep(0.2, 0.8, noise(P)); /* noise(P) is a noisy
|
||||
value between 0 and 1. soft_mask will vary smoothly between 0 and 1 based
|
||||
on noise(P), with a smoother curve than linearstep */
|
||||
|
||||
// Splines
|
||||
// Splines are smooth curves based on a set of control points
|
||||
|
||||
/* The type of interpolation ranges from "catmull-rom", "bezier",
|
||||
"bspline", "hermite", "linear", or "constant" */
|
||||
|
||||
// Spline with knot vector
|
||||
float[] knots = {0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1};
|
||||
point[] controls = {point(0),point(1, 2, 1),point(2, 1, 2),point(3, 3, 1)};
|
||||
spline curve1 = spline("bezier", 0.5, len(knots), controls);
|
||||
// curve1 is a Bezier spline evaluated at u = 0.5
|
||||
|
||||
// Spline with control points
|
||||
spline curve2 = spline("catmull-rom", 0.25, point(0, 0, 0), point(1, 2, 1),
|
||||
point(2, 1, 2), point(3, 3, 1));
|
||||
// curve2 is a Catmull-Rom spline evaluated at u = 0.25
|
||||
|
||||
// Constant spline with a single float value
|
||||
float value = 10;
|
||||
u = 0.1;
|
||||
spline curve5 = spline("constant", u, value);
|
||||
// curve5 is a constant spline with value 10 evaluated at u = 0.1
|
||||
|
||||
// Hermite spline with point and vector controls
|
||||
point q0 = point(0, 0, 0), q1 = point(3, 3, 3);
|
||||
vector t0 = vector(1, 0, 0), t1 = vector(-1, 1, 1);
|
||||
u = 0.75;
|
||||
spline curve3 = spline("hermite", u, q0, t0, q1, t1);
|
||||
// curve3 is a Hermite spline evaluated at u = 0.75
|
||||
|
||||
// Linear spline with float controls
|
||||
float f0 = 0, f1 = 1, f2 = 2, f3 = 3;
|
||||
u = 0.4;
|
||||
spline curve4 = spline("linear", u, f0, f1, f2, f3);
|
||||
// curve4 is a linear spline evaluated at u = 0.4
|
||||
|
||||
// InverseSplines also exist
|
||||
|
||||
// Inverse spline with control values
|
||||
float y0 = 0, y1 = 1, y2 = 2, y3 = 3;
|
||||
float v = 1.5;
|
||||
float u1 = splineinverse("linear", v, y0, y1, y2, y3);
|
||||
// u1 = 0.5 (linear interpolation between y1 and y2)
|
||||
|
||||
// Inverse spline with knot vector
|
||||
float[] knots = {0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1};
|
||||
float[] values = {0, 1, 4, 9};
|
||||
v = 6;
|
||||
float u2 = splineinverse("bezier", v, len(knots), values);
|
||||
// u2 = 0.75 (Bezier spline inverse evaluated at v = 6)
|
||||
|
||||
// Inverse spline with constant value
|
||||
v = 10;
|
||||
float u3 = splineinverse("constant", v, 10);
|
||||
// u3 = 0 (since the constant spline always returns 10)
|
||||
|
||||
// Inverse spline with periodic values
|
||||
float y4 = 0, y5 = 1, y6 = 0;
|
||||
v = 0.5;
|
||||
float u4 = splineinverse("periodic", v, y4, y5, y6);
|
||||
// u4 = 0.75 (periodic spline inverse evaluated at v = 0.5)
|
||||
|
||||
|
||||
|
||||
// Calculus Operators
|
||||
// Partial derivative of f with respect to x, y and z using Dx, Dy, Dz
|
||||
float a = 3.14;
|
||||
float dx = Dx(a); // partial derivative of a with respect to x
|
||||
|
||||
point p = point(1.0, 2.0, 3.0);
|
||||
vector dp_dx = Dx(p); // partial derivative of p with respect to x
|
||||
|
||||
vector dv_dy = Dy(N); // partial derivative of normal with respect to y
|
||||
|
||||
color c = color(0.5, 0.2, 0.8);
|
||||
color dc_dz = Dz(c); // partial derivative of c with respect to z
|
||||
|
||||
|
||||
float area (point p) // gives the surface area at the position p
|
||||
|
||||
float filterwidth (float x) // gives the changes of x in adjacent samples
|
||||
|
||||
// Texture Functions
|
||||
// lookup for a texture at coordinates (x,y)
|
||||
color col1 = texture("texture.png", 0.5, 0.2);
|
||||
// Lookup color at (0.5, 0.2) in texture.png
|
||||
|
||||
// 3D lookup for a texture at coordinates (x,y)
|
||||
color col3 = texture3d("texture3d.vdb", point(0.25, 0.5, 0.75));
|
||||
|
||||
// parameters are ("blur","width","wrap","fill","alpha","interp", ...)
|
||||
color col2 = texture("texture.png",1.0,0.75,"blur",0.1,"wrap", "periodic");
|
||||
// Lookup color at (1.0, 0.75) with blur 0.1 and periodic wrap mode
|
||||
|
||||
// Light Functions
|
||||
|
||||
float surfacearea (); // Returns the surface area of area light covers
|
||||
int backfacing (); // Outputs 1 if the normals are backfaced, else 0
|
||||
int raytype (string name); // returns 1 if the ray is a particular raytype
|
||||
|
||||
// Tracing a ray from a position in a direction
|
||||
point pos = point(0, 0, 0); // Starting position of the ray
|
||||
vector dir = vector(0, 0, 1); // Direction of the ray
|
||||
int hit = trace(pos, dir); // returns 1 if it hits, else 0
|
||||
|
||||
```
|
||||
### Further reading
|
||||
|
||||
* [Blender Docs for OSL](https://docs.blender.org/manual/en/latest/render/shader_nodes/osl.html)
|
||||
* [C4D Docs for OSL](https://docs.otoy.com/cinema4d//OpenShadingLanguageOSL.html)
|
||||
* Open Shading Language on [Github](https://github.com/AcademySoftwareFoundation/OpenShadingLanguage)
|
||||
* [Official OSL Documentation](https://open-shading-language.readthedocs.io/en/main/)
|
136
p5.html.markdown
136
p5.html.markdown
@ -10,40 +10,142 @@ filename: p5.js
|
||||
p5.js is a JavaScript library that starts with the original goal of [Processing](https://processing.org), to make coding accessible for artists, designers, educators, and beginners, and reinterprets this for today's web.
|
||||
Since p5 is a JavaScript library, you should learn [Javascript](https://learnxinyminutes.com/docs/javascript/) first.
|
||||
|
||||
To run p5.js code, you can go to [the online editor](https://editor.p5js.org/).
|
||||
|
||||
```js
|
||||
///////////////////////////////////
|
||||
// p5.js has two important functions to work with.
|
||||
|
||||
function setup() {
|
||||
// the setup function gets executed just once when the window is loaded
|
||||
// the setup function gets executed just once when the window is loaded
|
||||
}
|
||||
function draw() {
|
||||
// the draw function gets called every single frame. This means that for a frameRate(30) it would get called 30 times per second.
|
||||
// the draw function gets called every single frame
|
||||
// if the framerate is set to 30, it would get called 30 times every second
|
||||
}
|
||||
|
||||
// the following code explains all features
|
||||
|
||||
function setup() {
|
||||
createCanvas(640, 480); // creates a new canvas element with 640px as width as 480px as height
|
||||
background(128); // changes the background color of the canvas, can accept rgb values like background(100,200,20) else grayscale values like background(0) = black or background(255) = white
|
||||
createCanvas(640, 480); // creates a new canvas element with 640px as width as 480px as height
|
||||
background(128); // sets the background color to rgb(128, 128, 128)
|
||||
// background('#aaf') // you can use hex codes and color names too
|
||||
}
|
||||
|
||||
function draw() {
|
||||
ellipse(10, 10, 50, 50); // creates a ellipse at the 10px from the left and 10px from the top with width and height as 50 each, so its basically a circle.
|
||||
//remember in p5.js the origin is at the top-left corner of the canvas
|
||||
background('#f2f2fc'); // usually, you call `background` in draw to clear the screen
|
||||
// creates an ellipse at 10px from the top and 10px from the left, with width and height 37
|
||||
ellipse(10, 10, 37, 37);
|
||||
// remember in p5.js the origin is at the top-left corner of the canvas
|
||||
|
||||
if (mouseIsPressed) {
|
||||
// mouseIsPressed is a boolean variable that changes to true if the mouse button is pressed down at that instant
|
||||
if (mouseIsPressed) {
|
||||
// mouseIsPressed is a boolean variable that is true when the mouse is down, and false otherwise
|
||||
|
||||
fill(0); // fill refers to the innner color or filling color of whatever shape you are going to draw next
|
||||
} else {
|
||||
fill(255); // you can give in rgb values like fill(72, 240, 80) to get colors, else a single values determines the grayscale where fill(255) stands for #FFF(white) and fill(0) stands for #000(black)
|
||||
fill(0); // fill sets the fill color, which will stay until it is changed
|
||||
} else {
|
||||
fill(255, 255, 255, 240); // fill(a, b, c, d) sets the fill color to rgba(a, b, c, d)
|
||||
}
|
||||
|
||||
ellipse(mouseX, mouseY, 80, 80);
|
||||
// mouseX and mouseY are the x and y position of the mouse, respectively
|
||||
// the above code creates and ellipse under the mouse, and fills it with white or black
|
||||
|
||||
|
||||
// some other 2d primitives (shapes) you can draw:
|
||||
rect(9, 3, 23, 26); // x, y, width, height
|
||||
noFill(); // sets the fill color to transparent
|
||||
triangle(100, 400, 130, 200, 200, 300); // x1, y1, x2, y2, x3, y3
|
||||
point(100, 300); // create a point at x, y
|
||||
// there are more, but they are more complex.
|
||||
}
|
||||
|
||||
/** Bouncing balls animation
|
||||
* You can copy-paste this code into the online editor at
|
||||
* https://editor.p5js.org/
|
||||
*/
|
||||
class Ball {
|
||||
constructor(x, y, xvel, yvel, radius, col) {
|
||||
this.position = createVector(x, y); // create a p5.Vector object which stores the x and y
|
||||
this.velocity = createVector(xvel, yvel); // make a p5.Vector storing the velocity
|
||||
this.radius = radius;
|
||||
this.col = col; // p5 already uses the word color, so we use col instead
|
||||
}
|
||||
|
||||
update() {
|
||||
this.position.add(this.velocity); // you can add vectors with p5.Vector.add(p5.Vector)
|
||||
if (this.position.x + this.radius > width) {
|
||||
// flip the direction the ball is going in if it touches the edge
|
||||
this.velocity.x *= -1;
|
||||
}
|
||||
if (this.position.x - this.radius < 0) {
|
||||
this.velocity.x *= -1;
|
||||
}
|
||||
if (this.position.y + this.radius > height) {
|
||||
this.velocity.y *= -1;
|
||||
}
|
||||
if (this.position.y - this.radius < 0) {
|
||||
this.velocity.y *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
ellipse(mouseX, mouseY, 80, 80);
|
||||
// mouseX is the x-coordinate of the mouse's current position and mouseY is the y-coordinate of the mouse's current position
|
||||
render() {
|
||||
// you can figure out what this does by now
|
||||
fill(this.col);
|
||||
ellipse(this.position.x, this.position.y, this.radius);
|
||||
}
|
||||
}
|
||||
|
||||
// the above code creates a circle wherever mouse's current position and fills it either black or white based on the mouseIsPressed
|
||||
let numBalls = 23;
|
||||
let balls = [];
|
||||
|
||||
function setup() {
|
||||
createCanvas(400, 400); // width, height
|
||||
for (let i = 0; i < numBalls; i++) {
|
||||
let r = random(255); // random number between 0 and 255
|
||||
let g = random(255);
|
||||
let b = random(255);
|
||||
|
||||
balls.push(
|
||||
new Ball(
|
||||
random(30, width), // x position
|
||||
random(height), // y position
|
||||
random(-4, 4), // x velocity
|
||||
random(-4, 4), // y velocity
|
||||
random(4, 10), // radius
|
||||
color(r, g, b) // fill color for the ball
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function draw() {
|
||||
background(255);
|
||||
for (let ball of balls) {
|
||||
ball.update();
|
||||
ball.render();
|
||||
}
|
||||
}
|
||||
|
||||
// So far, we have only seen the default rendering mode.
|
||||
// This time, we will use the 'webgl' renderer
|
||||
|
||||
function setup() {
|
||||
createCanvas(400, 400, WEBGL); // width, height, rendering mode
|
||||
}
|
||||
|
||||
function draw() {
|
||||
background(0);
|
||||
|
||||
stroke('#000');
|
||||
fill('#aaf');
|
||||
|
||||
// rotate around the x, y, and z axes by the frame count divided by 50
|
||||
rotateX(frameCount / 50);
|
||||
rotateY(frameCount / 50);
|
||||
rotateZ(frameCount / 50);
|
||||
// frameCount is a p5.js variable that stores the amount of frames that have passed
|
||||
|
||||
box(50, 50, 50); // width, height, depth
|
||||
}
|
||||
```
|
||||
|
||||
@ -51,3 +153,9 @@ function draw() {
|
||||
|
||||
- [p5.js | get started](http://p5js.org/get-started/) The official documentation
|
||||
- [Code! Programming for Beginners with p5.js - YouTube](https://www.youtube.com/watch?v=yPWkPOfnGsw&vl=en) Introduction and Coding challenges using Processing and p5.js by Coding Train
|
||||
- [The Coding Train](https://codingtra.in/) A website with sketches made in p5 and processing
|
||||
|
||||
## Source
|
||||
|
||||
- [p5's source code](https://github.com/processing/p5.js)
|
||||
- [p5.sound.js source](https://github.com/processing/p5.js-sound)
|
||||
|
@ -92,9 +92,10 @@ $escaped = "This contains a \t tab character.";
|
||||
$unescaped = 'This just contains a slash and a t: \t';
|
||||
|
||||
// Enclose a variable in curly braces if needed
|
||||
$apples = "I have {$number} apples to eat.";
|
||||
$oranges = "I have ${number} oranges to eat.";
|
||||
$money = "I have $${number} in the bank.";
|
||||
$number = 23;
|
||||
$apples = "I have {$number} apples to eat."; // => I have 23 apples to eat.
|
||||
$oranges = "I have ${number} oranges to eat."; // => I have 23 oranges to eat.
|
||||
$money = "I have $${number} in the bank."; // => I have $23 in the bank.
|
||||
|
||||
// Since PHP 5.3, nowdocs can be used for uninterpolated multi-liners
|
||||
$nowdoc = <<<'END'
|
||||
@ -109,7 +110,7 @@ $sgl_quotes
|
||||
END;
|
||||
|
||||
// String concatenation is done with .
|
||||
echo 'This string ' . 'is concatenated';
|
||||
echo 'This string ' . 'is concatenated'; // Returns 'This string is concatenated'
|
||||
|
||||
// Strings can be passed in as parameters to echo
|
||||
echo 'Multiple', 'Parameters', 'Valid'; // Returns 'MultipleParametersValid'
|
||||
|
@ -118,14 +118,15 @@ $False - 5 # => -5
|
||||
2 -lt 3 -and 3 -lt 2 # => False
|
||||
|
||||
# (-is vs. -eq) -is checks if two objects are the same type.
|
||||
# -eq checks if the objects have the same values.
|
||||
# -eq checks if the objects have the same values, but sometimes doesn't work
|
||||
# as expected.
|
||||
# Note: we called '[Math]' from .NET previously without the preceeding
|
||||
# namespaces. We can do the same with [Collections.ArrayList] if preferred.
|
||||
[System.Collections.ArrayList]$a = @() # Point a at a new list
|
||||
$a = (1,2,3,4)
|
||||
$b = $a # => Point b at what a is pointing to
|
||||
$b -is $a.GetType() # => True, a and b equal same type
|
||||
$b -eq $a # => True, a and b values are equal
|
||||
$b -eq $a # => None! See below
|
||||
[System.Collections.Hashtable]$b = @{} # => Point a at a new hash table
|
||||
$b = @{'one' = 1
|
||||
'two' = 2}
|
||||
@ -154,6 +155,13 @@ $age = 22
|
||||
"$name's name is $($name.Length) characters long."
|
||||
# => "Steve's name is 5 characters long."
|
||||
|
||||
# Strings can be compared with -eq, but are case insensitive. We can
|
||||
# force with -ceq or -ieq.
|
||||
"ab" -eq "ab" # => True
|
||||
"ab" -eq "AB" # => True!
|
||||
"ab" -ceq "AB" # => False
|
||||
"ab" -ieq "AB" # => True
|
||||
|
||||
# Escape Characters in Powershell
|
||||
# Many languages use the '\', but Windows uses this character for
|
||||
# file paths. Powershell thus uses '`' to escape characters
|
||||
@ -274,6 +282,10 @@ $array.AddRange($otherArray) # Now $array is [1, 2, 3, 4, 5, 6]
|
||||
# Examine length with "Count" (Note: "Length" on arrayList = each items length)
|
||||
$array.Count # => 6
|
||||
|
||||
# -eq doesn't compare array but extract the matching elements
|
||||
$array = 1,2,3,1,1
|
||||
$array -eq 1 # => 1,1,1
|
||||
($array -eq 1).Count # => 3
|
||||
|
||||
# Tuples are like arrays but are immutable.
|
||||
# To use Tuples in powershell, you must use the .NET tuple class.
|
||||
@ -574,7 +586,7 @@ Get-Process | Foreach-Object ProcessName | Group-Object
|
||||
1..10 | ForEach-Object { "Loop number $PSITEM" }
|
||||
1..10 | Where-Object { $PSITEM -gt 5 } | ConvertTo-Json
|
||||
|
||||
# A notable pitfall of the pipeline is it's performance when
|
||||
# A notable pitfall of the pipeline is its performance when
|
||||
# compared with other options.
|
||||
# Additionally, raw bytes are not passed through the pipeline,
|
||||
# so passing an image causes some issues.
|
||||
|
@ -5,7 +5,7 @@ contributors:
|
||||
translators:
|
||||
- ["David Lima", "https://github.com/davelima"]
|
||||
lang: pt-br
|
||||
filename: asciidoc-pt.md
|
||||
filename: asciidoc-pt.adoc
|
||||
---
|
||||
|
||||
AsciiDoc é uma linguagem de marcação similar ao Markdown e pode ser
|
||||
|
@ -202,7 +202,7 @@ function string_functions( localvar, arr) {
|
||||
# Ambas retornam o número de instâncias substituídas
|
||||
localvar = "fooooobar"
|
||||
sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar"
|
||||
gsub("e", ".", localvar) # localvar => "m..t m. at th. bar"
|
||||
gsub("e", ".", localvar) # localvar => "M..t m. at th. bar"
|
||||
|
||||
# Localiza um texto que casa com uma expressão regular
|
||||
# index() faz a mesma coisa, mas não permite uma expressão regular
|
||||
|
104
pt-br/bc-pt.html.markdown
Normal file
104
pt-br/bc-pt.html.markdown
Normal file
@ -0,0 +1,104 @@
|
||||
---
|
||||
language: bc
|
||||
contributors:
|
||||
- ["Btup"]
|
||||
translators:
|
||||
- ["David Lima", "https://github.com/davelima"]
|
||||
lang: pt-br
|
||||
filename: learnbc-pt.bc
|
||||
---
|
||||
```c
|
||||
/*Este é um comentário
|
||||
multi-linhas*/
|
||||
# Este é um comentário de uma única linha! (em bc GNU).
|
||||
|
||||
/*1. Variáveis e estruturas de controle*/
|
||||
num = 45 /*Todas as variáveis apenas salvam dados do tipo double, e
|
||||
você não pode salvar strings diretamente em constantes.*/
|
||||
num 45; /*Você pode adicionar ponto-e-vírgula após cada linha.
|
||||
Isto é opcional*/
|
||||
/*Blocos são denotados usando os operadores {} (similar ao C):*/
|
||||
while(num < 50) {
|
||||
num += 1 /*equivalente a num=num+1.
|
||||
a = a op b é equivalente a a op= b.*/
|
||||
}
|
||||
/*E existem os operadores ++ (incrementar) e -- (decrementar).*/
|
||||
/* Existem 3 tipos especiais de variáveis:
|
||||
scale: define a escala de números double.
|
||||
ibase: define a base de da entrada.
|
||||
obase: define a base da saída.
|
||||
*/
|
||||
/*Cláusulas If:*/
|
||||
hora = read() /*Lê a entrada de um número*/
|
||||
|
||||
if(hora < 12) { /*Os operadores são idênticos ao C.*/
|
||||
print "Bom dia\n" /*"print" imprime strings ou variáveis
|
||||
separados por vírgula (,).*/
|
||||
} else if(hora == 12) {
|
||||
print "Olá\n"
|
||||
/*Para escapar strings, inicie a string com \.
|
||||
Para deixar o escape de strings mais claros,
|
||||
aqui está uma lista simplificada das strings escapadas
|
||||
que funcionarão com bc:
|
||||
\b: backspace
|
||||
\c: carriage return (enter)
|
||||
\n: newline (nova linha)
|
||||
\t: tab
|
||||
\\: backslash (barra inertida)*/
|
||||
} else {
|
||||
/*Variáveis são globais por padrão.*/
|
||||
istoEGlobal = 5
|
||||
/*Para tornar uma variável local, use a palavra-chave "auto" em uma função.*/
|
||||
}
|
||||
|
||||
/*Todas as variáveis por padrão tem o valor 0*/
|
||||
num = variavelEmBranco /*num é igual a 0.*/
|
||||
|
||||
/*Assim como no C, "0" é considerado "false"*/
|
||||
if(!num) {print "false\n"}
|
||||
|
||||
/*Diferente do C, bc não tem o operador ?:. Por exemplo,
|
||||
este bloco de código causaria um erro:
|
||||
a = (num) ? 1 : 0
|
||||
Entretanto, você pode simular da seguinte forma:
|
||||
a = (num) && (1) || (0) /*&& é "E", || é "OU"*/
|
||||
*/
|
||||
|
||||
/*Loops For*/
|
||||
num = 0
|
||||
for(i = 1; i <= 100; i++) {/*Similar ao loop For do C.*/
|
||||
num += i
|
||||
}
|
||||
|
||||
/*2.Funções e arrays*/
|
||||
define fac(n) { /*para definir uma função, use "define".*/
|
||||
if(n == 1 || n == 0) {
|
||||
return 1 /*retorna um valor*/
|
||||
}
|
||||
return n * fac(n - 1) /*recursão é permitido*/
|
||||
}
|
||||
|
||||
/*Closures e funções anônimas não são permitidas*/
|
||||
|
||||
num = fac(4) /*24*/
|
||||
|
||||
/*Exemplo de variáveis locais:*/
|
||||
define x(n) {
|
||||
auto x
|
||||
x = 1
|
||||
return n + x
|
||||
}
|
||||
x(3) /*4*/
|
||||
print x /*A variável "x" não será acessível de fora da função*/
|
||||
/*Arrays são equivalentes aos arrays em C.*/
|
||||
for(i = 0; i <= 3; i++) {
|
||||
a[i] = 1
|
||||
}
|
||||
/*Para acessar um array, faça assim:*/
|
||||
print a[0], " ", a[1], " ", a[2], " ", a[3], "\n"
|
||||
quit /*Adicione essa linha no final do código
|
||||
para garantir que o programa encerre. Essa linha é opcional.*/
|
||||
```
|
||||
Aproveite bem essa simples calculadora! (Ou essa linguagem de programação, para ser exato.)
|
||||
|
||||
Este programa inteiro foi escrito em GNU bc. Para rodá-lo, use ```bc learnbc-pt.bc```
|
@ -363,7 +363,7 @@ void OwnedDog::print() const
|
||||
{
|
||||
Dog::print(); // Chame a função de impressão na classe Dog base de
|
||||
std::cout << "Dog is owned by " << owner << "\n";
|
||||
// Prints "Dog is <name> and weights <weight>"
|
||||
// Imprime "Dog is <name> and weights <weight>"
|
||||
// "Dog is owned by <owner>"
|
||||
}
|
||||
|
||||
|
@ -384,7 +384,6 @@ int main() {
|
||||
// Por exemplo, quando um array é passado para uma função ou é atribuído a um
|
||||
// ponteiro, ele transforma-se (convertido implicitamente) em um ponteiro.
|
||||
// Exceções: quando o array é o argumento de um operador `&` (endereço-de):
|
||||
// Exceptions: when the array is the argument of the `&` (address-of) operator:
|
||||
int arr[10];
|
||||
int (*ptr_to_arr)[10] = &arr; // &arr não é do tipo `int *`!
|
||||
// É do tipo "ponteiro para array" (de `int`s).
|
||||
|
@ -153,7 +153,7 @@ on a new line! ""Wow!"", the masses cried";
|
||||
intArray[1] = 1;
|
||||
|
||||
// Listas
|
||||
// Listas são usadas frequentemente tanto quanto matriz por serem mais flexiveis
|
||||
// Listas são usadas frequentemente tanto quanto matriz por serem mais flexíveis
|
||||
// O formato de declarar uma lista é o seguinte:
|
||||
// List<tipodado> <var nome> = new List<tipodado>();
|
||||
List<int> intList = new List<int>();
|
||||
|
262
pt-br/d-pt.html.markdown
Normal file
262
pt-br/d-pt.html.markdown
Normal file
@ -0,0 +1,262 @@
|
||||
---
|
||||
language: D
|
||||
filename: learnd-pt.d
|
||||
contributors:
|
||||
- ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"]
|
||||
translators:
|
||||
- ["Julio Vanzelli", "https://github.com/JulioVanzelli"]
|
||||
lang: pt-br
|
||||
---
|
||||
|
||||
```d
|
||||
// Você sabe o que está por vir...
|
||||
module hello;
|
||||
|
||||
import std.stdio;
|
||||
|
||||
// args é opcional
|
||||
void main(string[] args) {
|
||||
writeln("Hello, World!");
|
||||
}
|
||||
```
|
||||
|
||||
Se você é como eu e passa muito tempo na Internet, é provável que tenha ouvido
|
||||
sobre [D] (http://dlang.org/). A linguagem de programação D é moderna, de uso geral,
|
||||
linguagem multiparadigma com suporte para tudo, desde recursos de baixo nível até
|
||||
abstrações expressivas de alto nível.
|
||||
|
||||
D é desenvolvido ativamente por um grande grupo de pessoas super-inteligentes e é liderado por
|
||||
[Walter Bright] (https://en.wikipedia.org/wiki/Walter_Bright) e
|
||||
[Andrei Alexandrescu] (https://en.wikipedia.org/wiki/Andrei_Alexandrescu).
|
||||
Com tudo isso fora do caminho, vamos dar uma olhada em alguns exemplos!
|
||||
|
||||
```d
|
||||
import std.stdio;
|
||||
|
||||
void main() {
|
||||
|
||||
// Condicionais e loops funcionam como esperado.
|
||||
for(int i = 0; i < 10000; i++) {
|
||||
writeln(i);
|
||||
}
|
||||
|
||||
// 'auto' pode ser usado para inferir tipos.
|
||||
auto n = 1;
|
||||
|
||||
// literais numéricos podem usar '_' como um separador de dígitos para maior clareza.
|
||||
while(n < 10_000) {
|
||||
n += n;
|
||||
}
|
||||
|
||||
do {
|
||||
n -= (n / 2);
|
||||
} while(n > 0);
|
||||
|
||||
// Por e enquanto são bons, mas em D-land preferimos loops 'foreach'.
|
||||
// O '..' cria um intervalo contínuo, incluindo o primeiro valor
|
||||
// mas excluindo o último.
|
||||
foreach(n; 1..1_000_000) {
|
||||
if(n % 2 == 0)
|
||||
writeln(n);
|
||||
}
|
||||
|
||||
// Há também 'foreach_reverse' quando você deseja fazer um loop para trás.
|
||||
foreach_reverse(n; 1..int.max) {
|
||||
if(n % 2 == 1) {
|
||||
writeln(n);
|
||||
} else {
|
||||
writeln("No!");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Podemos definir novos tipos com `struct`,` class`, `union` e` enum`. Estruturas e uniões
|
||||
são passados para funções por valor(ou seja, copiados) e as classes são passadas por referência. Além disso,
|
||||
podemos usar modelos para parametrizar tudo isso em tipos e valores!
|
||||
|
||||
```d
|
||||
// Aqui, 'T' é um parâmetro de tipo. Pense '<T>' em C++/C#/Java.
|
||||
struct LinkedList(T) {
|
||||
T data = null;
|
||||
|
||||
// Usar '!' para instanciar um tipo parametrizado. Mais uma vez, pense '<T>'.
|
||||
LinkedList!(T)* next;
|
||||
}
|
||||
|
||||
class BinTree(T) {
|
||||
T data = null;
|
||||
|
||||
// Se houver apenas um parâmetro de modelo, podemos omitir os parênteses.
|
||||
BinTree!T left;
|
||||
BinTree!T right;
|
||||
}
|
||||
|
||||
enum Day {
|
||||
Sunday,
|
||||
Monday,
|
||||
Tuesday,
|
||||
Wednesday,
|
||||
Thursday,
|
||||
Friday,
|
||||
Saturday,
|
||||
}
|
||||
|
||||
// Use o alias para criar abreviações para tipos.
|
||||
alias IntList = LinkedList!int;
|
||||
alias NumTree = BinTree!double;
|
||||
|
||||
// Também podemos criar modelos de funções!
|
||||
T max(T)(T a, T b) {
|
||||
if(a < b)
|
||||
return b;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
// Use a palavra-chave ref para garantir a passagem por referência. Ou seja, mesmo que 'a'
|
||||
// e 'b' sejam tipos de valor, eles sempre serão passados por referência a 'swap ()'.
|
||||
void swap(T)(ref T a, ref T b) {
|
||||
auto temp = a;
|
||||
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
// Com os modelos, também podemos parametrizar valores, não apenas tipos.
|
||||
class Matrix(uint m, uint n, T = int) {
|
||||
T[m] rows;
|
||||
T[n] columns;
|
||||
}
|
||||
|
||||
auto mat = new Matrix!(3, 3); // O tipo 'T' foi padronizado como 'int'.
|
||||
|
||||
```
|
||||
|
||||
Falando em aulas, vamos falar sobre propriedades por um segundo. Uma propriedade
|
||||
é aproximadamente uma função que pode agir como um valor I, para que possamos
|
||||
ter a sintaxe das estruturas POD (`structure.x = 7`) com a semântica de
|
||||
métodos getter e setter (`object.setX (7)`)!
|
||||
|
||||
```d
|
||||
// Considere uma classe parametrizada nos tipos 'T' e 'U'.
|
||||
class MyClass(T, U) {
|
||||
T _data;
|
||||
U _other;
|
||||
}
|
||||
|
||||
// E os métodos "getter" e "setter", assim:
|
||||
class MyClass(T, U) {
|
||||
T _data;
|
||||
U _other;
|
||||
|
||||
// Os construtores sempre são chamados de 'this'.
|
||||
this(T t, U u) {
|
||||
// This will call the setter methods below.
|
||||
data = t;
|
||||
other = u;
|
||||
}
|
||||
|
||||
// getters
|
||||
@property T data() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
@property U other() {
|
||||
return _other;
|
||||
}
|
||||
|
||||
// setters
|
||||
@property void data(T t) {
|
||||
_data = t;
|
||||
}
|
||||
|
||||
@property void other(U u) {
|
||||
_other = u;
|
||||
}
|
||||
}
|
||||
|
||||
// E nós os usamos desta maneira:
|
||||
void main() {
|
||||
auto mc = new MyClass!(int, string)(7, "seven");
|
||||
|
||||
// Importe o módulo 'stdio' da biblioteca padrão para gravar no
|
||||
// console (as importações podem ser locais para um escopo).
|
||||
import std.stdio;
|
||||
|
||||
// Ligue para os getters para buscar os valores.
|
||||
writefln("Earlier: data = %d, str = %s", mc.data, mc.other);
|
||||
|
||||
// Ligue para os setters para atribuir novos valores.
|
||||
mc.data = 8;
|
||||
mc.other = "eight";
|
||||
|
||||
// Ligue para os getters novamente para buscar os novos valores.
|
||||
writefln("Later: data = %d, str = %s", mc.data, mc.other);
|
||||
}
|
||||
```
|
||||
|
||||
Com propriedades, podemos adicionar qualquer quantidade de lógica para
|
||||
nossos métodos getter e setter, e mantenha a sintaxe limpa de
|
||||
acessando membros diretamente!
|
||||
|
||||
Outras guloseimas orientadas a objetos à nossa disposição,
|
||||
incluem interfaces, classes abstratas,
|
||||
e métodos de substituição. D faz herança como Java:
|
||||
Estenda uma classe, implemente quantas interfaces você desejar.
|
||||
|
||||
Vimos as instalações OOP de D, mas vamos mudar de marcha. D oferece
|
||||
programação funcional com funções de primeira classe, `pura`
|
||||
funções e dados imutáveis. Além disso, todos os seus favoritos
|
||||
algoritmos funcionais (mapear, filtrar, reduzir e amigos) podem ser
|
||||
encontrado no maravilhoso módulo `std.algorithm`!
|
||||
|
||||
```d
|
||||
import std.algorithm : map, filter, reduce;
|
||||
import std.range : iota; // cria uma gama exclusiva de final
|
||||
|
||||
void main() {
|
||||
// Queremos imprimir a soma de uma lista de quadrados de ints pares
|
||||
// de 1 a 100. Fácil!
|
||||
|
||||
// Basta passar expressões lambda como parâmetros de modelo!
|
||||
// Você pode passar qualquer função que desejar, mas as lambdas são convenientes aqui.
|
||||
auto num = iota(1, 101).filter!(x => x % 2 == 0)
|
||||
.map!(y => y ^^ 2)
|
||||
.reduce!((a, b) => a + b);
|
||||
|
||||
writeln(num);
|
||||
}
|
||||
```
|
||||
|
||||
Observe como conseguimos construir um bom pipeline haskelliano para calcular num?
|
||||
Isso se deve a uma inovação em D, conhecida como Uniform Function Call Syntax (UFCS).
|
||||
Com o UFCS, podemos optar por escrever uma chamada de função como método
|
||||
ou chamada de função grátis! Walter escreveu um bom artigo sobre isso
|
||||
[aqui.] (http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394)
|
||||
Em resumo, você pode chamar funções cujo primeiro parâmetro
|
||||
é de algum tipo A em qualquer expressão do tipo A como método.
|
||||
|
||||
Eu gosto de paralelismo. Alguém mais gosta de paralelismo? Com certeza. Vamos fazer um pouco!
|
||||
|
||||
```d
|
||||
// Digamos que queremos preencher uma matriz grande com a raiz quadrada de todos
|
||||
// os números inteiros consecutivos começando de 1 (até o tamanho da matriz), e queremos
|
||||
// fazer isso simultaneamente, aproveitando o número de núcleos que temos
|
||||
// disponível.
|
||||
|
||||
import std.stdio;
|
||||
import std.parallelism : parallel;
|
||||
import std.math : sqrt;
|
||||
|
||||
void main() {
|
||||
// Crie sua grande variedade
|
||||
auto arr = new double[1_000_000];
|
||||
|
||||
// Use um índice, acesse todos os elementos da matriz por referência (porque vamos
|
||||
// mudar cada elemento) e apenas chame paralelo na matriz!
|
||||
foreach(i, ref elem; parallel(arr)) {
|
||||
elem = sqrt(i + 1.0);
|
||||
}
|
||||
}
|
||||
```
|
@ -98,7 +98,7 @@ linhas.
|
||||
# Ranges são representados como `início..fim` (ambos inclusivos)
|
||||
1..10 #=> 1..10
|
||||
menor..maior = 1..10 # Pattern matching pode ser usada em ranges também
|
||||
[lower, upper] #=> [1, 10]
|
||||
[menor, maior] #=> [1, 10]
|
||||
|
||||
## ---------------------------
|
||||
## -- Operadores
|
||||
@ -167,7 +167,7 @@ else
|
||||
"Isso será"
|
||||
end
|
||||
|
||||
# Lembra do patter matching? Muitas estruturas de fluxo de controle em Elixir contam com ela.
|
||||
# Lembra do pattern matching? Muitas estruturas de fluxo de controle em Elixir contam com ela.
|
||||
|
||||
# `case` nos permite comparar um valor com muitos patterns:
|
||||
case {:um, :dois} do
|
||||
|
60
pt-br/emacs-pt.html.markdown
Normal file
60
pt-br/emacs-pt.html.markdown
Normal file
@ -0,0 +1,60 @@
|
||||
---
|
||||
category: tool
|
||||
tool: emacs
|
||||
filename: emacs.txt
|
||||
contributors:
|
||||
- ["Joseph Riad", "https://github.com/Joseph-Riad"]
|
||||
translators:
|
||||
- ["André de Santa Gabriel", "https://github.com/andredesanta"]
|
||||
lang: pt-br
|
||||
---
|
||||
|
||||
O Emacs começou sua vida como (https://www.gnu.org/software/emacs/emacs-paper.html) e cresceu
|
||||
ao longo dos anos em um ecossistema completo. Muitas tarefas, geralmente
|
||||
relegado a um conjunto diversificado de ferramentas pode ser realizado de dentro
|
||||
Emacs em uma interface consistente e familiar. Exemplos incluem
|
||||
gerenciamento de diretório, visualização de documentos PDF, edição de arquivos via SSH, gerenciamento de
|
||||
repos git. Em suma, o Emacs é seu para fazer
|
||||
o que você quiser: o espectro de usuários varia daqueles que o usam para
|
||||
editar arquivos de texto para puristas extremos que o usam para substituir virtualmente seu
|
||||
sistema operacional.
|
||||
|
||||
O Emacs é extensível através de um dialeto especializado do Lisp conhecido como Emacs
|
||||
Lisp (Elisp), que possui muitas macros voltadas para a edição de texto e
|
||||
gerenciamento de buffers de texto. Qualquer tecla (combinação) usada no Emacs está vinculada
|
||||
para uma função Emacs Lisp e pode ser remapeado para qualquer outra função,
|
||||
incluindo aqueles que você escreve
|
||||
você mesmo.
|
||||
|
||||
# Conceitos básicos de Emacs
|
||||
|
||||
Aqui, discuto alguns conceitos e terminologia básicos do Emacs que podem ser
|
||||
confusos para os recém-chegados (especialmente para as pessoas acostumadas à terminologia do Vim):
|
||||
|
||||
- O texto que o Emacs está editando é conhecido como **buffer**
|
||||
|
||||
- Um buffer não corresponde necessariamente a um arquivo real no disco. Pode ser apenas texto na memória.
|
||||
|
||||
- Quando um buffer corresponde a um arquivo no disco, dizemos que o buffer está **visitando** esse arquivo.
|
||||
|
||||
- O Emacs normalmente possui muitos buffers abertos ao mesmo tempo.
|
||||
|
||||
- A exibição do Emacs pode ser dividida em diferentes **windows**.
|
||||
|
||||
- Uma janela do sistema operacional para o Emacs é chamada de **frame**. Assim, quando o manual do Emacs fala sobre a abertura de um novo frame, esse essencialmente significa abrir uma nova janela do SO contendo uma (outra) instância do Emacs.
|
||||
|
||||
- Os conceitos convencionalmente conhecidos como recortar e colar são referido como **killing** e **yanking**, respectivamente no Emacs.
|
||||
|
||||
- A posição atual do cursor é chamada de **point** no Emacs. Tecnicamente, **point** é definido como a posição imediatamente antes do caractere onde o cursor está atualmente.
|
||||
|
||||
- Finalmente, cada buffer pode ter vários **modes** associados: o **major mode** e possivelmente vários **minor modes**.
|
||||
|
||||
- O **major mode** define o principal comportamento do Emacs no buffer atualmente selecionado. Isso pode ser pensado como o tipo de arquivo. Por exemplo, se você estiver editando um arquivo Python, os principais modes é (por padrão) `python-mode`, que faz com que o Emacs destaque a sintaxe Python e idente automaticamente seus blocos de código conforme exigido sintaticamente pelo seu código Python.
|
||||
|
||||
- **Minor modes** definem mudanças sutis no comportamento e várias alterações menores Os modos podem estar ativos ao mesmo tempo no mesmo buffer. Um exemplo menor modo é o modo flyspell, que destaca automaticamente os erros de ortografia no seu buffer.
|
||||
|
||||
# Recursos adicionais
|
||||
|
||||
- [The GNU Emacs Manual](https://www.gnu.org/software/emacs/manual/emacs.html)
|
||||
- [Emacs Stack Exchange](https://emacs.stackexchange.com/)
|
||||
- [Emacs Wiki](https://www.emacswiki.org/emacs/EmacsWiki)
|
@ -77,7 +77,7 @@ pode incluir quebras de linha.` // mesmo tipo string
|
||||
// literal não-ASCII. A linguagem Go utiliza de raiz a codificação UTF-8.
|
||||
g := 'Σ' // tipo rune, um alias para int32, que contém um código unicode
|
||||
|
||||
f := 3.14195 // float64, número de vírgula flutuante de 64bit (IEEE-754)
|
||||
f := 3.14159 // float64, número de vírgula flutuante de 64bit (IEEE-754)
|
||||
c := 3 + 4i // complex128, representado internamente com dois float64s
|
||||
|
||||
// Declaração de variáveis, com inicialização.
|
||||
@ -295,17 +295,17 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
## Leitura Recomendada
|
||||
|
||||
A principal fonte de informação é o [web site oficial Go](http://golang.org/).
|
||||
A principal fonte de informação é o [web site oficial Go](https://go.dev/).
|
||||
Lá é possível seguir o tutorial, experimentar de forma iterativa, e ler muito.
|
||||
|
||||
A própria especificação da linguagem é altamente recomendada. É fácil de ler e
|
||||
incrivelmente curta (em relação ao que é habitual hoje em dia).
|
||||
|
||||
Na lista de leitura para os aprendizes de Go deve constar o [código fonte da
|
||||
biblioteca padrão](http://golang.org/src/pkg/). Exaustivamente documentado, é
|
||||
biblioteca padrão](https://go.dev/src/). Exaustivamente documentado, é
|
||||
a melhor demonstração de código fácil de ler e de perceber, do estilo Go, e da
|
||||
sua escrita idiomática. Ou então clique no nome de uma função na [documentação]
|
||||
(http://golang.org/pkg/) e veja o código fonte aparecer!
|
||||
(https://go.dev/pkg/) e veja o código fonte aparecer!
|
||||
|
||||
Outra ótima fonte para aprender Go é o [Go by example](https://gobyexample.com/).
|
||||
Apesar de ser em inglês, é possível recodificar os exemplos para aprender sobre
|
||||
|
211
pt-br/pug-pt.html.markdown
Normal file
211
pt-br/pug-pt.html.markdown
Normal file
@ -0,0 +1,211 @@
|
||||
---
|
||||
language: Pug
|
||||
contributors:
|
||||
- ["Michael Warner", "https://github.com/MichaelJGW"]
|
||||
filename: index-pt.pug
|
||||
translators:
|
||||
- ["Adaías Magdiel", "https://adaiasmagdiel.com/"]
|
||||
lang: pt-br
|
||||
---
|
||||
|
||||
## Começando com Pug
|
||||
|
||||
Pug é uma pequena linguagem que compila para HTML. Possui uma sintaxe limpa
|
||||
com algumas funcionalidades adicionais, como declarações if e loops. Também pode ser utilizada
|
||||
como uma linguagem de templates no lado do servidor para tecnologias como o Node.js.
|
||||
|
||||
### The Language
|
||||
```pug
|
||||
|
||||
//- Comentário de uma linha
|
||||
|
||||
//- Comentário de
|
||||
várias linhas
|
||||
|
||||
//- ---TAGS---
|
||||
//- Básico
|
||||
div
|
||||
//- <div></div>
|
||||
h1
|
||||
//- <h1></h1>
|
||||
minha-propriaTag
|
||||
//- <minha-propriaTag></minha-propriaTag>
|
||||
|
||||
//- Tags irmãs
|
||||
div
|
||||
div
|
||||
//- <div></div>
|
||||
<div></div>
|
||||
|
||||
//- Tags aninhadas
|
||||
div
|
||||
div
|
||||
//- <div>
|
||||
<div></div>
|
||||
</div>
|
||||
|
||||
//- Textos
|
||||
h1 Olá, pessoas
|
||||
//- <h1>Olá, pessoas</h1>
|
||||
|
||||
//- Texto de várias linhas
|
||||
div.
|
||||
Oi,
|
||||
tudo bem?
|
||||
//- <div>
|
||||
Oi,
|
||||
tudo bem?
|
||||
</div>
|
||||
|
||||
//- ---ATRIBUTOS---
|
||||
div(class="minha-class" id="meu-id" meu-proprio-atributo="data" enabled)
|
||||
//- <div class="minha-class" id="meu-id" meu-proprio-atributo="data" enabled></div>
|
||||
|
||||
//- Abreviações
|
||||
span.minha-class
|
||||
//- <span class="minha-class"></span>
|
||||
.minha-class
|
||||
//- <div class="minha-class"></div>
|
||||
div#meu-id
|
||||
//- <div id="meu-id"></div>
|
||||
div#meu-id.minha-class
|
||||
//- <div class="minha-class" id="meu-id"></div>
|
||||
|
||||
|
||||
//- ---JAVASCRIPT---
|
||||
- const lang = "pug";
|
||||
|
||||
//- Javascript em várias linhas
|
||||
-
|
||||
const lang = "pug";
|
||||
const awesome = true;
|
||||
|
||||
//- Classes com Javascript
|
||||
- const myClass = ['class1', 'class2', 'class3']
|
||||
div(class=myClass)
|
||||
//- <div class="class1 class2 class3"></div>
|
||||
|
||||
//- Estilos com Javascript
|
||||
- const myStyles = {'color':'white', 'background-color':'blue'}
|
||||
div(styles=myStyles)
|
||||
//- <div styles="{"color":"white","background-color":"blue"}"></div>
|
||||
|
||||
//- Atributos com Javascript
|
||||
- const myAttributes = {"src": "photo.png", "alt": "My Photo"}
|
||||
img&attributes(myAttributes)
|
||||
//- <img src="photo.png" alt="My Photo">
|
||||
- let disabled = false
|
||||
input(type="text" disabled=disabled)
|
||||
//- <input type="text">
|
||||
- disabled = true
|
||||
input(type="text" disabled=disabled)
|
||||
//- <input type="text" disabled>
|
||||
|
||||
//- Templates com Javascript
|
||||
- const name = "Bob";
|
||||
h1 Olá, #{name}
|
||||
h1= name
|
||||
//- <h1>Olá, Bob</h1>
|
||||
//- <h1>Bob</h1>
|
||||
|
||||
//- ---LOOPS---
|
||||
|
||||
//- 'each' e 'for' tem a mesma função, aqui nós usaremos apenas 'each'.
|
||||
|
||||
each value, i in [1,2,3]
|
||||
p=value
|
||||
//-
|
||||
<p>1</p>
|
||||
<p>2</p>
|
||||
<p>3</p>
|
||||
|
||||
each value, index in [1,2,3]
|
||||
p=value + '-' + index
|
||||
//-
|
||||
<p>1-0</p>
|
||||
<p>2-1</p>
|
||||
<p>3-2</p>
|
||||
|
||||
each value in []
|
||||
p=value
|
||||
//-
|
||||
|
||||
each value in []
|
||||
p=value
|
||||
else
|
||||
p Sem valores
|
||||
|
||||
//- <p>Sem valores</p>
|
||||
|
||||
//- ---CONDICIONAIS---
|
||||
|
||||
- const number = 5
|
||||
if number < 5
|
||||
p o número é menor do que 5
|
||||
else if number > 5
|
||||
p o número é maior do que 5
|
||||
else
|
||||
p o número é 5
|
||||
//- <p>o número é 5</p>
|
||||
|
||||
- const orderStatus = "Aguardando";
|
||||
case orderStatus
|
||||
when "Aguardando"
|
||||
p.warn Seu pedido está em espera
|
||||
when "Completado"
|
||||
p.success Seu pedido foi completado.
|
||||
when -1
|
||||
p.error Ocorreu algum erro
|
||||
default
|
||||
p Nenhum registro de pedido encontrado
|
||||
//- <p class="warn">Seu pedido está em espera</p>
|
||||
|
||||
//- --INCLUINDO CONTEÚDOS--
|
||||
//- Caminho do arquivo -> "includes/nav.pug"
|
||||
h1 Indústrias ACME
|
||||
nav
|
||||
a(href="index.html") Início
|
||||
a(href="about.html") Sobre Nós
|
||||
|
||||
//- Caminho do arquivo -> "index.pug"
|
||||
html
|
||||
body
|
||||
include includes/nav.pug
|
||||
//-
|
||||
<html>
|
||||
<body>
|
||||
<h1>Indústrias ACME</h1>
|
||||
<nav><a href="index.html">Início</a><a href="about.html">Sobre Nós</a></nav>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
//- Importando Javascript e CSS
|
||||
script
|
||||
include scripts/index.js
|
||||
style
|
||||
include styles/theme.css
|
||||
|
||||
//- ---MIXIN---
|
||||
mixin basic
|
||||
div Olá
|
||||
+basic
|
||||
//- <div>Olá</div>
|
||||
|
||||
mixin comment(nome, comentario)
|
||||
div
|
||||
span.comment-name= nome
|
||||
div.comment-text= comentario
|
||||
+comment("Gil", "Tudo é divino, tudo é maravilhoso")
|
||||
//-
|
||||
<div>
|
||||
<span class="comment-name">Gil</span>
|
||||
<div class="comment-text">Tudo é divino, tudo é maravilhoso</div>
|
||||
</div>
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Saiba Mais
|
||||
- [Site Oficial](https://pugjs.org/)
|
||||
- [Documentação](https://pugjs.org/api/getting-started.html)
|
||||
- [Repositório no Github](https://github.com/pugjs/pug)
|
@ -4,6 +4,7 @@ filename: learnsass-pt.scss
|
||||
contributors:
|
||||
- ["Laura Kyle", "https://github.com/LauraNK"]
|
||||
- ["Sean Corrales", "https://github.com/droidenator"]
|
||||
- ["Thalles Augusto", "https://github.com/Theslladev"]
|
||||
translators:
|
||||
- ["Gabriel Gomes", "https://github.com/gabrielgomesferraz"]
|
||||
- ["Cássio Böck", "https://github.com/cassiobsilva"]
|
||||
@ -16,7 +17,7 @@ Sass (e outros pré-processadores, como [Less](http://lesscss.org/)) ajudam os d
|
||||
Sass tem duas opções de sintaxe diferentes para escolher. SCSS, que tem a mesma sintaxe de CSS, mas com os recursos adicionais de Sass. Ou Sass (a sintaxe original), que usa o recuo, em vez de chaves e ponto e vírgula.
|
||||
Este tutorial é escrito usando SCSS.
|
||||
|
||||
Se você já está familiarizado com CSS3, você será capaz de pegar Sass de forma relativamente rápida. Ele não fornece quaisquer novas opções de estilo, mas sim as ferramentas para escrever sua CSS de forma mais eficiente e fazer a manutenção mais fácilmente.
|
||||
Se você já está familiarizado com CSS3, você será capaz de pegar Sass de forma relativamente rápida. Ele não fornece quaisquer novas opções de estilo, mas sim as ferramentas para escrever sua CSS de forma mais eficiente e fazer a manutenção mais facilmente.
|
||||
|
||||
```scss
|
||||
|
||||
@ -249,7 +250,7 @@ ul {
|
||||
/* '&' será substituído pelo selector pai (parent). */
|
||||
/* Você também pode aninhar pseudo-classes. */
|
||||
/* Tenha em mente que o excesso de nidificação vai fazer seu código menos sustentável.
|
||||
Essas práticas também recomendam não vai mais de 3 níveis de profundidade quando nidificação.
|
||||
Essas práticas também recomendam não mais de 3 níveis de profundidade quando nidificação.
|
||||
Por exemplo: */
|
||||
|
||||
|
||||
@ -379,7 +380,7 @@ body {
|
||||
|
||||
/* Sass fornece os seguintes operadores: +, -, *, /, e %. estes podem
|
||||
ser úteis para calcular os valores diretamente no seu arquivos Sass em vez
|
||||
de usar valores que você já calculados manualmente. O exemplo abaixo é
|
||||
de usar valores que você já calcula manualmente. O exemplo abaixo é
|
||||
de um projeto simples de duas colunas. */
|
||||
|
||||
$content-area: 960px;
|
||||
|
129
pt-br/set-theory-pt.html.markdown
Normal file
129
pt-br/set-theory-pt.html.markdown
Normal file
@ -0,0 +1,129 @@
|
||||
---
|
||||
category: Algorithms & Data Structures
|
||||
name: Set theory
|
||||
lang: pt-br
|
||||
contributors:
|
||||
- ["Andrew Ryan Davis", "https://github.com/AndrewDavis1191"]
|
||||
translators:
|
||||
- ["Bárbara Luz", "https://github.com/barbluz"]
|
||||
---
|
||||
|
||||
Teoria de conjuntos é uma área da matemática que estuda conjuntos, suas operações e propriedades.
|
||||
- Um conjunto é uma coleção de itens disjuntos.
|
||||
|
||||
## Símbolos básicos
|
||||
|
||||
### Operações
|
||||
- a operação de união `∪`, significa "ou"
|
||||
- a operação de interseção `∩`, que significa "e"
|
||||
- a operação de exclusão `\`, significa "sem" ou "menos"
|
||||
- a operação de conjunto complementar `'`, que significa "o inverso de"
|
||||
- a operação de produto cartesiano `×`,que significa "o produto cartesiano de"
|
||||
|
||||
### Outros símbolos
|
||||
- `:` ou `|`, símbolos que significam "tal que"
|
||||
- o símbolo de pertencimento `∈`, que significa "pertence a"
|
||||
- o símbolo `⊆`, que significa "subconjunto de" (neste caso, o subconjunto pode ser igual ao conjunto)
|
||||
- o símbolo `⊂`, que significa "subconjunto próprio" (neste caso, o subconjunto não pode ser igual ao conjunto)
|
||||
|
||||
### Conjuntos canônicos
|
||||
- `∅`, o conjunto vazio, isto é, o conjunto que não possui itens
|
||||
- `ℕ`, o conjunto de todos os números naturais
|
||||
- `ℤ`, o conjunto de todos os números inteiros
|
||||
- `ℚ`, o conjunto de todos os números racionais
|
||||
- `ℝ`, o conjunto de todos os números reais
|
||||
|
||||
Existem algumas ressalvas sobre os conjuntos canônicos:
|
||||
- Apesar de o conjunto vazio não conter itens, o conjunto vazio é subconjunto de si mesmo (e portanto de todos os outros conjuntos)
|
||||
- Matemáticos geralmente não concordam sobre o zero ser um número natural e os livros tipicamente explicitam se o autor considera ou não o zero como um número natural
|
||||
|
||||
|
||||
### Cardinalidade
|
||||
A cardinalidade (ou tamanho) de um conjunto é determinado pela quantidade de itens no conjunto. O operador de cardinalidade é `|...|`
|
||||
|
||||
Por exemplo, se `S = {1, 2, 4}`, então `|S| = 3`.
|
||||
|
||||
### O Conjunto Vazio
|
||||
- o conjunto vazio pode ser contruído em notação de conjuntos utilizando condições impossíveis, como por exemplo: `∅ = { x : x ≠ x }`, ou `∅ = { x : x ∈ N, x < 0 }`
|
||||
- o conjunto vazio é sempre único (ou seja, existe um e apenas um conjunto vazio)
|
||||
- o conjunto vazio é subconjunto de todos os conjuntos
|
||||
- a cardinalidade do conjunto vazio é `0`, ou seja, `|∅| = 0`.
|
||||
|
||||
## Representando conjuntos
|
||||
|
||||
### Definição Literal
|
||||
Um conjunto pode ser contruído literalmente fornecendo uma lista completa dos itens contigos no conjunto. Por exemplo `S = { a, b, c, d }`
|
||||
|
||||
Listas longas podem ser encurtadas com reticências, desde que o contexto seja claro. Por exemplo, `E = { 2, 4, 6, 8, ... }` é claramente o conjunto de todos os números pares, contendo um número infinito de objetos, embora só tenhamos escrito explicitamente quatro deles.
|
||||
|
||||
### Definição por compreensão
|
||||
Conjuntos também podem ser descritos de uma maneira mais descritiva, baseando-se em sujeito e predicado, de forma tal que `S = {sujeito : predicado}`. Por exemplo:
|
||||
|
||||
```
|
||||
A = { x : x é uma vogal } = { a, e, i, o, u } (lê-se x, tal que x é uma vogal)
|
||||
B = { x : x ∈ N, x < 10 } = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
|
||||
C = { x : x = 2k, k ∈ N } = { 0, 2, 4, 6, 8, ... }
|
||||
```
|
||||
|
||||
Ou pode-se também aplicar uma função ao sujeito, ex:
|
||||
```
|
||||
D = { 2x : x ∈ N } = { 0, 2, 4, 6, 8, ... }
|
||||
```
|
||||
|
||||
## Relações
|
||||
|
||||
### Pertencimento
|
||||
- Se um valor `a` está contido num conjunto `A`, então dizemos que `a` pertence a `A` e denotamos por `a ∈ A`
|
||||
- Se o valor `a` não está contido no conjunto `A`, então dizemos que `a` não pertence a `A` e denotamos por `a ∉ A`
|
||||
|
||||
### Igualdade
|
||||
- Se dois conjuntos contém os mesmos itens, então dizemos que os conjuntos são iguals, ex. `A = B`
|
||||
- A ordenação não importa quando vamos avaliar a igualdade, ex: `{ 1, 2, 3, 4 } = { 2, 3, 1, 4 }`
|
||||
- Conjuntos são disjuntos, o que significa que os elementos não podem ser repetidos, ex: `{ 1, 2, 2, 3, 4, 3, 4, 2 } = { 1, 2, 3, 4 }`
|
||||
- Dois conjuntos `A` e `B` são iguais se, e somente se, `A ⊆ B` e `B ⊆ A`
|
||||
|
||||
### Conjuntos especiais
|
||||
O Conjunto das Partes
|
||||
- Seja `A` um conjunto qualquer. O conjunto que contém todos os possíveis subconjuntos de `A` é chamado "conjunto das partes" e é denotado como `P(A)`. Se o conjunto `A` contém `n` elementos, então o conjunto das partes conterá `2^n` elementos.
|
||||
```
|
||||
P(A) = { x : x ⊆ A }
|
||||
```
|
||||
|
||||
## Operações entre dois conjuntos
|
||||
|
||||
### União
|
||||
Dados dois conjuntos `A` e `B`, a união entre esses dois conjuntos são os itens que aparecem em `A` ou em `B`, denotado por `A ∪ B`.
|
||||
|
||||
```
|
||||
A ∪ B = { x : x ∈ A ∪ x ∈ B }
|
||||
```
|
||||
|
||||
### Interseção
|
||||
Dados dois conjuntos `A` e `B`, a interseção entre esses dois conjuntos são os itens que aparecem em `A` e em `B`, denotado por `A ∩ B`.
|
||||
|
||||
```
|
||||
A ∩ B = { x : x ∈ A, x ∈ B }
|
||||
```
|
||||
|
||||
### Diferença
|
||||
Dados dois conjuntos `A` e `B`, o conjunto da diferença entre `A` e `B` são todos os itens de `A` que não pertencem a `B`.
|
||||
```
|
||||
A \ B = { x : x ∈ A, x ∉ B }
|
||||
```
|
||||
|
||||
### Diferença simétrica
|
||||
Dados dois conjuntos `A` e `B`, a diferença simétrica são todos os itens entre `A` e `B` que não aparecem na interseção desses dois conjuntos.
|
||||
|
||||
```
|
||||
A △ B = { x : ((x ∈ A) ∩ (x ∉ B)) ∪ ((x ∈ B) ∩ (x ∉ A)) }
|
||||
|
||||
A △ B = (A \ B) ∪ (B \ A)
|
||||
```
|
||||
|
||||
### Produto Cartesiano
|
||||
Dados dois conjuntos `A` e `B`, o produto cartesiano de `A` e `B` consiste no conjunto contendo todas as combinações dos itens de `A` e `B`.
|
||||
```
|
||||
A × B = { (x, y) | x ∈ A, y ∈ B }
|
||||
```
|
||||
|
||||
|
232
pt-br/toml-pt.html.markdown
Normal file
232
pt-br/toml-pt.html.markdown
Normal file
@ -0,0 +1,232 @@
|
||||
---
|
||||
language: toml
|
||||
filename: learntoml-pt.toml
|
||||
contributors:
|
||||
- ["Alois de Gouvello", "https://github.com/aloisdg"]
|
||||
translators:
|
||||
- ["Adaías Magdiel", "https://adaiasmagdiel.com/"]
|
||||
lang: pt-br
|
||||
---
|
||||
|
||||
TOML significa Tom's Obvious, Minimal Language. É uma linguagem de serialização de dados projetada para ser um formato de arquivo de configuração mínimo que é fácil de ler devido à semântica óbvia.
|
||||
|
||||
É uma alternativa ao YAML e JSON. Tem como objetivo ser mais amigável para humanos do que JSON e mais simples que YAML. TOML é projetado para mapear de forma inequívoca para uma tabela de hash e deve ser fácil de converter em estruturas de dados em uma ampla variedade de linguagens.
|
||||
|
||||
Cuidado, a especificação do TOML ainda passa por muitas mudanças. Até que seja marcado como 1.0, você deve assumir que é instável e agir de acordo. Este documento segue o TOML v0.4.0.
|
||||
|
||||
```toml
|
||||
# Comentários em TOML são feitos desta forma.
|
||||
|
||||
###################
|
||||
# TIPOS ESCALARES #
|
||||
###################
|
||||
|
||||
# Nosso objeto raiz (que continuará por todo o documento) será um mapa,
|
||||
# que é equivalente a um dicionário, hash ou objeto em outras linguagens.
|
||||
|
||||
# A chave, o sinal de igual e o valor precisam estar na mesma linha
|
||||
# (embora alguns valores possam ser quebrados em várias linhas).
|
||||
chave = "valor"
|
||||
string = "Olá"
|
||||
number = 42
|
||||
float = 3.14
|
||||
boolean = true
|
||||
dateTime = 2002-07-16T20:32:00-03:00
|
||||
scientificNotation = 1e+12
|
||||
"chaves podem estar entre aspas" = true # Tanto " quanto ' são aceitáveis
|
||||
"chaves podem conter" = "letras, números, underscores e hífens"
|
||||
|
||||
# Uma chave não pode ser vazia, mas uma chave vazia entre aspas é permitido
|
||||
"" = "blank" # VÁLIDO mas não é recomendado
|
||||
'' = 'blank' # VÁLIDO mas não é recomendado
|
||||
|
||||
##########
|
||||
# String #
|
||||
##########
|
||||
|
||||
# Todas as strings precisam ter apenas caracteres UTF-8 válidos.
|
||||
# Podemos escapar caracteres e alguns deles têm uma sequência de escape compacta.
|
||||
# Por exemplo: \t adiciona uma tabulação. Leia a spec para conhecer todos.
|
||||
basicString = "São cercadas por aspas. \"Sou digno de citação\". Nome\tJosé."
|
||||
|
||||
multiLineString = """
|
||||
são cercadas por três aspas
|
||||
em cada lado e permitem novas linhas."""
|
||||
|
||||
literalString = 'são cercadas por aspas simples. Escape de caracteres não é permitido.'
|
||||
|
||||
multiLineString = '''
|
||||
são cercadas por três aspas simples em cada lado
|
||||
e permitem novas linhas. Escape de caracteres também não é permitido.
|
||||
A primeira quebra de linha é removida em strings brutas
|
||||
Todo outro espaço em branco
|
||||
é preservado. #! foi preservado?
|
||||
'''
|
||||
|
||||
# Para dados binários é recomendado que você use Base64, outra codificação ASCII ou UTF8.
|
||||
# A manipulação dessa codificação será específico da aplicação.
|
||||
|
||||
############
|
||||
# Inteiros #
|
||||
############
|
||||
|
||||
## Inteiros podem começar com um +, um -, ou nada.
|
||||
## Zeros à frente não são permitidos.
|
||||
## Formatos em hexadecimal, octal e binário são permitidos.
|
||||
## Não são permitidos valores que não podem ser expressados como uma série de dígitos.
|
||||
int1 = +42
|
||||
int2 = 0
|
||||
int3 = -21
|
||||
int4 = 0xcafebabe
|
||||
int5 = 0o755
|
||||
int6 = 0b11011100
|
||||
integerRange = 64
|
||||
|
||||
## Você pode usar underscores para melhorar a legibilidade.
|
||||
## Cada underscore precisa estar entre, pelo menos, um dígito.
|
||||
int7 = 5_349_221
|
||||
int8 = 1_2_3_4_5 # VÁLIDO, mas não é recomendado
|
||||
|
||||
#########
|
||||
# Float #
|
||||
#########
|
||||
|
||||
# Floats são inteiros seguidos por uma fração e/ou de um expoente.
|
||||
flt1 = 3.1415
|
||||
flt2 = -5e6
|
||||
flt3 = 6.626E-34
|
||||
|
||||
#############
|
||||
# Booleanos #
|
||||
#############
|
||||
|
||||
bool1 = true
|
||||
bool2 = false
|
||||
booleanosPrecisamEstarEmMinusculo = true
|
||||
|
||||
############
|
||||
# Datetime #
|
||||
############
|
||||
|
||||
date1 = 1979-05-27T07:32:00Z # Tempo UTC, seguindo especificação RFC 3339/ISO 8601
|
||||
date2 = 1979-05-26T15:32:00+08:00 # com um deslocamento segundo a RFC 3339/ISO 8601
|
||||
date3 = 1979-05-27T07:32:00 # sem deslocamento
|
||||
date4 = 1979-05-27 # sem as horas e sem deslocamento
|
||||
|
||||
####################
|
||||
# TIPOS DE COLEÇÃO #
|
||||
####################
|
||||
|
||||
#########
|
||||
# Array #
|
||||
#########
|
||||
|
||||
array1 = [ 1, 2, 3 ]
|
||||
array2 = [ "Vírgulas", "são", "delimitadores" ]
|
||||
array3 = [ "Não misture", "tipos", "diferentes" ]
|
||||
array4 = [ [ 1.2, 2.4 ], ["todas as", 'strings', """são do mesmo""", '''tipo'''] ]
|
||||
array5 = [
|
||||
"Espaços em branco", "são", "ignorados"
|
||||
]
|
||||
|
||||
##########
|
||||
# Tabela #
|
||||
##########
|
||||
|
||||
# Tabelas (ou tabelas de hash, ou dicionários) é uma coleção de pares chave/valor.
|
||||
# Eles aparecem entre colchetes em uma linha separada.
|
||||
# Tabelas vazias são permitidas e simplesmente não possuem chave/valor associado.
|
||||
[tabela]
|
||||
|
||||
# Abaixo disso, e até a próxima tabela ou final do arquivo, estão as chaves/valores dessa tabela.
|
||||
# Os pares de chave/valor dentro das tabelas não têm garantia de estar em nenhuma ordem específica.
|
||||
[table-1]
|
||||
chave1 = "algum texto"
|
||||
chave2 = 123
|
||||
|
||||
[table-2]
|
||||
chave1 = "outro texto"
|
||||
chave2 = 456
|
||||
|
||||
# Pontos são proibidos em chaves simples porque são usados para indicar tabelas aninhadas.
|
||||
# As regras de nomenclatura para cada parte separada por ponto são as mesmas que para chaves.
|
||||
[dog."tater.man"]
|
||||
type = "pug"
|
||||
|
||||
# Na terra do JSON, você teria a seguinte estrutura:
|
||||
# { "dog": { "tater.man": { "type": "pug" } } }
|
||||
|
||||
# Espaços em branco em torno das partes separadas por pontos são ignorados, de qualquer forma,
|
||||
# é sempre recomendado não utilizar espaços em branco desnecessários.
|
||||
[a.b.c] # isso é o recomendado
|
||||
[ d.e.f ] # mesmo que [d.e.f]
|
||||
[ j . "ʞ" . 'l' ] # mesmo que [j."ʞ".'l']
|
||||
|
||||
# Você não precisa especificar todas as super-tabelas se não quiser. TOML sabe
|
||||
# como lidar com isso para você.
|
||||
# [x] você
|
||||
# [x.y] não precisa
|
||||
# [x.y.z] disso
|
||||
[x.y.z.w] # para isso funcionar
|
||||
|
||||
# Mesmo que uma super-tabela não tenha sido definida diretamente e não tenha definido uma
|
||||
# chave específica, ainda é possível escrever nela.
|
||||
[a.b]
|
||||
c = 1
|
||||
|
||||
[a]
|
||||
d = 2
|
||||
|
||||
# Irá gerar o seguinte JSON:
|
||||
# { "a": {"b": {"c": 1}, "d": 2 } }
|
||||
|
||||
# Você não pode definir uma chave ou tabela mais de uma vez. É inválido fazer isso.
|
||||
|
||||
# NÃO FAÇA ISSO
|
||||
[a]
|
||||
b = 1
|
||||
|
||||
[a]
|
||||
c = 2
|
||||
|
||||
# NEM MESMO ISSO
|
||||
[a]
|
||||
b = 1
|
||||
|
||||
[a.b]
|
||||
c = 2
|
||||
|
||||
# O nome de todas as tabelas não pode ser vazio.
|
||||
[] # INVÁLIDO
|
||||
[a.] # INVÁLIDO
|
||||
[a..b] # INVÁLIDO
|
||||
[.b] # INVÁLIDO
|
||||
[.] # INVÁLIDO
|
||||
|
||||
####################
|
||||
# Tabelas em linha #
|
||||
####################
|
||||
|
||||
tabelasEmLinha = { sãoFechadasCom = "{ e }", precisamEstarEmUmaLinha = true }
|
||||
ponto = { x = 1, y = 2 }
|
||||
|
||||
####################
|
||||
# Array de Tabelas #
|
||||
####################
|
||||
|
||||
# Um array de tabelas pode ser expresso usando um nome de tabela entre colchetes duplos.
|
||||
# Cada tabela com o mesmo nome entre colchetes duplos será um item no array.
|
||||
# As tabelas são inseridas na ordem em que são encontradas.
|
||||
|
||||
[[produtos]]
|
||||
nome = "array de tabelas"
|
||||
sku = 738594937
|
||||
tabelasVaziasSaoPermitidas = true
|
||||
|
||||
[[produtos]]
|
||||
|
||||
[[produtos]]
|
||||
nome = "Unhas"
|
||||
sku = 284758393
|
||||
color = "cinza"
|
||||
```
|
@ -28,12 +28,12 @@ module Module1
|
||||
Console.WriteLine ("2. Entrada Olá Mundo" )
|
||||
Console.WriteLine ("3. Cálculando números inteiros " )
|
||||
Console.WriteLine ("4. Calculando números decimais " )
|
||||
Console.WriteLine ("5 . Calculadora de Trabalho " )
|
||||
Console.WriteLine ("5. Calculadora de Trabalho " )
|
||||
Console.WriteLine ("6. Usando Do While Loops " )
|
||||
Console.WriteLine ("7. Usando Para While Loops " )
|
||||
Console.WriteLine ("8 . Declarações condicionais " )
|
||||
Console.WriteLine ("8. Declarações condicionais " )
|
||||
Console.WriteLine ("9. Selecione uma bebida" )
|
||||
Console.WriteLine ("50 . About" )
|
||||
Console.WriteLine ("50. About" )
|
||||
Console.WriteLine ("Por favor, escolha um número da lista acima " )
|
||||
Seleção Dim As String = Console.ReadLine
|
||||
Select A seleção dos casos
|
||||
@ -76,7 +76,7 @@ module Module1
|
||||
End Sub
|
||||
|
||||
' Um - Eu estou usando números para ajudar com a navegação acima quando eu voltar
|
||||
' depois de construí-lo .
|
||||
' depois de construí-lo.
|
||||
|
||||
" Nós usamos subs privadas para separar diferentes seções do programa.
|
||||
Private Sub HelloWorldOutput ()
|
||||
@ -94,12 +94,12 @@ module Module1
|
||||
Console.Title = " Olá Mundo YourName | Saiba X em Y Minutes"
|
||||
' Variáveis
|
||||
'Os dados inseridos por um usuário precisam ser armazenados.
|
||||
' As variáveis também começar com um Dim e terminar com um Como VariableType .
|
||||
' As variáveis também começar com um Dim e terminar com um Como VariableType.
|
||||
|
||||
' Neste tutorial, nós queremos saber qual é o seu nome, e faça o programa
|
||||
' Responder ao que é dito.
|
||||
Nome de usuário Dim As String
|
||||
" Nós usamos string como string é uma variável de texto baseado .
|
||||
" Nós usamos string como string é uma variável de texto baseado.
|
||||
Console.WriteLine (" Olá, Qual é o seu nome? ") ' Peça ao usuário seu nome.
|
||||
username = Console.ReadLine () ' armazena o nome do usuário.
|
||||
Console.WriteLine (" Olá " + username) ' A saída é "Olá < seu nome >".
|
||||
@ -124,10 +124,10 @@ module Module1
|
||||
'Quatro
|
||||
Sub CalculatingDecimalNumbers particulares ()
|
||||
Console.Title = " Calculando com duplo | Saiba X em Y Minutes"
|
||||
' Claro que gostaria de ser capaz de somar decimais .
|
||||
' Claro que gostaria de ser capaz de somar decimais.
|
||||
" Por isso, poderia mudar o acima de Integer para Double.
|
||||
|
||||
" Digite um número inteiro , 1,2 , 2,4 , 50,1 , 104,9 ect
|
||||
" Digite um número inteiro como 1, 2, 50, 104, etc
|
||||
Console.Write ("Primeiro número:")
|
||||
Dim a As Double = Console.ReadLine
|
||||
Console.Write ("Segundo número:") 'Enter segundo número inteiro.
|
||||
@ -141,9 +141,9 @@ module Module1
|
||||
' Cinco
|
||||
Private Sub WorkingCalculator ()
|
||||
Console.Title = " A Calculadora de Trabalho | Saiba X em Y Minutes"
|
||||
" No entanto, se você gostaria que a calculadora para subtrair, dividir , múltiplos e
|
||||
" No entanto, se você gostaria que a calculadora para subtrair, dividir, múltiplos e
|
||||
' somar.
|
||||
' Copie e cole o código acima novamente .
|
||||
' Copie e cole o código acima novamente.
|
||||
Console.Write ("Primeiro número:")
|
||||
Dim a As Double = Console.ReadLine
|
||||
Console.Write ("Segundo número:") 'Enter segundo número inteiro.
|
||||
@ -153,7 +153,7 @@ module Module1
|
||||
Dim e As Integer = a - b
|
||||
Dim f As Integer = a / b
|
||||
|
||||
" Ao adicionar as linhas abaixo , somos capazes de calcular a subtração ,
|
||||
" Ao adicionar as linhas abaixo, somos capazes de calcular a subtração,
|
||||
' multply bem como dividir os valores de a e b
|
||||
Console.Gravar ( a.ToString ( ) + " + " + b.ToString ( ) )
|
||||
'Queremos pad as respostas para a esquerda por três espaços.
|
||||
@ -172,8 +172,8 @@ module Module1
|
||||
Sub UsingDoWhileLoops particulares ()
|
||||
' Assim como o sub privado anterior
|
||||
' Desta vez, perguntar se o usuário deseja continuar ( Sim ou Não ? )
|
||||
' Estamos usando Do While Loop , como não temos certeza se o usuário quer usar o
|
||||
'programa mais de uma vez .
|
||||
' Estamos usando Do While Loop, como não temos certeza se o usuário quer usar o
|
||||
'programa mais de uma vez.
|
||||
Console.Title = " UsingDoWhileLoops | Saiba X em Y Minutes"
|
||||
Dim resposta As String ' Nós usamos a variável " String" como a resposta é um texto
|
||||
Do ' Começamos o programa com
|
||||
@ -195,12 +195,12 @@ module Module1
|
||||
Console.Write ( a.ToString () + "/" + b.ToString ())
|
||||
Console.WriteLine (" =" + e.ToString.PadLeft (3) )
|
||||
Console.ReadLine ()
|
||||
' Faça a pergunta , se o usuário deseja continuar? Infelizmente,
|
||||
' Faça a pergunta, se o usuário deseja continuar? Infelizmente,
|
||||
"é sensível a maiúsculas.
|
||||
Console.Write ( "Deseja continuar? (Sim / não )")
|
||||
" O programa pega a variável e imprime e começa de novo.
|
||||
answer = Console.ReadLine
|
||||
" O comando para a variável para trabalhar seria , neste caso, " sim "
|
||||
" O comando para a variável para trabalhar seria, neste caso, " sim "
|
||||
Loop While resposta = "yes"
|
||||
|
||||
End Sub
|
||||
@ -233,7 +233,7 @@ module Module1
|
||||
outro
|
||||
Console.WriteLine (" Olá " + nome do usuário)
|
||||
Console.WriteLine (" Você check-out www.learnxinyminutes.com " )
|
||||
Console.ReadLine () ' Fins e imprime a declaração acima .
|
||||
Console.ReadLine () ' Fins e imprime a declaração acima.
|
||||
End If
|
||||
End Sub
|
||||
|
||||
@ -242,15 +242,15 @@ module Module1
|
||||
Console.Title = "Se Declaração / Else | Saiba X em Y Minutes"
|
||||
'Às vezes é importante ter em conta mais de duas alternativas.
|
||||
'Às vezes, há um bom número de outros.
|
||||
'Quando este for o caso , mais do que uma if seria necessária .
|
||||
'Uma instrução if é ótimo para máquinas de venda automática . Quando o usuário digita um código.
|
||||
' A1 , A2, A3 , ect para selecionar um item.
|
||||
'Quando este for o caso, mais do que uma if seria necessária.
|
||||
'Uma instrução if é ótimo para máquinas de venda automática. Quando o usuário digita um código.
|
||||
' A1, A2, A3, etc para selecionar um item.
|
||||
'Todas as opções podem ser combinadas em uma única if.
|
||||
|
||||
Seleção Dim Valor String = Console.ReadLine ' para a seleção
|
||||
Console.WriteLine (" A1. Para Soda " )
|
||||
Console.WriteLine (" A2. Para Fanta " )
|
||||
Console.WriteLine (" A3 . Para Guaraná" )
|
||||
Console.WriteLine (" A3. Para Guaraná" )
|
||||
Console.WriteLine (" A4. Para Coca Diet" )
|
||||
Console.ReadLine ()
|
||||
Se a seleção = "A1" Então
|
||||
|
@ -74,7 +74,8 @@ um_mapa_aninhado:
|
||||
# Mapas não tem que ter chaves com string.
|
||||
0.25: uma chave com valor flutuante
|
||||
|
||||
# As chaves podem ser também objetos multi linhas, utilizando ? para indicar o começo de uma chave.
|
||||
# As chaves podem ser complexas, como sequência de várias linhas
|
||||
# Utilizando ? seguido por espaço para indicar o começo de uma chave complexa.
|
||||
? |
|
||||
Esta é uma chave
|
||||
que tem várias linhas
|
||||
@ -91,13 +92,13 @@ um_mapa_aninhado:
|
||||
uma_sequencia:
|
||||
- Item 1
|
||||
- Item 2
|
||||
- 0.5 # sequencias podem conter tipos diferentes.
|
||||
- 0.5 # sequências podem conter tipos diferentes.
|
||||
- Item 4
|
||||
- chave: valor
|
||||
outra_chave: outro_valor
|
||||
-
|
||||
- Esta é uma sequencia
|
||||
- dentro de outra sequencia
|
||||
- Esta é uma sequência
|
||||
- dentro de outra sequência
|
||||
- - - Indicadores de sequência aninhadas
|
||||
- podem ser recolhidas
|
||||
|
||||
@ -170,7 +171,7 @@ conjunto:
|
||||
? item3
|
||||
ou: {item1, item2, item3}
|
||||
|
||||
# Como Python, são apenas conjuntos de mapas com valors nulos; o acima é equivalente a:
|
||||
# Como Python, são apenas conjuntos de mapas com valores nulos; o acima é equivalente a:
|
||||
conjunto2:
|
||||
item1: null
|
||||
item2: null
|
||||
|
473
pt-pt/kotlin-pt.html.markdown
Normal file
473
pt-pt/kotlin-pt.html.markdown
Normal file
@ -0,0 +1,473 @@
|
||||
---
|
||||
language: kotlin
|
||||
filename: LearnKotlin-pt.kt
|
||||
lang: pt-pt
|
||||
contributors:
|
||||
- ["S Webber", "https://github.com/s-webber"]
|
||||
translators:
|
||||
- ["André Martins", "https://github.com/chriptus13"]
|
||||
---
|
||||
|
||||
Kotlin é uma linguagem de programação de tipificação estática para a JVM, Android e browser. Ela é 100% interoperável com Java.
|
||||
[Lê mais aqui.](https://kotlinlang.org/)
|
||||
|
||||
```kotlin
|
||||
// Comentários de linha começam com //
|
||||
/*
|
||||
Comentários de múltiplas linhas são assim.
|
||||
*/
|
||||
|
||||
// A palavra-chave "package" funciona da mesma forma que em Java.
|
||||
package com.learnxinyminutes.kotlin
|
||||
|
||||
/*
|
||||
O ponto de entrada de um programa em Kotlin é a função chamada "main".
|
||||
Esta função tem como único parâmetro um array contendo todos os argumentos passados na linha de comandos.
|
||||
Desde a versão 1.3 que esta pode também ser definida sem parâmetros.
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
/*
|
||||
A declaração de variáveis é feita usando "var" ou "val".
|
||||
Variáveis declaradas com "val" não podem ser redefinidas, já as declaradas com "var" podem.
|
||||
*/
|
||||
val fooVal = 10 // não podemos redefinir mais tarde o valor de fooVal para algo diferente
|
||||
var fooVar = 10
|
||||
fooVar = 20 // fooVar pode ser redefinida
|
||||
|
||||
/*
|
||||
Na maioria dos casos, o Kotlin pode determinar (inferir) o tipo de uma variável,
|
||||
assim não precisamos de o dizer explicitamente sempre.
|
||||
Para especificar o tipo explicitamente fazemos assim:
|
||||
*/
|
||||
val foo: Int = 7
|
||||
|
||||
/*
|
||||
As Strings são representadas de uma forma semelhante ao Java.
|
||||
O escape é feito com barras invertidas.
|
||||
*/
|
||||
val fooString = "A minha String está aqui!"
|
||||
val barString = "Imprimir numa nova linha?\nSem problemas!"
|
||||
val bazString = "Adicionar um tab?\tSem problemas!"
|
||||
println(fooString)
|
||||
println(barString)
|
||||
println(bazString)
|
||||
|
||||
/*
|
||||
Uma raw string é delimitada por aspas triplas (""").
|
||||
Raw strings podem conter caracteres de nova linha ou qualquer outro.
|
||||
*/
|
||||
val fooRawString = """
|
||||
fun helloWorld(val name : String) {
|
||||
println("Hello, world!")
|
||||
}
|
||||
"""
|
||||
println(fooRawString)
|
||||
|
||||
/*
|
||||
As strings podem também conter template expressions.
|
||||
Uma template expression começa com o símbolo do dollar ($).
|
||||
*/
|
||||
val fooTemplateString = "$fooString tem ${fooString.length} caracteres"
|
||||
println(fooTemplateString) // => A minha String está aqui! tem 25 caracteres
|
||||
|
||||
/*
|
||||
Para que uma variável possa ter o valor de null esta tem de ser
|
||||
especificada explicitamente como nullable.
|
||||
Uma variável pode ser marcada como nullable adicionando um ? ao seu tipo.
|
||||
A variable can be specified as nullable by appending a ? to its type.
|
||||
Usando o operador ?. podemos facilmente aceder a propriedades de
|
||||
uma variável nullable, se esta for null o resultado da expressão será também ele null.
|
||||
Podemos também usar o operador ?: para especificar um valor alternativo
|
||||
no caso da variavél ser null.
|
||||
*/
|
||||
var fooNullable: String? = "abc"
|
||||
println(fooNullable?.length) // => 3
|
||||
println(fooNullable?.length ?: -1) // => 3
|
||||
fooNullable = null
|
||||
println(fooNullable?.length) // => null
|
||||
println(fooNullable?.length ?: -1) // => -1
|
||||
|
||||
/*
|
||||
As funções são declaradas usando a palavra-chave "fun".
|
||||
Os parâmetros da função são especificados entre parênteses a seguir ao nome da função.
|
||||
Estes parâmetros podem opcionalmente ter um valor por omissão.
|
||||
O tipo de retorno da função, se necessário, é especificado após os parâmetros.
|
||||
*/
|
||||
fun hello(name: String = "world"): String {
|
||||
return "Hello, $name!"
|
||||
}
|
||||
println(hello("foo")) // => Hello, foo!
|
||||
println(hello(name = "bar")) // => Hello, bar!
|
||||
println(hello()) // => Hello, world!
|
||||
|
||||
/*
|
||||
Para que uma função receba um número variável de parâmetros podemos
|
||||
marcar um, e apenas um, parâmetro com a palavra-chave "vararg".
|
||||
*/
|
||||
fun varargExample(vararg names: Int) {
|
||||
println("Argument has ${names.size} elements")
|
||||
}
|
||||
varargExample() // => A chamada à função tem 0 argumentos
|
||||
varargExample(1) // => A chamada à função tem 1 argumentos
|
||||
varargExample(1, 2, 3) // => A chamada à função tem 3 argumentos
|
||||
|
||||
/*
|
||||
Quando uma função consiste em apenas uma expressão as chavetas podem ser omitidas
|
||||
O corpo da mesma é especificado após o símbolo de igual (=).
|
||||
*/
|
||||
fun odd(x: Int): Boolean = x % 2 == 1
|
||||
println(odd(6)) // => false
|
||||
println(odd(7)) // => true
|
||||
|
||||
// Se o tipo de retorno da função pode ser inferido então não é necessário especificá-lo.
|
||||
fun even(x: Int) = x % 2 == 0
|
||||
println(even(6)) // => true
|
||||
println(even(7)) // => false
|
||||
|
||||
// As funções podem ter outras funções como parâmetros e/ou como retorno.
|
||||
fun not(f: (Int) -> Boolean): (Int) -> Boolean {
|
||||
return {n -> !f.invoke(n)}
|
||||
}
|
||||
// O operador :: pode ser usado para referênciar funções existentes.
|
||||
val notOdd = not(::odd)
|
||||
val notEven = not(::even)
|
||||
/*
|
||||
Expressões lambda podem ser usadas da seguinte forma.
|
||||
Os lambdas quando passados a outras funções podem estar
|
||||
fora dos parênteses da chamada, caso sejam o último parâmetro.
|
||||
*/
|
||||
val notZero = not {n -> n == 0}
|
||||
/*
|
||||
Se o lambda apenas tiver um parâmetro então a sua
|
||||
declaração pode ser omitida (em conjunto com "->").
|
||||
O nome por omissão do parâmetro será "it".
|
||||
*/
|
||||
val notPositive = not {it > 0}
|
||||
for (i in 0..4) {
|
||||
println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}")
|
||||
}
|
||||
|
||||
// Para declararmos classes usa-se a palavra-chave "class".
|
||||
class ExampleClass(val x: Int) {
|
||||
fun aMethod(y: Int): Int {
|
||||
return x + y
|
||||
}
|
||||
|
||||
infix fun infixMemberFunction(y: Int): Int {
|
||||
return x * y
|
||||
}
|
||||
}
|
||||
/*
|
||||
Para se instanciar uma classe usamos o constructor.
|
||||
De notar que em Kotlin não existe a palavra-chave "new" como no Java.
|
||||
*/
|
||||
val fooExampleClass = ExampleClass(7)
|
||||
// Os métodos da classe podem então ser chamados usando o ponto.
|
||||
println(fooExampleClass.aMethod(4)) // => 11
|
||||
/*
|
||||
Uma função marcada com a palavra-chave "infix" pode ser chamada
|
||||
usando a notação infixa.
|
||||
*/
|
||||
println(fooExampleClass infixMemberFunction 4) // => 28
|
||||
|
||||
/*
|
||||
Data classes são uma forma concisa de criar classes que apenas contêm dados.
|
||||
Neste tipo de classes os métodos "hashCode"/"equals" e "toString" são gerados
|
||||
automáticamente.
|
||||
*/
|
||||
data class DataClassExample (val x: Int, val y: Int, val z: Int)
|
||||
val fooData = DataClassExample(1, 2, 4)
|
||||
println(fooData) // => DataClassExample(x=1, y=2, z=4)
|
||||
|
||||
// Instâncias deste tipo de classes têm acesso ao método "copy".
|
||||
val fooCopy = fooData.copy(y = 100)
|
||||
println(fooCopy) // => DataClassExample(x=1, y=100, z=4)
|
||||
|
||||
// Os objectos podem ser desconstruídos para variáveis.
|
||||
val (a, b, c) = fooCopy
|
||||
println("$a $b $c") // => 1 100 4
|
||||
|
||||
// desconstrucção dentro de um ciclo "for"
|
||||
for ((a, b, c) in listOf(fooData)) {
|
||||
println("$a $b $c") // => 1 2 4
|
||||
}
|
||||
|
||||
val mapData = mapOf("a" to 1, "b" to 2)
|
||||
// Instâncias de Map.Entry podem também ser desconstruídas.
|
||||
for ((key, value) in mapData) {
|
||||
println("$key -> $value")
|
||||
}
|
||||
|
||||
// A função "with" é semelhante ao bloco "with" do JavaScript.
|
||||
data class MutableDataClassExample (var x: Int, var y: Int, var z: Int)
|
||||
val fooMutableData = MutableDataClassExample(7, 4, 9)
|
||||
with (fooMutableData) {
|
||||
x -= 2
|
||||
y += 2
|
||||
z--
|
||||
}
|
||||
println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8)
|
||||
|
||||
/*
|
||||
Podemos criar listas usando a função "listOf".
|
||||
No Kotlin, por padrão, as listas são imútaveis - não podendo
|
||||
assim adicionar ou remover elementos das mesmas.
|
||||
*/
|
||||
val fooList = listOf("a", "b", "c")
|
||||
println(fooList.size) // => 3
|
||||
println(fooList.first()) // => a
|
||||
println(fooList.last()) // => c
|
||||
// Os elementos de uma lista podem ser acedidos usando o seu índice.
|
||||
println(fooList[1]) // => b
|
||||
|
||||
// Listas mútaveis podem ser criadas usando a função "mutableListOf".
|
||||
val fooMutableList = mutableListOf("a", "b", "c")
|
||||
fooMutableList.add("d")
|
||||
println(fooMutableList.last()) // => d
|
||||
println(fooMutableList.size) // => 4
|
||||
|
||||
// Podemos criar conjuntos usando a função "setOf".
|
||||
val fooSet = setOf("a", "b", "c")
|
||||
println(fooSet.contains("a")) // => true
|
||||
println(fooSet.contains("z")) // => false
|
||||
|
||||
// Podemos criar mapas usando a função "mapOf" e através da função infixa "to".
|
||||
val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9)
|
||||
// Os valores do mapa podem ser acedidos usando a sua chave.
|
||||
println(fooMap["a"]) // => 8
|
||||
|
||||
/*
|
||||
No Kotlin as sequências representam collecções de dados avaliadas de forma lazy.
|
||||
Podemos cirar uma sequência usando a função "generateSequence".
|
||||
*/
|
||||
val fooSequence = generateSequence(1, { it + 1 })
|
||||
val x = fooSequence.take(10).toList()
|
||||
println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
|
||||
// Um exemplo de uso das sequências para gerar os números de Fibonacci:
|
||||
fun fibonacciSequence(): Sequence<Long> {
|
||||
var a = 0L
|
||||
var b = 1L
|
||||
|
||||
fun next(): Long {
|
||||
val result = a + b
|
||||
a = b
|
||||
b = result
|
||||
return a
|
||||
}
|
||||
|
||||
return generateSequence(::next)
|
||||
}
|
||||
val y = fibonacciSequence().take(10).toList()
|
||||
println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
|
||||
|
||||
// O Kotlin fornece funções de ordem superior convenientes para a manipulação de colecções.
|
||||
val z = (1..9).map {it * 3}
|
||||
.filter {it < 20}
|
||||
.groupBy {it % 2 == 0}
|
||||
.mapKeys {if (it.key) "even" else "odd"}
|
||||
println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]}
|
||||
|
||||
// Um ciclo "for" pode ser usado com qualquer coisa que forneça um iterador.
|
||||
for (c in "hello") {
|
||||
println(c)
|
||||
}
|
||||
|
||||
// Um ciclo "while" funciona da mesma forma que em outras linguagens.
|
||||
var ctr = 0
|
||||
while (ctr < 5) {
|
||||
println(ctr)
|
||||
ctr++
|
||||
}
|
||||
do {
|
||||
println(ctr)
|
||||
ctr++
|
||||
} while (ctr < 10)
|
||||
|
||||
/*
|
||||
Um "if" pode ser usado como uma expressão que produz um valor.
|
||||
Por esta razão o operador ternário não é necessário no Kotlin.
|
||||
*/
|
||||
val num = 5
|
||||
val message = if (num % 2 == 0) "even" else "odd"
|
||||
println("$num is $message") // => 5 is odd
|
||||
|
||||
// O bloco "when" pode ser usado como alternativa para cadeias de "if-else if".
|
||||
val i = 10
|
||||
when {
|
||||
i < 7 -> println("first block")
|
||||
fooString.startsWith("hello") -> println("second block")
|
||||
else -> println("else block")
|
||||
}
|
||||
|
||||
// O "when" pode ser usado como um "switch" do Java.
|
||||
when (i) {
|
||||
0, 21 -> println("0 or 21")
|
||||
in 1..20 -> println("in the range 1 to 20")
|
||||
else -> println("none of the above")
|
||||
}
|
||||
|
||||
// O "when" pode também ser usado como expressão para produzir um valor.
|
||||
var result = when (i) {
|
||||
0, 21 -> "0 or 21"
|
||||
in 1..20 -> "in the range 1 to 20"
|
||||
else -> "none of the above"
|
||||
}
|
||||
println(result)
|
||||
|
||||
/*
|
||||
Podemos utilizar o operador "is" para verificar se um objecto é de um certo tipo.
|
||||
Se um objecto passar a verificação do tipo pode ser usado como sendo desse tipo
|
||||
sem conversão explicita, sendo isto chamado de smart cast.
|
||||
*/
|
||||
fun smartCastExample(x: Any) : Boolean {
|
||||
if (x is Boolean) {
|
||||
// x is automatically cast to Boolean
|
||||
return x
|
||||
} else if (x is Int) {
|
||||
// x is automatically cast to Int
|
||||
return x > 0
|
||||
} else if (x is String) {
|
||||
// x is automatically cast to String
|
||||
return x.isNotEmpty()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
println(smartCastExample("Hello, world!")) // => true
|
||||
println(smartCastExample("")) // => false
|
||||
println(smartCastExample(5)) // => true
|
||||
println(smartCastExample(0)) // => false
|
||||
println(smartCastExample(true)) // => true
|
||||
|
||||
// Os smart casts funcionam também com o bloco "when".
|
||||
fun smartCastWhenExample(x: Any) = when (x) {
|
||||
is Boolean -> x
|
||||
is Int -> x > 0
|
||||
is String -> x.isNotEmpty()
|
||||
else -> false
|
||||
}
|
||||
|
||||
/*
|
||||
Extensões são uma forma de adicionar funcionalidade a classes existentes.
|
||||
Isto é semelhante aos métodos de extensão do C#.
|
||||
*/
|
||||
fun String.remove(c: Char): String {
|
||||
return this.filter {it != c}
|
||||
}
|
||||
println("Hello, world!".remove('l')) // => Hello, world!
|
||||
}
|
||||
|
||||
// Enum classes são o equivalente aos tipos enum do Java.
|
||||
enum class EnumExample {
|
||||
A, B, C // As constantes da enumeração são separadas por vírgula.
|
||||
}
|
||||
fun printEnum() = println(EnumExample.A) // => A
|
||||
|
||||
/*
|
||||
Como cada constante é uma instância da classe enum,
|
||||
estas podem ser inicializadas da seguinte forma:
|
||||
*/
|
||||
enum class EnumExample(val value: Int) {
|
||||
A(value = 1),
|
||||
B(value = 2),
|
||||
C(value = 3)
|
||||
}
|
||||
fun printProperty() = println(EnumExample.A.value) // => 1
|
||||
|
||||
/*
|
||||
Cada constante de enumerações tem propriedades para
|
||||
obter o nome e o ordinal (posição) na respectiva classe.
|
||||
*/
|
||||
fun printName() = println(EnumExample.A.name) // => A
|
||||
fun printPosition() = println(EnumExample.A.ordinal) // => 0
|
||||
|
||||
/*
|
||||
A palavra-chave "object" pode ser usada para criar objectos singleton.
|
||||
Estes não podem ser instânciados, porém podem ser referênciados como uma
|
||||
única instância através do seu nome.
|
||||
São semelhantes aos objectos singleton do Scala.
|
||||
*/
|
||||
object ObjectExample {
|
||||
fun hello(): String {
|
||||
return "hello"
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "Hello, it's me, ${ObjectExample::class.simpleName}"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun useSingletonObject() {
|
||||
println(ObjectExample.hello()) // => hello
|
||||
// Em Kotlin o tipo "Any" é a raíz da hierárquia de classes, tal como o tipo "Object" em Java.
|
||||
val someRef: Any = ObjectExample
|
||||
println(someRef) // => Hello, it's me, ObjectExample
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
O operador !! serve para realizar um assert de not-null. Este converte qualquer
|
||||
valor nullable para non-null ou lança exceção se o mesmo for null.
|
||||
*/
|
||||
var b: String? = "abc"
|
||||
val l = b!!.length // lançaria exceção caso "b" fosse null
|
||||
|
||||
// O modificador "operator" permite fazer overload dos operadores
|
||||
// [Ver lista de operadores](https://kotlinlang.org/docs/operator-overloading.html)
|
||||
data class Counter(var value: Int) {
|
||||
// overload para Counter += Int
|
||||
operator fun plusAssign(increment: Int) {
|
||||
this.value += increment
|
||||
}
|
||||
|
||||
// overload para Counter++ e ++Counter
|
||||
operator fun inc() = Counter(value + 1)
|
||||
|
||||
// overload para Counter + Counter
|
||||
operator fun plus(other: Counter) = Counter(this.value + other.value)
|
||||
|
||||
// overload para Counter * Counter
|
||||
operator fun times(other: Counter) = Counter(this.value * other.value)
|
||||
|
||||
// overload para Counter * Int
|
||||
operator fun times(value: Int) = Counter(this.value * value)
|
||||
|
||||
// overload para Counter in Counter
|
||||
operator fun contains(other: Counter) = other.value == this.value
|
||||
|
||||
// overload para Counter[Int] = Int
|
||||
operator fun set(index: Int, value: Int) {
|
||||
this.value = index + value
|
||||
}
|
||||
|
||||
// overload para invocação da instância Counter
|
||||
operator fun invoke() = println("The value of the counter is $value")
|
||||
}
|
||||
/* Podemos também dar overload dos operadores através de métodos de extensão */
|
||||
// overload para -Counter
|
||||
operator fun Counter.unaryMinus() = Counter(-this.value)
|
||||
|
||||
fun operatorOverloadingDemo() {
|
||||
var counter1 = Counter(0)
|
||||
var counter2 = Counter(5)
|
||||
counter1 += 7
|
||||
println(counter1) // => Counter(value=7)
|
||||
println(counter1 + counter2) // => Counter(value=12)
|
||||
println(counter1 * counter2) // => Counter(value=35)
|
||||
println(counter2 * 2) // => Counter(value=10)
|
||||
println(counter1 in Counter(5)) // => false
|
||||
println(counter1 in Counter(7)) // => true
|
||||
counter1[26] = 10
|
||||
println(counter1) // => Counter(value=36)
|
||||
counter1() // => The value of the counter is 36
|
||||
println(-counter2) // => Counter(value=-5)
|
||||
}
|
||||
```
|
||||
|
||||
### Leituras Adicionais
|
||||
|
||||
* [Tutoriais de Kotlin](https://kotlinlang.org/docs/tutorials/)
|
||||
* [Experimenta Kotlin no browser](https://play.kotlinlang.org/)
|
||||
* [Recursos adicionais](http://kotlin.link/)
|
@ -158,13 +158,13 @@ case orderStatus
|
||||
//- <p class="warn">Your order is pending</p>
|
||||
|
||||
//- --INCLUDE--
|
||||
//- File path -> "includes/nav.png"
|
||||
//- File path -> "includes/nav.pug"
|
||||
h1 Company Name
|
||||
nav
|
||||
a(href="index.html") Home
|
||||
a(href="about.html") About Us
|
||||
|
||||
//- File path -> "index.png"
|
||||
//- File path -> "index.pug"
|
||||
html
|
||||
body
|
||||
include includes/nav.pug
|
||||
|
@ -185,7 +185,7 @@ print("Hello, World", end="!") # => Hello, World!
|
||||
input_string_var = input("Enter some data: ") # Returns the data as a string
|
||||
|
||||
# There are no declarations, only assignments.
|
||||
# Convention is to use lower_case_with_underscores
|
||||
# Convention in naming variables is snake_case style
|
||||
some_var = 5
|
||||
some_var # => 5
|
||||
|
||||
@ -226,7 +226,7 @@ li[4] # Raises an IndexError
|
||||
li[1:3] # Return list from index 1 to 3 => [2, 4]
|
||||
li[2:] # Return list starting from index 2 => [4, 3]
|
||||
li[:3] # Return list from beginning until index 3 => [1, 2, 4]
|
||||
li[::2] # Return list selecting every second entry => [1, 4]
|
||||
li[::2] # Return list selecting elements with a step size of 2 => [1, 4]
|
||||
li[::-1] # Return list in reverse order => [3, 4, 2, 1]
|
||||
# Use any combination of these to make advanced slices
|
||||
# li[start:end:step]
|
||||
@ -603,7 +603,7 @@ all_the_args(1, 2, a=3, b=4) prints:
|
||||
"""
|
||||
|
||||
# When calling functions, you can do the opposite of args/kwargs!
|
||||
# Use * to expand tuples and use ** to expand kwargs.
|
||||
# Use * to expand args (tuples) and use ** to expand kwargs (dictionaries).
|
||||
args = (1, 2, 3, 4)
|
||||
kwargs = {"a": 3, "b": 4}
|
||||
all_the_args(*args) # equivalent: all_the_args(1, 2, 3, 4)
|
||||
@ -655,6 +655,22 @@ def create_adder(x):
|
||||
add_10 = create_adder(10)
|
||||
add_10(3) # => 13
|
||||
|
||||
# Closures in nested functions:
|
||||
# We can use the nonlocal keyword to work with variables in nested scope which shouldn't be declared in the inner functions.
|
||||
def create_avg():
|
||||
total = 0
|
||||
count = 0
|
||||
def avg(n):
|
||||
nonlocal total, count
|
||||
total += n
|
||||
count += 1
|
||||
return total/count
|
||||
return avg
|
||||
avg = create_avg()
|
||||
avg(3) # => 3.0
|
||||
avg(5) # (3+5)/2 => 4.0
|
||||
avg(7) # (8+7)/3 => 5.0
|
||||
|
||||
# There are also anonymous functions
|
||||
(lambda x: x > 2)(3) # => True
|
||||
(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
|
||||
@ -685,8 +701,8 @@ print(math.sqrt(16)) # => 4.0
|
||||
|
||||
# You can get specific functions from a module
|
||||
from math import ceil, floor
|
||||
print(ceil(3.7)) # => 4.0
|
||||
print(floor(3.7)) # => 3.0
|
||||
print(ceil(3.7)) # => 4
|
||||
print(floor(3.7)) # => 3
|
||||
|
||||
# You can import all functions from a module.
|
||||
# Warning: this is not recommended
|
||||
@ -733,7 +749,9 @@ class Human:
|
||||
self.name = name
|
||||
|
||||
# Initialize property
|
||||
self._age = 0
|
||||
self._age = 0 # the leading underscore indicates the "age" property is
|
||||
# intended to be used internally
|
||||
# do not rely on this to be enforced: it's a hint to other devs
|
||||
|
||||
# An instance method. All methods take "self" as the first argument
|
||||
def say(self, msg):
|
||||
@ -876,7 +894,8 @@ if __name__ == '__main__':
|
||||
if type(sup) is Superhero:
|
||||
print('I am a superhero')
|
||||
|
||||
# Get the Method Resolution search Order used by both getattr() and super()
|
||||
# Get the "Method Resolution Order" used by both getattr() and super()
|
||||
# (the order in which classes are searched for an attribute or method)
|
||||
# This attribute is dynamic and can be updated
|
||||
print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
|
||||
# => <class 'human.Human'>, <class 'object'>)
|
||||
@ -958,8 +977,7 @@ class Batman(Superhero, Bat):
|
||||
if __name__ == '__main__':
|
||||
sup = Batman()
|
||||
|
||||
# Get the Method Resolution search Order used by both getattr() and super().
|
||||
# This attribute is dynamic and can be updated
|
||||
# The Method Resolution Order
|
||||
print(Batman.__mro__) # => (<class '__main__.Batman'>,
|
||||
# => <class 'superhero.Superhero'>,
|
||||
# => <class 'human.Human'>,
|
||||
@ -1016,31 +1034,67 @@ gen_to_list = list(values)
|
||||
print(gen_to_list) # => [-1, -2, -3, -4, -5]
|
||||
|
||||
|
||||
# Decorators
|
||||
# In this example `beg` wraps `say`. If say_please is True then it
|
||||
# will change the returned message.
|
||||
from functools import wraps
|
||||
# Decorators are a form of syntactic sugar.
|
||||
# They make code easier to read while accomplishing clunky syntax.
|
||||
|
||||
# Wrappers are one type of decorator.
|
||||
# They're really useful for adding logging to existing functions without needing to modify them.
|
||||
|
||||
def beg(target_function):
|
||||
@wraps(target_function)
|
||||
def log_function(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
msg, say_please = target_function(*args, **kwargs)
|
||||
if say_please:
|
||||
return "{} {}".format(msg, "Please! I am poor :(")
|
||||
return msg
|
||||
|
||||
print("Entering function", func.__name__)
|
||||
result = func(*args, **kwargs)
|
||||
print("Exiting function", func.__name__)
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
@log_function # equivalent:
|
||||
def my_function(x,y): # def my_function(x,y):
|
||||
return x+y # return x+y
|
||||
# my_function = log_function(my_function)
|
||||
# The decorator @log_function tells us as we begin reading the function definition
|
||||
# for my_function that this function will be wrapped with log_function.
|
||||
# When function definitions are long, it can be hard to parse the non-decorated
|
||||
# assignment at the end of the definition.
|
||||
|
||||
@beg
|
||||
def say(say_please=False):
|
||||
msg = "Can you buy me a beer?"
|
||||
return msg, say_please
|
||||
my_function(1,2) # => "Entering function my_function"
|
||||
# => "3"
|
||||
# => "Exiting function my_function"
|
||||
|
||||
# But there's a problem.
|
||||
# What happens if we try to get some information about my_function?
|
||||
|
||||
print(my_function.__name__) # => 'wrapper'
|
||||
print(my_function.__code__.co_argcount) # => 0. The argcount is 0 because both arguments in wrapper()'s signature are optional.
|
||||
|
||||
# Because our decorator is equivalent to my_function = log_function(my_function)
|
||||
# we've replaced information about my_function with information from wrapper
|
||||
|
||||
# Fix this using functools
|
||||
|
||||
from functools import wraps
|
||||
|
||||
def log_function(func):
|
||||
@wraps(func) # this ensures docstring, function name, arguments list, etc. are all copied
|
||||
# to the wrapped function - instead of being replaced with wrapper's info
|
||||
def wrapper(*args, **kwargs):
|
||||
print("Entering function", func.__name__)
|
||||
result = func(*args, **kwargs)
|
||||
print("Exiting function", func.__name__)
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
@log_function
|
||||
def my_function(x,y):
|
||||
return x+y
|
||||
|
||||
my_function(1,2) # => "Entering function my_function"
|
||||
# => "3"
|
||||
# => "Exiting function my_function"
|
||||
|
||||
print(my_function.__name__) # => 'my_function'
|
||||
print(my_function.__code__.co_argcount) # => 2
|
||||
|
||||
print(say()) # Can you buy me a beer?
|
||||
print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
|
||||
```
|
||||
|
||||
### Free Online
|
||||
|
@ -8,7 +8,7 @@ filename: restructuredtext.rst
|
||||
|
||||
RST, Restructured Text, is a file format created by the Python community to write documentation. It is part of [Docutils](https://docutils.sourceforge.io/rst.html).
|
||||
|
||||
RST is a markdown language like HTML but is much more lightweight and easier to read.
|
||||
RST is a markup language like HTML but is much more lightweight and easier to read.
|
||||
|
||||
|
||||
## Installation
|
||||
|
@ -48,7 +48,7 @@ f(n) — время выполнения. Тогда для данного ал
|
||||
С помощью О-символики можно оценить функцию или алгоритм
|
||||
несколькими различными способами. Например, можно оценить алгоритм исходя
|
||||
из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается
|
||||
анализ на основе верхней оценки. Как правило не используется нижняя оценка,
|
||||
анализ на основе верхней оценки. Как правило, не используется нижняя оценка,
|
||||
потому что она не подходит под планируемые условия. Отличный пример — алгоритмы
|
||||
сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка
|
||||
большинства таких алгоритмов может быть дана как одна операция. В то время как в
|
||||
@ -155,8 +155,8 @@ c (c > 0) и n<sub>0</sub> (n<sub>0</sub> > 0), такие, что `f(n)` >= `c
|
||||
|
||||
### Примечание
|
||||
|
||||
Асимптотические оценки, сделаные при помощи О Большого и Омега Большого, могут
|
||||
как являться, так и не являться точными. Для того, чтобы обозначить, что границы не
|
||||
Асимптотические оценки, сделанные при помощи О Большого и Омега Большого, могут
|
||||
как являться, так и не являться точными. Для того чтобы обозначить, что границы не
|
||||
являются асимптотически точными, используются записи О Малое и Омега Малое.
|
||||
|
||||
### О Малое
|
||||
|
@ -55,7 +55,7 @@ def search(arr, x):
|
||||
|
||||
### На заметку
|
||||
|
||||
Существует и другая форма двоичного поиска, которая можеть быть полезна.
|
||||
Существует и другая форма двоичного поиска, которая может быть полезна.
|
||||
|
||||
## На почитать
|
||||
|
||||
|
@ -17,7 +17,7 @@ C++ - компилируемый, статически типизированн
|
||||
|
||||
- "лучшая замена C"
|
||||
- язык с поддержкой абстракции данных
|
||||
- язык с поддержкой объектно-ориентированого программирования
|
||||
- язык с поддержкой объектно-ориентированного программирования
|
||||
- язык с поддержкой обобщенного программирования
|
||||
|
||||
Хотя его синтаксис может показаться более трудным или сложным для понимания, чем в более современных языках,
|
||||
|
@ -476,7 +476,7 @@ void str_reverse_through_pointer(char *str_in) {
|
||||
Если у вас появился вопрос, почитайте [compl.lang.c Frequently Asked Questions](http://c-faq.com).
|
||||
|
||||
Очень важно использовать правильные отступы и ставить пробелы в нужных местах.
|
||||
Читаемый код лучше чем красивый или быстрый код.
|
||||
Читаемый код лучше, чем красивый или быстрый код.
|
||||
Чтобы научиться писать хороший код, почитайте [Linux kernel coding style](https://www.kernel.org/doc/Documentation/CodingStyle).
|
||||
|
||||
Также не забывайте, что [Google](http://google.com) и [Яндекс](http://yandex.ru) – ваши хорошие друзья.
|
||||
|
@ -14,7 +14,8 @@ Common Lisp - мультипарадигменный язык программи
|
||||
спектра задач.
|
||||
Его частенько называют программируемым языком программирования.
|
||||
|
||||
Идеальная отправная точка - книга [Common Lisp на практике (перевод)](http://lisper.ru/pcl/).
|
||||
Идеальная отправная точка - книга
|
||||
[Common Lisp на практике (перевод)](https://github.com/pcl-ru/pcl-ru/releases/download/v1.1/pcl-ru.pdf).
|
||||
Ещё одна популярная книга [Land of Lisp](http://landoflisp.com/).
|
||||
И одна из последних книг [Common Lisp Recipes](http://weitz.de/cl-recipes/) вобрала в себя лучшие
|
||||
архитектурные решения на основе опыта коммерческой работки автора.
|
||||
@ -674,7 +675,7 @@ nil ; ложь; а ещё пустой список () тож
|
||||
## Для чтения
|
||||
|
||||
На русском
|
||||
- [Practical Common Lisp](http://www.gigamonkeys.com/book/)
|
||||
- [Practical Common Lisp](https://github.com/pcl-ru/pcl-ru/releases/download/v1.1/pcl-ru.pdf)
|
||||
|
||||
На английском
|
||||
- [Practical Common Lisp](http://www.gigamonkeys.com/book/)
|
||||
@ -685,7 +686,7 @@ nil ; ложь; а ещё пустой список () тож
|
||||
|
||||
На русском
|
||||
|
||||
- [Lisper.ru](http://lisper.ru/)
|
||||
- [Сообщество в Telegram](https://t.me/lisp_forever)
|
||||
|
||||
На английском
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user