mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-28 03:38:51 +00:00
Merge remote-tracking branch 'refs/remotes/adambard/master'
This commit is contained in:
commit
62102d0299
@ -948,13 +948,59 @@ for (int i = 0; i < 10; ++i)
|
|||||||
|
|
||||||
// Following line sets size of v to 0, but destructors don't get called
|
// Following line sets size of v to 0, but destructors don't get called
|
||||||
// and resources aren't released!
|
// and resources aren't released!
|
||||||
v.empty();
|
v.clear();
|
||||||
v.push_back(Foo()); // New value is copied into the first Foo we inserted
|
v.push_back(Foo()); // New value is copied into the first Foo we inserted
|
||||||
|
|
||||||
// Truly destroys all values in v. See section about temporary objects for
|
// Truly destroys all values in v. See section about temporary objects for
|
||||||
// explanation of why this works.
|
// explanation of why this works.
|
||||||
v.swap(vector<Foo>());
|
v.swap(vector<Foo>());
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// Tuples (C++11 and above)
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
#include<tuple>
|
||||||
|
|
||||||
|
// Conceptually, Tuples are similar to old data structures (C-like structs) but instead of having named data members ,
|
||||||
|
// its elements are accessed by their order in the tuple.
|
||||||
|
|
||||||
|
// We start with constructing a tuple.
|
||||||
|
// Packing values into tuple
|
||||||
|
auto first = make_tuple(10, 'A');
|
||||||
|
const int maxN = 1e9;
|
||||||
|
const int maxL = 15;
|
||||||
|
auto second = make_tuple(maxN, maxL);
|
||||||
|
|
||||||
|
// printing elements of 'first' tuple
|
||||||
|
cout << get<0>(first) << " " << get<1>(first) << "\n"; //prints : 10 A
|
||||||
|
|
||||||
|
// printing elements of 'second' tuple
|
||||||
|
cout << get<0>(second) << " " << get<1>(second) << "\n"; // prints: 1000000000 15
|
||||||
|
|
||||||
|
// Unpacking tuple into variables
|
||||||
|
|
||||||
|
int first_int;
|
||||||
|
char first_char;
|
||||||
|
tie(first_int, first_char) = first;
|
||||||
|
cout << first_int << " " << first_char << "\n"; // prints : 10 A
|
||||||
|
|
||||||
|
// We can also create tuple like this.
|
||||||
|
|
||||||
|
tuple<int, char, double> third(11, 'A', 3.14141);
|
||||||
|
// tuple_size returns number of elements in a tuple (as a constexpr)
|
||||||
|
|
||||||
|
cout << tuple_size<decltype(third)>::value << "\n"; // prints: 3
|
||||||
|
|
||||||
|
// tuple_cat concatenates the elements of all the tuples in the same order.
|
||||||
|
|
||||||
|
auto concatenated_tuple = tuple_cat(first, second, third);
|
||||||
|
// concatenated_tuple becomes = (10, 'A', 1e9, 15, 11, 'A' ,3.14141)
|
||||||
|
|
||||||
|
cout << get<0>(concatenated_tuple) << "\n"; // prints: 10
|
||||||
|
cout << get<3>(concatenated_tuple) << "\n"; // prints: 15
|
||||||
|
cout << get<5>(concatenated_tuple) << "\n"; // prints: 'A'
|
||||||
|
|
||||||
```
|
```
|
||||||
Further Reading:
|
Further Reading:
|
||||||
|
|
||||||
|
@ -4,17 +4,16 @@ filename: learngo-de.go
|
|||||||
contributors:
|
contributors:
|
||||||
- ["Joseph Adams", "https://github.com/jcla1"]
|
- ["Joseph Adams", "https://github.com/jcla1"]
|
||||||
- ["Dennis Keller", "https://github.com/denniskeller"]
|
- ["Dennis Keller", "https://github.com/denniskeller"]
|
||||||
|
- ["Jerome Meinke", "https://github.com/jmeinke"]
|
||||||
lang: de-de
|
lang: de-de
|
||||||
---
|
---
|
||||||
Go wurde entwickelt, um Probleme zu lösen. Sie ist zwar nicht der neueste Trend in
|
Die Sprache Go (auch golang) wurde von Google entwickelt und wird seit 2007
|
||||||
der Informatik, aber sie ist einer der neuesten und schnellsten Wege, um Aufgabe in
|
benutzt. Go ähnelt in der Syntax der Sprache C, bietet darüber hinaus aber viele
|
||||||
der realen Welt zu lösen.
|
Vorteile. Einerseits verzichtet Gp auf Speicherarithmetik und
|
||||||
|
benutzt einen Garbabe Collector. Andererseits enthält Go native Sprachelemente
|
||||||
Sie hat vertraute Elemente von imperativen Sprachen mit statischer Typisierung
|
für die Unterstützung von Nebenläufigkeit. Durch den Fokus auf einen schnellen
|
||||||
und kann schnell kompiliert und ausgeführt werden. Verbunden mit leicht zu
|
Kompilierprozess wird außerdem die Softwareentwicklung in Großprojekten
|
||||||
verstehenden Parallelitäts-Konstrukten, um die heute üblichen mehrkern
|
erleichtert.
|
||||||
Prozessoren optimal nutzen zu können, eignet sich Go äußerst gut für große
|
|
||||||
Programmierprojekte.
|
|
||||||
|
|
||||||
Außerdem beinhaltet Go eine gut ausgestattete Standardbibliothek und hat eine
|
Außerdem beinhaltet Go eine gut ausgestattete Standardbibliothek und hat eine
|
||||||
aktive Community.
|
aktive Community.
|
||||||
@ -24,7 +23,7 @@ aktive Community.
|
|||||||
/* Mehr-
|
/* Mehr-
|
||||||
zeiliger Kommentar */
|
zeiliger Kommentar */
|
||||||
|
|
||||||
// Eine jede Quelldatei beginnt mit einer Paket-Klausel.
|
// Wie bei Java gehört jede Quelldatei einem Paket an (Modularisierung).
|
||||||
// "main" ist ein besonderer Paketname, da er ein ausführbares Programm
|
// "main" ist ein besonderer Paketname, da er ein ausführbares Programm
|
||||||
// einleitet, im Gegensatz zu jedem anderen Namen, der eine Bibliothek
|
// einleitet, im Gegensatz zu jedem anderen Namen, der eine Bibliothek
|
||||||
// deklariert.
|
// deklariert.
|
||||||
@ -40,7 +39,7 @@ import (
|
|||||||
|
|
||||||
// Es folgt die Definition einer Funktion, in diesem Fall von "main". Auch hier
|
// Es folgt die Definition einer Funktion, in diesem Fall von "main". Auch hier
|
||||||
// ist der Name wieder besonders. "main" markiert den Eintrittspunkt des
|
// ist der Name wieder besonders. "main" markiert den Eintrittspunkt des
|
||||||
// Programms. Vergessen Sie nicht die geschweiften Klammern!
|
// Programms.
|
||||||
func main() {
|
func main() {
|
||||||
// Println gibt eine Zeile zu stdout aus.
|
// Println gibt eine Zeile zu stdout aus.
|
||||||
// Der Prefix "fmt" bestimmt das Paket aus welchem die Funktion stammt.
|
// Der Prefix "fmt" bestimmt das Paket aus welchem die Funktion stammt.
|
||||||
@ -50,8 +49,8 @@ func main() {
|
|||||||
beyondHello()
|
beyondHello()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Funktionen können Parameter akzeptieren, diese werden in Klammern deklariert,
|
// Funktionen können Parameter akzeptieren. Diese werden in Klammern deklariert,
|
||||||
// die aber auch bei keinen Parametern erforderlich sind.
|
// die aber auch ohne Parameter erforderlich sind.
|
||||||
func beyondHello() {
|
func beyondHello() {
|
||||||
var x int // Deklaration einer Variable, muss vor Gebrauch geschehen.
|
var x int // Deklaration einer Variable, muss vor Gebrauch geschehen.
|
||||||
x = 3 // Zuweisung eines Werts.
|
x = 3 // Zuweisung eines Werts.
|
||||||
@ -99,7 +98,7 @@ Zeilenumbrüche beinhalten.` // Selber Zeichenketten-Typ
|
|||||||
// "slices" haben eine dynamische Größe. Arrays und Slices haben beide ihre
|
// "slices" haben eine dynamische Größe. Arrays und Slices haben beide ihre
|
||||||
// Vorzüge, aber slices werden viel häufiger verwendet
|
// Vorzüge, aber slices werden viel häufiger verwendet
|
||||||
s3 := []int{4, 5, 9} // Vergleichen Sie mit a3, hier: keine Ellipse
|
s3 := []int{4, 5, 9} // Vergleichen Sie mit a3, hier: keine Ellipse
|
||||||
s4 := make([]int, 4) // Weist Speicher für 4 ints zu, alle mit Initialwert 0
|
s4 := make([]int, 4) // Weist Speicher für 4 ints zu, alle mit Wert 0
|
||||||
var d2 [][]float64 // Nur eine Deklaration, keine Speicherzuweisung
|
var d2 [][]float64 // Nur eine Deklaration, keine Speicherzuweisung
|
||||||
bs := []byte("eine slice") // Umwandlungs-Syntax
|
bs := []byte("eine slice") // Umwandlungs-Syntax
|
||||||
|
|
||||||
@ -201,7 +200,8 @@ type pair struct {
|
|||||||
x, y int
|
x, y int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Definiere eine Methode von "pair". Dieser Typ erfüllt jetzt das Stringer interface.
|
// Definiere eine Methode von "pair".
|
||||||
|
// Dieser Typ erfüllt jetzt das Stringer interface.
|
||||||
func (p pair) String() string { // p ist der Empfänger
|
func (p pair) String() string { // p ist der Empfänger
|
||||||
// Sprintf ist eine weitere öffentliche Funktion von fmt.
|
// Sprintf ist eine weitere öffentliche Funktion von fmt.
|
||||||
// Der Syntax mit Punkt greift auf die Felder zu.
|
// Der Syntax mit Punkt greift auf die Felder zu.
|
||||||
@ -255,8 +255,9 @@ func learnConcurrency() {
|
|||||||
// Die selbe "make"-Funktion wie vorhin. Sie initialisiert Speicher für
|
// Die selbe "make"-Funktion wie vorhin. Sie initialisiert Speicher für
|
||||||
// maps, slices und Kanäle.
|
// maps, slices und Kanäle.
|
||||||
c := make(chan int)
|
c := make(chan int)
|
||||||
// Starte drei parallele "Goroutines". Die Zahlen werden parallel (concurrently)
|
// Starte drei parallele "Goroutines".
|
||||||
// erhöht. Alle drei senden ihr Ergebnis in den gleichen Kanal.
|
// Die Zahlen werden parallel (concurrently) erhöht.
|
||||||
|
// Alle drei senden ihr Ergebnis in den gleichen Kanal.
|
||||||
go inc(0, c) // "go" ist das Statement zum Start einer neuen Goroutine
|
go inc(0, c) // "go" ist das Statement zum Start einer neuen Goroutine
|
||||||
go inc(10, c)
|
go inc(10, c)
|
||||||
go inc(-805, c)
|
go inc(-805, c)
|
||||||
@ -306,14 +307,13 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Weitere Resourcen
|
## Weitere Resourcen
|
||||||
Alles zu Go finden Sie auf der [offiziellen Go Webseite](http://golang.org/).
|
Informationen zu Go findet man auf der [offiziellen Go Webseite](http://golang.org/).
|
||||||
Dort können sie dem Tutorial folgen, interaktiv Quelltext ausprobieren und viel
|
Dort gibt es unter anderem ein Tutorial und interaktive Quelltext-Beispiele, vor
|
||||||
Dokumentation lesen.
|
allem aber Dokumentation zur Sprache und den Paketen.
|
||||||
|
|
||||||
Auch zu empfehlen ist die Spezifikation von Go, die nach heutigen Standards sehr
|
Auch zu empfehlen ist die Spezifikation von Go, die nach heutigen Standards sehr
|
||||||
kurz und auch gut verständlich formuliert ist. Auf der Leseliste von Go-Neulingen
|
kurz und gut verständlich formuliert ist. Auf der Leseliste von Go-Neulingen
|
||||||
ist außerdem der Quelltext der [Go standard Bibliothek](http://golang.org/src/pkg/).
|
ist außerdem der Quelltext der [Go standard Bibliothek](http://golang.org/src/pkg/)
|
||||||
Gut dokumentiert, demonstriert sie leicht zu verstehendes und im idiomatischen Stil
|
einzusehen. Dieser kann als Referenz für leicht zu verstehendes und im idiomatischen Stil
|
||||||
verfasstes Go. Erreichbar ist der Quelltext auch durch das Klicken der Funktionsnamen
|
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](http://golang.org/pkg/).
|
||||||
|
|
||||||
|
268
fr-fr/make-fr.html.markdown
Normal file
268
fr-fr/make-fr.html.markdown
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
---
|
||||||
|
language: make
|
||||||
|
contributors:
|
||||||
|
- ["Robert Steed", "https://github.com/robochat"]
|
||||||
|
translators:
|
||||||
|
- ["altaris", "https://github.com/altaris"]
|
||||||
|
filename: Makefile-fr
|
||||||
|
lang: fr-fr
|
||||||
|
---
|
||||||
|
|
||||||
|
Un makefile est un fichier qui définit un ensemble de règles liées entre elles
|
||||||
|
pour créer une ou plusieurs cibles. L'idée est d'effectuer le moins de travail
|
||||||
|
possible afin de mettre à jour la ou les cibles en fonction des dépendances.
|
||||||
|
|
||||||
|
Écrit en un week-end par Stuart Feldman en 1976, le make et les
|
||||||
|
makefiles sont encore très utilisés (principalement dans les systèmes Unix),
|
||||||
|
malgré la concurrence et les critiques faites à son égard.
|
||||||
|
|
||||||
|
Le programme make a plusieurs variantes. Dans ce tutoriel, nous utiliserons
|
||||||
|
l'implémentation standard : GNU make.
|
||||||
|
|
||||||
|
```make
|
||||||
|
|
||||||
|
# Ceci est un commentaire.
|
||||||
|
|
||||||
|
# Un makefile devrait être nommé "Makefile" (avec ou sans la
|
||||||
|
# majuscule). Il peut alors être exécuté par `make <cible>`.
|
||||||
|
# Ce nommage n'est toutefois pas obligatoire : utiliser
|
||||||
|
# `make -f "fichier" <cible>`.
|
||||||
|
|
||||||
|
# ATTENTION : l'indentation est quant à elle obligatoire, et se fait avec des
|
||||||
|
# tabulations, pas avec des espaces !
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Les basiques
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Une règle. Elle ne sera exécutée que si fichier0.txt n'existe pas.
|
||||||
|
fichier0.txt:
|
||||||
|
echo "truc" > fichier0.txt
|
||||||
|
# Même les commentaires sont transférés dans le terminal.
|
||||||
|
|
||||||
|
# Cette règle ne sera exécutée que si fichier0.txt est plus récent que
|
||||||
|
# fichier1.txt.
|
||||||
|
fichier1.txt: fichier0.txt
|
||||||
|
cat fichier0.txt > fichier1.txt
|
||||||
|
# Utiliser la même syntaxe que dans un terminal.
|
||||||
|
@cat fichier0.txt >> fichier1.txt
|
||||||
|
# @ empêche l'affichage de la sortie texte d'une commande.
|
||||||
|
-@echo 'hello'
|
||||||
|
# - signifie que la règle devrait continuer à s'exécuter si cette commande
|
||||||
|
# échoue.
|
||||||
|
|
||||||
|
# Une règle peut avoir plusieurs cibles et plusieurs dépendances.
|
||||||
|
fichier2.txt fichier3.txt: fichier0.txt fichier1.txt
|
||||||
|
touch fichier2.txt
|
||||||
|
touch fichier3.txt
|
||||||
|
|
||||||
|
# Make affichera un avertissement si le makefile comporte plusieurs règles pour
|
||||||
|
# une même cible. Cependant les règles vides ne comptent pas, et peuvent être
|
||||||
|
# utilisées pour ajouter des dépendances plus facilement.
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Fausses règles
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Une fausse règle est une règle qui ne correspond pas à un fichier.
|
||||||
|
# Par définition, elle ne peut pas être à jour, et donc make l’exécutera à
|
||||||
|
# chaque demande.
|
||||||
|
all: maker process
|
||||||
|
|
||||||
|
# La déclaration des règles peut être faite dans n'importe quel ordre.
|
||||||
|
maker:
|
||||||
|
touch ex0.txt ex1.txt
|
||||||
|
|
||||||
|
# On peut transformer une règle en fausse règle grâce à la cible spéciale
|
||||||
|
# suivante :
|
||||||
|
.PHONY: all maker process
|
||||||
|
|
||||||
|
# Une règle dépendante d'une fausse règle sera toujours exécutée.
|
||||||
|
ex0.txt ex1.txt: maker
|
||||||
|
|
||||||
|
# Voici quelques exemples fréquents de fausses règles : all, make, clean,
|
||||||
|
# install...
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Variables automatiques et wildcards
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Utilise un wildcard pour des noms de fichier
|
||||||
|
process: fichier*.txt
|
||||||
|
@echo $^ # $^ est une variable contenant la liste des dépendances de la
|
||||||
|
# cible actuelle.
|
||||||
|
@echo $@ # $@ est le nom de la cible actuelle. En cas de cibles
|
||||||
|
# multiples, $@ est le nom de la cible ayant causé l'exécution
|
||||||
|
# de cette règle.
|
||||||
|
@echo $< # $< contient la première dépendance.
|
||||||
|
@echo $? # $? contient la liste des dépendances qui ne sont pas à jour.
|
||||||
|
@echo $+ # $+ contient la liste des dépendances avec d'éventuels
|
||||||
|
# duplicatas, contrairement à $^.
|
||||||
|
@echo $| # $| contient la liste des cibles ayant préséance sur la cible
|
||||||
|
# actuelle.
|
||||||
|
|
||||||
|
# Même si la définition de la règle est scindée en plusieurs morceaux, $^
|
||||||
|
# listera toutes les dépendances indiquées.
|
||||||
|
process: ex1.txt fichier0.txt
|
||||||
|
# Ici, fichier0.txt est un duplicata dans $+.
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Pattern matching
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# En utilisant le pattern matching, on peut par exemple créer des règles pour
|
||||||
|
# convertir les fichiers d'un certain format dans un autre.
|
||||||
|
%.png: %.svg
|
||||||
|
inkscape --export-png $^
|
||||||
|
|
||||||
|
# Make exécute une règle même si le fichier correspondant est situé dans un sous
|
||||||
|
# dossier. En cas de conflit, la règle avec la meilleure correspondance est
|
||||||
|
# choisie.
|
||||||
|
small/%.png: %.svg
|
||||||
|
inkscape --export-png --export-dpi 30 $^
|
||||||
|
|
||||||
|
# Dans ce type de conflit (même cible, même dépendances), make exécutera la
|
||||||
|
# dernière règle déclarée...
|
||||||
|
%.png: %.svg
|
||||||
|
@echo cette règle est choisie
|
||||||
|
|
||||||
|
# Dans ce type de conflit (même cible mais pas les mêmes dépendances), make
|
||||||
|
# exécutera la première règle pouvant être exécutée.
|
||||||
|
%.png: %.ps
|
||||||
|
@echo cette règle n\'est pas choisie si *.svg et *.ps sont présents
|
||||||
|
|
||||||
|
# Make a des règles pré établies. Par exemple, il sait comment créer la cible
|
||||||
|
# *.o à partir de *.c.
|
||||||
|
|
||||||
|
# Les makefiles plus vieux utilisent un matching par extension de fichier.
|
||||||
|
.png.ps:
|
||||||
|
@echo cette règle est similaire à une règle par pattern matching
|
||||||
|
|
||||||
|
# Utiliser cette règle spéciale pour déclarer une règle comme ayant un
|
||||||
|
# matching par extension de fichier.
|
||||||
|
.SUFFIXES: .png
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Variables, ou macros
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Les variables sont des chaînes de caractères.
|
||||||
|
|
||||||
|
variable = Ted
|
||||||
|
variable2="Sarah"
|
||||||
|
|
||||||
|
echo:
|
||||||
|
@echo $(variable)
|
||||||
|
@echo ${variable2}
|
||||||
|
@echo $variable # Cette syntaxe signifie $(n)ame et non pas $(variable) !
|
||||||
|
@echo $(variable3) # Les variables non déclarées valent "" (chaîne vide).
|
||||||
|
|
||||||
|
# Les variables sont déclarées de 4 manières, de la plus grande priorité à la
|
||||||
|
# plus faible :
|
||||||
|
# 1 : dans la ligne de commande qui invoque make,
|
||||||
|
# 2 : dans le makefile,
|
||||||
|
# 3 : dans les variables d’environnement du terminal qui invoque make,
|
||||||
|
# 4 : les variables prédéfinies.
|
||||||
|
|
||||||
|
# Assigne la variable si une variable d’environnement du même nom n'existe pas
|
||||||
|
# déjà.
|
||||||
|
variable4 ?= Jean
|
||||||
|
|
||||||
|
# Empêche cette variable d'être modifiée par la ligne de commande.
|
||||||
|
override variable5 = David
|
||||||
|
|
||||||
|
# Concatène à une variable (avec un espace avant).
|
||||||
|
variable4 +=gris
|
||||||
|
|
||||||
|
# Assignations de variable pour les règles correspondant à un pattern
|
||||||
|
# (spécifique à GNU make).
|
||||||
|
*.png: variable2 = Sara # Pour toutes les règles correspondant à *.png, et tous
|
||||||
|
# leurs descendants, la variable variable2 vaudra
|
||||||
|
# "Sara".
|
||||||
|
# Si le jeux des dépendances et descendances devient vraiment trop compliqué,
|
||||||
|
# des incohérences peuvent survenir.
|
||||||
|
|
||||||
|
# Certaines variables sont prédéfinies par make :
|
||||||
|
affiche_predefinies:
|
||||||
|
echo $(CC)
|
||||||
|
echo ${CXX}
|
||||||
|
echo $(FC)
|
||||||
|
echo ${CFLAGS}
|
||||||
|
echo $(CPPFLAGS)
|
||||||
|
echo ${CXXFLAGS}
|
||||||
|
echo $(LDFLAGS)
|
||||||
|
echo ${LDLIBS}
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Variables : le retour
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Les variables sont évaluées à chaque instance, ce qui peut être coûteux en
|
||||||
|
# calculs. Pour parer à ce problème, il existe dans GNU make une seconde
|
||||||
|
# manière d'assigner des variables pour qu'elles ne soient évaluées qu'une seule
|
||||||
|
# fois seulement.
|
||||||
|
|
||||||
|
var := A B C
|
||||||
|
var2 ::= $(var) D E F # := et ::= sont équivalents.
|
||||||
|
|
||||||
|
# Ces variables sont évaluées procéduralement (i.e. dans leur ordre
|
||||||
|
# d'apparition), contrairement aux règles par exemple !
|
||||||
|
|
||||||
|
# Ceci ne fonctionne pas.
|
||||||
|
var3 ::= $(var4) et fais de beaux rêves
|
||||||
|
var4 ::= bonne nuit
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Fonctions
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Make a une multitude de fonctions. La syntaxe générale est
|
||||||
|
# $(fonction arg0,arg1,arg2...).
|
||||||
|
|
||||||
|
# Quelques exemples :
|
||||||
|
|
||||||
|
fichiers_source = $(wildcard *.c */*.c)
|
||||||
|
fichiers_objet = $(patsubst %.c,%.o,$(fichiers_source))
|
||||||
|
|
||||||
|
ls: * src/*
|
||||||
|
@echo $(filter %.txt, $^)
|
||||||
|
@echo $(notdir $^)
|
||||||
|
@echo $(join $(dir $^),$(notdir $^))
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Directives
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Inclut d'autres makefiles.
|
||||||
|
include meuh.mk
|
||||||
|
|
||||||
|
# Branchements conditionnels.
|
||||||
|
sport = tennis
|
||||||
|
report:
|
||||||
|
ifeq ($(sport),tennis) # Il y a aussi ifneq.
|
||||||
|
@echo 'jeu, set et match'
|
||||||
|
else
|
||||||
|
@echo "C'est pas ici Wimbledon ?"
|
||||||
|
endif
|
||||||
|
|
||||||
|
truc = true
|
||||||
|
ifdef $(truc) # Il y a aussi ifndef.
|
||||||
|
machin = 'salut'
|
||||||
|
endif
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quelques références
|
||||||
|
|
||||||
|
### En français
|
||||||
|
|
||||||
|
+ [Introduction à Makefile (developpez.com)]
|
||||||
|
(http://gl.developpez.com/tutoriel/outil/makefile/),
|
||||||
|
+ [Compilez sous GNU/Linux ! (openclassrooms)]
|
||||||
|
(https://openclassrooms.com/courses/compilez-sous-gnu-linux).
|
||||||
|
|
||||||
|
### En anglais
|
||||||
|
|
||||||
|
+ [Documentation de GNU make](https://www.gnu.org/software/make/manual/),
|
||||||
|
+ [Software carpentry tutorial](http://swcarpentry.github.io/make-novice/),
|
||||||
|
+ Learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html)
|
||||||
|
[ex28](http://c.learncodethehardway.org/book/ex28.html).
|
167
fr-fr/wolfram-fr.html.markdown
Normal file
167
fr-fr/wolfram-fr.html.markdown
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
---
|
||||||
|
language: wolfram
|
||||||
|
contributors:
|
||||||
|
- ["hyphz", "http://github.com/hyphz/"]
|
||||||
|
translators:
|
||||||
|
- ["altaris", "http://github.com/altaris/"]
|
||||||
|
filename: learnwolfram-fr.nb
|
||||||
|
lang: fr-fr
|
||||||
|
---
|
||||||
|
|
||||||
|
Le langage Wolfram est utilisé dans les programmes suivants :
|
||||||
|
* La ligne de commandes interactive noyau du Raspberry Pi, mais elle ne peut pas
|
||||||
|
gérer des éléments graphiques.
|
||||||
|
* _Mathematica_, un éditeur de texte riche spécialisé pour les mathématiques :
|
||||||
|
appuyer sur `Shift + Entrée` dans une cellule de code crée un nouvelle cellule
|
||||||
|
contenant le résultat.
|
||||||
|
* _Wolfram Wokbench_, une variante d'Eclipse spécialisée pour le langage
|
||||||
|
Wolfram.
|
||||||
|
|
||||||
|
Ce code d'exemple peut être utilisé et modifié dans ces logiciels. Cependant, le
|
||||||
|
copier-coller directement dans Mathematica peut causer des problèmes de
|
||||||
|
formatage, car il ne contient aucune information de mise en page.
|
||||||
|
|
||||||
|
```
|
||||||
|
(* Ceci est un commentaire *)
|
||||||
|
|
||||||
|
(* Dans Mathematica, au lieu d'utiliser ces commentaires, vous pouvez créer des
|
||||||
|
cellules de texte et insérer de jolies images *)
|
||||||
|
|
||||||
|
(* Saisissez une opération et appuyez sur Shift + Entrée pour obtenir le
|
||||||
|
résultat *)
|
||||||
|
2*2 (* 4 *)
|
||||||
|
5+8 (* 13 *)
|
||||||
|
|
||||||
|
(* Appels de fonction *)
|
||||||
|
Sin[Pi/2] (* 1 *)
|
||||||
|
(* Syntaxe alternative pour les appels de fonction à 1 paramètre *)
|
||||||
|
Sin@(Pi/2) (* 1 *)
|
||||||
|
(Pi/2) // Sin (* 1 *)
|
||||||
|
|
||||||
|
(* Attention : le langage est sensible à la casse ! *)
|
||||||
|
|
||||||
|
(* Toutes les expressions sont en réalité des appels de fonction *)
|
||||||
|
Times[2, 2] (* 4 *)
|
||||||
|
Plus[5, 8] (* 13 *)
|
||||||
|
|
||||||
|
(* Utiliser une variable pour la première fois la déclare globalement *)
|
||||||
|
x = 5 (* 5 *)
|
||||||
|
x == 5 (* True, l'assignation et le test d'égalité est écrit comme
|
||||||
|
en C *)
|
||||||
|
x (* 5 *)
|
||||||
|
x = x + 5 (* 10 *)
|
||||||
|
x (* 10 *)
|
||||||
|
Set[x, 20] (* TOUT est un appel de fonction, TOUUUUUUUUT *)
|
||||||
|
x (* 20 *)
|
||||||
|
|
||||||
|
(* Le langage Wolfram effectue des manipulations symboliques, donc utiliser des
|
||||||
|
variables non déclarées est légal *)
|
||||||
|
truc + 5 (* 5 + truc, comme truc n'est pas déclarée, l'évaluation
|
||||||
|
s'arrête là *)
|
||||||
|
truc + 5 + 10 (* 15 + truc, on évalue ce qu'on peut... *)
|
||||||
|
% (* 15 + truc, % représente le dernier résultat *)
|
||||||
|
% - truc (* 15, les variables non déclarées peuvent quand même
|
||||||
|
s'annuler *)
|
||||||
|
chose = truc + 5 (* Attention : chose est ici une expression et non un nombre *)
|
||||||
|
|
||||||
|
(* Déclaration d'une fonction *)
|
||||||
|
Double[x_] := x * 2 (* Le symbole := empêche l'évaluation immédiate du terme
|
||||||
|
à droite *)
|
||||||
|
Double[10] (* 20 *)
|
||||||
|
Double[Sin[Pi/2]] (* 2 *)
|
||||||
|
Double @ Sin @ (Pi/2) (* 2, Utiliser @ évite les paquets de crochets
|
||||||
|
fermants si moches *)
|
||||||
|
(Pi/2) // Sin // Double (* 2, Utiliser // permet d'écrire les fonctions dans
|
||||||
|
l'ordre d'appel *)
|
||||||
|
|
||||||
|
(* En programmation impérative, utiliser ; pour séparer les expressions *)
|
||||||
|
Salut[] := (Print@"Hello"; Print@"World") (* Les parenthèses sont nécessaires
|
||||||
|
car ; est prioritaire sur := *)
|
||||||
|
Salut[] (* Hello World *)
|
||||||
|
|
||||||
|
(* Boucles For à la C *)
|
||||||
|
Compter[x_] := For[y=0, y<x, y++, (Print[y])] (* L'évaluation des boucles For
|
||||||
|
se fait comme en C *)
|
||||||
|
Compter[5] (* 0 1 2 3 4 *)
|
||||||
|
|
||||||
|
(* Boucles While *)
|
||||||
|
x = 0; While[x < 2, (Print@x; x++)] (* De nouveau, comme en C *)
|
||||||
|
|
||||||
|
(* Expressions conditionnelles et If *)
|
||||||
|
x = 8; If[x==8, Print@"Huit", Print@"Pas huit"] (* If [condition, si vrai,
|
||||||
|
si faux] *)
|
||||||
|
Switch[x, 2, Print@"Deux", 8, Print@"Huit"] (* Switch par valeur *)
|
||||||
|
Which[x==2, Print@"Deux", x==8, Print@"Huit"] (* Switch du type if, else if,
|
||||||
|
else if, ..., else *)
|
||||||
|
|
||||||
|
(* Les variables autres que les paramètres de fonctions sont par défaut
|
||||||
|
globales, même à l'intérieur des fonctions *)
|
||||||
|
y = 10 (* 10, y est une variable globale *)
|
||||||
|
Compter[5] (* 0 1 2 3 4 *)
|
||||||
|
y (* 5, y a été modifiée par Compter *)
|
||||||
|
x = 20 (* 20, x est une variable globale *)
|
||||||
|
Compter[5] (* 0 1 2 3 4 *)
|
||||||
|
x (* 20, dans Compter, le paramètre x masque la variable
|
||||||
|
globale x *)
|
||||||
|
|
||||||
|
(* La fonction Module permet d'utiliser des variables locales *)
|
||||||
|
MieuxCompter[x_] := Module[{y}, (For[y=0, y<x, y++, (Print@y)])]
|
||||||
|
y = 20 (* y est une variable globale *)
|
||||||
|
MieuxCompter[5] (* 0 1 2 3 4 *)
|
||||||
|
y (* 20, y n'a pas été modifiée car le y du Module masque le
|
||||||
|
y global. C'est bien mieux comme ça ! *)
|
||||||
|
|
||||||
|
(* Module permet de faire des déclarations globales aussi *)
|
||||||
|
Module[{compte}, compte=0; (* compte est une variable locale *)
|
||||||
|
(Incrementer[] := ++compte); (* Ce module déclare des fonctions, mais elles
|
||||||
|
ne sont globales. Elles ont cependant accès
|
||||||
|
aux variables locales au module. *)
|
||||||
|
(Decrementer[] := --compte)]
|
||||||
|
compte (* compte, car il n'y a pas de variable globale nommée
|
||||||
|
compte *)
|
||||||
|
Incrementer[] (* 1, la fonction utilise la variable compte du module *)
|
||||||
|
Incrementer[] (* 2, le précédent appel de Incrementer a modifié compte *)
|
||||||
|
Decrementer[] (* 1 *)
|
||||||
|
compte (* compte, car il n'existe toujours pas de variable globale
|
||||||
|
nommé compte *)
|
||||||
|
|
||||||
|
(* Listes *)
|
||||||
|
liste = {1, 2, 3, 4} (* {1, 2, 3, 4} *)
|
||||||
|
liste[[1]] (* 1, les indexes commencent à 1 et non 0 !!! *)
|
||||||
|
Map[Double, liste] (* {2, 4, 6, 8}, appliquer une fonction à une liste de
|
||||||
|
manière fonctionnelle *)
|
||||||
|
Double /@ liste (* {2, 4, 6, 8}, syntaxe abrégée de la ligne
|
||||||
|
précédente *)
|
||||||
|
Scan[Print, liste] (* 1 2 3 4, boucle impérative sur une liste *)
|
||||||
|
Fold[Plus, 0, liste] (* 10 (0+1+2+3+4) *)
|
||||||
|
FoldList[Plus, 0, liste] (* {0, 1, 3, 6, 10}, variante de la fonction
|
||||||
|
précédente qui donne aussi les résultats
|
||||||
|
intermédiaires *)
|
||||||
|
Append[liste, 5] (* {1, 2, 3, 4, 5}, liste n'est pas modifiée... *)
|
||||||
|
Prepend[liste, 5] (* {5, 1, 2, 3, 4}, ... mais elle peut l'être en
|
||||||
|
écrivant "liste = " *)
|
||||||
|
Join[liste, {3, 4}] (* {1, 2, 3, 4, 3, 4} *)
|
||||||
|
liste[[2]] = 5 (* {1, 5, 3, 4}, ceci modifie bien la liste *)
|
||||||
|
|
||||||
|
(* Tables associatives, ou dictionnaires *)
|
||||||
|
table = <|"Vert" -> 2, "Rouge" -> 1|> (* Crée une table associative *)
|
||||||
|
table[["Vert"]] (* 2, l'utilise *)
|
||||||
|
table[["Vert"]] := 5 (* 5, la modifie *)
|
||||||
|
table[["Bleu"]] := 3.5 (* 3.5, l'étend *)
|
||||||
|
KeyDropFrom[table, "Vert"] (* Supprime la clé "Vert" *)
|
||||||
|
Keys[table] (* {Rouge, Bleu} *)
|
||||||
|
Values[table] (* {1, 3.5} *)
|
||||||
|
|
||||||
|
(* Pour finir, toute bonne démonstration du langage Wolfram contient un
|
||||||
|
Manipulate ! *)
|
||||||
|
Manipulate[y^2, {y, 0, 20}] (* Crée une interface graphique interactive qui
|
||||||
|
affiche y^2, permettant à l'utilisateur de
|
||||||
|
modifier la valeur de y grâce à un contrôle
|
||||||
|
allant de 0 à 20. Ne fonctionne que si le
|
||||||
|
logiciel utilisé gère les éléments graphiques. *)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Envie d'aller plus loin ?
|
||||||
|
|
||||||
|
* [Documentation du langage Wolfram (en anglais)]
|
||||||
|
(http://reference.wolfram.com/language/)
|
@ -193,7 +193,7 @@ foo = (+10)
|
|||||||
foo 5 -- 15
|
foo 5 -- 15
|
||||||
|
|
||||||
-- function composition
|
-- function composition
|
||||||
-- the (.) function chains functions together.
|
-- the operator `.` chains functions together.
|
||||||
-- For example, here foo is a function that takes a value. It adds 10 to it,
|
-- For example, here foo is a function that takes a value. It adds 10 to it,
|
||||||
-- multiplies the result of that by 4, and then returns the final value.
|
-- multiplies the result of that by 4, and then returns the final value.
|
||||||
foo = (*4) . (+10)
|
foo = (*4) . (+10)
|
||||||
@ -401,11 +401,26 @@ main'' = do
|
|||||||
|
|
||||||
let foo = 5
|
let foo = 5
|
||||||
|
|
||||||
-- You can see the type of any value with `:t`:
|
-- You can see the type of any value or expression with `:t`:
|
||||||
|
|
||||||
>:t foo
|
> :t foo
|
||||||
foo :: Integer
|
foo :: Integer
|
||||||
|
|
||||||
|
-- Operators, such as `+`, `:` and `$`, are functions.
|
||||||
|
-- Their type can be inspected by putting the operator in parentheses:
|
||||||
|
|
||||||
|
> :t (:)
|
||||||
|
(:) :: a -> [a] -> [a]
|
||||||
|
|
||||||
|
-- You can get additional information on any `name` using `:i`:
|
||||||
|
|
||||||
|
> :i (+)
|
||||||
|
class Num a where
|
||||||
|
(+) :: a -> a -> a
|
||||||
|
...
|
||||||
|
-- Defined in ‘GHC.Num’
|
||||||
|
infixl 6 +
|
||||||
|
|
||||||
-- You can also run any action of type `IO ()`
|
-- You can also run any action of type `IO ()`
|
||||||
|
|
||||||
> sayHello
|
> sayHello
|
||||||
|
848
id-id/php-id.html.markdown
Normal file
848
id-id/php-id.html.markdown
Normal file
@ -0,0 +1,848 @@
|
|||||||
|
---
|
||||||
|
language: PHP
|
||||||
|
contributors:
|
||||||
|
- ["Malcolm Fell", "http://emarref.net/"]
|
||||||
|
- ["Trismegiste", "https://github.com/Trismegiste"]
|
||||||
|
filename: learnphp-id.php
|
||||||
|
translators:
|
||||||
|
- ["Ahmad Zafrullah", "https://github.com/23Pstars"]
|
||||||
|
lang: id-id
|
||||||
|
---
|
||||||
|
|
||||||
|
Dokumen ini menjelaskan tentang PHP5 keatas.
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php // Skrip PHP harus diawali dengan tag <?php
|
||||||
|
|
||||||
|
// Jika dokumen PHP hanya mengandung kode PHP, sebaiknya tidak menggunakan
|
||||||
|
// tag penutup PHP untuk menghindari ketidaksengajaan tampilnya sesuatu.
|
||||||
|
|
||||||
|
// Dua garis miring diawal digunakan untuk komentar satu baris.
|
||||||
|
|
||||||
|
/*
|
||||||
|
Membatasi teks dalam garis miring-bintang dan bintang-garis miring
|
||||||
|
membuat komentar untuk banyak-baris sekaligus.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Gunakan "echo" or "print" untuk menampilkan sesuatu
|
||||||
|
print('Halo '); // Menampilkan "Halo " tanpa baris baru
|
||||||
|
|
||||||
|
// () boleh tidak digunakan dalam menggunakan "print" dan "echo"
|
||||||
|
echo "Dunia\n"; // Menampilkan "Dunia" dengan baris baru
|
||||||
|
// (semua perintah harus diakhiri dengan titik koma)
|
||||||
|
|
||||||
|
// Apapun yang berada diluar tag <?php akan ditampilkan secara otomatis
|
||||||
|
?>
|
||||||
|
Halo Dunia, lagi!
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
* Tipe Data & Variabel
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Variabel diawali dengan simnbol $.
|
||||||
|
// Nama variabel yang benar diawali dengan huruf atau garis-bawah,
|
||||||
|
// diikuti dengan beberapa huruf, angka, dan garis-bawah lainnya.
|
||||||
|
|
||||||
|
// Nilai Boolean adalah case-insensitive
|
||||||
|
$boolean = true; // atau TRUE atau True
|
||||||
|
$boolean = false; // atau FALSE atau False
|
||||||
|
|
||||||
|
// Nilai Integer
|
||||||
|
$int1 = 12; // => 12
|
||||||
|
$int2 = -12; // => -12
|
||||||
|
$int3 = 012; // => 10 (awalan 0 menandakan bilangan Oktal)
|
||||||
|
$int4 = 0x0F; // => 15 (awalan 0x menandakan bilangan Heksadesimal)
|
||||||
|
// Bilangan Biner Integer tersedia mulai dari PHP 5.4.0.
|
||||||
|
$int5 = 0b11111111; // 255 (awalan 0b menandakan bilangan Biner)
|
||||||
|
|
||||||
|
// Nilai Floats (dikenal juga sebagai Doubles)
|
||||||
|
$float = 1.234;
|
||||||
|
$float = 1.2e3;
|
||||||
|
$float = 7E-10;
|
||||||
|
|
||||||
|
// Menghapus variable
|
||||||
|
unset($int1);
|
||||||
|
|
||||||
|
// Aritmatika
|
||||||
|
$jumlah = 1 + 1; // 2
|
||||||
|
$selisih = 2 - 1; // 1
|
||||||
|
$perkalian = 2 * 2; // 4
|
||||||
|
$pembagian = 2 / 1; // 2
|
||||||
|
|
||||||
|
// Aritmatika singkat
|
||||||
|
$angka = 0;
|
||||||
|
$angka += 1; // Menjumlahkan $angka dengan 1
|
||||||
|
echo $angka++; // Menampilkan 1 (dijumlahkan dengan 1 setelah ditampilkan)
|
||||||
|
echo ++$angka; // Menampilkan 3 (dijumlahkan dengan 1 sebelum ditampilkan)
|
||||||
|
$angka /= $float; // Membagi dan menyimpan hasil pembagian pada $angka;
|
||||||
|
|
||||||
|
// String biasanya diawali dan ditutup dengan petik satu.
|
||||||
|
$sgl_quotes = '$String'; // => '$String'
|
||||||
|
|
||||||
|
// Hindari menggunakan petik dua kecuali menyertakan variabel lain
|
||||||
|
$dbl_quotes = "Ini adalah $sgl_quotes."; // => 'Ini adalah $String.'
|
||||||
|
|
||||||
|
// Karakter khusus hanya berlaku pada petik dua
|
||||||
|
$berfungsi = "Ini mengandung \t karakter tab.";
|
||||||
|
$tidak_berfungsi = 'Ini hanya mengandung garis miring dan huruf t: \t';
|
||||||
|
|
||||||
|
// Batasi variabel dengan kurung kurawal jika diperlukan
|
||||||
|
$uang = "Saya memiliki $${angka} di Bank.";
|
||||||
|
|
||||||
|
// Sejak PHP 5.3, nowdocs dapat digunakan untuk tak-terinterpolasi banyak-baris
|
||||||
|
$nowdoc = <<<'END'
|
||||||
|
Banyak baris
|
||||||
|
string
|
||||||
|
END;
|
||||||
|
|
||||||
|
// Heredocs akan melakukan interpolasi
|
||||||
|
$heredoc = <<<END
|
||||||
|
Banyak baris
|
||||||
|
$sgl_quotes
|
||||||
|
END;
|
||||||
|
|
||||||
|
// Menyambung string dapat dilakukan menggunakan .
|
||||||
|
echo 'String ini ' . 'tersambung';
|
||||||
|
|
||||||
|
// String dapat dijadikan parameter pada "echo"
|
||||||
|
echo 'Banyak', 'Parameter', 'String'; // Menampilkan 'BanyakParameterString'
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Konstan
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Sebuah konstan didifinisikan menggunakan fungsi define()
|
||||||
|
// dan tidak bisa diganti/rubah selama program berjalan!
|
||||||
|
|
||||||
|
// Nama konstan yang benar diawali dengan huruf dan garis-bawah,
|
||||||
|
// diikuti dengan beberapa huruf, angka, atau garis-bawah.
|
||||||
|
define("FOO", "sesuatu");
|
||||||
|
|
||||||
|
// Mengakses konstan memungkinkan untuk dapat dipanggil tanpa menggunakan simbol $
|
||||||
|
echo FOO; // Menampilkan 'sesuatu'
|
||||||
|
echo 'Keluaran ini adalah ' . FOO; // Menampilkan 'Keluaran ini adalah sesuatu'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Larik (Array)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Semua larik dalam PHP bersifat asosiatif (saling berhubungan).
|
||||||
|
|
||||||
|
// Berfungsi pada semua versi PHP
|
||||||
|
$asosiatif = array('Satu' => 1, 'Dua' => 2, 'Tiga' => 3);
|
||||||
|
|
||||||
|
// Pada PHP 5.4 diperkenalkan cara penulisan (sintaks) baru
|
||||||
|
$asosiatif = ['Satu' => 1, 'Dua' => 2, 'Tiga' => 3];
|
||||||
|
|
||||||
|
echo $asosiatif['Satu']; // menampilkan 1
|
||||||
|
|
||||||
|
// Daftar literal secara tidak langsung ditentukan oleh kunci integer
|
||||||
|
$larik = ['Satu', 'Dua', 'Tiga'];
|
||||||
|
echo $larik[0]; // => "Satu"
|
||||||
|
|
||||||
|
// Menambahkan sebuah elemen pada akhir larik
|
||||||
|
$larik[] = 'Empat';
|
||||||
|
// atau
|
||||||
|
array_push($larik, 'Lima');
|
||||||
|
|
||||||
|
// Menghapus elemen dari larik
|
||||||
|
unset($larik[3]);
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Keluaran
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo('Halo Dunia!');
|
||||||
|
// Menampilkan Halo Dunia! ke "stdout".
|
||||||
|
// "stdout" adalah sebuah halaman web ketika dijalankan dalam peramban (browser).
|
||||||
|
|
||||||
|
print('Halo Dunia!'); // Sama seperti "echo"
|
||||||
|
|
||||||
|
// "echo" dan "print" merupakan bahasa konstruksi, jadi tanda kurung dapat dihilangkan
|
||||||
|
echo 'Halo Dunia!';
|
||||||
|
print 'Halo Dunia!';
|
||||||
|
|
||||||
|
$paragraf = 'paragraf';
|
||||||
|
|
||||||
|
echo 100; // Menampilkan variabel skalar secara langsung
|
||||||
|
echo $paragraf; // atau sebuat variabel
|
||||||
|
|
||||||
|
// Jika PHP tag-singkat telah dikonfigurasi, atau versi PHP yang digunakan
|
||||||
|
// adalah 5.4.0 keatas, dapat digunakan sintaks "echo" singkat
|
||||||
|
|
||||||
|
?>
|
||||||
|
<p><?= $paragraf ?></p>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$x = 1;
|
||||||
|
$y = 2;
|
||||||
|
$x = $y; // $x sekarang berisi nilai yang sama dengan $y
|
||||||
|
$z = &$y;
|
||||||
|
// $z sekarang berisi referensi ke $y. Mengubah nilai dari $z
|
||||||
|
// akan mengubah nilai dari $y juga, begitupun sebaliknya.
|
||||||
|
// $x tetap tidak berubah sebagaimana nilai asli dari $y
|
||||||
|
|
||||||
|
echo $x; // => 2
|
||||||
|
echo $z; // => 2
|
||||||
|
$y = 0;
|
||||||
|
echo $x; // => 2
|
||||||
|
echo $z; // => 0
|
||||||
|
|
||||||
|
// Menampilkan tipe dan nilai dari variabel ke "stdout"
|
||||||
|
var_dump($z); // prints int(0)
|
||||||
|
|
||||||
|
// Menampilkan variabel ke "stdout" dalam format yang mudah dibaca
|
||||||
|
print_r($larik); // menampilkan: Array ( [0] => Satu [1] => Dua [2] => Tiga )
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Logika
|
||||||
|
*/
|
||||||
|
$a = 0;
|
||||||
|
$b = '0';
|
||||||
|
$c = '1';
|
||||||
|
$d = '1';
|
||||||
|
|
||||||
|
// menegaskan lemparan sebuah peringatan jika pernyataan tidak benar
|
||||||
|
|
||||||
|
// Perbandingan berikut akan selalu benar, meskipun memiliki tipe yang berbeda.
|
||||||
|
assert($a == $b); // kesamaan
|
||||||
|
assert($c != $a); // ketidak-samaan
|
||||||
|
assert($c <> $a); // versi lain dari ketidak-samaan
|
||||||
|
assert($a < $c);
|
||||||
|
assert($c > $b);
|
||||||
|
assert($a <= $b);
|
||||||
|
assert($c >= $d);
|
||||||
|
|
||||||
|
// Dibawah ini hanya akan bernilai benar jika nilainya memiliki tipe yang sama.
|
||||||
|
assert($c === $d);
|
||||||
|
assert($a !== $d);
|
||||||
|
assert(1 === '1');
|
||||||
|
assert(1 !== '1');
|
||||||
|
|
||||||
|
// Operator 'Spaceship' (sejak PHP 7)
|
||||||
|
// Mengembalikan 0 jika nilai pada kedua sisi adalah sama
|
||||||
|
// Mengembalikan 1 jika nilai pada sisi kiri lebih besar
|
||||||
|
// Mengembalikan -1 jika nilai pada sisi kanan lebih besar
|
||||||
|
|
||||||
|
$a = 100;
|
||||||
|
$b = 1000;
|
||||||
|
|
||||||
|
echo $a <=> $a; // 0 karena keduanya sama
|
||||||
|
echo $a <=> $b; // -1 karena $a < $b
|
||||||
|
echo $b <=> $a; // 1 karena $b > $a
|
||||||
|
|
||||||
|
// Variabel dapat dikonversi menjadi tipe lain, sesuai penggunaannya.
|
||||||
|
|
||||||
|
$integer = 1;
|
||||||
|
echo $integer + $integer; // => 2
|
||||||
|
|
||||||
|
$string = '1';
|
||||||
|
echo $string + $string; // => 2 (string dipaksa menjadi integer)
|
||||||
|
|
||||||
|
$string = 'satu';
|
||||||
|
echo $string + $string; // => 0
|
||||||
|
// Menghasilkan 0 karena operator (+) tidak dapat memaksa string 'satu' menjadi sebuah integer
|
||||||
|
|
||||||
|
// Perubahan tipe dapat dimanfaatkan untuk diperlakukan sebagai tipe lainnya
|
||||||
|
|
||||||
|
$boolean = (boolean) 1; // => true
|
||||||
|
|
||||||
|
$nol = 0;
|
||||||
|
$boolean = (boolean) $nol; // => false
|
||||||
|
|
||||||
|
// Terdapat juga fungsi khusus untuk melakukan perubahan terhadap beberapa tipe
|
||||||
|
$integer = 5;
|
||||||
|
$string = strval($integer);
|
||||||
|
|
||||||
|
$var = null; // Nilai Null
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Struktur Kontrol
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
print 'Saya tampil';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
print 'Saya tidak tampil';
|
||||||
|
} else {
|
||||||
|
print 'Saya tampil';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
print 'Tidak tampil';
|
||||||
|
} elseif(true) {
|
||||||
|
print 'Tampil';
|
||||||
|
}
|
||||||
|
|
||||||
|
// operator ternary
|
||||||
|
print (false ? 'Tidak tampil' : 'Tampil');
|
||||||
|
|
||||||
|
// cara pintas operator ternary mulai dirilis sejak PHP 5.3
|
||||||
|
// persamaan dari "$x ? $x : 'Kerjakan'"
|
||||||
|
$x = false;
|
||||||
|
print($x ?: 'Kerjakan');
|
||||||
|
|
||||||
|
// operator null coalesce sejak PHP 7
|
||||||
|
$a = null;
|
||||||
|
$b = 'Ditampilkan';
|
||||||
|
echo $a ?? 'a belum di-set'; // menampilkan 'a belum di-set'
|
||||||
|
echo $b ?? 'b belum di-set'; // menampilkan 'Ditampilkan'
|
||||||
|
|
||||||
|
|
||||||
|
$x = 0;
|
||||||
|
if ($x === '0') {
|
||||||
|
print 'Tidak ditampilkan';
|
||||||
|
} elseif($x == '1') {
|
||||||
|
print 'Tidak ditampilkan';
|
||||||
|
} else {
|
||||||
|
print 'Tampil';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Alternatif sintaks untuk kebutuhan templat:
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if ($x): ?>
|
||||||
|
Ini ditampilkan jika pengujian benar.
|
||||||
|
<?php else: ?>
|
||||||
|
Selain tersebut ini yang akan ditampilkan.
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Gunakan "switch" untuk menghemat logika.
|
||||||
|
switch ($x) {
|
||||||
|
case '0':
|
||||||
|
print 'Switch mendukung tipe paksaan';
|
||||||
|
break; // Kata kunci "break" harus disertakan, jika tidak
|
||||||
|
// maka logika tersebut akan berlanjut ke bagian "dua" dan "tiga"
|
||||||
|
case 'dua':
|
||||||
|
case 'tiga':
|
||||||
|
// Lakukan sesuatu jika $x bernilai "dua" atau "tiga"
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Aksi cadangan
|
||||||
|
}
|
||||||
|
|
||||||
|
// "while", "do...while" dan perulangan "for"
|
||||||
|
$i = 0;
|
||||||
|
while ($i < 5) {
|
||||||
|
echo $i++;
|
||||||
|
}; // Menampilkan "01234"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
do {
|
||||||
|
echo $i++;
|
||||||
|
} while ($i < 5); // Menampilkan "01234"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
for ($x = 0; $x < 10; $x++) {
|
||||||
|
echo $x;
|
||||||
|
} // Menampilkan "0123456789"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
$roda = ['sepeda' => 2, 'mobil' => 4];
|
||||||
|
|
||||||
|
// Perulangan "foreach" dapat melakukan iterasi pada larik (array)
|
||||||
|
foreach ($roda as $jumlah_roda) {
|
||||||
|
echo $jumlah_roda;
|
||||||
|
} // Menampilkan "24"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
// Iterasi dapat dilakukan terhadap "key" (kunci) dan "value" (nilai)
|
||||||
|
foreach ($roda as $mesin => $jumlah_roda) {
|
||||||
|
echo "$mesin memiliki $jumlah_roda buah roda";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
while ($i < 5) {
|
||||||
|
if ($i === 3) {
|
||||||
|
break; // Menghentikan proses perulangan
|
||||||
|
}
|
||||||
|
echo $i++;
|
||||||
|
} // Menampilkan "012"
|
||||||
|
|
||||||
|
for ($i = 0; $i < 5; $i++) {
|
||||||
|
if ($i === 3) {
|
||||||
|
continue; // Melewati tahapan iterasi saat ini
|
||||||
|
}
|
||||||
|
echo $i;
|
||||||
|
} // Menampilkan "0124"
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Fungsi
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Fungsi didefinisikan dengan "function":
|
||||||
|
function fungsi_saya () {
|
||||||
|
return 'Halo';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo fungsi_saya(); // => "Halo"
|
||||||
|
|
||||||
|
// Nama fungsi yang baik dan benar diawali dengan sebuah huruf atau garis-bawah, diikuti oleh
|
||||||
|
// beberapa huruf, angka, atau garis-bawah.
|
||||||
|
|
||||||
|
function jumlah ($x, $y = 1) { // $y merupakan opsional, jika tidak ditentukan akan bernilai 1
|
||||||
|
$hasil = $x + $y;
|
||||||
|
return $hasil;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo jumlah(4); // => 5
|
||||||
|
echo jumlah(4, 2); // => 6
|
||||||
|
|
||||||
|
// $hasil tidak dapat diakses dari luar fungsi
|
||||||
|
// print $hasil; // Akan menghasilkan sebuah "warning".
|
||||||
|
|
||||||
|
// Sejak PHP 5.3 fungsi dapat dideklarasikan menjadi tanpa-nama (anonymous);
|
||||||
|
$inc = function ($x) {
|
||||||
|
return $x + 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
echo $inc(2); // => 3
|
||||||
|
|
||||||
|
function foo ($x, $y, $z) {
|
||||||
|
echo "$x - $y - $z";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fungsi dapat mengembalikan fungsi juga
|
||||||
|
function bar ($x, $y) {
|
||||||
|
// Gunakan "use" untuk mengakses variabel diluar fungsi
|
||||||
|
return function ($z) use ($x, $y) {
|
||||||
|
foo($x, $y, $z);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$bar = bar('A', 'B');
|
||||||
|
$bar('C'); // Menampilkan "A - B - C"
|
||||||
|
|
||||||
|
// Fungsi uang memiliki nama dapat dipanggil berdasarkan string
|
||||||
|
$nama_fungsi = 'jumlah';
|
||||||
|
echo $nama_fungsi(1, 2); // => 3
|
||||||
|
// Bermanfaat untuk menentukan fungsi mana yang akan dipanggil secara dinamis.
|
||||||
|
// Atau, dapat juga menggunakan fungsi call_user_func(callable $callback [, $parameter [, ... ]]);
|
||||||
|
|
||||||
|
// Akses semua parameter yang dikirim ke sebuah fungsi
|
||||||
|
function parameter() {
|
||||||
|
$jumlah_param = func_num_args();
|
||||||
|
if( $jumlah_param > 0 ) {
|
||||||
|
echo func_get_arg(0) . ' | ';
|
||||||
|
}
|
||||||
|
$daftar_param = func_get_args();
|
||||||
|
foreach( $daftar_param as $kunci => $param ) {
|
||||||
|
echo $kunci . ' - ' . $param . ' | ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter('Halo', 'Dunia'); // Halo | 0 - Halo | 1 - Dunia |
|
||||||
|
|
||||||
|
// Sejak PHP 5.6, mendapatkan jumlah variabel yang ada pada parameter
|
||||||
|
function variabel($kata, ...$daftar) {
|
||||||
|
echo $kata . " || ";
|
||||||
|
foreach ($daftar as $item) {
|
||||||
|
echo $item . ' | ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable("Pemisah", "Halo", "Dunia") // Pemisah || Halo | Dunia |
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Penyertaan ("include")
|
||||||
|
*/
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// Skrip PHP yang berada dalam dokumen "include" juga harus dibuka dengan tag PHP.
|
||||||
|
|
||||||
|
include 'dokumen-saya.php';
|
||||||
|
// Kode yang ada dalam dokumen-saya.php sekarang dapat diakses dari cakupan saat ini.
|
||||||
|
// Jika dokumen tidak dapat disertakan (include, seperti dokumen tidak ditemukan), maka pesan peringatan akan muncul.
|
||||||
|
|
||||||
|
include_once 'dokumen-saya.php';
|
||||||
|
// Jika dokumen-saya telah disertakan (include) oleh perintah sebelumnya, maka
|
||||||
|
// dokumen tersebut tidak akan disertakan lagi. Ini bertujuan untuk menghindari kesalahan
|
||||||
|
// yang diakibatkan oleh deklarasi ganda.
|
||||||
|
|
||||||
|
require 'dokumen-saya.php';
|
||||||
|
require_once 'dokumen-saya.php';
|
||||||
|
// Memiliki fungsi yang sama dengan "include", namun jika dokumen tidak ditemukan
|
||||||
|
// atau tidak dapat disertakan maka akan menghasilkan pesan kesalahan fatal.
|
||||||
|
|
||||||
|
// Isi dari dokumen-saya.php:
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return 'Apapun yang kamu suka.';
|
||||||
|
// akhir dari dokumen
|
||||||
|
|
||||||
|
// "include" dan "require" dapat mengembalikan sebuah nilai.
|
||||||
|
$nilai = include 'dokumen-saya.php';
|
||||||
|
|
||||||
|
// Dokumen akan disertakan berdasarkan lokasi direktori dokumen (file path) yang diberikan, jika tidak didefinisikan
|
||||||
|
// maka akan digunakan konfigurasi dari "include_path". Jika dokumen tidak ditemukan dalam "include_path",
|
||||||
|
// fungsi include akan melakukan pengecekan pada direktori yang sama dengan dokumen yang menggunakan fungsi include tersebut,
|
||||||
|
// jika tidak ditemukan juga maka pesan gagal akan dimunculkan.
|
||||||
|
/* */
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Kelas (class)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Kelas didefinisikan dengan kata "class"
|
||||||
|
|
||||||
|
class KelasSaya
|
||||||
|
{
|
||||||
|
const NILAI_KONSTAN = 'nilai'; // Sebuah konstan
|
||||||
|
|
||||||
|
static $nilaiStatis = 'statis';
|
||||||
|
|
||||||
|
// Variabel statis dan hak jenis aksesnya
|
||||||
|
public static $variabelStatisPublik = 'nilaiStatisPublik';
|
||||||
|
// Hanya dapat diakses dalam kelas
|
||||||
|
private static $variabelStatisPrivat = 'nilaiStatisPrivat';
|
||||||
|
// Dapat diakses dalam kelas dan kelas turunan
|
||||||
|
protected static $variabelStatisTerlindungi = 'nilaiStatisTerlindungi';
|
||||||
|
|
||||||
|
// Properti harus mendeklarasikan hak aksesnya
|
||||||
|
public $properti = 'publik';
|
||||||
|
public $PropertiInstansi;
|
||||||
|
protected $variabel = 'terlindungi'; // Dapat diakses dari kelas itu sendiri dan kelas turunannya
|
||||||
|
private $variabel = 'tersembunyi'; // Hanya dapat diakses dari kelas itu sendiri
|
||||||
|
|
||||||
|
// Membuat konstruktor dengan perintah __construct
|
||||||
|
public function __construct($PropertiInstansi) {
|
||||||
|
// Akses variabel instansi menggunakan perintah $this
|
||||||
|
$this->PropertiInstansi = $PropertiInstansi;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method dideklarasikan sebagai fungsi didalam kelas
|
||||||
|
public function methodSaya()
|
||||||
|
{
|
||||||
|
print 'KelasSaya';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perintah "final" membuat sebuah fungsi tidak dapat di-override oleh kelas turunannya
|
||||||
|
final function tidakDapatDiOverride()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deklarasi properti atau method pada kelas sebagai statis membuat properti atau method tersebut
|
||||||
|
* dapat diakses tanpa melakukan instansiasi kelas. Properti statis tidak dapat diakses melalui
|
||||||
|
* objek kelas yang hasil instansiasi, sedangkan method statis bisa.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static function methodStatisSaya()
|
||||||
|
{
|
||||||
|
print 'Saya adalah statis';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Konstan pada kelas dapat diakses secara statis
|
||||||
|
echo KelasSaya::NILAI_KONSTAN; // Menampilkan 'nilai'
|
||||||
|
|
||||||
|
echo KelasSaya::$nilaiStatis; // Menampilkan 'statis'
|
||||||
|
KelasSaya::methodStatisSaya(); // Menampilkan 'Saya adalah statis'
|
||||||
|
|
||||||
|
// Instansi kelas menggunakan perintah "new"
|
||||||
|
$kelas_saya = new KelasSaya('Sebuah properti instansiasi');
|
||||||
|
// Tanda kurung adalah opsional jika tidak ingin menggunakan argumen.
|
||||||
|
|
||||||
|
// Akses anggota kelas menggunakan ->
|
||||||
|
echo $kelas_saya->properti; // => "publik"
|
||||||
|
echo $kelas_saya->propertiInstansi; // => "Sebuah properti instansi"
|
||||||
|
$kelas_saya->methodSaya(); // => "KelasSaya"
|
||||||
|
|
||||||
|
// Menurunkan kelas menggunakan kata kunci "extends"
|
||||||
|
class KelasSayaLainnya extends KelasSaya
|
||||||
|
{
|
||||||
|
function tampilkanPropertiTerlindungi()
|
||||||
|
{
|
||||||
|
echo $this->properti;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "override" terhadap sebuah method
|
||||||
|
function methodSaya()
|
||||||
|
{
|
||||||
|
parent::methodSaya();
|
||||||
|
print ' > KelasSayaLainnya';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$kelas_saya_lainnya = new KelasSayaLainnya('Instansiasi properti');
|
||||||
|
$kelas_saya_lainnya->tampilkanPropertiTerlindung(); // => Menampilkan "terlindungi"
|
||||||
|
$kelas_saya_lainnya->methodSaya(); // Menampilkan "KelasSaya > KelasSayaLainnya"
|
||||||
|
|
||||||
|
final class SayaTidakBisaDiturunkan
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gunakan method ajaib (magic method) untuk membuat fungsi "getters" dan "setters"
|
||||||
|
class PetaKelasSaya
|
||||||
|
{
|
||||||
|
private $properti;
|
||||||
|
|
||||||
|
public function __get($key)
|
||||||
|
{
|
||||||
|
return $this->$key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($key, $value)
|
||||||
|
{
|
||||||
|
$this->$key = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = new PetaKelasSaya();
|
||||||
|
echo $x->properti; // akan memanggil method __get()
|
||||||
|
$x->properti = 'Sesuatu'; // akan memanggil method __set();
|
||||||
|
|
||||||
|
// Kelas dapat dijadikan abstrak (menggunakan kata kunci "abstract"), atau
|
||||||
|
// meng-implementasikan interfaces (menggunakan kata kunci "implements").
|
||||||
|
// Sebuah interface dideklarasikan dengan perintah "interface".
|
||||||
|
|
||||||
|
interface InterfaceSatu
|
||||||
|
{
|
||||||
|
public function kerjakanSesuatu();
|
||||||
|
}
|
||||||
|
|
||||||
|
interface InterfaceDua
|
||||||
|
{
|
||||||
|
public function kerjakanYangLain();
|
||||||
|
}
|
||||||
|
|
||||||
|
// interface dapat diturunkan
|
||||||
|
interface InterfaceTiga extends InterfaceDua
|
||||||
|
{
|
||||||
|
public function kerjakanYangBerbeda();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class KelasAbstrakSaya implements InterfaceSatu
|
||||||
|
{
|
||||||
|
public $x = 'kerjakanSesuatu';
|
||||||
|
}
|
||||||
|
|
||||||
|
class KelasKongkritSaya extends KelasAbstrakSaya implements InterfaceTwo
|
||||||
|
{
|
||||||
|
public function kerjakanSesuatu()
|
||||||
|
{
|
||||||
|
echo $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function kerjakanYangLain()
|
||||||
|
{
|
||||||
|
echo 'kerjakanYangLain';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kelas dapat diimplementasikan pada banyak interface
|
||||||
|
class KelasLainnya implements InterfaceSatu, InterfaceDua
|
||||||
|
{
|
||||||
|
public function kerjakanSesuatu()
|
||||||
|
{
|
||||||
|
echo 'kerjakanSesuatu';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function kerjakanYangLain()
|
||||||
|
{
|
||||||
|
echo 'kerjakanYangLain';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Sifat (Traits)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Traits mulai tersedia sejak PHP 5.4.0 dan dideklarasikan menggunakan kata kunci "trait"
|
||||||
|
|
||||||
|
trait TraitSaya
|
||||||
|
{
|
||||||
|
public function methodTraitSaya()
|
||||||
|
{
|
||||||
|
print 'Saya menggunakan Trait';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KelasTraitSaya
|
||||||
|
{
|
||||||
|
use TraitSaya;
|
||||||
|
}
|
||||||
|
|
||||||
|
$kls = new KelasTraitSaya();
|
||||||
|
$kls->methodTraitSaya(); // menampilkan "Saya menggunakan Trait"
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* Namespaces
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Bagian ini telah dibatasi, karena deklarasi "namespace"
|
||||||
|
// karena harus ditempatkan diawal dokumen.
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Secara default, kelas tersedia sebagai namespace umum, dan dapat
|
||||||
|
// secara khusus dipanggil dengan garis-miring terbalik (backslash).
|
||||||
|
|
||||||
|
$kls = new \KelasSaya();
|
||||||
|
|
||||||
|
|
||||||
|
// Menentukan namespace untuk sebuah dokumen
|
||||||
|
namespace Saya\Namespace;
|
||||||
|
|
||||||
|
class KelasSaya
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// (dari dokumen lainnya)
|
||||||
|
$kls = new Saya\Namespace\KelasSaya;
|
||||||
|
|
||||||
|
// Atau dari dalam namespace lainnya.
|
||||||
|
namespace Saya\Lainnya\Namespace;
|
||||||
|
|
||||||
|
use Saya\Namespace\KelasSaya;
|
||||||
|
|
||||||
|
$kls = new KelasSaya();
|
||||||
|
|
||||||
|
// Namespace dapat menggunakan alias
|
||||||
|
|
||||||
|
namespace Saya\Lainnya\Namespace;
|
||||||
|
|
||||||
|
use Saya\Namespace as SuatuKelasLainnya;
|
||||||
|
|
||||||
|
$kls = new SuatuKelasLainnya\KelasSaya();
|
||||||
|
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* Late Static Binding
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class KelasInduk {
|
||||||
|
public static function siapa() {
|
||||||
|
echo "Ini adalah " . __CLASS__ . "\n";
|
||||||
|
}
|
||||||
|
public static function coba() {
|
||||||
|
// kata kunci "self" merujuk pada method yang berada dalam satu kelas
|
||||||
|
self::who();
|
||||||
|
// kata kunci "static" merujuk pada method yang berada di kelas dimana method itu dijalankan
|
||||||
|
static::who();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KelasInduk::coba();
|
||||||
|
/*
|
||||||
|
Ini adalah KelasInduk
|
||||||
|
Ini adalah KelasInduk
|
||||||
|
*/
|
||||||
|
|
||||||
|
class KelasAnak extends KelasInduk {
|
||||||
|
public static function siapa() {
|
||||||
|
echo "Tapi ini adalah " . __CLASS__ . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KelasAnak::tes();
|
||||||
|
/*
|
||||||
|
Ini adalah KelasInduk
|
||||||
|
Tapi ini adalah KelasAnak
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* Magic constants
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Mendapatkan nama dari suatu kelas. Harus dideklarasikan didalam kelas tersebut.
|
||||||
|
echo "Nama kelas ini adalah " . __CLASS__;
|
||||||
|
|
||||||
|
// Mendapatkan alamat lengkap direktori
|
||||||
|
echo "Alamat direktori ini adalah " . __DIR__;
|
||||||
|
|
||||||
|
// Beberapa yang banyak digunakan
|
||||||
|
require __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
// Mendapatkan alamat lengkap dokumen
|
||||||
|
echo "Alamat dokumen ini adalah " . __FILE__;
|
||||||
|
|
||||||
|
// Mendapatkan nama fungsi
|
||||||
|
echo "Nama fungsi ini adalah " . __FUNCTION__;
|
||||||
|
|
||||||
|
// Mendapatkan nomor baris perintah
|
||||||
|
echo "Nomor baris perintah ini adalah " . __LINE__;
|
||||||
|
|
||||||
|
// Mendapatkan nama method. Hanya mengembalikan sebuah nilai jika berada didalam trait atau deklarasi objek.
|
||||||
|
echo "Nama method ini adalah " . __METHOD__;
|
||||||
|
|
||||||
|
// Mendapatkan nama namespace
|
||||||
|
echo "Namespace saat ini adalah " . __NAMESPACE__;
|
||||||
|
|
||||||
|
// Mendapatkan nama dari trait. Hanya mengembalikan sebuah nilai jika berada didalam trait atau deklarasi objek.
|
||||||
|
echo "Namespace saat ini adalah " . __TRAIT__;
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* Penanganan Kesalahan (Error)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Penanganan error sederhana menggunakan "try...catch"
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Kerjakan sesuatu
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Penanganan exception
|
||||||
|
}
|
||||||
|
|
||||||
|
// Menggunakan "try...catch" blok pada namespace
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Kerjakan sesuatu
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// Penanganan exception
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exception khusus
|
||||||
|
|
||||||
|
class ExceptionSaya extends Exception {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
$kondisi = true;
|
||||||
|
|
||||||
|
if ($kondisi) {
|
||||||
|
throw new ExceptionSaya('Terjadi sesuatu');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (ExceptionSaya $e) {
|
||||||
|
// Penanganan untuk exception khusus
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Informasi lainnya
|
||||||
|
|
||||||
|
Kunjungi [Dokumentasi resmi PHP](http://www.php.net/manual/) untuk referensi dan masukan komunitas.
|
||||||
|
|
||||||
|
Jika anda tertarik untuk belajar lebih dalam, kunjungi
|
||||||
|
[PHP The Right Way](http://www.phptherightway.com/).
|
||||||
|
|
||||||
|
Jika anda terbiasa dengan manajemen paket, kunjungi
|
||||||
|
[Composer](http://getcomposer.org/).
|
||||||
|
|
||||||
|
Untuk standar umum, kunjungi PHP Framework Interoperability Group's
|
||||||
|
[PSR standards](https://github.com/php-fig/fig-standards).
|
@ -5,19 +5,76 @@ contributors:
|
|||||||
- ["João Farias", "https://github.com/JoaoGFarias"]
|
- ["João Farias", "https://github.com/JoaoGFarias"]
|
||||||
translators:
|
translators:
|
||||||
- ["Rizky Luthfianto", "https://github.com/rilut"]
|
- ["Rizky Luthfianto", "https://github.com/rilut"]
|
||||||
|
- ["Ahmad Zafrullah", "https://github.com/23Pstars"]
|
||||||
lang: id-id
|
lang: id-id
|
||||||
---
|
---
|
||||||
|
|
||||||
XML adalah bahasa markup yang dirancang untuk menyimpan dan mengirim data.
|
XML adalah bahasa markup yang dirancang untuk menyimpan dan mengirim data. XML mudah dibaca oleh manusia dan mesin.
|
||||||
|
|
||||||
Tidak seperti HTML, XML tidak menentukan bagaimana menampilkan atau format data, hanya membawanya.
|
Tidak seperti HTML, XML tidak menentukan bagaimana menampilkan atau format data, hanya membawanya.
|
||||||
|
|
||||||
* Sintaks XML
|
Terdapat perbedaan antara **konten** dan **markup**. Singkatnya, konten dapat berupa apapun dan markup adalah sebagai penentu.
|
||||||
|
|
||||||
|
## Definisi dan Pendahuluan
|
||||||
|
|
||||||
|
Dokumen XML pada dasarnya disusun oleh *elemen* yang dapat memiliki *atribut* untuk menjelaskan elemen tersebut dan dapat memiliki beberapa konten tekstual atau beberapa elemen sebagai anak-nya. Setiap dokumen XML hendaknya memiliki satu elemen akar, yang menjadi induk dari semua elemen dalam dokumen XML.
|
||||||
|
|
||||||
|
Pengurai XML dirancang menjadi sangat ketat, dan akan berhenti melakukan penguraian terhadap dokumen yang cacat. Oleh karena itu semua dokumen XML harus mengikuti [Aturan Sintaks XML](http://www.w3schools.com/xml/xml_syntax.asp).
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<!-- Komentar di XML seperti ini -->
|
<!-- Ini adalah komentar. Komentar harus memiliki dua tanda penghubung secara berurutan (-). -->
|
||||||
|
<!-- Komentar dapat renggang
|
||||||
|
menjadi banyak baris -->
|
||||||
|
|
||||||
|
<!-- Elemen -->
|
||||||
|
<!-- Elemen merupakan komponen dasar dari XML. Ada dua tipe dari elemen, kosong: -->
|
||||||
|
<elemen1 atribut="nilai" /> <!-- Elemen kosong tidak memiliki konten apapun -->
|
||||||
|
<!-- dan tidak-kosong: -->
|
||||||
|
<elemen2 atribut="nilai">Konten</elemen2>
|
||||||
|
<!-- Nama elemen hanya dapat berupa huruf dan angka saja. -->
|
||||||
|
|
||||||
|
<kosong /> <!-- Elemen yang terdiri dari tag elemen kosong… -->
|
||||||
|
<!-- …tidak memiliki content apapun dan murni markup. -->
|
||||||
|
|
||||||
|
<tidakkosong> <!-- Atau, elemen ini memiliki tag pembuka… -->
|
||||||
|
<!-- …suatu konten… -->
|
||||||
|
</tidakkosong> <!-- dan sebuah tag penutup. -->
|
||||||
|
|
||||||
|
<!-- Nama elemen merupakan *case sensitive*. -->
|
||||||
|
<elemen />
|
||||||
|
<!-- …tidak sama dengan elemen sebelumnya -->
|
||||||
|
<eLEMEN />
|
||||||
|
|
||||||
|
<!-- Atribut -->
|
||||||
|
<!-- Sebuah atribut merupakan hubungan kunci-nilai yang terdapat pada elemen. -->
|
||||||
|
<elemen atribut="nilai" lainnya="nilaiLainnya" banyakNilai="daftar nilai ber-spasi" />
|
||||||
|
<!-- Sebuah atribut digunakan hanya sekali dalam sebuah elemen. Dan hanya memiliki satu nilai.
|
||||||
|
Salah satu solusi untuk mengatasi permasalahan tersebut adalah dengan menggunakan daftar nilai ber-spasi. -->
|
||||||
|
|
||||||
|
<!-- Elemen bersarang -->
|
||||||
|
<!-- Konten dari sebuah elemen dapat berupa elemen lainnya:: -->
|
||||||
|
<ayah>
|
||||||
|
<anak>Teks</anak>
|
||||||
|
<oranglain />
|
||||||
|
</ayah>
|
||||||
|
<!-- Mengikuti standar tatanan pohon. Setiap elemen disebut *node*.
|
||||||
|
Induk yang berada satu tingkat diatasnya disebut *parent*, keturunan yang berada satu tingkat dibawahnya disebut *children*.
|
||||||
|
Elemen yang berada pada *parent* yang sama disebut Saudara (*siblings*). -->
|
||||||
|
|
||||||
|
<!-- XML mempertahankan spasi. -->
|
||||||
|
<anak>
|
||||||
|
Teks
|
||||||
|
</anak>
|
||||||
|
<!-- …tidak sama dengan -->
|
||||||
|
<anak>Teks</anak>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Dokumen XML
|
||||||
|
|
||||||
|
```xml
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- XML prolog, boleh tidak digunakan namun direkomendasikan untuk digunakan. -->
|
||||||
<tokobuku>
|
<tokobuku>
|
||||||
<buku category="MEMASAK">
|
<buku category="MEMASAK">
|
||||||
<judul lang="en">Everyday Italian</judul>
|
<judul lang="en">Everyday Italian</judul>
|
||||||
@ -65,7 +122,7 @@ Tidak seperti HTML, XML tidak menentukan bagaimana menampilkan atau format data,
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
* Dokumen yang well-formated & Validasi
|
## Dokumen yang well-formated & Validasi
|
||||||
|
|
||||||
Sebuah dokumen XML disebut well-formated jika sintaksisnya benar.
|
Sebuah dokumen XML disebut well-formated jika sintaksisnya benar.
|
||||||
Namun, juga mungkin untuk mendefinisikan lebih banyak batasan dalam dokumen,
|
Namun, juga mungkin untuk mendefinisikan lebih banyak batasan dalam dokumen,
|
||||||
@ -128,3 +185,17 @@ Dengan alat ini, Anda dapat memeriksa data XML di luar logika aplikasi.
|
|||||||
</buku>
|
</buku>
|
||||||
</tokobuku>
|
</tokobuku>
|
||||||
```
|
```
|
||||||
|
## Kompatibilitas DTD dan Definisi Skema XML
|
||||||
|
|
||||||
|
Dukungan untuk DTD dapat ditemukan dimana-mana karena sudah sangat lama. Namun sayangnya, fitur XML terkini seperti *namespaces* tidak didukung oleh DTD. XML Xchema Definitions (XSDs) bertujuan untuk mengganti DTD dalam mendefinisikan tatabahasa dokumen XML.
|
||||||
|
|
||||||
|
## Sumber
|
||||||
|
|
||||||
|
* [Validasi dokumen XML](http://www.xmlvalidation.com)
|
||||||
|
|
||||||
|
## Bacaan lainnya
|
||||||
|
|
||||||
|
* [XML Schema Definitions Tutorial](http://www.w3schools.com/schema/)
|
||||||
|
* [DTD Tutorial](http://www.w3schools.com/xml/xml_dtd_intro.asp)
|
||||||
|
* [XML Tutorial](http://www.w3schools.com/xml/default.asp)
|
||||||
|
* [Using XPath queries to parse XML](http://www.w3schools.com/xml/xml_xpath.asp)
|
||||||
|
777
ja-jp/php-jp.html.markdown
Normal file
777
ja-jp/php-jp.html.markdown
Normal file
@ -0,0 +1,777 @@
|
|||||||
|
---
|
||||||
|
language: PHP
|
||||||
|
contributors:
|
||||||
|
- ["Malcolm Fell", "http://emarref.net/"]
|
||||||
|
- ["Trismegiste", "https://github.com/Trismegiste"]
|
||||||
|
translators:
|
||||||
|
- ["Kazushige Tominaga", "https://github.com/kazu9su"]
|
||||||
|
filename: learnphp-jp.php
|
||||||
|
lang: ja-jp
|
||||||
|
---
|
||||||
|
|
||||||
|
このドキュメントでは、 PHP 5+ について説明します。
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php // PHPのコードは、<?php タグで囲む必要があります。
|
||||||
|
|
||||||
|
// もしあなたのphpファイルがPHPのみで構成される場合、
|
||||||
|
// 意図しない出力を防ぐために、phpの閉じタグは省略するのがベストプラクティスです。
|
||||||
|
// 一行のコメントを書く場合、2つのスラッシュで始めます。
|
||||||
|
# ハッシュ(ポンド記号として知られる)を使いたいでしょうが、//のほうが一般的です
|
||||||
|
/*
|
||||||
|
スラッシュとアスタリスク、アスタリスクとスラッシュで囲むと、
|
||||||
|
複数行のコメントを書けます。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 出力をプリントしたい場合は、"echo" か "print" を使います。
|
||||||
|
print('Hello '); // これは "Hello " という改行なしの文字列をプリントします。
|
||||||
|
|
||||||
|
// カッコ()はprintとecho関数に置いては省略できます。
|
||||||
|
echo "World\n"; // これは改行ありの"World"という文字列をプリントします。
|
||||||
|
// (全ての命令文では、セミコロンを最後に付けることが必須です。)
|
||||||
|
|
||||||
|
// <?php タグの外側にあるものは、自動的にプリントされます。
|
||||||
|
?>
|
||||||
|
Hello World Again!
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
* 型と変数について
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 変数は"$"マークで始まります
|
||||||
|
// 有効な変数名にするには、文字またはアンダースコア(_)で始めて,
|
||||||
|
// その後はどんな数字でも、文字でも、アンダースコアで続けても構いません
|
||||||
|
|
||||||
|
//ブーリアン値は大文字、小文字問いません
|
||||||
|
$boolean = true; // or TRUE or True
|
||||||
|
$boolean = false; // or FALSE or False
|
||||||
|
|
||||||
|
// 数値
|
||||||
|
$int1 = 12; // => 12
|
||||||
|
$int2 = -12; // => -12
|
||||||
|
$int3 = 012; // => 10 (先頭の0は8進法を示す)
|
||||||
|
$int4 = 0x0F; // => 15 (先頭の0xは16進法を示す)
|
||||||
|
|
||||||
|
// floats(浮動小数) (別名double)
|
||||||
|
$float = 1.234;
|
||||||
|
$float = 1.2e3;
|
||||||
|
$float = 7E-10;
|
||||||
|
|
||||||
|
// 変数の削除
|
||||||
|
unset($int1);
|
||||||
|
|
||||||
|
// 計算式
|
||||||
|
$sum = 1 + 1; // 2
|
||||||
|
$difference = 2 - 1; // 1
|
||||||
|
$product = 2 * 2; // 4
|
||||||
|
$quotient = 2 / 1; // 2
|
||||||
|
|
||||||
|
// 式の省略
|
||||||
|
$number = 0;
|
||||||
|
$number += 1; // $numberに1加算Increment $number by 1
|
||||||
|
echo $number++; // 1 がプリントされる(式の評価の後に加算される)
|
||||||
|
echo ++$number; // 3 がプリントされる(式の評価の前に加算される)
|
||||||
|
$number /= $float; // 割り算した結果の商を$numberに割り当てる
|
||||||
|
|
||||||
|
// 文字列はシングルクォートで囲むのが望ましいです
|
||||||
|
$sgl_quotes = '$String'; // => '$String'
|
||||||
|
|
||||||
|
// 文字列中に、他の変数を埋め込みたい場合以外は、ダブルクォートを使用するのはやめましょう
|
||||||
|
$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'
|
||||||
|
|
||||||
|
// Special characters are only escaped in double quotes
|
||||||
|
// 特殊文字はダブルクォートによってのみ、エスケープされます
|
||||||
|
$escaped = "This contains a \t tab character.";
|
||||||
|
$unescaped = 'This just contains a slash and a t: \t';
|
||||||
|
|
||||||
|
// 必要があれば、変数を波括弧で囲みます
|
||||||
|
$money = "I have $${number} in the bank.";
|
||||||
|
|
||||||
|
// PHP 5.3から、nowdocs形式が変数の挿入をしない複数行の文字列の定義に使用できます
|
||||||
|
$nowdoc = <<<'END'
|
||||||
|
Multi line
|
||||||
|
string
|
||||||
|
END;
|
||||||
|
|
||||||
|
// ヒアドキュメント形式なら、文字列中に変数の挿入を行えます。
|
||||||
|
$heredoc = <<<END
|
||||||
|
Multi line
|
||||||
|
$sgl_quotes
|
||||||
|
END;
|
||||||
|
|
||||||
|
// 文字列の連結は . で行います
|
||||||
|
echo 'This string ' . 'is concatenated';
|
||||||
|
|
||||||
|
// 別々のパラメータとしてechoに渡すこともできます
|
||||||
|
echo 'Multiple', 'Parameters', 'Valid';
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* 定数
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 定数は define() を使って定義します
|
||||||
|
// また、実行中は変更することができないので注意が必要です!
|
||||||
|
|
||||||
|
// 有効は定数は文字かアンダースコアで始めます
|
||||||
|
// それ移行のは、どんな数値でも文字列でもアンダースコアでも構いません
|
||||||
|
define("FOO", "something");
|
||||||
|
|
||||||
|
// 定義した名前をそのまま($はつけずに)使用することで、定数にアクセスできます
|
||||||
|
// access to a constant is possible by direct using the choosen name
|
||||||
|
echo 'This outputs '.FOO;
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* 配列
|
||||||
|
*/
|
||||||
|
|
||||||
|
// PHPの配列はすべて連想配列です
|
||||||
|
|
||||||
|
// 連想配列は、他の言語ではハッシュ(ハッシュマップ)として知られています
|
||||||
|
|
||||||
|
// すべてのバージョンのPHPで動作します
|
||||||
|
$associative = array('One' => 1, 'Two' => 2, 'Three' => 3);
|
||||||
|
|
||||||
|
// PHP 5.4 から、新しいシンタックスが導入されました
|
||||||
|
$associative = ['One' => 1, 'Two' => 2, 'Three' => 3];
|
||||||
|
|
||||||
|
echo $associative['One']; // 1とプリントされます
|
||||||
|
|
||||||
|
// キーを指定しないシンプルな配列にも、自動的に数値キーが振られます
|
||||||
|
$array = ['One', 'Two', 'Three'];
|
||||||
|
echo $array[0]; // => "One"
|
||||||
|
|
||||||
|
// 配列の最後に要素を追加する
|
||||||
|
$array[] = 'Four';
|
||||||
|
// または、次のようにも書けます
|
||||||
|
array_push($array, 'Five');
|
||||||
|
|
||||||
|
// 配列から要素を削除
|
||||||
|
unset($array[3]);
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* 出力
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo('Hello World!');
|
||||||
|
// 標準出力にHello World! とプリントします
|
||||||
|
// 標準出力はブラウザーで実行していればWebページに出力されます
|
||||||
|
// Stdout is the web page if running in a browser.
|
||||||
|
|
||||||
|
print('Hello World!'); // echoの結果と同じです
|
||||||
|
|
||||||
|
// echo は言語自体の構成要素であり、括弧なしで呼び出せます
|
||||||
|
// echo is actually a language construct, so you can drop the parentheses.
|
||||||
|
echo 'Hello World!';
|
||||||
|
print 'Hello World!'; // printも同様です
|
||||||
|
|
||||||
|
$paragraph = 'paragraph';
|
||||||
|
|
||||||
|
echo 100; // スカラー数値を直接出力します
|
||||||
|
echo $paragraph; // 変数も使用できます
|
||||||
|
|
||||||
|
// PHPタグの短縮型が設定されているか、使用しているPHPのバージョンが
|
||||||
|
// 5.4.0 以上であれば、短縮echoシンタックスを使用できます
|
||||||
|
?>
|
||||||
|
<p><?= $paragraph ?></p>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$x = 1;
|
||||||
|
$y = 2;
|
||||||
|
$x = $y; // $xに$yの値を代入します
|
||||||
|
$z = &$y;
|
||||||
|
// $zは$yへの参照です。
|
||||||
|
// $zの値を変更すると$yの値も変更されるでしょう。逆も同様です。
|
||||||
|
// $xは$yの最初の値を変わらず保持しています
|
||||||
|
|
||||||
|
echo $x; // => 2
|
||||||
|
echo $z; // => 2
|
||||||
|
$y = 0;
|
||||||
|
echo $x; // => 2
|
||||||
|
echo $z; // => 0
|
||||||
|
|
||||||
|
// 変数の型と値を標準出力へダンプします
|
||||||
|
var_dump($z); // int(0) と出力されます
|
||||||
|
|
||||||
|
// 人間が読めるフォーマットで変数を標準出力にプリントします
|
||||||
|
print_r($array); // prints: Array ( [0] => One [1] => Two [2] => Three )
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* ロジック
|
||||||
|
*/
|
||||||
|
$a = 0;
|
||||||
|
$b = '0';
|
||||||
|
$c = '1';
|
||||||
|
$d = '1';
|
||||||
|
|
||||||
|
// assertは引数がfalseの場合、Exceptionを投げます
|
||||||
|
|
||||||
|
//これらの比較は型が違ったとしても、常に真です。
|
||||||
|
assert($a == $b); // equality
|
||||||
|
assert($c != $a); // inequality
|
||||||
|
assert($c <> $a); // alternative inequality
|
||||||
|
assert($a < $c);
|
||||||
|
assert($c > $b);
|
||||||
|
assert($a <= $b);
|
||||||
|
assert($c >= $d);
|
||||||
|
|
||||||
|
// 次の比較は値が等しく、かつ同じ型である場合のみ真です
|
||||||
|
assert($c === $d);
|
||||||
|
assert($a !== $d);
|
||||||
|
assert(1 === '1');
|
||||||
|
assert(1 !== '1');
|
||||||
|
|
||||||
|
// spaceship演算子はPHP7から使用可能です
|
||||||
|
$a = 100;
|
||||||
|
$b = 1000;
|
||||||
|
|
||||||
|
echo $a <=> $a; // 等しいので0になります
|
||||||
|
echo $a <=> $b; // $a < $b なので -1 です
|
||||||
|
echo $b <=> $a; // $b > $a なので 1 です
|
||||||
|
|
||||||
|
// 変数は使用するコンテキストによって、変換されます
|
||||||
|
|
||||||
|
$integer = 1;
|
||||||
|
echo $integer + $integer; // => 2
|
||||||
|
|
||||||
|
$string = '1';
|
||||||
|
echo $string + $string; // => 2 (文字列は強制的に数値として処理されます)
|
||||||
|
|
||||||
|
$string = 'one';
|
||||||
|
echo $string + $string; // => 0
|
||||||
|
// '+'演算子は文字列'one'を数値にキャストできないので、0と出力されます
|
||||||
|
|
||||||
|
// 型のキャスティングによって、変数を指定したもう一つの型として扱うことができます
|
||||||
|
// Type casting can be used to treat a variable as another type
|
||||||
|
|
||||||
|
$boolean = (boolean) 1; // => true
|
||||||
|
|
||||||
|
$zero = 0;
|
||||||
|
$boolean = (boolean) $zero; // => false
|
||||||
|
|
||||||
|
// 型をキャストするため専用の関数も存在します
|
||||||
|
$integer = 5;
|
||||||
|
$string = strval($integer);
|
||||||
|
|
||||||
|
$var = null; // Null値
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* 制御構造
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
print 'I get printed';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
print 'I don\'t';
|
||||||
|
} else {
|
||||||
|
print 'I get printed';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
print 'Does not get printed';
|
||||||
|
} elseif(true) {
|
||||||
|
print 'Does';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 三項演算子
|
||||||
|
print (false ? 'Does not get printed' : 'Does');
|
||||||
|
|
||||||
|
// PHP 5.3から、三項演算子の短縮形が使用できます
|
||||||
|
// $x ? $x : 'Does'と同義です
|
||||||
|
$x = false;
|
||||||
|
print($x ?: 'Does');
|
||||||
|
|
||||||
|
// null合体演算子はPHP 7から使用できます
|
||||||
|
$a = null;
|
||||||
|
$b = 'Does print';
|
||||||
|
echo $a ?? 'a is not set'; // prints 'a is not set'
|
||||||
|
echo $b ?? 'b is not set'; // prints 'Does print'
|
||||||
|
|
||||||
|
|
||||||
|
$x = 0;
|
||||||
|
if ($x === '0') {
|
||||||
|
print 'Does not print';
|
||||||
|
} elseif($x == '1') {
|
||||||
|
print 'Does not print';
|
||||||
|
} else {
|
||||||
|
print 'Does print';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// :を用いる別の構文はテンプレートで有用です
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if ($x): ?>
|
||||||
|
この部分はifが真のとき表示されます
|
||||||
|
<?php else: ?>
|
||||||
|
それ以外の場合は、この部分が表示されます
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// いくつかのロジックを保存するにはswitchを使用します
|
||||||
|
switch ($x) {
|
||||||
|
case '0':
|
||||||
|
print 'Switch does type coercion';
|
||||||
|
break; // breakを書く必要があります。
|
||||||
|
// でなければ、次の'two', 'three'のcase文を続けて実行することになります。
|
||||||
|
case 'two':
|
||||||
|
case 'three':
|
||||||
|
// 変数が'two'または'three'の場合、何かを実行します
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//デフォルトで何かを実行します
|
||||||
|
}
|
||||||
|
|
||||||
|
// while, do, forの構文は、おそらく他の言語とも共通なものです
|
||||||
|
$i = 0;
|
||||||
|
while ($i < 5) {
|
||||||
|
echo $i++;
|
||||||
|
}; // Prints "01234"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
do {
|
||||||
|
echo $i++;
|
||||||
|
} while ($i < 5); // Prints "01234"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
for ($x = 0; $x < 10; $x++) {
|
||||||
|
echo $x;
|
||||||
|
} // Prints "0123456789"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
$wheels = ['bicycle' => 2, 'car' => 4];
|
||||||
|
|
||||||
|
//Foreachループによって、 配列を反復処理できます
|
||||||
|
foreach ($wheels as $wheel_count) {
|
||||||
|
echo $wheel_count;
|
||||||
|
} // Prints "24"
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
// 値と同じ様に、keyも反復処理できます
|
||||||
|
foreach ($wheels as $vehicle => $wheel_count) {
|
||||||
|
echo "A $vehicle has $wheel_count wheels";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "\n";
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
while ($i < 5) {
|
||||||
|
if ($i === 3) {
|
||||||
|
break; // Exit out of the while loop
|
||||||
|
}
|
||||||
|
echo $i++;
|
||||||
|
} // Prints "012"
|
||||||
|
|
||||||
|
for ($i = 0; $i < 5; $i++) {
|
||||||
|
if ($i === 3) {
|
||||||
|
continue; // Skip this iteration of the loop
|
||||||
|
}
|
||||||
|
echo $i;
|
||||||
|
} // Prints "0124"
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* 関数
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 関数を"function"で定義します
|
||||||
|
function my_function () {
|
||||||
|
return 'Hello';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo my_function(); // => "Hello"
|
||||||
|
|
||||||
|
// 有効な関数名は、文字またはアンダースコアで始めます。それ以降は
|
||||||
|
// どれだけ長い文字、数値、アンダースコアを続けても構いません
|
||||||
|
|
||||||
|
function add ($x, $y = 1) { // $yはオプショナルな値であり、デフォルトで 1 です
|
||||||
|
$result = $x + $y;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo add(4); // => 5
|
||||||
|
echo add(4, 2); // => 6
|
||||||
|
|
||||||
|
// $result には、関数の外からアクセス出来ません
|
||||||
|
// print $result; // エラーになります
|
||||||
|
|
||||||
|
// PHP 5.3 から、無名関数が使えます
|
||||||
|
$inc = function ($x) {
|
||||||
|
return $x + 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
echo $inc(2); // => 3
|
||||||
|
|
||||||
|
function foo ($x, $y, $z) {
|
||||||
|
echo "$x - $y - $z";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 関数は、関数を返すことができます
|
||||||
|
function bar ($x, $y) {
|
||||||
|
// 関数外の変数を利用したいときは、'use'を使います
|
||||||
|
return function ($z) use ($x, $y) {
|
||||||
|
foo($x, $y, $z);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$bar = bar('A', 'B');
|
||||||
|
$bar('C'); // Prints "A - B - C"
|
||||||
|
|
||||||
|
// 文字列を使って、定義済みの関数を呼び出すことができます
|
||||||
|
$function_name = 'add';
|
||||||
|
echo $function_name(1, 2); // => 3
|
||||||
|
|
||||||
|
// プログラミング中に、動的に動かす関数を決める場合に便利です。
|
||||||
|
// もしくは、call_user_func(callable $callback [, $parameter [, ... ]]) を使っても同じことができます
|
||||||
|
|
||||||
|
|
||||||
|
// 特に指定しなくても、渡された引数を受け取ることもできます
|
||||||
|
function parameters() {
|
||||||
|
$numargs = func_num_args();
|
||||||
|
if ($numargs > 0) {
|
||||||
|
echo func_get_arg(0) . ' | ';
|
||||||
|
}
|
||||||
|
$args_array = func_get_args();
|
||||||
|
foreach ($args_array as $key => $arg) {
|
||||||
|
echo $key . ' - ' . $arg . ' | ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters('Hello', 'World'); // Hello | 0 - Hello | 1 - World |
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* ファイルの読み込み
|
||||||
|
*/
|
||||||
|
|
||||||
|
<?php
|
||||||
|
// 読み込まれたファイル中のPHPは、同じくPHPのオープンタグで始める必要があります
|
||||||
|
|
||||||
|
include 'my-file.php';
|
||||||
|
// my-file.php中のコードは、現在のスコープの中で使用可能です
|
||||||
|
// もしファイルを読み込めなければ (例:file not found)、警告が発せられます
|
||||||
|
|
||||||
|
include_once 'my-file.php';
|
||||||
|
// my-file.phpのコードが既にどこかで読み込まれていれば、
|
||||||
|
// ファイルを読み込みません。これは、クラスの多重定義のエラーを防ぎます
|
||||||
|
|
||||||
|
require 'my-file.php';
|
||||||
|
require_once 'my-file.php';
|
||||||
|
// include()と同じように、require()はもしファイルを読み込むことができなければ、
|
||||||
|
// 致命的エラーの原因となります
|
||||||
|
|
||||||
|
// my-include.phpの内容
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return 'Anything you like.';
|
||||||
|
// End file
|
||||||
|
|
||||||
|
// include()とrequire()は一つの値を返します
|
||||||
|
$value = include 'my-include.php';
|
||||||
|
|
||||||
|
// ファイルは与えられたファイルパスを基に読み込まれます。
|
||||||
|
// ファイルパスを指定しない場合は、include_path の設定を利用します。
|
||||||
|
// もしファイルがinclude_path中に見つからない場合は、
|
||||||
|
// 呼び出し元スクリプトのディレクトリと作業ディレクトリの中も探します。
|
||||||
|
// それでも見つからない場合、失敗します。
|
||||||
|
/* */
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* クラス
|
||||||
|
*/
|
||||||
|
|
||||||
|
// クラスはclassキーワードで定義します
|
||||||
|
|
||||||
|
class MyClass
|
||||||
|
{
|
||||||
|
const MY_CONST = 'value'; // クラス定数です
|
||||||
|
|
||||||
|
static $staticVar = 'static';
|
||||||
|
|
||||||
|
// スタティック変数とアクセス制限
|
||||||
|
public static $publicStaticVar = 'publicStatic';
|
||||||
|
// クラス内でのみアクセス可能
|
||||||
|
private static $privateStaticVar = 'privateStatic';
|
||||||
|
// そのクラスと子クラスで参照可能
|
||||||
|
protected static $protectedStaticVar = 'protectedStatic';
|
||||||
|
|
||||||
|
// プロパティはアクセス制限を宣言する必要があります
|
||||||
|
public $property = 'public';
|
||||||
|
public $instanceProp;
|
||||||
|
protected $prot = 'protected'; // そのクラスと子クラスで参照可能
|
||||||
|
private $priv = 'private'; // クラス内でのみアクセス可能
|
||||||
|
|
||||||
|
// __constructでコンストラクターを生成します
|
||||||
|
public function __construct($instanceProp) {
|
||||||
|
// $thisでインスタンス変数にアクセスします
|
||||||
|
$this->instanceProp = $instanceProp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// メソッドはクラス内で関数として定義されます
|
||||||
|
public function myMethod()
|
||||||
|
{
|
||||||
|
print 'MyClass';
|
||||||
|
}
|
||||||
|
|
||||||
|
// finalキーワードは関数の上書きを禁止します
|
||||||
|
final function youCannotOverrideMe()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* クラスプロパティまたはメソッドをstaticとして作成すれば、
|
||||||
|
* クラスをインスタンス化(newすること)しなくてもアクセスできます。
|
||||||
|
* プロパティをstaticとして定義すると、
|
||||||
|
* インスタンス化されたクラスオブジェクトを通してのアクセスはできなくなります。
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static function myStaticMethod()
|
||||||
|
{
|
||||||
|
print 'I am static';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// クラス定数は、いつでも静的にアクセスできます。
|
||||||
|
echo MyClass::MY_CONST; // Outputs 'value';
|
||||||
|
|
||||||
|
echo MyClass::$staticVar; // Outputs 'static';
|
||||||
|
MyClass::myStaticMethod(); // Outputs 'I am static';
|
||||||
|
|
||||||
|
// クラスをインスタンス化するには、newを使います。
|
||||||
|
$my_class = new MyClass('An instance property');
|
||||||
|
// 括弧はもし引数を渡す必要がなければ省略可能です。
|
||||||
|
|
||||||
|
// ->を使ってクラスのメンバにアクセスします。
|
||||||
|
echo $my_class->property; // => "public"
|
||||||
|
echo $my_class->instanceProp; // => "An instance property"
|
||||||
|
$my_class->myMethod(); // => "MyClass"
|
||||||
|
|
||||||
|
|
||||||
|
// extendsを使用してクラスを継承します。
|
||||||
|
class MyOtherClass extends MyClass
|
||||||
|
{
|
||||||
|
function printProtectedProperty()
|
||||||
|
{
|
||||||
|
echo $this->prot;
|
||||||
|
}
|
||||||
|
|
||||||
|
// メソッドを上書きします。
|
||||||
|
function myMethod()
|
||||||
|
{
|
||||||
|
parent::myMethod();
|
||||||
|
print ' > MyOtherClass';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$my_other_class = new MyOtherClass('Instance prop');
|
||||||
|
$my_other_class->printProtectedProperty(); // => Prints "protected"
|
||||||
|
$my_other_class->myMethod(); // Prints "MyClass > MyOtherClass"
|
||||||
|
|
||||||
|
final class YouCannotExtendMe
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// 「マジックメソッド」を使ってゲッターとセッターを生成できます。
|
||||||
|
class MyMapClass
|
||||||
|
{
|
||||||
|
private $property;
|
||||||
|
|
||||||
|
public function __get($key)
|
||||||
|
{
|
||||||
|
return $this->$key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($key, $value)
|
||||||
|
{
|
||||||
|
$this->$key = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = new MyMapClass();
|
||||||
|
echo $x->property; // __get() メソッドを使用します
|
||||||
|
$x->property = 'Something'; // __set() メソッドを使用します
|
||||||
|
|
||||||
|
// クラスは抽象クラスにもできます(abstractキーワードを使用します)し、
|
||||||
|
// インターフェースを実装することもできます(implementsキーワードを使用します)。
|
||||||
|
// インターフェースはinterfaceキーワードで定義します。
|
||||||
|
|
||||||
|
interface InterfaceOne
|
||||||
|
{
|
||||||
|
public function doSomething();
|
||||||
|
}
|
||||||
|
|
||||||
|
interface InterfaceTwo
|
||||||
|
{
|
||||||
|
public function doSomethingElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
// インターフェースは継承することができます
|
||||||
|
interface InterfaceThree extends InterfaceTwo
|
||||||
|
{
|
||||||
|
public function doAnotherContract();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class MyAbstractClass implements InterfaceOne
|
||||||
|
{
|
||||||
|
public $x = 'doSomething';
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyConcreteClass extends MyAbstractClass implements InterfaceTwo
|
||||||
|
{
|
||||||
|
public function doSomething()
|
||||||
|
{
|
||||||
|
echo $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function doSomethingElse()
|
||||||
|
{
|
||||||
|
echo 'doSomethingElse';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// クラスは1つ以上のインターフェースを実装できます。
|
||||||
|
class SomeOtherClass implements InterfaceOne, InterfaceTwo
|
||||||
|
{
|
||||||
|
public function doSomething()
|
||||||
|
{
|
||||||
|
echo 'doSomething';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function doSomethingElse()
|
||||||
|
{
|
||||||
|
echo 'doSomethingElse';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* トレイト
|
||||||
|
*/
|
||||||
|
|
||||||
|
// トレイトはPHP 5.4.0 以上で使用可能で、traitキーワードで定義します。
|
||||||
|
|
||||||
|
trait MyTrait
|
||||||
|
{
|
||||||
|
public function myTraitMethod()
|
||||||
|
{
|
||||||
|
print 'I have MyTrait';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyTraitfulClass
|
||||||
|
{
|
||||||
|
use MyTrait;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cls = new MyTraitfulClass();
|
||||||
|
$cls->myTraitMethod(); // Prints "I have MyTrait"
|
||||||
|
|
||||||
|
|
||||||
|
/********************************
|
||||||
|
* 名前空間
|
||||||
|
*/
|
||||||
|
|
||||||
|
// このセクションは名前空間の定義はファイルの先頭で宣言される必要があるため、
|
||||||
|
// 独立しています。
|
||||||
|
// そのケースには当てはまらないふりをして続けましょう。
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// デフォルトでは、クラスはグローバルな名前空間に存在し、
|
||||||
|
// バックスラッシュによって明確にコールできます。
|
||||||
|
|
||||||
|
$cls = new \MyClass();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ファイルに名前空間をセットします
|
||||||
|
namespace My\Namespace;
|
||||||
|
|
||||||
|
class MyClass
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// (別のファイルからの呼び出し)
|
||||||
|
$cls = new My\Namespace\MyClass;
|
||||||
|
|
||||||
|
// 異なる名前空間からの呼び出し
|
||||||
|
namespace My\Other\Namespace;
|
||||||
|
|
||||||
|
use My\Namespace\MyClass;
|
||||||
|
|
||||||
|
$cls = new MyClass();
|
||||||
|
|
||||||
|
// 名前空間に別名をつけることもできます
|
||||||
|
|
||||||
|
namespace My\Other\Namespace;
|
||||||
|
|
||||||
|
use My\Namespace as SomeOtherNamespace;
|
||||||
|
|
||||||
|
$cls = new SomeOtherNamespace\MyClass();
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* エラーハンドリング
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// シンプルなエラーハンドリングは、try catchを使えば行えます
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 処理を実行します
|
||||||
|
} catch ( Exception $e) {
|
||||||
|
// 例外を処理します
|
||||||
|
}
|
||||||
|
|
||||||
|
// try catchを名前空間を持った環境で使用するときは、次のようにします。
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Do something
|
||||||
|
// 処理を実行します
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// 例外を処理します
|
||||||
|
}
|
||||||
|
|
||||||
|
// 例外のカスタマイズ
|
||||||
|
|
||||||
|
class MyException extends Exception {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
$condition = true;
|
||||||
|
|
||||||
|
if ($condition) {
|
||||||
|
throw new MyException('Something just happend');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (MyException $e) {
|
||||||
|
// Handle my exception
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## より詳しい情報
|
||||||
|
|
||||||
|
リファレンスを見るため、またコミュニティへの情報提供のために、 [PHP公式ドキュメント](http://www.php.net/manual/) を訪れてみてください。
|
||||||
|
|
||||||
|
もし最新のベストプラクティスに興味があるなら、
|
||||||
|
[PHP The Right Way](http://www.phptherightway.com/)を訪れてみてください。
|
||||||
|
|
||||||
|
|
||||||
|
もしあなたがよいパッケージマネジメント・システムを持つ言語で開発経験があるのなら、
|
||||||
|
[Composer](http://getcomposer.org/)も確かめてみてください。
|
||||||
|
|
||||||
|
|
||||||
|
共通基準を知るためには、PHP Framework Interoperability Groupの
|
||||||
|
[PSR standards](https://github.com/php-fig/fig-standards)にも訪れてみてください。
|
@ -5,6 +5,7 @@ language: perl
|
|||||||
filename: learnperl.pl
|
filename: learnperl.pl
|
||||||
contributors:
|
contributors:
|
||||||
- ["Korjavin Ivan", "http://github.com/korjavin"]
|
- ["Korjavin Ivan", "http://github.com/korjavin"]
|
||||||
|
- ["Dan Book", "http://github.com/Grinnz"]
|
||||||
---
|
---
|
||||||
|
|
||||||
Perl 5 is a highly capable, feature-rich programming language with over 25 years of development.
|
Perl 5 is a highly capable, feature-rich programming language with over 25 years of development.
|
||||||
@ -14,6 +15,15 @@ Perl 5 runs on over 100 platforms from portables to mainframes and is suitable f
|
|||||||
```perl
|
```perl
|
||||||
# Single line comments start with a number sign.
|
# Single line comments start with a number sign.
|
||||||
|
|
||||||
|
#### Strict and warnings
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
# All perl scripts and modules should include these lines. Strict causes
|
||||||
|
# compilation to fail in cases like misspelled variable names, and warnings
|
||||||
|
# will print warning messages in case of common pitfalls like concatenating
|
||||||
|
# to an undefined value.
|
||||||
|
|
||||||
#### Perl variable types
|
#### Perl variable types
|
||||||
|
|
||||||
@ -37,7 +47,9 @@ my @animals = ("camel", "llama", "owl");
|
|||||||
my @numbers = (23, 42, 69);
|
my @numbers = (23, 42, 69);
|
||||||
my @mixed = ("camel", 42, 1.23);
|
my @mixed = ("camel", 42, 1.23);
|
||||||
|
|
||||||
|
# Array elements are accessed using square brackets, with a $ to indicate
|
||||||
|
# one value will be returned.
|
||||||
|
my $second = $animals[1];
|
||||||
|
|
||||||
## Hashes
|
## Hashes
|
||||||
# A hash represents a set of key/value pairs:
|
# A hash represents a set of key/value pairs:
|
||||||
@ -50,11 +62,39 @@ my %fruit_color = (
|
|||||||
apple => "red",
|
apple => "red",
|
||||||
banana => "yellow",
|
banana => "yellow",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# Hash elements are accessed using curly braces, again with the $ sigil.
|
||||||
|
my $color = $fruit_color{apple};
|
||||||
|
|
||||||
# Scalars, arrays and hashes are documented more fully in perldata.
|
# Scalars, arrays and hashes are documented more fully in perldata.
|
||||||
# (perldoc perldata).
|
# (perldoc perldata).
|
||||||
|
|
||||||
# More complex data types can be constructed using references, which allow you
|
#### References
|
||||||
# to build lists and hashes within lists and hashes.
|
|
||||||
|
# More complex data types can be constructed using references, which allow
|
||||||
|
# you to build arrays and hashes within arrays and hashes.
|
||||||
|
|
||||||
|
my $array_ref = \@array;
|
||||||
|
my $hash_ref = \%hash;
|
||||||
|
my @array_of_arrays = (\@array1, \@array2, \@array3);
|
||||||
|
|
||||||
|
# You can also create anonymous arrays or hashes, returning a reference:
|
||||||
|
|
||||||
|
my $fruits = ["apple", "banana"];
|
||||||
|
my $colors = {apple => "red", banana => "yellow"};
|
||||||
|
|
||||||
|
# References can be dereferenced by prefixing the appropriate sigil.
|
||||||
|
|
||||||
|
my @fruits_array = @$fruits;
|
||||||
|
my %colors_hash = %$colors;
|
||||||
|
|
||||||
|
# As a shortcut, the arrow operator can be used to dereference and access a
|
||||||
|
# single value.
|
||||||
|
|
||||||
|
my $first = $array_ref->[0];
|
||||||
|
my $value = $hash_ref->{banana};
|
||||||
|
|
||||||
|
# See perlreftut and perlref for more in-depth documentation on references.
|
||||||
|
|
||||||
#### Conditional and looping constructs
|
#### Conditional and looping constructs
|
||||||
|
|
||||||
@ -105,6 +145,9 @@ for (@elements) {
|
|||||||
# the Perlish post-condition way again
|
# the Perlish post-condition way again
|
||||||
print for @elements;
|
print for @elements;
|
||||||
|
|
||||||
|
# iterating through the keys and values of a referenced hash
|
||||||
|
print $hash_ref->{$_} for keys %$hash_ref;
|
||||||
|
|
||||||
#### Regular expressions
|
#### Regular expressions
|
||||||
|
|
||||||
# Perl's regular expression support is both broad and deep, and is the subject
|
# Perl's regular expression support is both broad and deep, and is the subject
|
||||||
@ -151,11 +194,101 @@ sub logger {
|
|||||||
# Now we can use the subroutine just as any other built-in function:
|
# Now we can use the subroutine just as any other built-in function:
|
||||||
|
|
||||||
logger("We have a logger subroutine!");
|
logger("We have a logger subroutine!");
|
||||||
|
|
||||||
|
#### Modules
|
||||||
|
|
||||||
|
# A module is a set of Perl code, usually subroutines, which can be used in
|
||||||
|
# other Perl code. It is usually stored in a file with the extension .pm so
|
||||||
|
# that Perl can find it.
|
||||||
|
|
||||||
|
package MyModule;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
sub trim {
|
||||||
|
my $string = shift;
|
||||||
|
$string =~ s/^\s+//;
|
||||||
|
$string =~ s/\s+$//;
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# From elsewhere:
|
||||||
|
|
||||||
|
use MyModule;
|
||||||
|
MyModule::trim($string);
|
||||||
|
|
||||||
|
# The Exporter module can help with making subroutines exportable, so they
|
||||||
|
# can be used like this:
|
||||||
|
|
||||||
|
use MyModule 'trim';
|
||||||
|
trim($string);
|
||||||
|
|
||||||
|
# Many Perl modules can be downloaded from CPAN (http://www.cpan.org/) and
|
||||||
|
# provide a range of features to help you avoid reinventing the wheel. A
|
||||||
|
# number of popular modules like Exporter are included with the Perl
|
||||||
|
# distribution itself. See perlmod for more details on modules in Perl.
|
||||||
|
|
||||||
|
#### Objects
|
||||||
|
|
||||||
|
# Objects in Perl are just references that know which class (package) they
|
||||||
|
# belong to, so that methods (subroutines) called on it can be found there.
|
||||||
|
# The bless function is used in constructors (usually new) to set this up.
|
||||||
|
# However, you never need to call it yourself if you use a module like Moose
|
||||||
|
# or Moo (see below).
|
||||||
|
|
||||||
|
package MyCounter;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
my $class = shift;
|
||||||
|
my $self = {count => 0};
|
||||||
|
return bless $self, $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub count {
|
||||||
|
my $self = shift;
|
||||||
|
return $self->{count};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub increment {
|
||||||
|
my $self = shift;
|
||||||
|
$self->{count}++;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# Methods can be called on a class or object instance with the arrow operator.
|
||||||
|
|
||||||
|
use MyCounter;
|
||||||
|
my $counter = MyCounter->new;
|
||||||
|
print $counter->count, "\n"; # 0
|
||||||
|
$counter->increment;
|
||||||
|
print $counter->count, "\n"; # 1
|
||||||
|
|
||||||
|
# The modules Moose and Moo from CPAN can help you set up your object classes.
|
||||||
|
# They provide a constructor and simple syntax for declaring attributes. This
|
||||||
|
# class can be used equivalently to the one above.
|
||||||
|
|
||||||
|
package MyCounter;
|
||||||
|
use Moo; # imports strict and warnings
|
||||||
|
|
||||||
|
has 'count' => (is => 'rwp', default => 0, init_arg => undef);
|
||||||
|
|
||||||
|
sub increment {
|
||||||
|
my $self = shift;
|
||||||
|
$self->_set_count($self->count + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# Object-oriented programming is covered more thoroughly in perlootut, and its
|
||||||
|
# low-level implementation in Perl is covered in perlobj.
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Using Perl modules
|
#### FAQ
|
||||||
|
|
||||||
Perl modules provide a range of features to help you avoid reinventing the wheel, and can be downloaded from CPAN (http://www.cpan.org/). A number of popular modules are included with the Perl distribution itself.
|
|
||||||
|
|
||||||
perlfaq contains questions and answers related to many common tasks, and often provides suggestions for good CPAN modules to use.
|
perlfaq contains questions and answers related to many common tasks, and often provides suggestions for good CPAN modules to use.
|
||||||
|
|
||||||
|
137
pl-pl/xml-pl.html.markdown
Normal file
137
pl-pl/xml-pl.html.markdown
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
---
|
||||||
|
language: xml
|
||||||
|
filename: learnxml-pl.xml
|
||||||
|
contributors:
|
||||||
|
- ["João Farias", "https://github.com/JoaoGFarias"]
|
||||||
|
translators:
|
||||||
|
- ["Tomasz Janiszewski", "https://github.com/janisz"]
|
||||||
|
lang: pl-pl
|
||||||
|
---
|
||||||
|
|
||||||
|
XML (_Extensible Markup Language_) to rozszerzalny język znaczników, stworzony
|
||||||
|
do przechowywania i transportu danych.
|
||||||
|
|
||||||
|
W przeciwieństwie do HTML, XML nie specyfikuje w jaki sposób wyświetlić dane, a
|
||||||
|
tylko je przechowuje.
|
||||||
|
|
||||||
|
* Składnia XML
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- Komentarze w XML wyglądają jak ten -->
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ksiegarnia>
|
||||||
|
<ksiazka kategoria="GOTOWANIE">
|
||||||
|
<tytul lang="pl">Codzienny Włoski</tytul>
|
||||||
|
<autor>Giada De Laurentiis</autor>
|
||||||
|
<rok>2005</rok>
|
||||||
|
<cena>30.00</cena>
|
||||||
|
</ksiazka>
|
||||||
|
<ksiazka kategoria="DZIECI">
|
||||||
|
<tytul lang="pl">Harry Potter</tytul>
|
||||||
|
<autor>J K. Rowling</autor>
|
||||||
|
<rok>2005</rok>
|
||||||
|
<cena>29.99</cena>
|
||||||
|
</ksiazka>
|
||||||
|
<ksiazka kategoria="WEB">
|
||||||
|
<tytul lang="pl">Nauka XML</tytul>
|
||||||
|
<autor>Erik T. Ray</autor>
|
||||||
|
<rok>2003</rok>
|
||||||
|
<cena>39.95</cena>
|
||||||
|
</ksiazka>
|
||||||
|
</ksiegarnia>
|
||||||
|
|
||||||
|
<!-- Powyżej jest typowy plik XML.
|
||||||
|
Zaczyna się od deklaracji zawierającej metadane (opcjonalne).
|
||||||
|
|
||||||
|
XML używa drzewiastej struktury. Powyżej, głównym wierzchołkiem jest
|
||||||
|
'ksiegarnia' , która zawiera trzy (3) węzły potomne, wszystkie 'ksiazki',
|
||||||
|
które zawierają swoje węzły potomne, i tak dalej...
|
||||||
|
|
||||||
|
Węzły są tworzone używające otwierających/zamykających znaczników.
|
||||||
|
Węzły potomne znajdują się pomiędzy otwierającym i zamykającym znacznikiem.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- XML przechowuje dwa typy danych
|
||||||
|
1 - Atrybuty -> metadane o węźle
|
||||||
|
Zazwyczaj parser XML używa tych informacji do przechowywania danych we
|
||||||
|
właściwy sposób. Atrybuty nadawane są poprzez wpisanie ich w otwierajacym
|
||||||
|
znaczniku.
|
||||||
|
2 - Elementy -> to są czyste dane.
|
||||||
|
Dane, które parser otrzymuje z pliku XML.
|
||||||
|
Elementy są deklarowane pomiędzy otwierajacym i zamykającym znacznikiem,
|
||||||
|
bez nawiasów. -->
|
||||||
|
|
||||||
|
<!-- Poniższy element ma dwa atrybuty -->
|
||||||
|
<plik type="gif" id="4293">komputer.gif</plik>
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* Dobrze sformatowany dokument i walidacja
|
||||||
|
|
||||||
|
Dokument XML jest dobrze sformatowany gdy jest syntaktycznie poprawny.
|
||||||
|
Jednakże możliwe jest wstrzykiwanie większej liczby ograniczeń w dokumencie,
|
||||||
|
używając definicji takich jak DTD i XML Schema.
|
||||||
|
|
||||||
|
Dokument XML, który jest zgodny ze swoją definicją jest poprawny.
|
||||||
|
|
||||||
|
|
||||||
|
Korzystając z tych narzędzi możesz sprawdzić dane zawarte w dokumencie poza
|
||||||
|
logiką aplikacji.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Poniżej jest uproszczona wersja dokumentu księgarni,
|
||||||
|
z dodatkową definicją DTD.-->
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE notatka SYSTEM "Ksiegarnia.dtd">
|
||||||
|
<ksiegarnia>
|
||||||
|
<ksiazka kategoria="GOTOWANIE">
|
||||||
|
<tytul >Everyday Italian</tytul>
|
||||||
|
<cena>30.00</cena>
|
||||||
|
</ksiazka>
|
||||||
|
</ksiegarnia>
|
||||||
|
|
||||||
|
<!-- DTD może wyglądać następująco:-->
|
||||||
|
|
||||||
|
<!DOCTYPE notatka
|
||||||
|
[
|
||||||
|
<!ELEMENT ksiegarnia (ksiazka+)>
|
||||||
|
<!ELEMENT ksiazka (tytul,cena)>
|
||||||
|
<!ATTLIST ksiazka kategoria CDATA "Literatura">
|
||||||
|
<!ELEMENT tytul (#PCDATA)>
|
||||||
|
<!ELEMENT cena (#PCDATA)>
|
||||||
|
]>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- DTD zaczyna się od deklaracji
|
||||||
|
Zaczynając od góry, główny węzeł jest zadeklarowany jako wymagający jednego
|
||||||
|
lub więcej węzłów potomnych typu 'ksiżka'.
|
||||||
|
Każda 'ksiażka' powinna zawierać dokładnie jeden 'tytuł' i 'cene' oraz atrybut
|
||||||
|
'kategoria' z 'literaturą' jako wartość domyślna.
|
||||||
|
'tytuł' i 'cena' to pola typu parsowalnych zmiennyc znakowych, co oznacza że
|
||||||
|
użyte znaczniki zostaną zinterpretowane < zamienione <. -->
|
||||||
|
|
||||||
|
<!-- DTD moze być deklarowane wewnątrz pliku XML. -->
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!DOCTYPE notatka
|
||||||
|
[
|
||||||
|
<!ELEMENT ksiegarnia (ksiazka+)>
|
||||||
|
<!ELEMENT ksiazka (tytul,cena)>
|
||||||
|
<!ATTLIST ksiazka kategoria CDATA "Literatura">
|
||||||
|
<!ELEMENT tytul (#PCDATA)>
|
||||||
|
<!ELEMENT cena (#PCDATA)>
|
||||||
|
]>
|
||||||
|
|
||||||
|
<ksiegarnia>
|
||||||
|
<ksiazka kategoria="GOTOWANIE">
|
||||||
|
<tytul >Everyday Italian</tytul>
|
||||||
|
<cena>30.00</cena>
|
||||||
|
</ksiazka>
|
||||||
|
</ksiegarnia>
|
||||||
|
```
|
@ -519,13 +519,13 @@ if (Object.create === undefined){ // Não o sobrescreve se já existir
|
|||||||
## Leitura Adicional
|
## Leitura Adicional
|
||||||
|
|
||||||
O [Mozilla Developer
|
O [Mozilla Developer
|
||||||
Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript) dispõe de uma
|
Network](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript) dispõe de uma
|
||||||
excelente documentação sobre Javascript e seu uso nos browsers. E mais,
|
excelente documentação sobre Javascript e seu uso nos browsers. E mais,
|
||||||
é uma wiki, portanto conforme você vai aprendendo, mais você pode ir ajudando
|
é uma wiki, portanto conforme você vai aprendendo, mais você pode ir ajudando
|
||||||
os outros compartilhando do seu conhecimento.
|
os outros compartilhando do seu conhecimento.
|
||||||
|
|
||||||
[Uma re-introdução do JavaScript pela MDN]
|
[Uma re-introdução do JavaScript pela MDN]
|
||||||
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
(https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
||||||
cobre muito dos conceitos abordados aqui em mais detalhes. Este guia fala
|
cobre muito dos conceitos abordados aqui em mais detalhes. Este guia fala
|
||||||
somente sobre a linguagem JavaScript em si; se você quiser aprender mais
|
somente sobre a linguagem JavaScript em si; se você quiser aprender mais
|
||||||
sobre e como usar o JavaScript em páginas na web, comece aprendendo sobre
|
sobre e como usar o JavaScript em páginas na web, comece aprendendo sobre
|
||||||
@ -542,5 +542,5 @@ profundo de todas as partes do JavaScript.
|
|||||||
/ livro de referência.
|
/ livro de referência.
|
||||||
|
|
||||||
Parte desse artigo foi adaptado do tutorial de Python do Louie Dinh que está
|
Parte desse artigo foi adaptado do tutorial de Python do Louie Dinh que está
|
||||||
nesse site e do [Tutorial de JS](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
nesse site e do [Tutorial de JS](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
||||||
da Mozilla Developer Network.
|
da Mozilla Developer Network.
|
||||||
|
@ -4,6 +4,7 @@ lang: pt-br
|
|||||||
filename: learnruby-pt.rb
|
filename: learnruby-pt.rb
|
||||||
contributors:
|
contributors:
|
||||||
- ["Bruno Henrique - Garu", "http://garulab.com"]
|
- ["Bruno Henrique - Garu", "http://garulab.com"]
|
||||||
|
- ["Jean Matheus Souto", "http://jeanmatheussouto.github.io"]
|
||||||
translators:
|
translators:
|
||||||
- ["Katyanna Moura", "https://twitter.com/amelie_kn"]
|
- ["Katyanna Moura", "https://twitter.com/amelie_kn"]
|
||||||
---
|
---
|
||||||
@ -161,9 +162,6 @@ hash['numero'] #=> 5
|
|||||||
hash['nada aqui'] #=> nil
|
hash['nada aqui'] #=> nil
|
||||||
|
|
||||||
# Interar sobre hashes com o método #each:
|
# Interar sobre hashes com o método #each:
|
||||||
hash.each do |k, v|
|
|
||||||
puts "#{k} is #{v}"
|
|
||||||
end
|
|
||||||
|
|
||||||
hash.each do |k, v|
|
hash.each do |k, v|
|
||||||
puts "#{k} é #{v}"
|
puts "#{k} é #{v}"
|
||||||
@ -385,3 +383,11 @@ Humano.bar # 0
|
|||||||
Doutor.bar # nil
|
Doutor.bar # nil
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Mais sobre Ruby
|
||||||
|
|
||||||
|
- [Documentação oficial](http://www.ruby-doc.org/core-2.1.1/)
|
||||||
|
- [Aprenda Ruby com desafios](http://www.learneroo.com/modules/61/nodes/338) - Uma coleção de desafios para testar a linguagem.
|
||||||
|
- [Ruby a partir de outras linguagens](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/)
|
||||||
|
- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/)- Um mais antigo [free edition](http://ruby-doc.com/docs/ProgrammingRuby/) e tambem uma versão online disponível.
|
||||||
|
- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - Uma versão colaborativa de um *style-guide*
|
||||||
|
@ -726,6 +726,7 @@ print say(say_please=True) # Can you buy me a beer? Please! I am poor :(
|
|||||||
* [Python Module of the Week](http://pymotw.com/2/)
|
* [Python Module of the Week](http://pymotw.com/2/)
|
||||||
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
|
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
|
||||||
* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
|
* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
|
||||||
|
* [LearnPython](http://www.learnpython.org/)
|
||||||
* [Fullstack Python](https://www.fullstackpython.com/)
|
* [Fullstack Python](https://www.fullstackpython.com/)
|
||||||
|
|
||||||
### Dead Tree
|
### Dead Tree
|
||||||
|
@ -780,6 +780,7 @@ print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
|
|||||||
* [A curated list of awesome Python frameworks, libraries and software](https://github.com/vinta/awesome-python)
|
* [A curated list of awesome Python frameworks, libraries and software](https://github.com/vinta/awesome-python)
|
||||||
* [30 Python Language Features and Tricks You May Not Know About](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html)
|
* [30 Python Language Features and Tricks You May Not Know About](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html)
|
||||||
* [Official Style Guide for Python](https://www.python.org/dev/peps/pep-0008/)
|
* [Official Style Guide for Python](https://www.python.org/dev/peps/pep-0008/)
|
||||||
|
* [Python 3 Computer Science Circles](http://cscircles.cemc.uwaterloo.ca/)
|
||||||
|
|
||||||
### Dead Tree
|
### Dead Tree
|
||||||
|
|
||||||
|
@ -285,7 +285,7 @@ hash.each do |key, value|
|
|||||||
puts "#{key} is #{value}"
|
puts "#{key} is #{value}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# If you still need and index you can use "each_with_index" and define an index
|
# If you still need an index you can use "each_with_index" and define an index
|
||||||
# variable
|
# variable
|
||||||
array.each_with_index do |element, index|
|
array.each_with_index do |element, index|
|
||||||
puts "#{element} is number #{index} in the array"
|
puts "#{element} is number #{index} in the array"
|
||||||
@ -411,6 +411,28 @@ def guests(*array)
|
|||||||
array.each { |guest| puts guest }
|
array.each { |guest| puts guest }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# If a method returns an array, you can use destructuring assignment
|
||||||
|
def foods
|
||||||
|
['pancake', 'sandwich', 'quesadilla']
|
||||||
|
end
|
||||||
|
breakfast, lunch, dinner = foods
|
||||||
|
breakfast #=> 'pancake'
|
||||||
|
dinner #=> 'quesadilla'
|
||||||
|
|
||||||
|
# By convention, all methods that return booleans end with a question mark
|
||||||
|
5.even? # false
|
||||||
|
5.odd? # true
|
||||||
|
|
||||||
|
# And if a method ends with an exclamation mark, it does something destructive
|
||||||
|
# like mutate the receiver. Many methods have a ! version to make a change, and
|
||||||
|
# a non-! version to just return a new changed version
|
||||||
|
company_name = "Dunder Mifflin"
|
||||||
|
company_name.upcase #=> "DUNDER MIFFLIN"
|
||||||
|
company_name #=> "Dunder Mifflin"
|
||||||
|
company_name.upcase! # we're mutating company_name this time!
|
||||||
|
company_name #=> "DUNDER MIFFLIN"
|
||||||
|
|
||||||
|
|
||||||
# Define a class with the class keyword
|
# Define a class with the class keyword
|
||||||
class Human
|
class Human
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ r foreach println
|
|||||||
|
|
||||||
(5 to 1 by -1) foreach (println)
|
(5 to 1 by -1) foreach (println)
|
||||||
|
|
||||||
// A while loops
|
// A while loop
|
||||||
var i = 0
|
var i = 0
|
||||||
while (i < 10) { println("i " + i); i += 1 }
|
while (i < 10) { println("i " + i); i += 1 }
|
||||||
|
|
||||||
@ -245,17 +245,18 @@ while (i < 10) { println("i " + i); i += 1 } // Yes, again. What happened? Why
|
|||||||
|
|
||||||
i // Show the value of i. Note that while is a loop in the classical sense -
|
i // Show the value of i. Note that while is a loop in the classical sense -
|
||||||
// it executes sequentially while changing the loop variable. while is very
|
// it executes sequentially while changing the loop variable. while is very
|
||||||
// fast, faster that Java loops, but using the combinators and
|
// fast, but using the combinators and comprehensions above is easier
|
||||||
// comprehensions above is easier to understand and parallelize
|
// to understand and parallelize
|
||||||
|
|
||||||
// A do while loop
|
// A do-while loop
|
||||||
i = 0
|
i = 0
|
||||||
do {
|
do {
|
||||||
println("i is still less than 10")
|
println("i is still less than 10")
|
||||||
i += 1
|
i += 1
|
||||||
} while (i < 10)
|
} while (i < 10)
|
||||||
|
|
||||||
// Tail recursion is an idiomatic way of doing recurring things in Scala.
|
// Recursion is the idiomatic way of repeating an action in Scala (as in most
|
||||||
|
// other functional languages).
|
||||||
// Recursive functions need an explicit return type, the compiler can't infer it.
|
// Recursive functions need an explicit return type, the compiler can't infer it.
|
||||||
// Here it's Unit.
|
// Here it's Unit.
|
||||||
def showNumbersInRange(a: Int, b: Int): Unit = {
|
def showNumbersInRange(a: Int, b: Int): Unit = {
|
||||||
@ -273,7 +274,7 @@ val x = 10
|
|||||||
if (x == 1) println("yeah")
|
if (x == 1) println("yeah")
|
||||||
if (x == 10) println("yeah")
|
if (x == 10) println("yeah")
|
||||||
if (x == 11) println("yeah")
|
if (x == 11) println("yeah")
|
||||||
if (x == 11) println ("yeah") else println("nay")
|
if (x == 11) println("yeah") else println("nay")
|
||||||
|
|
||||||
println(if (x == 10) "yeah" else "nope")
|
println(if (x == 10) "yeah" else "nope")
|
||||||
val text = if (x == 10) "yeah" else "nope"
|
val text = if (x == 10) "yeah" else "nope"
|
||||||
|
795
solidity.html.markdown
Normal file
795
solidity.html.markdown
Normal file
@ -0,0 +1,795 @@
|
|||||||
|
---
|
||||||
|
language: Solidity
|
||||||
|
filename: learnSolidity.sol
|
||||||
|
contributors:
|
||||||
|
- ["Nemil Dalal", "https://www.nemil.com"]
|
||||||
|
- ["Joseph Chow", ""]
|
||||||
|
---
|
||||||
|
|
||||||
|
Solidity lets you program on [Ethereum](https://www.ethereum.org/), a
|
||||||
|
blockchain-based virtual machine that allows the creation and
|
||||||
|
execution of smart contracts, without needing centralized or trusted parties.
|
||||||
|
|
||||||
|
Solidity is a statically typed, contract programming language that has
|
||||||
|
similarities to Javascript and C. Like objects in OOP, each contract contains
|
||||||
|
state variables, functions, and common data types. Contract-specific features
|
||||||
|
include modifier (guard) clauses, event notifiers for listeners, and custom
|
||||||
|
global variables.
|
||||||
|
|
||||||
|
Some Ethereum contract examples include crowdfunding, voting, and blind auctions.
|
||||||
|
|
||||||
|
As Solidity and Ethereum are under active development, experimental or beta
|
||||||
|
features are explicitly marked, and subject to change. Pull requests welcome.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// First, a simple Bank contract
|
||||||
|
// Allows deposits, withdrawals, and balance checks
|
||||||
|
|
||||||
|
// simple_bank.sol (note .sol extension)
|
||||||
|
/* **** START EXAMPLE **** */
|
||||||
|
|
||||||
|
// Start with Natspec comment (the three slashes)
|
||||||
|
// used for documentation - and as descriptive data for UI elements/actions
|
||||||
|
|
||||||
|
/// @title SimpleBank
|
||||||
|
/// @author nemild
|
||||||
|
|
||||||
|
/* 'contract' has similarities to 'class' in other languages (class variables,
|
||||||
|
inheritance, etc.) */
|
||||||
|
contract SimpleBank { // CamelCase
|
||||||
|
// Declare state variables outside function, persist through life of contract
|
||||||
|
|
||||||
|
// dictionary that maps addresses to balances
|
||||||
|
mapping (address => uint) private balances;
|
||||||
|
|
||||||
|
// "private" means that other contracts can't directly query balances
|
||||||
|
// but data is still viewable to other parties on blockchain
|
||||||
|
|
||||||
|
address public owner;
|
||||||
|
// 'public' makes externally readable (not writeable) by users or contracts
|
||||||
|
|
||||||
|
// Events - publicize actions to external listeners
|
||||||
|
event DepositMade(address accountAddress, uint amount);
|
||||||
|
|
||||||
|
// Constructor, can receive one or many variables here; only one allowed
|
||||||
|
function AcmeBank() {
|
||||||
|
// msg provides details about the message that's sent to the contract
|
||||||
|
// msg.sender is contract caller (address of contract creator)
|
||||||
|
owner = msg.sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Deposit ether into bank
|
||||||
|
/// @return The balance of the user after the deposit is made
|
||||||
|
function deposit() public returns (uint) {
|
||||||
|
balances[msg.sender] += msg.value;
|
||||||
|
// no "this." or "self." required with state variable
|
||||||
|
// all values set to data type's initial value by default
|
||||||
|
|
||||||
|
DepositMade(msg.sender, msg.value); // fire event
|
||||||
|
|
||||||
|
return balances[msg.sender];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Withdraw ether from bank
|
||||||
|
/// @dev This does not return any excess ether sent to it
|
||||||
|
/// @param withdrawAmount amount you want to withdraw
|
||||||
|
/// @return The balance remaining for the user
|
||||||
|
function withdraw(uint withdrawAmount) public returns (uint remainingBal) {
|
||||||
|
if(balances[msg.sender] >= withdrawAmount) {
|
||||||
|
balances[msg.sender] -= withdrawAmount;
|
||||||
|
|
||||||
|
if (!msg.sender.send(withdrawAmount)) {
|
||||||
|
// to be safe, may be sending to contract that
|
||||||
|
// has overridden 'send' which may then fail
|
||||||
|
balances[msg.sender] += withdrawAmount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return balances[msg.sender];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @notice Get balance
|
||||||
|
/// @return The balance of the user
|
||||||
|
// 'constant' prevents function from editing state variables;
|
||||||
|
// allows function to run locally/off blockchain
|
||||||
|
function balance() constant returns (uint) {
|
||||||
|
return balances[msg.sender];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback function - Called if other functions don't match call or
|
||||||
|
// sent ether without data
|
||||||
|
// Typically, called when invalid data is sent
|
||||||
|
// Added so ether sent to this contract is reverted if the contract fails
|
||||||
|
// otherwise, the sender's money is transferred to contract
|
||||||
|
function () {
|
||||||
|
throw; // throw reverts state to before call
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ** END EXAMPLE **
|
||||||
|
|
||||||
|
|
||||||
|
// Now, the basics of Solidity
|
||||||
|
|
||||||
|
// 1. DATA TYPES AND ASSOCIATED METHODS
|
||||||
|
// uint used for currency amount (there are no doubles
|
||||||
|
// or floats) and for dates (in unix time)
|
||||||
|
uint x;
|
||||||
|
|
||||||
|
// int of 256 bits, cannot be changed after instantiation
|
||||||
|
int constant a = 8;
|
||||||
|
int256 constant a = 8; // same effect as line above, here the 256 is explicit
|
||||||
|
uint constant VERSION_ID = 0x123A1; // A hex constant
|
||||||
|
// with 'constant', compiler replaces each occurrence with actual value
|
||||||
|
|
||||||
|
|
||||||
|
// For int and uint, can explicitly set space in steps of 8 up to 256
|
||||||
|
// e.g., int8, int16, int24
|
||||||
|
uint8 b;
|
||||||
|
int64 c;
|
||||||
|
uint248 e;
|
||||||
|
|
||||||
|
// Be careful that you don't overflow, and protect against attacks that do
|
||||||
|
|
||||||
|
// No random functions built in, use other contracts for randomness
|
||||||
|
|
||||||
|
// Type casting
|
||||||
|
int x = int(b);
|
||||||
|
|
||||||
|
bool b = true; // or do 'var b = true;' for inferred typing
|
||||||
|
|
||||||
|
// Addresses - holds 20 byte/160 bit Ethereum addresses
|
||||||
|
// No arithmetic allowed
|
||||||
|
address public owner;
|
||||||
|
|
||||||
|
// Types of accounts:
|
||||||
|
// Contract account: address set on create (func of creator address, num transactions sent)
|
||||||
|
// External Account: (person/external entity): address created from public key
|
||||||
|
|
||||||
|
// Add 'public' field to indicate publicly/externally accessible
|
||||||
|
// a getter is automatically created, but NOT a setter
|
||||||
|
|
||||||
|
// All addresses can be sent ether
|
||||||
|
owner.send(SOME_BALANCE); // returns false on failure
|
||||||
|
if (owner.send) {} // typically wrap in 'if', as contract addresses have
|
||||||
|
// functions have executed on send and can fail
|
||||||
|
|
||||||
|
// can override send by defining your own
|
||||||
|
|
||||||
|
// Can check balance
|
||||||
|
owner.balance; // the balance of the owner (user or contract)
|
||||||
|
|
||||||
|
|
||||||
|
// Bytes available from 1 to 32
|
||||||
|
byte a; // byte is same as bytes1
|
||||||
|
bytes2 b;
|
||||||
|
bytes32 c;
|
||||||
|
|
||||||
|
// Dynamically sized bytes
|
||||||
|
bytes m; // A special array, same as byte[] array (but packed tightly)
|
||||||
|
// More expensive than byte1-byte32, so use those when possible
|
||||||
|
|
||||||
|
// same as bytes, but does not allow length or index access (for now)
|
||||||
|
string n = "hello"; // stored in UTF8, note double quotes, not single
|
||||||
|
// string utility functions to be added in future
|
||||||
|
// prefer bytes32/bytes, as UTF8 uses more storage
|
||||||
|
|
||||||
|
// Type inferrence
|
||||||
|
// var does inferred typing based on first assignment,
|
||||||
|
// can't be used in functions parameters
|
||||||
|
var a = true;
|
||||||
|
// use carefully, inference may provide wrong type
|
||||||
|
// e.g., an int8, when a counter needs to be int16
|
||||||
|
|
||||||
|
// var can be used to assign function to variable
|
||||||
|
function a(uint x) returns (uint) {
|
||||||
|
return x * 2;
|
||||||
|
}
|
||||||
|
var f = a;
|
||||||
|
f(22); // call
|
||||||
|
|
||||||
|
// by default, all values are set to 0 on instantiation
|
||||||
|
|
||||||
|
// Delete can be called on most types
|
||||||
|
// (does NOT destroy value, but sets value to 0, the initial value)
|
||||||
|
uint x = 5;
|
||||||
|
|
||||||
|
|
||||||
|
// Destructuring/Tuples
|
||||||
|
(x, y) = (2, 7); // assign/swap multiple value
|
||||||
|
|
||||||
|
|
||||||
|
// 2. DATA STRUCTURES
|
||||||
|
// Arrays
|
||||||
|
bytes32[5] nicknames; // static array
|
||||||
|
bytes32[] names; // dynamic array
|
||||||
|
uint newLength = names.push("John"); // adding returns new length of the array
|
||||||
|
// Length
|
||||||
|
names.length; // get length
|
||||||
|
names.length = 1; // lengths can be set (for dynamic arrays in storage only)
|
||||||
|
|
||||||
|
// multidimensional array
|
||||||
|
uint x[][5]; // arr with 5 dynamic array elements (opp order of most languages)
|
||||||
|
|
||||||
|
// Dictionaries (any type to any other type)
|
||||||
|
mapping (string => uint) public balances;
|
||||||
|
balances["charles"] = 1;
|
||||||
|
console.log(balances["ada"]); // is 0, all non-set key values return zeroes
|
||||||
|
// 'public' allows following from another contract
|
||||||
|
contractName.balances("claude"); // returns 1
|
||||||
|
// 'public' created a getter (but not setter) like the following:
|
||||||
|
function balances(address _account) returns (uint balance) {
|
||||||
|
return balances[_account];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nested mappings
|
||||||
|
mapping (address => mapping (address => uint)) public custodians;
|
||||||
|
|
||||||
|
// To delete
|
||||||
|
delete balances["John"];
|
||||||
|
delete balances; // sets all elements to 0
|
||||||
|
|
||||||
|
// Unlike other languages, CANNOT iterate through all elements in
|
||||||
|
// mapping, without knowing source keys - can build data structure
|
||||||
|
// on top to do this
|
||||||
|
|
||||||
|
// Structs and enums
|
||||||
|
struct Bank {
|
||||||
|
address owner;
|
||||||
|
uint balance;
|
||||||
|
}
|
||||||
|
Bank b = Bank({
|
||||||
|
owner: msg.sender,
|
||||||
|
balance: 5
|
||||||
|
});
|
||||||
|
// or
|
||||||
|
Bank c = Bank(msg.sender, 5);
|
||||||
|
|
||||||
|
c.amount = 5; // set to new value
|
||||||
|
delete b;
|
||||||
|
// sets to initial value, set all variables in struct to 0, except mappings
|
||||||
|
|
||||||
|
// Enums
|
||||||
|
enum State { Created, Locked, Inactive }; // often used for state machine
|
||||||
|
State public state; // Declare variable from enum
|
||||||
|
state = State.Created;
|
||||||
|
// enums can be explicitly converted to ints
|
||||||
|
uint createdState = uint(State.Created); // 0
|
||||||
|
|
||||||
|
// Data locations: Memory vs. storage vs. stack - all complex types (arrays,
|
||||||
|
// structs) have a data location
|
||||||
|
// 'memory' does not persist, 'storage' does
|
||||||
|
// Default is 'storage' for local and state variables; 'memory' for func params
|
||||||
|
// stack holds small local variables
|
||||||
|
|
||||||
|
// for most types, can explicitly set which data location to use
|
||||||
|
|
||||||
|
|
||||||
|
// 3. Simple operators
|
||||||
|
// Comparisons, bit operators and arithmetic operators are provided
|
||||||
|
// exponentiation: **
|
||||||
|
// exclusive or: ^
|
||||||
|
// bitwise negation: ~
|
||||||
|
|
||||||
|
|
||||||
|
// 4. Global Variables of note
|
||||||
|
// ** this **
|
||||||
|
this; // address of contract
|
||||||
|
// often used at end of contract life to send remaining balance to party
|
||||||
|
this.balance;
|
||||||
|
this.someFunction(); // calls func externally via call, not via internal jump
|
||||||
|
|
||||||
|
// ** msg - Current message received by the contract ** **
|
||||||
|
msg.sender; // address of sender
|
||||||
|
msg.value; // amount of ether provided to this contract in wei
|
||||||
|
msg.data; // bytes, complete call data
|
||||||
|
msg.gas; // remaining gas
|
||||||
|
|
||||||
|
// ** tx - This transaction **
|
||||||
|
tx.origin; // address of sender of the transaction
|
||||||
|
tx.gasprice; // gas price of the transaction
|
||||||
|
|
||||||
|
// ** block - Information about current block **
|
||||||
|
now; // current time (approximately), alias for block.timestamp (uses Unix time)
|
||||||
|
block.number; // current block number
|
||||||
|
block.difficulty; // current block difficulty
|
||||||
|
block.blockhash(1); // returns bytes32, only works for most recent 256 blocks
|
||||||
|
block.gasLimit();
|
||||||
|
|
||||||
|
// ** storage - Persistent storage hash **
|
||||||
|
storage['abc'] = 'def'; // maps 256 bit words to 256 bit words
|
||||||
|
|
||||||
|
|
||||||
|
// 4. FUNCTIONS AND MORE
|
||||||
|
// A. Functions
|
||||||
|
// Simple function
|
||||||
|
function increment(uint x) returns (uint) {
|
||||||
|
x += 1;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functions can return many arguments, and by specifying returned arguments
|
||||||
|
// name don't need to explicitly return
|
||||||
|
function increment(uint x, uint y) returns (uint x, uint y) {
|
||||||
|
x += 1;
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
// Call previous functon
|
||||||
|
uint (a,b) = increment(1,1);
|
||||||
|
|
||||||
|
// 'constant' indicates that function does not/cannot change persistent vars
|
||||||
|
// Constant function execute locally, not on blockchain
|
||||||
|
uint y;
|
||||||
|
|
||||||
|
function increment(uint x) constant returns (uint x) {
|
||||||
|
x += 1;
|
||||||
|
y += 1; // this line would fail
|
||||||
|
// y is a state variable, and can't be changed in a constant function
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'Function Visibility specifiers'
|
||||||
|
// These can be placed where 'constant' is, including:
|
||||||
|
// public - visible externally and internally (default)
|
||||||
|
// external
|
||||||
|
// private - only visible in the current contract
|
||||||
|
// internal - only visible in current contract, and those deriving from it
|
||||||
|
|
||||||
|
// Functions hoisted - and can assign a function to a variable
|
||||||
|
function a() {
|
||||||
|
var z = b;
|
||||||
|
b();
|
||||||
|
}
|
||||||
|
|
||||||
|
function b() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Prefer loops to recursion (max call stack depth is 1024)
|
||||||
|
|
||||||
|
// B. Events
|
||||||
|
// Events are notify external parties; easy to search and
|
||||||
|
// access events from outside blockchain (with lightweight clients)
|
||||||
|
// typically declare after contract parameters
|
||||||
|
|
||||||
|
// Declare
|
||||||
|
event Sent(address from, address to, uint amount); // note capital first letter
|
||||||
|
|
||||||
|
// Call
|
||||||
|
Sent(from, to, amount);
|
||||||
|
|
||||||
|
// For an external party (a contract or external entity), to watch:
|
||||||
|
Coin.Sent().watch({}, '', function(error, result) {
|
||||||
|
if (!error) {
|
||||||
|
console.log("Coin transfer: " + result.args.amount +
|
||||||
|
" coins were sent from " + result.args.from +
|
||||||
|
" to " + result.args.to + ".");
|
||||||
|
console.log("Balances now:\n" +
|
||||||
|
"Sender: " + Coin.balances.call(result.args.from) +
|
||||||
|
"Receiver: " + Coin.balances.call(result.args.to));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Common paradigm for one contract to depend on another (e.g., a
|
||||||
|
// contract that depends on current exchange rate provided by another)
|
||||||
|
|
||||||
|
// C. Modifiers
|
||||||
|
// Modifiers validate inputs to functions such as minimal balance or user auth;
|
||||||
|
// similar to guard clause in other languages
|
||||||
|
|
||||||
|
// '_' (underscore) often included as last line in body, and indicates
|
||||||
|
// function being called should be placed there
|
||||||
|
modifier onlyAfter(uint _time) { if (now <= _time) throw; _ }
|
||||||
|
modifier onlyOwner { if (msg.sender == owner) _ }
|
||||||
|
// commonly used with state machines
|
||||||
|
modifier onlyIfState (State currState) { if (currState != State.A) _ }
|
||||||
|
|
||||||
|
// Append right after function declaration
|
||||||
|
function changeOwner(newOwner)
|
||||||
|
onlyAfter(someTime)
|
||||||
|
onlyOwner()
|
||||||
|
onlyIfState(State.A)
|
||||||
|
{
|
||||||
|
owner = newOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
// underscore can be included before end of body,
|
||||||
|
// but explicitly returning will skip, so use carefully
|
||||||
|
modifier checkValue(uint amount) {
|
||||||
|
_
|
||||||
|
if (msg.value > amount) {
|
||||||
|
msg.sender.send(amount - msg.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 6. BRANCHING AND LOOPS
|
||||||
|
|
||||||
|
// All basic logic blocks work - including if/else, for, while, break, continue
|
||||||
|
// return - but no switch
|
||||||
|
|
||||||
|
// Syntax same as javascript, but no type conversion from non-boolean
|
||||||
|
// to boolean (comparison operators must be used to get the boolean val)
|
||||||
|
|
||||||
|
|
||||||
|
// 7. OBJECTS/CONTRACTS
|
||||||
|
|
||||||
|
// A. Calling external contract
|
||||||
|
contract infoFeed {
|
||||||
|
function info() returns (uint ret) { return 42; }
|
||||||
|
}
|
||||||
|
|
||||||
|
contract Consumer {
|
||||||
|
InfoFeed feed; // points to contract on blockchain
|
||||||
|
|
||||||
|
// Set feed to existing contract instance
|
||||||
|
function setFeed(address addr) {
|
||||||
|
// automatically cast, be careful; constructor is not called
|
||||||
|
feed = InfoFeed(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set feed to new instance of contract
|
||||||
|
function createNewFeed() {
|
||||||
|
feed = new InfoFeed(); // new instance created; constructor called
|
||||||
|
}
|
||||||
|
|
||||||
|
function callFeed() {
|
||||||
|
// final parentheses call contract, can optionally add
|
||||||
|
// custom ether value or gas
|
||||||
|
feed.info.value(10).gas(800)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// B. Inheritance
|
||||||
|
|
||||||
|
// Order matters, last inherited contract (i.e., 'def') can override parts of
|
||||||
|
// previously inherited contracts
|
||||||
|
contract MyContract is abc, def("a custom argument to def") {
|
||||||
|
|
||||||
|
// Override function
|
||||||
|
function z() {
|
||||||
|
if (msg.sender == owner) {
|
||||||
|
def.z(); // call overridden function from def
|
||||||
|
super.z(); // call immediate parent overriden function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// abstract function
|
||||||
|
function someAbstractFunction(uint x);
|
||||||
|
// cannot be compiled, so used in base/abstract contracts
|
||||||
|
// that are then implemented
|
||||||
|
|
||||||
|
// C. Import
|
||||||
|
|
||||||
|
import "filename";
|
||||||
|
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";
|
||||||
|
|
||||||
|
// Importing under active development
|
||||||
|
// Cannot currently be done at command line
|
||||||
|
|
||||||
|
|
||||||
|
// 8. OTHER KEYWORDS
|
||||||
|
|
||||||
|
// A. Throwing
|
||||||
|
// Throwing
|
||||||
|
throw; // reverts unused money to sender, state is reverted
|
||||||
|
// Can't currently catch
|
||||||
|
|
||||||
|
// Common design pattern is:
|
||||||
|
if (!addr.send(123)) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// B. Selfdestruct
|
||||||
|
// selfdestruct current contract, sending funds to address (often creator)
|
||||||
|
selfdestruct(SOME_ADDRESS);
|
||||||
|
|
||||||
|
// removes storage/code from current/future blocks
|
||||||
|
// helps thin clients, but previous data persists in blockchain
|
||||||
|
|
||||||
|
// Common pattern, lets owner end the contract and receive remaining funds
|
||||||
|
function remove() {
|
||||||
|
if(msg.sender == creator) { // Only let the contract creator do this
|
||||||
|
selfdestruct(creator); // Makes contract inactive, returns funds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// May want to deactivate contract manually, rather than selfdestruct
|
||||||
|
// (ether sent to selfdestructed contract is lost)
|
||||||
|
|
||||||
|
|
||||||
|
// 9. CONTRACT DESIGN NOTES
|
||||||
|
|
||||||
|
// A. Obfuscation
|
||||||
|
// All variables are publicly viewable on blockchain, so anything
|
||||||
|
// that is private needs to be obfuscated (e.g., hashed w/secret)
|
||||||
|
|
||||||
|
// Steps: 1. Commit to something, 2. Reveal commitment
|
||||||
|
sha3("some_bid_amount", "some secret"); // commit
|
||||||
|
|
||||||
|
// call contract's reveal function in the future
|
||||||
|
// showing bid plus secret that hashes to SHA3
|
||||||
|
reveal(100, "mySecret");
|
||||||
|
|
||||||
|
// B. Storage optimization
|
||||||
|
// Writing to blockchain can be expensive, as data stored forever; encourages
|
||||||
|
// smart ways to use memory (eventually, compilation will be better, but for now
|
||||||
|
// benefits to planning data structures - and storing min amount in blockchain)
|
||||||
|
|
||||||
|
// Cost can often be high for items like multidimensional arrays
|
||||||
|
// (cost is for storing data - not declaring unfilled variables)
|
||||||
|
|
||||||
|
// C. Data access in blockchain
|
||||||
|
// Cannot restrict human or computer from reading contents of
|
||||||
|
// transaction or transaction's state
|
||||||
|
|
||||||
|
// While 'private' prevents other *contracts* from reading data
|
||||||
|
// directly - any other party can still read data in blockchain
|
||||||
|
|
||||||
|
// All data to start of time is stored in blockchain, so
|
||||||
|
// anyone can observe all previous data and changes
|
||||||
|
|
||||||
|
// D. Cron Job
|
||||||
|
// Contracts must be manually called to handle time-based scheduling; can create external
|
||||||
|
// code to regularly ping, or provide incentives (ether) for others to
|
||||||
|
|
||||||
|
// E. Observer Pattern
|
||||||
|
// An Observer Pattern lets you register as a subscriber and
|
||||||
|
// register a function which is called by the oracle (note, the oracle pays
|
||||||
|
// for this action to be run)
|
||||||
|
// Some similarities to subscription in Pub/sub
|
||||||
|
|
||||||
|
// This is an abstract contract, both client and server classes import
|
||||||
|
// the client should implement
|
||||||
|
contract SomeOracleCallback {
|
||||||
|
function oracleCallback(int _value, uint _time, bytes32 info) external;
|
||||||
|
}
|
||||||
|
|
||||||
|
contract SomeOracle {
|
||||||
|
SomeOracleCallback[] callbacks; // array of all subscribers
|
||||||
|
|
||||||
|
// Register subscriber
|
||||||
|
function addSubscriber(SomeOracleCallback a) {
|
||||||
|
callbacks.push(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
function notify(value, time, info) private {
|
||||||
|
for(uint i = 0;i < callbacks.length; i++) {
|
||||||
|
// all called subscribers must implement the oracleCallback
|
||||||
|
callbacks[i].oracleCallback(value, time, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function doSomething() public {
|
||||||
|
// Code to do something
|
||||||
|
|
||||||
|
// Notify all subscribers
|
||||||
|
notify(_value, _time, _info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, your client contract can addSubscriber by importing SomeOracleCallback
|
||||||
|
// and registering with Some Oracle
|
||||||
|
|
||||||
|
// F. State machines
|
||||||
|
// see example below for State enum and inState modifier
|
||||||
|
|
||||||
|
|
||||||
|
// *** EXAMPLE: A crowdfunding example (broadly similar to Kickstarter) ***
|
||||||
|
// ** START EXAMPLE **
|
||||||
|
|
||||||
|
// CrowdFunder.sol
|
||||||
|
|
||||||
|
/// @title CrowdFunder
|
||||||
|
/// @author nemild
|
||||||
|
contract CrowdFunder {
|
||||||
|
// Variables set on create by creator
|
||||||
|
address public creator;
|
||||||
|
address public fundRecipient; // creator may be different than recipient
|
||||||
|
uint public minimumToRaise; // required to tip, else everyone gets refund
|
||||||
|
string campaignUrl;
|
||||||
|
|
||||||
|
// Data structures
|
||||||
|
enum State {
|
||||||
|
Fundraising,
|
||||||
|
ExpiredRefundPending,
|
||||||
|
Successful,
|
||||||
|
ExpiredRefundComplete
|
||||||
|
}
|
||||||
|
struct Contribution {
|
||||||
|
uint amount;
|
||||||
|
address contributor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// State variables
|
||||||
|
State public state = State.Fundraising; // initialize on create
|
||||||
|
uint public totalRaised;
|
||||||
|
uint public raiseBy;
|
||||||
|
Contribution[] contributions;
|
||||||
|
|
||||||
|
event fundingReceived(address addr, uint amount, uint currentTotal);
|
||||||
|
event allRefundsSent();
|
||||||
|
event winnerPaid(address winnerAddress);
|
||||||
|
|
||||||
|
modifier inState(State _state) {
|
||||||
|
if (state != _state) throw;
|
||||||
|
_
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier isCreator() {
|
||||||
|
if (msg.sender != creator) throw;
|
||||||
|
_
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier atEndOfLifecycle() {
|
||||||
|
if(state != State.ExpiredRefundComplete && state != State.Successful) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function CrowdFunder(
|
||||||
|
uint timeInHoursForFundraising,
|
||||||
|
string _campaignUrl,
|
||||||
|
address _fundRecipient,
|
||||||
|
uint _minimumToRaise)
|
||||||
|
{
|
||||||
|
creator = msg.sender;
|
||||||
|
fundRecipient = _fundRecipient;
|
||||||
|
campaignUrl = _campaignUrl;
|
||||||
|
minimumToRaise = _minimumToRaise;
|
||||||
|
raiseBy = now + (timeInHoursForFundraising * 1 hours);
|
||||||
|
}
|
||||||
|
|
||||||
|
function contribute()
|
||||||
|
public
|
||||||
|
inState(State.Fundraising)
|
||||||
|
{
|
||||||
|
contributions.push(
|
||||||
|
Contribution({
|
||||||
|
amount: msg.value,
|
||||||
|
contributor: msg.sender
|
||||||
|
}) // use array, so can iterate
|
||||||
|
);
|
||||||
|
totalRaised += msg.value;
|
||||||
|
|
||||||
|
fundingReceived(msg.sender, msg.value, totalRaised);
|
||||||
|
|
||||||
|
checkIfFundingCompleteOrExpired();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkIfFundingCompleteOrExpired() {
|
||||||
|
if (totalRaised > minimumToRaise) {
|
||||||
|
state = State.Successful;
|
||||||
|
payOut();
|
||||||
|
|
||||||
|
// could incentivize sender who initiated state change here
|
||||||
|
} else if ( now > raiseBy ) {
|
||||||
|
state = State.ExpiredRefundPending;
|
||||||
|
refundAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function payOut()
|
||||||
|
public
|
||||||
|
inState(State.Successful)
|
||||||
|
{
|
||||||
|
if(!fundRecipient.send(this.balance)) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
winnerPaid(fundRecipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
function refundAll()
|
||||||
|
public
|
||||||
|
inState(State.ExpiredRefundPending)
|
||||||
|
{
|
||||||
|
uint length = contributions.length;
|
||||||
|
for (uint i = 0; i < length; i++) {
|
||||||
|
if(!contributions[i].contributor.send(contributions[i].amount)) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allRefundsSent();
|
||||||
|
state = State.ExpiredRefundComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeContract()
|
||||||
|
public
|
||||||
|
isCreator()
|
||||||
|
atEndOfLifecycle()
|
||||||
|
{
|
||||||
|
selfdestruct(msg.sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
function () { throw; }
|
||||||
|
}
|
||||||
|
// ** END EXAMPLE **
|
||||||
|
|
||||||
|
|
||||||
|
// 10. OTHER NATIVE FUNCTIONS
|
||||||
|
|
||||||
|
// Currency units
|
||||||
|
// Currency is defined using wei, smallest unit of Ether
|
||||||
|
uint minAmount = 1 wei;
|
||||||
|
uint a = 1 finney; // 1 ether == 1000 finney
|
||||||
|
// Other units, see: http://ether.fund/tool/converter
|
||||||
|
|
||||||
|
// Time units
|
||||||
|
1 == 1 second
|
||||||
|
1 minutes == 60 seconds
|
||||||
|
|
||||||
|
// Can multiply a variable times unit, as units are not stored in a variable
|
||||||
|
uint x = 5;
|
||||||
|
(x * 1 days); // 5 days
|
||||||
|
|
||||||
|
// Careful about leap seconds/years with equality statements for time
|
||||||
|
// (instead, prefer greater than/less than)
|
||||||
|
|
||||||
|
// Cryptography
|
||||||
|
// All strings passed are concatenated before hash action
|
||||||
|
sha3("ab", "cd");
|
||||||
|
ripemd160("abc");
|
||||||
|
sha256("def");
|
||||||
|
|
||||||
|
|
||||||
|
// 11. LOW LEVEL FUNCTIONS
|
||||||
|
// call - low level, not often used, does not provide type safety
|
||||||
|
successBoolean = someContractAddress.call('function_name', 'arg1', 'arg2');
|
||||||
|
|
||||||
|
// callcode - Code at target address executed in *context* of calling contract
|
||||||
|
// provides library functionality
|
||||||
|
someContractAddress.callcode('function_name');
|
||||||
|
|
||||||
|
|
||||||
|
// 12. STYLE NOTES
|
||||||
|
// Based on Python's PEP8 style guide
|
||||||
|
|
||||||
|
// Quick summary:
|
||||||
|
// 4 spaces for indentation
|
||||||
|
// Two lines separate contract declarations (and other top level declarations)
|
||||||
|
// Avoid extraneous spaces in parentheses
|
||||||
|
// Can omit curly braces for one line statement (if, for, etc)
|
||||||
|
// else should be placed on own line
|
||||||
|
|
||||||
|
|
||||||
|
// 13. NATSPEC COMENTS
|
||||||
|
// used for documentation, commenting, and external UIs
|
||||||
|
|
||||||
|
// Contract natspec - always above contract definition
|
||||||
|
/// @title Contract title
|
||||||
|
/// @author Author name
|
||||||
|
|
||||||
|
// Function natspec
|
||||||
|
/// @notice information about what function does; shown when function to execute
|
||||||
|
/// @dev Function documentation for developer
|
||||||
|
|
||||||
|
// Function parameter/return value natspec
|
||||||
|
/// @param someParam Some description of what the param does
|
||||||
|
/// @return Description of the return value
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional resources
|
||||||
|
- [Solidity Docs](https://solidity.readthedocs.org/en/latest/)
|
||||||
|
- [Solidity Style Guide](https://ethereum.github.io/solidity//docs/style-guide/): Ethereum's style guide is heavily derived from Python's [pep8](https://www.python.org/dev/peps/pep-0008/) style guide.
|
||||||
|
- [Browser-based Solidity Editor](http://chriseth.github.io/browser-solidity/)
|
||||||
|
- [Gitter Chat room](https://gitter.im/ethereum/solidity)
|
||||||
|
- [Modular design strategies for Ethereum Contracts](https://docs.erisindustries.com/tutorials/solidity/)
|
||||||
|
- Editor Snippets ([Ultisnips format](https://gist.github.com/nemild/98343ce6b16b747788bc))
|
||||||
|
|
||||||
|
## Sample contracts
|
||||||
|
- [Dapp Bin](https://github.com/ethereum/dapp-bin)
|
||||||
|
- [Solidity Baby Step Contracts](https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts)
|
||||||
|
- [ConsenSys Contracts](https://github.com/ConsenSys/dapp-store-contracts)
|
||||||
|
- [State of Dapps](http://dapps.ethercasts.com/)
|
||||||
|
|
||||||
|
## Information purposefully excluded
|
||||||
|
- Libraries
|
||||||
|
|
||||||
|
## Style
|
||||||
|
- Python's [PEP8](https://www.python.org/dev/peps/pep-0008/) is used as the baseline style guide, including its general philosophy
|
||||||
|
|
||||||
|
## Future To Dos
|
||||||
|
- New keywords: protected, inheritable
|
||||||
|
|
||||||
|
Feel free to send a pull request with any edits - or email nemild -/at-/ gmail
|
@ -302,7 +302,7 @@ class Bicycle {
|
|||||||
|
|
||||||
// 构造函数是初始化一个对象的方式
|
// 构造函数是初始化一个对象的方式
|
||||||
// 以下是一个默认构造函数
|
// 以下是一个默认构造函数
|
||||||
public Bi450635425cycle() {
|
public Bicycle() {
|
||||||
gear = 1;
|
gear = 1;
|
||||||
cadence = 50;
|
cadence = 50;
|
||||||
speed = 5;
|
speed = 5;
|
||||||
@ -328,7 +328,7 @@ class Bicycle {
|
|||||||
return cadence;
|
return cadence;
|
||||||
}
|
}
|
||||||
|
|
||||||
// void返450635425回值函数没有返回值
|
// void返回值函数没有返回值
|
||||||
public void setCadence(int newValue) {
|
public void setCadence(int newValue) {
|
||||||
cadence = newValue;
|
cadence = newValue;
|
||||||
}
|
}
|
||||||
|
@ -91,10 +91,10 @@ until num == 0
|
|||||||
-- 2. 函数。
|
-- 2. 函数。
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
|
||||||
function fib(n)
|
function fib(n)
|
||||||
if n < 2 then return 1 end
|
if n < 2 then return n end
|
||||||
return fib(n - 2) + fib(n - 1)
|
return fib(n - 2) + fib(n - 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 支持闭包及匿名函数:
|
-- 支持闭包及匿名函数:
|
||||||
function adder(x)
|
function adder(x)
|
||||||
@ -129,9 +129,11 @@ function f(x) return x * x end
|
|||||||
f = function (x) return x * x end
|
f = function (x) return x * x end
|
||||||
|
|
||||||
-- 这些也是等价的:
|
-- 这些也是等价的:
|
||||||
local function g(x) return math.sin(x) end
|
local function g(x) return math.sin(x) end
|
||||||
local g; g = function (x) return math.sin(x) end
|
local g; g = function (x) return math.sin(x) end
|
||||||
-- 'local g'使得g可以自引用。
|
-- 以上均因'local g',使得g可以自引用。
|
||||||
|
local g = function(x) return math.sin(x) end
|
||||||
|
-- 等价于 local function g(x)..., 但函数体中g不可自引用
|
||||||
|
|
||||||
-- 顺便提下,三角函数以弧度为单位。
|
-- 顺便提下,三角函数以弧度为单位。
|
||||||
|
|
||||||
@ -328,7 +330,7 @@ seymour:makeSound() -- 'woof woof woof' -- 4.
|
|||||||
|
|
||||||
-- 如果有必要,子类也可以有new(),与基类相似:
|
-- 如果有必要,子类也可以有new(),与基类相似:
|
||||||
function LoudDog:new()
|
function LoudDog:new()
|
||||||
newObj = {}
|
local newObj = {}
|
||||||
-- 初始化newObj
|
-- 初始化newObj
|
||||||
self.__index = self
|
self.__index = self
|
||||||
return setmetatable(newObj, self)
|
return setmetatable(newObj, self)
|
||||||
@ -340,7 +342,9 @@ end
|
|||||||
|
|
||||||
|
|
||||||
--[[ 我把这部分给注释了,这样脚本剩下的部分可以运行
|
--[[ 我把这部分给注释了,这样脚本剩下的部分可以运行
|
||||||
|
```
|
||||||
|
|
||||||
|
```lua
|
||||||
-- 假设文件mod.lua的内容类似这样:
|
-- 假设文件mod.lua的内容类似这样:
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
@ -411,4 +415,9 @@ lua-users.org上的[Lua简明参考](http://lua-users.org/files/wiki_insecure/us
|
|||||||
* <a href="http://lua-users.org/wiki/IoLibraryTutorial">io library</a>
|
* <a href="http://lua-users.org/wiki/IoLibraryTutorial">io library</a>
|
||||||
* <a href="http://lua-users.org/wiki/OsLibraryTutorial">os library</a>
|
* <a href="http://lua-users.org/wiki/OsLibraryTutorial">os library</a>
|
||||||
|
|
||||||
|
顺便说一下,整个文件是可运行的Lua;
|
||||||
|
保存为 learn-cn.lua 用命令 `lua learn.lua` 启动吧!
|
||||||
|
|
||||||
|
本文首次撰写于 [tylerneylon.com](http://tylerneylon.com) 同时也有 [github gist](https://gist.github.com/tylerneylon/5853042) 版.
|
||||||
|
|
||||||
使用Lua,欢乐常在!
|
使用Lua,欢乐常在!
|
||||||
|
Loading…
Reference in New Issue
Block a user