Pages

mardi 25 décembre 2012

La vis cacher de getopt

Voici une petite information très mal connue et peu utilisée du getopt de la lib C et de la commande shell. Ainsi que de Boost.Program_options (parce que boost c'est bien ^^).

Les noms des options longues n'ont pas besoin d'être écrites entièrement.

$ getopt -o '' --long \
option-longue,option-encore-plus-longue,une-autre-option: \
-n 'example' -- \
--option-l --u plop bidule
> --option-longue --une-autre-option 'plop' -- 'bidule'

La commande shell getopt est un peu plus souple que les autres, si ambiguïté la première option correspondante sera sélectionnée. Si l'option -a existe ce n'est plus le cas et le code d'erreur 1 est retourné ainsi qu'un petit message listant les options possibles. Mais avec -a les options longues peuvent commencer par un simple tiret.

La plupart des commandes Linux utilisant getopt, cette astuce peut s'utiliser assez souvent.

jeudi 20 décembre 2012

Taguer vos classes, cataloguées les

Le C++ a l'avantage de faire de la surcharge de fonction et permet ainsi de spécifier des algorithmes selon des critères> Ici ce seront des `tags`.

Comme exemple je vais utiliser les tags présents dans les itérateurs de la stl et une implémentation de la fonction std::advance().

Première implémentation

La fonction std::advance() permet d'incrémenter un itérateur de N éléments (ou décrémenter si N est négatif). D'après cette description, un premier algorithme peut être émis:

template<class InputIt, class Distance>
void advance(InputIt& it, Distance n)
{
  if (n < 0){
    while (n++)
      --it;
  }
  else {
    while (n--)
      ++it;
  }
}

Optimisation

Maintenant que se passe-t-il quand l'itérateur est un pointeur ? Réponse: Une boucle.
Ne serait-il pas préférable de faire it += n !?
C'est là que les tag rentrent en jeux.

Utilisation des tags

Les itérateurs possèdent des types prédéfinis qui sont: pointer, value_type, reference, difference_type et iterator_category. C'est ce dernier qui correspond au tag de l'itérateur.

En réalité un tag est une classe vide, cela suffit, le type est porteur de l'information. Les tags des itérateurs possèdent aussi une hiérarchie et certains sont donc hérités.

Pour récupérer le type contenu dans un itérateur il faut passer par std::iterator_traits<>, cela permet de fonctionner même avec un type scalaire comme le pointeur qui ne possède pas de type interne.

Le tag d'un pointeur étant std::random_access_iterator_tag voici une implémentation:

template<class It>
class std::iterator_traits<It>::iterator_category
iterator_category(const It&)
{ return typename std::iterator_traits<It>::iterator_category(); }

template<class RandomIt, class Distance>
void advance(RandomIt& it, Distance n, std::random_access_iterator_tag)
{ it  += n; }

template<class InputIt, class Distance>
void advance(InputIt& it, Distance n)
{ advance(it, n, iterator_category(it)); }

Bien sûr, on change aussi le prototype de la précédente implémentation.

template<class InputIt, class Distance, class Tag>
void advance(InputIt& it, Distance n, Tag);

Problème avec ForwardIterator

Toutefois un problème persiste, lorsqu'un ForwardIterator est utilisé, il n'y a pas d'opération de décrémentation, et la compilation ne se fait pas. Il faut de nouveau changer notre première implémentation pour qu'elle ne fonctionne qu'avec bidirectional_iterator_tag et une implémentation généraliste qui fait une incrémentation.

template<class InputIt, class Distance, class Tag>
void advance(InputIt& it, Distance n, Tag)
{
  while (n--)
    ++it;
}

template<class InputIt, class Distance>
void advance(InputIt& it, Distance n, std::bidirectional_iterator_tag)
{
  if (n < 0){
    while (n++)
      --it;
  }
  else {
    while (n--)
      ++it;
  }
}

Conclusion

L'utilisation de tag combinée avec la surcharge de fonction est plus simple que la spécialisation de template et permet un meilleur ciblage dans les algorithmes utilisés.

Good conclusion :D

samedi 15 décembre 2012

Les littéraux

En C++11 le langage introduit les littéraux définis par l'utilisateur. Pour rappel, les littéraux permettent de forcer un type via un suffixe, comme avec 1L pour créer un long.

Les littéraux se définissent par un nouvel opérateur: operator "", et le nom du suffixe (identifiant) doit obligatoirement être précédé d'un underscore. Les suffixes sans underscrore sont réservés par les standards existants ou à venir.
À noter qu'un espace -ou saut de ligne- est obligatoire après "".

Il existe deux types de littéraux, ceux sur des nombres et ceux sur des caractères.

Littéraux sur nombres

result_type operator "" _suffix(unsigned long long); // 334_suffix
result_type operator "" _suffix(double long); // 334.2_suffix
template<char...> result_type operator "" _suffix(); // 334_suffix ou  334.2_suffix
result_type operator "" _s(const char *); // 334_suffix ou  334.2_suffix

Quatre prototypes, le premier s'utilise sur des entiers, le second sur des nombres flottants, les troisième et quatrième pour entiers ou flottants et sont cachés par les 2 premiers si définis.

L'overflow

Le problème est que le paramètre peut être plus grand que le contenu du type de retour.
Par exemple, si _suffix retourne un short alors 99999_suffix doit générer une erreur de compilation car la valeur est trop grande.
En utilisant les 2 premiers prototypes, cette vérification ne peut pas se faire, le paramètre d'une fonction n'étant pas considéré comme const-expressif, static_cast ne peut pas être utilisé dessus et donc: pas de vérification à la compilation.
Le troisième prototype est le seul moyen de gérer l'overflow. Cependant son utilisation peut devenir complexe…
J'intégrerai bientôt dans falcon/literal une classe pour simplifier cette vérification ;).

Littéraux sur caractères

result_type operator "" _suffix(char); // '2'_suffix
result_type operator "" _suffix(const char *, std::size_t len); // "334"_suffix

Un prototype pour les caractères et un autre pour les chaînes. Ce dernier prend la taille de la chaîne en second paramètre.
À noter que char peut être remplacé par wchar_t, char16_t ou char32_t, ce qui fait un total de 8 prototypes.

Un cas d'utilisation simple est la concaténation de chaîne std::string("text: ") + str qui peut être simplifier en "text: "_s + str

std::string operator "" _s(const char * s, std::size_t len)
{ return std::string(s, len); }

Pour finir

Je vous propose d'aller jeter un œil ou deux dans falcon/literal (sans vouloir insister :o)).
En cadeau la liste des littéraux prédéfinis dans le standard:

lundi 10 décembre 2012

Les lambdas en C++

Les lambdas ou fonctions anonymes sont un mécanisme présent dans beaucoup de langages de programmation, C++11 en fait partie :).

Le principe est simple, créer un foncteur à la volée pour le passer directement à une fonction/classe ou le stocker dans une variable. Par exemple, dans mon précédant billet sur le C++, la variable f contient une lambda.

La plus courte et inutile lambda existante fait 4 caractères, ce sont les 4 caractères obligatoires à la création d'une lambda : []{}

La syntaxe complète est celle-ci :
[clause-de-capture](paramètres...) mutable-specification exception-specification -> type-de-retour { corps-du-lambda }
Ce qui fait 6 parties

Clause de capture

[clause-de-capture]: spécifie comment l'expression lambda accède aux variables dans la portée englobante. Par défaut, aucune variable n'est accessible.
Un & indique un accès par référence et un = par valeur.
Si la & est préfixée d'un nom de variable, alors seule cette variable est accessible par référence.
Si le nom de variable n'est pas préfixé alors la variable est accessible par valeur.
Pour finir, la clause this permet d’accéder au scope de la classe (si créé dans une classe, évidemment).
Bien sûr, plusieurs clauses peuvent être indiquées en les séparant par des virgules.

  • [=] tous par valeur
  • [&] tous par référence
  • [x] x par valeur
  • [&x] x par référence
  • [&, x] x par valeur, tout le reste par référence
  • [=, &x] x par référence, tout le reste par valeur
  • [this] permet d'utiliser le pointeur this

Liste de paramètres

(paramètres...): Pareil que pour une fonction mais pas de template. En c++14, les types peuvent être auto pour remplacer les templates.
Facultative si mutable-specification, exception-specification et type-de-retour ne sont pas indiqués.

Spécification mutable

mutable: Permet de modifier les variables qui sont capturées par valeur.

[=](){++x} // erreur car x est en lecture seule
[=]() mutable {++x} // ok

Spécification d'exception

noexcept: Là rien d'extraordinaire, on l'indique si aucune exception n'est retournée.

Type de retour

-> type-de-retour: Indique le type de retour. Optionnel, le compilateur utilisant automatiquement un decltype.

Corps du lambda

{ corps-du-lambda }: le super algorithme de la mort qui tue.
À noter que les variables globales et statiques sont accessibles.

mercredi 5 décembre 2012

setTimeout/setInterval et le eval caché

Tout le monde sait que eval c'est le mal, surtout parce que les interpréteurs (ou compilateurs) n'optimisent pas les codes générés avec.

Il existe au moins deux fonctions faisant un eval() si mal utilisées: setTimeout et setInterval.

Ces deux fonctions peuvent prendre une chaîne de caractères, et si c'est le cas, le mal, euuh eval est enclenché.

Une dernière chose mal connue car n'existant pas sur IE (jusqu'à je ne sais quelle version) est que les paramètres supplémentaires seront transmis à la fonction lors de son appel.

setTimeout(alert, 1000, "plop") //alert("plop") au bout d'une seconde

Et pour la perte du this (qui se présente toujours lors de passage de fonction), il y a Function.bind depuis js 1.8.5. Comme souvent (toujours ?) une implémentation est présente pour les navigateurs ne l'implémentant pas encore.

vendredi 30 novembre 2012

Déduction de type

Avec la nouvelle norme du C++ certains mots réservés se sont vu modifiés et de nouveaux mots-clefs sont apparus. C'est le cas de auto et decltype.

auto permet maintenant de ne pas indiquer de type lors de l'initialisation, le compilateur le faisant tout seul.

auto i = 8; // int
auto& x = i; // int&
auto p = new A; // A*
auto f = [](int n) { return n + 1; }; // quelque chose :)

decltype quant à lui permet de copier le type d'une variable ou d'une expression. Il s'utilise là où auto ne peut l'être, lors de la déclaration d'une variable.

decltype(f(8)) r; // int
decltype(x) ref; // int&

À noter que 2 parenthèses transforment le type en référence.

decltype((i)) a; // int&

Encore plus fort, auto et decltype peuvent être combinés pour déduire le retour d'une fonction.

template<typename _T, typename _U>
auto f(const _T& a, const _U&) -> decltype(a + b)
{ return a + b; }

dimanche 25 novembre 2012

Initialisation de membre non statique

Depuis gcc-4.7 il est possible d'initialiser des membres non statiques, ce qui simplifie l'écriture des constructeurs, notamment quand ceux-ci sont nombreux.
struct A {
  int i = 42;
} a; // initialise a.i avec 42

mardi 20 novembre 2012

Délégation de constructeur

Une belle nouveauté du langage est la délégation du constructeur
struct A {
 A(int);
 A(): A(42) { } // déléguer au constructeur A(int)
};

jeudi 15 novembre 2012

Héritage de constructeur

Une autre utilisation de using permet d'inclure les fonctions d'une classe parente dans la classe fille.

En C++11 cela s'étend aussi pour les constructeurs.

class A {
  int i;
public:
  A(int n)
  : i(n)
  {}
  //...
};
struct B : A {
  using A::A;
  //...
};
//...
B b(8);

Malheureusement pour ceux qui utilisent gcc, ce n'est disponible qu'à partir de la version 4.8.

samedi 10 novembre 2012

Alias templates

Ce message comme les quelques-uns qui suivront, sont dédiés aux nouveautés qu'apportent le C++11 et les parties déjà implémentées par gcc-4.7.

Pour aujourd'hui ce sera les alias sur templates. Qui n'a jamais eu envie de faire un typedef sur une structure template, définir quelques paramètres en dur et laisser les autres variables ? Définir par exemple une map qui contient des clefs en string et des valeurs définies par l'utilisateur ?

En C++89 c'est possible en passant par un intermédiaire: un trait.

template<typename _T>
struct build_map_key_string
{ typedef std::map<std::string, _T> type; };
//...
build_map_key_string<int>::type strmap;

Pas très beau :/.

Maintenant c'est possible de le faire de façon transparente, exactement comme avec un typedef. Sauf que typedef, en C++11, c'est dépasser, le nouveau mot clef à utiliser est using ‑même si pour la compatibilité typedef est toujours existant.

template<typename _T>
using map_key_string = std::map<std::string, _T>;
//...
map_key_string<int> strmap;

Simple et efficace !

J'hésitais à l’utiliser dans falcon mais depuis qu'un test echoué en gcc-4.6 est passé en gcc-4.7 je me suis mis à l'utiliser. Un exemple se trouve dans falcon/iterator/indirect_iterator.hpp où on peut voir un code vachement simplifié: un alias contre un héritage (les 2 y sont ;)). Je l'utilise également dans mon module property ce qui permet de simplifier l'utilisation compliquée d'une classe générique et cela de façon très élégante.

mardi 6 novembre 2012

Sed tout puissant

Il y 3 semaines environ je cherchais le moyen d'utiliser la commande sed avec une regex sur plusieurs lignes. En fait je voulais transformer tous les /\+\n\s+""/ en rien du tout (oui, les supprimer…). Sauf que comme tel, ça ne fonctionne pas, sed comme beaucoup de commandes unix fonctionne par ligne. Après de lourdes et pompeuses recherches d'au moins 7 secondes montre en main, je suis tombé sur la solution.

Pour ce faire, il suffit d'un identifiant, un petit label, une information de multi-ligne au milieu et 3 autres bricoles ; rien que ça :D.
Ce qui se traduit par:

sed -e :a -e N -e '$!ba' -e s'/\+\n\s+""//g'

Et en version courte:

sed ':a;N;$!ba;s/\+\n\s+""//g'

Je sais ce que vous vous demandez: pourquoi il n'y a pas -e dans la version courte ?
Mais parce que c'est la version courte, évidemment !

Sinon dans une moindre mesure.

:a
pour créer un identifiant, mais il peut très bien se nommer bidule
N
pour indiquer plusieurs lignes
$!ba
combinaison pour indiquer plein de choses, la seule dont je suis sûr c'est que b demande un identifiant (ici 'a')…

N peut être utilisé tout seul mais à ce moment c'est comme si on découpait le fichier par nombres de lignes égales à celle de la regex et qu'on les traitait indépendamment. Résultat, il peut y avoir des trous.

$ cat t
titi
titi
toto
titi
titi
$ sed ':a;N;$!ba;s/titi\ntiti/tutu/g' t
tutu
toto
tutu
$ sed 'N;s/titi\ntiti/tutu/g' t
tutu
toto
titi
titi

Et en bonus

sed 2,5s/e/U/g #remplace e par U à partir de la ligne 2 jusqu'à la 5.
sed "/$debut/,/$fin/"s/A/a/g #depuis $debut jusqu'à $fin.
sed "/$debut/,+5"s/A/a/g #depuis $debut et sur 5 ligne.

vendredi 26 octobre 2012

Alléger le code des classes template.

Une chose sympa à savoir quand on fait de grosses classes template en C++, c'est que le nom de la classe à l'intérieur d'elle-même est suffisante pour indiquer son type ; pas besoin d'ajouter les paramètres de template.
template<typename _T>
struct A
{
 A operator(const A&)
 { return *this; }
};
Voyez, pas de A<_T>.

dimanche 14 octobre 2012

Zsh et le danger des modificateurs

Zsh est très bien comme shell mais fait plus de choses que bash, ce qui peut engendrer des bugs quand celui-ci est le shell par défaut et que des scripts ne définissent pas l’interpréteur utilisé…
Actuellement j'ai eu le coup une fois, lorsqu'il fallait charger le module canberra-gtk pour les programmes java.
En fait une variable $GTK_MODULES est définie et contient tous les modules gtk séparés par des deux points (:).
Visiblement j'ai 2 modules gtk, tous 2 servant à ajouter canberra-gtk-module. Les fautifs ? 52libcanberra-gtk-module_add-to-gtk-modules et 52libcanberra-gtk3-module_add-to-gtk-modules. Avec un code identique :

if [ -z "$GTK_MODULES" ] ; then
    GTK_MODULES="canberra-gtk-module"
else
    GTK_MODULES="$GTK_MODULES:canberra-gtk-module"
fi

export GTK_MODULES
Et la paf c'est le drame, GTK_MODULES=canberra-gtk-moduleanberra-gtk-module. naturellement :D.
Vous venez d'assister à l'effet du modifier :c qui au passage n'existe pas et disparaît. Pour info, ce n'est pas le cas de :g, tout aussi inexistant mais qui s'affiche quand même…
Possible que ma doc ne soit pas à jour.

Les modifiers existe aussi dans bash mais sont moins nombreux et ne s'utilisent qu'avec l'historique (paragraphe HISTORY EXPANSION du man).

echo unfichier.txt
echo !:1:r

resultat :
unfichier.txt
unfichier

Quasiment jamais utilisé en fait.
Mais voilà, zsh les généralise aussi aux variables ce qui engendre une erreur dans la variable GTK_MODULES.

Alors comment faire ?
Simple, entourer la variable d'accolades:
GTK_MODULES="${GTK_MODULES}:canberra-gtk-module"

lundi 8 octobre 2012

Java et l'apparence graphique

Il y quelques jours, suite à la création d'interface graphique en java et l'apparence par défaut que je trouve particulièrement désagréable, je me suis attelé de changer le thème graphique.
En fait j'ai trouvé toutes les infos sur cette page de oracle.

Pour fortement synthétiser, le thème peut être choisi au lancement du programme avec l'option -D :
java -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel MyApp

Ou de façon permanente si dans le fichier swing.properties (dossier /etc/java-$JAVA_JDK_VERSION-openjdk/ sur linux). Pour moi la ligne était en commentaire.

Pour Windows la ligne est swing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel
Et j'imagine que pour Mac c'est swing.defaultlaf=com.sun.java.swing.plaf.macintosh.MacintoshLookAndFeel

Il y a d'autres thèmes comme Motif ou Métal (celui par défaut) mais je n'en ai pas trouvé pour Qt ou KDE… Au final je me sers du paquet gtk2-engines-oxygen pour que GTK utilise le thème Oxygen (Configuration du système → Apparence → Apparence GTK+ dans KDE).

dimanche 9 septembre 2012

Allouer un tableau constant et statique dans une classe

Avec la version 4.7 de gcc, il est possible de faire des tableaux const static à l'intérieur d'une classe. La façon de faire est cependant assez déroutante: le tableau doit être re-déclaré sinon la variable est indéfinie.
struct A
{
 constexpr static int a[4]{1,2,6,96};
};
constexpr int A::a[4];

int main()
{
 return A::a[3];
}

lundi 27 août 2012

Bien surcharger les flux

La surcharge de flux se fait avec les opérateurs << et >>, avec respectivement les classes std::basic_ostream<_CharT, _Traits> et std::basic_istream<_CharT, _Traits>.
Leurs définitions -ainsi que tous les types de flux et buffers de la std- se trouvent dans <iosfwd> (pour ios forward, voir le billet précédent ;)). Inutile d'inclure <ostream> ou <istream> et encore moins <iostream>.

Sur le web beaucoup d'exemples se basent uniquement sur std::ostream et std::istream, mais ce ne sont en fait que des alias.

typedef basic_istream<char> istream;
typedef basic_ostream<char> ostream;

Les exemples montrés avec ces 2 types ne fonctionnent pas lorsque par exemple un std::wcout est utilisé (flux de sortie standard de type wostream = basic_ostream<wchar_t>).

Pour un maximum de compatibilité, il faut utiliser les classes de bases, ce qui donne :

#include <iosfwd>

template<typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& os, const MyType& a)
{
 return os << ...;
}

template<typename _CharT, typename _Traits>
std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& is, MyType& a)
{
 return is >> ...;
}

Dans certaines circonstances, le flux devrait avoir un accès aux membres privés, il faudra donc en faire une fonction amie.

class MyType
{
 //...
 template<typename _CharT, typename _Traits>
 friend std::basic_ostream<_CharT, _Traits>&
 operator<<(std::basic_ostream<_CharT, _Traits>& os, const MyType& a);
};

samedi 25 août 2012

Réduire le temps de compilation avec la déclaration anticipée

Il existe un moyen simple de réduire le temps de compilation d'un programme avec sources et en-têtes séparés : la déclaration anticipée (ou forward declaration).
Cette méthode proposée par certain IDE permet de réduire les dépendances entre en-tête, ce qui réduit le nombre de fichiers analysés. De plus, moins il y a de dépendances moins une modification d'en-tête engendre la re-compilation de source.

La déclaration anticipée ne peut se faire que sur des types indirects comme les pointeurs et références et dont les attributs et méthodes n'ont pas besoin d'être connus dans le fichier.

class B; //forward declaration

class A
{
 B * b;
 //prototype des méthodes
};

lundi 20 août 2012

Comment passer les valeurs d'une tuple à une fonction ?

Par exemple fonction g() retourne une tuple de trois éléments: int, double et string.

std::tuple<int, double, std::string> g();

Une seconde fonction nommée f() attend 3 éléments: string, int et double.

void f(std::string s, int i, double d);

Et nous voulons passer les valeurs de la tuple à f().

auto t = g();
f(std::get<2>(t), std::get<0>(t), std::get<1>(t));

Mais ceci n'est pas suffisant, nous voulons maintenant avoir une fonction qui le fasse pour nous et de façon plus généraliste. On lui indique les 2 fonctions et les index de la tuple à transférer.

template<std::size_t... _indexes>
class parameter_index;

template<typename _TupleGenerator, typename _Function,
std::size_t... _Indexes>
void delegate(const parameter_index<_indexes...>& ,
              _TupleGenerator generator,
              _Function func); 

Maintenant il suffit simplement de donner les index à std::get() pour récupérer toutes les valeurs:

{
 /*return */func(std::get<_indexes>(generator())...);
}

Et c'est tout simple à utiliser:

delegate(parameter_index<2,0,1>(), &g, &f);

Avec un trait qui génère automatiquement le parameter_index et si les valeurs de la tuple sont à transmettre dans le même ordre, il est possible de simplifier en ne mettant pas le parameter_index en paramètre. Un exemple avec tuple_apply tout droit sorti de ma lib falcon.

jeudi 16 août 2012

La récursivité et le mauvais exemple de Fibonacci

Quasiment toute personne ayant suivi un cours sur la récursivité a eu un problème du style : coder la suite de Fibonacci en récursif et en itératif.

Mais partout où j'ai vu une implémentation récursive je suis tombé sur un algorithme non efficace. Pour rappel voici ce qu'on peut trouver.


long long fib(unsigned int n)
{
  if (n == 0)
    return n;
  int a = 0, b = 1, tmp;
  while (--n)
  {
    tmp = a + b;
    a = b;
    b = tmp;
  }
  return b;
}

long long fib_r(unsigned int n)
{
  if (0 == n || 1 == n)
    return n;
  return fib_r(n-1) + fib_r(n-2);
}

Sauf que cet algorithme récursif est pourri, il recalcule sans cesse fib-1 et fib-2 et fait monter la pile là où l'algorithme itératif additionne une variable.
Pour avoir un algorithme récursif équivalent à l'itératif il faut garder le même comportement, c'est à dire garder a et b.


long long fib_r_impl(unsigned int n, long long r, long long rp)
{
  if (0 == n)
    return r;
  return fib_r_impl(n-1, r+rp, r);
}

long long fib_r(unsigned int n)
{
  return fib_r_impl(n,0,1);
}

Cet algo est strictement identique au premier car applique la récursion terminale. Ainsi le code généré par un compilateur (avec les flags d'optimisations) donnera un binaire identique (ou très proche). D'autres langages comme OCaml ou java-script optimise la pile quand il y a une récursion terminale.

mercredi 15 août 2012

Java-script n'est pas réservé à votre navigateur !

Non, java-script permet aussi de créer des commandes Katepart… (cf 90 commandes pour Katepart, qui au passage gravite maintenant autour de 120).

Il est souvent utilisé pour faire des plugins ou des extensions pour divers logiciels. Mais en réalité, avec la bonne API derrière, java-script permet la création de programmes complets et graphiques.

KDE propose la création de plasmoïde (sorte de widget de bureau) en java-script, ruby, python ou C++.En fait l’interpréteur java-script de KDE (nommé tout naturellement kjs) permet de communiquer avec les API Qt/KDE pour bénéficier de toute la panoplie des widgets graphiques et de bien d'autres composants.

Kjs n'est pas le seul, rhino qui n'est autre que l’interpréteur de Mozilla permet de communiquer directement avec les classes java. De plus, rhino est actuellement le seul à supporter la version 1.8 de java-script. Les autres interpréteurs ne rajoutent que des objets ou méthodes. Tous les ajouts syntaxiques sur le langage comme la notation lambda, les générateurs d'expression, l'array compréhension et d'autres sont inexistants (nouveauté de js 1.8 sur developer.mozilla.org).

Il existe aussi la plate-forme Node.js de plus en plus répandu sur les serveurs web.

Et MongoDB, une base de donnée NoSQL utilise java-script comme langage de requête.

Tout ça pour dire que java-script est utilisé au-delà du navigateur, contrairement à ce qu'en pensent certains.

mardi 14 août 2012

Je reviens (le retour de ma seconde absence)

Après une grande réflexion de plusieurs mois et un silence radio total sur ce blog ‑qui n'a jamais vraiment été vivant‑, j'ai décidé de le mettre à jour !

Parler de façon déchronologique de toutes mes découvertes dans le monde riche des langages de programmation.

En plus je viens de voir 2 brouillons non publiés sur le C++.

C'est Denis qui va être content (imagine que je fais ça pour toi :)).

Mais dans toute ma gentillesse, le prochain message ne l’intéressera sans doute pas.

jeudi 12 janvier 2012

Hashage de mots de passe

Voici une page expliquant le hashage de mots de passe. C'est capital pour la sécurité !
Hélas, nombreux sont les sites stockant en clair les mdp. Suffit de voir les exploits des Anonymous l'année dernière, la plupart des sites hackés ne hashaient pas les mots de passe…

mercredi 4 janvier 2012

La puissance des itérateurs en php

Quasiment tous les langages possèdent des itérateurs et une boucle pour les utiliser (for/foreach). Php ne fait pas exception et possède l'interface Iterator et la boucle foreach.
La spl fournit bon nombre de classes d'itérateurs ou implémentant Iterator (à une exception près: SplFileInfo). Et cela simplifie souvent les choses.
L'avantage des itérateurs est d'unifier le parcours d'objet.
Ainsi il est tout à fait possible de traverser un objet de manière récursive, d'itérer sur plusieurs itérateurs en un tour de boucle ou de simplement ignorer certaines valeurs. Libre cours à votre imagination :).

lundi 2 janvier 2012

php et les classes de traits, une solution à l'héritage multiple

Quelle ne fut pas ma surprise de constater que php fournit enfin une solution à l'héritage multiple: les classes de traits. Pratique pour définir des comportements :).
Le principe n'est pas nouveau mais PHP 5.4 s'avère excellent :p