summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--fr-fr/lua-fr.html.markdown449
-rw-r--r--javascript.html.markdown31
-rw-r--r--julia.html.markdown6
-rw-r--r--objective-c.html.markdown151
-rw-r--r--scala.html.markdown2
5 files changed, 620 insertions, 19 deletions
diff --git a/fr-fr/lua-fr.html.markdown b/fr-fr/lua-fr.html.markdown
new file mode 100644
index 00000000..922d6ebc
--- /dev/null
+++ b/fr-fr/lua-fr.html.markdown
@@ -0,0 +1,449 @@
+---
+language: lua
+filename: learnlua-fr.lua
+contributors:
+ - ["Tyler Neylon", "http://tylerneylon.com/"]
+translators:
+ - ["Roland Yonaba", "http://github.com/Yonaba"]
+lang: fr-fr
+---
+
+```lua
+-- Les commentaires unilignes commencent par un double tiret.
+
+--[[
+ Les doubles crochets à la suite du double tiret
+ permettent d'insérer des commentaires multilignes.
+--]]
+
+----------------------------------------------------
+-- 1. Variables et contrôle d'exécution.
+----------------------------------------------------
+
+num = 42 -- Tous les nombres sont de type double.
+-- Rassurez vous cependant, les doubles stockés sur 64-bits
+-- en réservent 52 pour la valeur exacte des entiers. La
+-- précision n'est donc pas un problème pour tout entier qui
+-- peut être codé sur moins de 52 bits.
+
+s = 'walternate' -- Chaines de caractères immuables comme en Python.
+t = "une chaine avec des guillemets doubles"
+u = [[les double crochets permettent
+ d'avoir une chaine de caractères
+ sur plusieurs lignes.]]
+t = nil -- Affecte la valeur nulle à t; Lua possède un ramasse-miettes
+
+-- Le do/end définit un bloc de code
+while num < 50 do
+ num = num + 1 -- Pas d'opérateurs de type ++ ou +=.
+end
+
+-- Les structures en if:
+if num > 40 then
+ print('supérieur à 40')
+elseif s ~= 'walternate' then -- ~= : est différent de.
+ -- Le test d'égalité se fait avec == comme en Python.
+ io.write('inférieur à 40\n') -- Écrit par defaut sur la sortie stdout.
+else
+ -- Les variables sont globales par défaut.
+ thisIsGlobal = 5 -- le style camelCase est courant.
+
+ -- Une variable locale est déclarée avec le mot-clé local:
+ local line = io.read() -- Permet de lire la ligne suivante dans stdin.
+
+ -- .. est l'opérateur de concaténation:
+ print("L'hiver approche, " .. line)
+end
+
+-- Les variables non définies reçoivent par défaut la valeur nil.
+foo = anUnknownVariable -- Maintenant, foo = nil.
+
+aBoolValue = false
+
+-- Seuls nil et false sont des valeurs fausses.
+-- Mais 0 et '' sont des valeurs vraies!
+if not aBoolValue then print('etait faux') end
+
+-- L'évaluation du 'or' et du 'and' est court-circuité.
+-- Comme avec les ternaires du C et du JS: a?b:c
+ans = aBoolValue and 'oui' or 'non' --> 'non'
+
+karlSum = 0
+for i = 1, 100 do -- Les bornes sont incluses dans l'intervalle.
+ karlSum = karlSum + i
+end
+
+-- Utilisez "100, 1, -1" pour la décrémentation:
+fredSum = 0
+for j = 100, 1, -1 do fredSum = fredSum + j end
+
+-- En général, l'intervalle est début, fin[, pas].
+
+-- Un autre type de boucle:
+repeat
+ print('the way of the future')
+ num = num - 1
+until num == 0
+
+
+----------------------------------------------------
+-- 2. Fonctions.
+----------------------------------------------------
+
+function fib(n)
+ if n < 2 then return n end
+ return fib(n - 2) + fib(n - 1)
+end
+
+-- Lua implémente les fermetures et les fonctions anonymes:
+function adder(x)
+ -- La fonction retournée est créée lorsque adder est appelé
+ -- et elle se rappelle de la valeur de x.
+ return function (y) return x + y end
+end
+a1 = adder(9)
+a2 = adder(36)
+print(a1(16)) --> 25
+print(a2(64)) --> 100
+
+-- Les valeurs de retour, les appels de fonction, les assignations
+-- supportent tous les listes qui peuvent ne pas correspondre en longueur.
+-- Dans ce cas, les variables à assigner en supplément reçoivent nil
+-- tandis que les valeurs à attribuer en supplément sont ignorées
+
+x, y = 1, 2 -- x = 1 et y = 2
+x, y, z = 1, 2 -- x = 1, y = 2 et z = nil
+x, y, z = 1, 2, 3, 4 -- x = 1, y = 2, z = 3, et 4 est ignoré.
+
+function bar(a, b, c)
+ print(a, b, c)
+ return 4, 8, 15, 16, 23, 42
+end
+
+x, y = bar('zaphod') --> affiche "zaphod nil nil"
+-- x = 4, y = 8, les valeurs 15 à 42 sont ignorées.
+
+-- Les fonctions sont des valeurs de première classe
+-- et peuvent être locales/globales.
+-- Les déclarations suivantes sont identiques:
+function f(x) return x * x end
+f = function (x) return x * x end
+
+-- Il en va de même pour les déclarations suivantes:
+local function g(x) return math.sin(x) end
+local g = function(x) return math.sin(x) end
+-- Sauf que pour le dernier cas, même si local g = function(x)
+-- est équivalent à local function g(x), il n'est pas possible
+-- de faire appel à g à l'intérieur du corps de la fonction (récursion)
+
+-- À moins de déclarer la fonction auparavant:
+local g; g = function (x) return math.sin(x) end
+
+-- À propos, les fonctions trigonométriques interprètent
+-- leurs arguments en radians.
+print(math.cos(math.pi)) -- affiche "-1"
+print(math.sin(math.pi)) -- affiche "0"
+
+-- Lorsqu'une fonction est appelée avec un seul argument qui est une chaine,
+-- les parenthèses peuvent être omises:
+print 'hello' -- équivalent à print('hello').
+
+-- Lorsqu'une fonction est appelée avec un seul argument qui est une table,
+-- les parenthèses peuvent aussi être omises.
+print {} -- équivalent à print({}).
+
+
+----------------------------------------------------
+-- 3. Tables.
+----------------------------------------------------
+
+-- Tables = Seule structure de données en Lua;
+-- Ce sont des listes assotiatives.
+-- Elles sont similaires aux tables PHP ou aux objets JS :
+-- des tables-dictionnaires que l'on peut utiliser en tant que listes.
+
+-- Tables en tant que dictionnaires:
+
+-- Les clés sont des chaines de caractères par défaut:
+t = {key1 = 'valeur1', key2 = false}
+
+-- Elles peuvent être indexées avec la notation en point, comme en JS:
+print(t.key1) -- Affiche "valeur1".
+t.newKey = {} -- Ajoute une nouvelle paire clé/valeur.
+t.key2 = nil -- Supprime la clé "key2" de la table.
+
+-- Notation littérale pour toute valeur non nulle en tant que clé:
+u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
+print(u[6.28]) -- affiche "tau"
+
+-- La correspondance des clés se fait par valeur pour
+-- les nombres et les chaines, mais par référence pour les tables.
+a = u['@!#'] -- a = 'qbert'.
+b = u[{}] -- On pourrait s'attendre à 1729, mais l'on obtient nil:
+-- b = nil car la clé utilisée n'est pas le même objet que celui
+-- utilisé pour stocker la valeur originale 1729.
+
+-- Si une fonction prend en argument une seule table, l'on peut
+-- omettre les parenthèses:
+function h(x) print(x.key1) end
+h{key1 = 'Sonmi~451'} -- Affiche 'Sonmi~451'.
+
+for key, val in pairs(u) do -- Parcours d'une table.
+ print(key, val)
+end
+
+-- _G est une table spéciale contenant toutes les variables globales,
+-- et donc elle même.
+print(_G['_G'] == _G) -- Affiche 'true'.
+
+-- Tables en tant que listes:
+
+-- De manière implicite, les clés sont des nombres entiers:
+v = {'value1', 'value2', 1.21, 'gigawatts'}
+for i = 1, #v do -- #v retourne la taille de la table v si elle est une liste.
+ print(v[i]) -- Attention, en Lua, les indices commencent à 1!
+end
+-- Il n'existe pas vraiment de type 'liste' en Lua, v est juste
+-- une table avec des clés qui sont des nombres entiers consécutifs
+-- commençant à 1. Lua le traite comme étant une liste.
+
+----------------------------------------------------
+-- 3.1 Métatables and métaméthodes.
+----------------------------------------------------
+
+-- Une table peut avoir une métatable qui confère à la table
+-- un patron/prototype de conception (surcharge d'opération). Nous verrons
+-- dans la suite comment les métatables imitent le prototypage du JS.
+
+f1 = {a = 1, b = 2} -- Représente la fraction a/b.
+f2 = {a = 2, b = 3}
+
+-- Ceci créée une erreur:
+-- s = f1 + f2
+
+metafraction = {}
+function metafraction.__add(f1, f2)
+ local sum = {}
+ sum.b = f1.b * f2.b
+ sum.a = f1.a * f2.b + f2.a * f1.b
+ return sum
+end
+
+setmetatable(f1, metafraction)
+setmetatable(f2, metafraction)
+
+s = f1 + f2 -- appèle __add(f1, f2) de la métatable de f1
+
+-- f1, f2 ne possèdent pas de clé qui pointent vers leur métatable, comme
+-- avec les prototypes en JS. Mais l'on peut utiliser getmetatable(f1).
+-- La métatable est une table normale avec des clés prédéfinies, comme __add.
+
+-- Mais la ligne suivante génère une erreur puisque s n'a pas de métatable:
+-- t = s + s
+-- En implémentant de l'orienté objet, comme nous le verrons par la suite,
+-- le problème est résolu.
+
+-- Une clé __index dans une métatable mt surcharge l'indexation dans sa table t
+-- si la clé est absente de cette table t:
+defaultFavs = {animal = 'gru', food = 'donuts'}
+myFavs = {food = 'pizza'}
+setmetatable(myFavs, {__index = defaultFavs})
+eatenBy = myFavs.animal -- Affiche "gru"! merci à la métatable!
+
+-- Ainsi donc, un accès direct à une valeur dans une table via une clé
+-- inexistante (ce qui normalement retourne "nil") conduira à exploiter
+-- le champ __index de la métatable. Cela peut être récursif.
+
+-- Le champ __index peut aussi être une fonction (tbl, clé)
+-- ce qui permet une gestion plus souple des indexations.
+
+-- Les clés __index, __add,... sont appelées métaméthodes.
+-- En voici la liste complète:
+
+-- __add(a, b) pour a + b
+-- __sub(a, b) pour a - b
+-- __mul(a, b) pour a * b
+-- __div(a, b) pour a / b
+-- __mod(a, b) pour a % b
+-- __pow(a, b) pour a ^ b
+-- __unm(a) pour -a
+-- __concat(a, b) pour a .. b
+-- __len(a) pour #a
+-- __eq(a, b) pour a == b
+-- __lt(a, b) pour a < b
+-- __le(a, b) pour a <= b
+-- __index(a, b) <fn ou table> pour a.b
+-- __newindex(a, b, c) pour a.b = c
+-- __call(a, ...) pour a(...)
+
+----------------------------------------------------
+-- 3.2 Pseudo-orienté objet et héritage.
+----------------------------------------------------
+
+-- Lua n'implémente pas d'orienté objet par défaut.
+-- Mais il reste possible d'imiter de plusieurs manières
+-- le concept de "classe" grâce aux tables et aux métatables.
+
+-- L'explication pour l'exemple qui suit vient juste après.
+
+Dog = {} -- 1.
+
+function Dog:new() -- 2.
+ local newObj = {sound = 'woof'} -- 3.
+ self.__index = self -- 4.
+ return setmetatable(newObj, self) -- 5.
+end
+
+function Dog:makeSound() -- 6.
+ print('Je dis: ' .. self.sound..'!')
+end
+
+mrDog = Dog:new() -- 7.
+mrDog:makeSound() -- 'Je dis: woof! -- 8.
+
+-- 1. Dog agit comme une classe; c'est une simple table.
+-- 2. L'expression tbl:fn(...) est identique à
+-- tbl.fn(self, ...)
+-- La notation : permet de passer par défaut un premier
+-- argument appelé "self" à la fonction tbl.fn
+-- Voir 7 & 8 ci-après pour comprendre comment self prend
+-- sa valeur.
+-- 3. newObj sera une instance de la classe Dog.
+-- 4. self = la classe instanciée. Souvent, self = Dog, mais
+-- cela peut changer du fait de l'héritage.
+-- newObj reçoit les fonctions de self si l'__index des
+-- métatables de newObj et de self pointent vers self.
+-- 5. Rappel: setmetatable retourne son premier argument.
+-- 6. La notation : fonctionne comme au 2, mais cette fois, self
+-- est une instance au lieu d'être une classe.
+-- 7. Similaire à Dog.new(Dog), donc self = Dog dans new().
+-- 8. Similaire à mrDog.makeSound(mrDog); self = mrDog.
+
+----------------------------------------------------
+
+-- Exemple d'héritage:
+
+LoudDog = Dog:new() -- 1.
+
+function LoudDog:makeSound()
+ local s = self.sound .. ' ' -- 2.
+ print(s .. s .. s..'!')
+end
+
+seymour = LoudDog:new() -- 3.
+seymour:makeSound() -- 'woof woof woof!' -- 4.
+
+-- 1. LoudDog reçoit les méthodes et les variables de Dog.
+-- 2. self possède une clé 'sound', reçue de new(), voir 3.
+-- 3. Similaire à LoudDog.new(LoudDog) et traduit en Dog.new(LoudDog),
+-- puisque LoudDog ne possède pas de clé 'new', mais a une métatable
+-- qui a la clé __index = Dog.
+-- Résulat: la métatable de seymour est LoudDog, et
+-- LoudDog.__index = LoudDog. Donc seymour.key deviendra soit égal à
+-- seymour.key, LoudDog.key, Dog.key, selon le fait qu'il s'agira
+-- de la première table ayant la clé 'key' en question, en remontant
+-- dans la hiérarchie.
+-- 4. La clé 'makeSound' est trouvée dans LoudDog; cela est similaire
+-- à LoudDog.makeSound(seymour).
+
+-- Si besoin est, la méthode new() de la sous-classe est
+-- identique à la méthode new() de sa classe mère:
+function LoudDog:new()
+ local newObj = {}
+ -- Prépare self à être la superclasse de newObj:
+ self.__index = self
+ return setmetatable(newObj, self)
+end
+
+----------------------------------------------------
+-- 4. Modules.
+----------------------------------------------------
+
+
+--[[ Cette section est mise en commentaire afin que le reste du
+-- ce script reste exécutable.
+```
+
+```lua
+-- Supposons que le fichier mod.lua contienne ceci:
+local M = {}
+
+local function sayMyName()
+ print('Hrunkner')
+end
+
+function M.sayHello()
+ print('hello')
+ sayMyName()
+end
+
+return M
+
+-- Un autre fichier peut exploiter le contenu défini dans mod.lua's:
+local mod = require('mod') -- Exécute le fichier mod.lua.
+
+-- require est le moyen par défaut d'inclure des modules.
+-- require agit comme: (si non trouvé en cache; voir ci-après)
+local mod = (function ()
+ <contenu de mod.lua>
+end)()
+-- Comme si le contenu de mod.lua était enveloppé dans le corps d'une fonction,
+-- si bien que les variables locales contenues dans mod.lua sont
+-- inaccessibles en dehors de ce module.
+
+-- Le code suivant fonctionne car mod = M (dans mod.lua):
+mod.sayHello() -- Dis bonjour à Hrunkner.
+
+-- Le code suivant génère une erreur car sayMyName est local à mod.lua:
+mod.sayMyName() -- erreur!
+
+-- Les valeurs retournées par require sont mises en cache, ce qui fait
+-- qu'un module est toujours chargé une seule fois, même s'il est inclus
+-- avec require à plusieurs reprises.
+
+-- Supposons que mod2.lua contienne le code "print('Hi!')".
+local a = require('mod2') -- Affiche "Hi!"
+local b = require('mod2') -- N'affiche rien; et a = b.
+
+-- dofile est identique à require, sauf qu'il ne fait pas de mise en cache:
+dofile('mod2') --> Hi!
+dofile('mod2') --> Hi! (le code de mod2.lua est encore exécuté)
+
+-- loadfile charge le contenu d'un fichier, sans l'exécuter.
+f = loadfile('mod2') -- L'appel f() exécute le contenu de mod2.lua.
+
+-- loadstring est similaire à loadfile, mais pour les chaines de caractères.
+g = loadstring('print(343)') -- Retourne une fonction.
+g() -- Affiche 343; Rien n'est affiché avant cet appel.
+
+--]]
+
+```
+## Références
+
+*Les références qui suivent sont en Anglais.*
+
+Les sujets non abordés dans ce tutoriel sont couverts en intégralité par
+les librairies standard:
+
+* La librairie <a href="http://lua-users.org/wiki/StringLibraryTutorial">string</a>
+* La librairie <a href="http://lua-users.org/wiki/TableLibraryTutorial">table</a>
+* La librairie <a href="http://lua-users.org/wiki/MathLibraryTutorial">math</a>
+* La librairie <a href="http://lua-users.org/wiki/IoLibraryTutorial">io</a>
+* La librairie <a href="http://lua-users.org/wiki/OsLibraryTutorial">os</a>
+
+Autres références complémentaires:
+
+* <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">Lua for programmers</a>
+* <a href="lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Courte de référence de Lua</a>
+* <a href="http://www.lua.org/pil/contents.html">Programming In Lua</a>
+* <a href="http://www.lua.org/manual/">Les manuels de référence Lua</a>
+
+A propos, ce fichier est exécutable. Sauvegardez-le sous le nom *learn.lua* et
+exécutez-le avec la commande `lua learn.lua` !
+
+Ce tutoriel a été originalement écrit pour <a href="tylerneylon.com">tylerneylon.com</a> et est aussi
+disponible en tant que <a href="https://gist.github.com/tylerneylon/5853042">gist</a>.
+Il a été traduit en français par Roland Yonaba (voir son <a href="http://github.com/Yonaba">github</a>).
+
+Amusez-vous bien avec Lua! \ No newline at end of file
diff --git a/javascript.html.markdown b/javascript.html.markdown
index 4584a28c..7fb7ba55 100644
--- a/javascript.html.markdown
+++ b/javascript.html.markdown
@@ -319,6 +319,37 @@ var myOtherFunc = function(){
myObj.myOtherFunc = myOtherFunc;
myObj.myOtherFunc(); // = "HELLO WORLD!"
+// We can also specify a context for a function to execute in when we invoke it
+// using 'call' or 'apply'.
+
+var anotherFunc = function(s){
+ return this.myString + s;
+}
+anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
+
+// The 'apply' function is nearly identical, but takes an array for an argument list.
+
+anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
+
+// This is useful when working with a function that accepts a sequence of arguments
+// and you want to pass an array.
+
+Math.min(42, 6, 27); // = 6
+Math.min([42, 6, 27]); // = NaN (uh-oh!)
+Math.min.apply(Math, [42, 6, 27]); // = 6
+
+// But, 'call' and 'apply' are only temporary. When we want it to stick, we can use
+// bind.
+
+var boundFunc = anotherFunc.bind(myObj);
+boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
+
+// Bind can also be used to partially apply (curry) a function.
+
+var product = function(a, b){ return a * b; }
+var doubler = product.bind(this, 2);
+doubler(8); // = 16
+
// When you call a function with the new keyword, a new object is created, and
// made available to the function via the this keyword. Functions designed to be
// called like that are called constructors.
diff --git a/julia.html.markdown b/julia.html.markdown
index ce55f956..4b946d46 100644
--- a/julia.html.markdown
+++ b/julia.html.markdown
@@ -105,7 +105,7 @@ some_var #=> 5
# Accessing a previously unassigned variable is an error
try
- some_other_var #=> ERROR: some_other_var not defined
+ some_other_var #=> ERROR: some_other_var not defined
catch e
println(e)
end
@@ -417,7 +417,7 @@ try
defaults('h') #=> ERROR: no method defaults(Char,)
defaults() #=> ERROR: no methods defaults()
catch e
-println(e)
+ println(e)
end
# You can define functions that take keyword arguments
@@ -509,7 +509,7 @@ type Tiger
end
# The default constructor's arguments are the properties
-# of the tyep, in order the order they are listed in the definition
+# of the type, in the order they are listed in the definition
tigger = Tiger(3.5,"orange") #=> Tiger(3.5,"orange")
# The type doubles as the constructor function for values of that type
diff --git a/objective-c.html.markdown b/objective-c.html.markdown
index 1ed0ed58..406b2e92 100644
--- a/objective-c.html.markdown
+++ b/objective-c.html.markdown
@@ -50,52 +50,105 @@ int main (int argc, const char * argv[])
// String
NSString *worldString = @"World";
- NSLog(@"Hello %@!", worldString); // Print "Hello World!"
+ NSLog(@"Hello %@!", worldString); // prints => "Hello World!"
+ // NSMutableString is a mutable version of the NSString object.
+ NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"];
+ [mutableString appendString:@" World!"];
+ NSLog(@"%@", mutableString); // prints => "Hello World!"
// Character literals
NSNumber *theLetterZNumber = @'Z';
- char theLetterZ = [theLetterZNumber charValue];
+ char theLetterZ = [theLetterZNumber charValue]; // or 'Z'
NSLog(@"%c", theLetterZ);
// Integral literals
NSNumber *fortyTwoNumber = @42;
- int fortyTwo = [fortyTwoNumber intValue];
+ int fortyTwo = [fortyTwoNumber intValue]; // or 42
NSLog(@"%i", fortyTwo);
NSNumber *fortyTwoUnsignedNumber = @42U;
- unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
+ unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue]; // or 42
NSLog(@"%u", fortyTwoUnsigned);
NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
- short fortyTwoShort = [fortyTwoShortNumber shortValue];
+ short fortyTwoShort = [fortyTwoShortNumber shortValue]; // or 42
NSLog(@"%hi", fortyTwoShort);
+
+ NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:41];
+ unsigned short fortyTwoUnsigned = [fortyTwoShortNumber unsignedShortValue]; // or 41
+ NSLog(@"%hu", fortyTwoUnsigned);
NSNumber *fortyTwoLongNumber = @42L;
- long fortyTwoLong = [fortyTwoLongNumber longValue];
+ long fortyTwoLong = [fortyTwoLongNumber longValue]; // or 42
NSLog(@"%li", fortyTwoLong);
+ NSNumber *fortyTwoLongNumber = @53L;
+ unsigned long fiftyThreeUnsigned = [fortyTwoLongNumber unsignedLongValue]; // or 53
+ NSLog(@"%lu", fiftyThreeUnsigned);
+
// Floating point literals
NSNumber *piFloatNumber = @3.141592654F;
- float piFloat = [piFloatNumber floatValue];
- NSLog(@"%f", piFloat);
+ float piFloat = [piFloatNumber floatValue]; // or 3.141592654f
+ NSLog(@"%f", piFloat); // prints => 3.141592654
+ NSLog(@"%5.2f", piFloat); // prints => " 3.14"
NSNumber *piDoubleNumber = @3.1415926535;
- double piDouble = [piDoubleNumber doubleValue];
+ double piDouble = [piDoubleNumber doubleValue]; // or 3.1415926535
NSLog(@"%f", piDouble);
+ NSLog(@"%4.2f", piDouble); // prints => "3.14"
+
+ // NSDecimalNumber is a fixed-point class that's more precise then float or double
+ NSDecimalNumber *oneDecNum = [NSDecimalNumber decimalNumberWithString:@"10.99"];
+ NSDecimalNumber *twoDecNum = [NSDecimalNumber decimalNumberWithString:@"5.002"];
+ // NSDecimalNumber isn't able to use standard +, -, *, / operators so it provides its own:
+ [oneDecNum decimalNumberByAdding:twoDecNum];
+ [oneDecNum decimalNumberBySubtracting:twoDecNum];
+ [oneDecNum decimalNumberByMultiplyingBy:twoDecNum];
+ [oneDecNum decimalNumberByDividingBy:twoDecNum];
+ NSLog(@"%@", oneDecNum); // prints => 10.99 as NSDecimalNumber is immutable.
// BOOL literals
NSNumber *yesNumber = @YES;
NSNumber *noNumber = @NO;
+ // or
+ BOOL yesBool = YES;
+ BOOL noBool = NO;
+ NSLog(@"%i", yesBool); // prints => 1
// Array object
NSArray *anArray = @[@1, @2, @3, @4];
NSNumber *thirdNumber = anArray[2];
NSLog(@"Third number = %@", thirdNumber); // Print "Third number = 3"
+ // NSMutableArray is mutable version of NSArray allowing to change items in array
+ // and extend or shrink array object. Convenient, but not as efficient as NSArray.
+ NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2];
+ [mutableArray addObject:@"Hello"];
+ [mutableArray addObject:@"World"];
+ [mutableArray removeObjectAtIndex:0];
+ NSLog(@"%@", [mutableArray objectAtIndex:0]); // prints => "World"
// Dictionary object
NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
NSObject *valueObject = aDictionary[@"A Key"];
NSLog(@"Object = %@", valueObject); // Print "Object = (null)"
+ // NSMutableDictionary also available as a mutable dictionary object.
+ NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+ [mutableDictionary setObject:@"value1" forKey:@"key1"];
+ [mutableDictionary setObject:@"value2" forKey:@"key2"];
+ [mutableDictionary removeObjectForKey:@"key1"];
+
+ // Set object
+ NSSet *set = [NSSet setWithObjects:@"Hello", @"Hello", @"World", nil];
+ NSLog(@"%@", set); // prints => {(Hello, World)} (may be in different order)
+ // NSMutableSet also available as a mutable set object.
+ NSMutableSet *mutableSet = [NSMutableSet setWithCapacity:2];
+ [mutableSet addObject:@"Hello"];
+ [mutableSet addObject:@"Hello"];
+ NSLog(@"%@", mutableSet); // prints => {(Hello)}
+
+ // Set object
+ NSSet *set = [NSSet setWithObjects:@"Hello", @"Hello", @"World", nil];
+ NSLog(@"%@", set); // prints => {(Hello, World)}
///////////////////////////////////////
// Operators
@@ -176,6 +229,14 @@ int main (int argc, const char * argv[])
// "2,"
// "3,"
+ // Object for loop statement. Can be used with any Objective-C object type.
+ for (id item in values) {
+ NSLog(@"%@,", item);
+ } // => prints "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
// Try-Catch-Finally statements
@try
{
@@ -225,14 +286,30 @@ int main (int argc, const char * argv[])
// @end
@interface MyClass : NSObject <MyProtocol>
{
- int count;
- id data;
- NSString *name;
+ // Instance variable declarations (can exist in either interface or implementation file)
+ int count; // Protected access by default.
+ @private id data; // Private access. (More convenient to declare in implementation file)
+ NSString *name;
}
-// Convenience notation to auto generate public getter and setter
+// Convenient notation to auto generate public access getter and setter
@property int count;
@property (copy) NSString *name; // Copy the object during assignment.
@property (readonly) id data; // Declare only a getter method.
+// To access public variable in implementation file, use '_' followed by variable name:
+_count = 5;
+NSLog(@"%d", _count); // prints => 5
+// To access public variable outside implementation file, @property generates setter method
+// automatically. Method name is 'set' followed by @property variable name:
+MyClass *myClass = [[MyClass alloc] init]; // create MyClass object instance.
+[myClass setCount:10];
+NSLog(@"%@", [myClass count]); // prints => 10
+// You can customize the getter and setter names instead of using default 'set' name:
+@property (getter=countGet, setter=countSet:) int count;
+[myClass countSet:32];
+NSLog(@"%i", [myClass countGet]); // prints => 32
+// For convenience, you may use dot notation to set object instance variables:
+myClass.count = 45;
+NSLog(@"%i", myClass.count); // prints => 45
// Methods
+/- (return type)methodSignature:(Parameter Type *)parameterName;
@@ -247,8 +324,9 @@ int main (int argc, const char * argv[])
@end
// Implement the methods in an implementation (MyClass.m) file:
-
-@implementation MyClass
+@implementation MyClass {
+ long count; // Private access instance variable.
+}
// Call when the object is releasing
- (void)dealloc
@@ -299,6 +377,49 @@ int main (int argc, const char * argv[])
@end
+///////////////////////////////////////
+// Memory Management
+///////////////////////////////////////
+/*
+For each object used in an application, memory must be allocated for that object. When the application
+is done using that object, memory must be deallocated to ensure application efficiency.
+Objective-C does not use garbage collection and instead uses reference counting. As long as
+there is at least one reference to an object (also called "owning" an object), then the object
+will be available to use (known as "ownership").
+
+When an instance owns an object, its reference counter is increments by one. When the
+object is released, the reference counter decrements by one. When reference count is zero,
+the object is removed from memory.
+
+With all object interactions, follow the pattern of:
+(1) create the object, (2) use the object, (3) then free the object from memory.
+*/
+
+MyClass *classVar = [MyClass alloc]; // alloc sets classVar's reference count to one. Returns pointer to object.
+[classVar release]; // Decrements classVar's reference count.
+// retain claims ownership of existing object instance and increments reference count. Returns pointer to object.
+MyClass *newVar = [classVar retain]; // If classVar is released, object is still in memory because newVar is owner.
+[classVar autorelease]; // Removes ownership of object at end of @autoreleasepool block. Returns pointer to object.
+
+// @property can use retain or assign as well for small convenient definitions.
+@property (retain) MyClass *instance; // Release old value and retain a new one (strong reference).
+@property (assign) NSSet *set; // Pointer to new value without retaining/releasing old (weak reference).
+
+// Because memory management can be a pain, Xcode 4.2 and iOS 4 introduced Automatic Reference Counting (ARC).
+// ARC is a compiler feature that inserts retain, release, and autorelease automatically for you, so when using ARC,
+// you must not use retain, relase, or autorelease.
+MyClass *arcMyClass = [[MyClass alloc] init]; // Without ARC, you will need to call: [arcMyClass release] after
+// you're done using arcMyClass. But with ARC, there is no need. It will insert this release statement for you.
+
+// As for the "assign" and "retain" @property attributes, with ARC you use "weak" and "strong".
+@property (weak) MyClass *weakVar; // weak does not take ownership of object. If original instance's reference count
+// is set to zero, weakVar will automatically receive value of nil to avoid application crashing.
+@property (strong) MyClass *strongVar; // strong takes ownership of object. Ensures object will stay in memory to use.
+
+// For regular variables (not @property declared variables), use the following:
+__strong NSString *strongString; // Default. Variable is retained in memory until it leaves it's scope.
+__weak NSSet *weakSet; // Weak reference to existing object. When existing object is released, weakSet is set to nil.
+__unsafe_unretained NSArray *unsafeArray; // Like __weak but unsafeArray not set to nil when existing object is released.
```
## Further Reading
diff --git a/scala.html.markdown b/scala.html.markdown
index 03c1ea76..5dfaefe0 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -396,7 +396,7 @@ object Application {
// To read a file line by line
import scala.io.Source
-for(line <- Source.fromPath("myfile.txt").getLines())
+for(line <- Source.fromFile("myfile.txt").getLines())
println(line)
// To write a file use Java's PrintWriter