Let your code know… your code

Has this ever happened to you ?

… you work on a legacy project, and there is this method called `getAccount` which sounds simple.
But this method is a compound one.
1°) It actually calls a database A to fetch a user Id.
2°) Then completes the data with a B Web service based on LDAP
3°) Then completes it with some extra data based on the account preferences from a service C
4°) It updates the database with the found data (yes, « getAccount » writes something… in a legacy project, you will certainly see that)
5°) It returns all the data.

What if you call getAccount from another point of view ? If you are the caller of the method, you could even do this :

if (getAccount (user) != null) {
String userName = getAccount (user).getName ();
}

Ugh… Did you realize that these 4 lines will call different external services 3 * 2 = 6 times… It has awful performance, and can be harmful (= with side effects) if the method getAccount is not idempotent (which is likely to happen in a legacy project)

What you need is not (really) refactoring. The technical debt is too tough to be attacked right now. What you need IS knowledge about the code. How can you know what is happening in the code ? Think painless, think about code to understand code …

I have created what I call a DiveDeepAnalyzer. The aim of this is to understand which sensitive methods are called directly or indirectly in each method.

https://gist.github.com/libetl/00bc6079b3dd91af55bb6cf8229e942a

Write down the list of sensitive calls (webservices, LDAP, databases, cache, drivers, hardware), and the algorithm will annotate each and every method that is likely to use these calls.

How to ?
1°) Copy this class in your project,
2°) change the params in the main method (you will need to exclude the DiveDeepAnalyzer class itself from the scan)
3°) run the class.

This analyzer uses spoon, an OSS made by a research lab in France (inria). You can find more about spoon at this address : http://spoon.gforge.inria.fr/

The Game of Go

I went to give a try in Go language.

Please consider this before starting something in Go :
– this can be seen as a recession if you are used to developing in Groovy, Scala or Python or if you need to have a comfortable, flexible syntax
– this can be seen as cheating if you use C or Pascal and if you are used to very strict snippets shapes (signature first, then declaration of vars, then code)

Here are the things similar and the things unfamiliar with Go :
– it uses pointers (Goodbye java lovers). Everything not referenced in pointers will be lost if the the current element of stackTrace is dismissed.
– it is not (so much) typed. There are different ways to declare a var. Here are two examples :
* var foo string //(note that the type appears AFTER the var name)
* bar := « test » //(note that it uses ‘:=’ as « this is a new var », else it would be ‘=’)
– it has some structs instead of objects. But you can declare some methods linked to the objects :

struct SayHelloToMe {
Name string //(the convention names looks like C# rather than C or Java, and there is no semicolon here)
}

func (SayHello SayHelloToMe) do () string { //func keyword, then owner struct, then function name, then returned object type
fmt.Println("Hello " + SayHello.Name)
}

Me := SayHelloToMe {Name:"Joe"} //No constructor necessary, the fields are initialized under brackets instead
Me.do() //Here, the func is called

– it can import a lot of different libraries. Just say import « fmt » at the begining of the code and use the fmt object as if it always existed.
– it uses a different notation for the loops. There is no « while » keyword there, only « for » exists :

for toto < 5 {...}
for key,element := range mySlice {...} //a slice is an array in the Go jargon.
for _,element := range mySlice {...} //To get only the element

– the pointers work as in C, except they are used with « new » or « make » instead of malloc :

newTree := new(Tree) // Tree is a struct here
make([]*Tree,10) //new array of 10 pointers, each one of a Tree
newTree = &Tree {"parent", nil, nil} //save the address of the new object in a pointer var.

– you can cast an object as you would do it in python : obj := string(myObj)
– one big project is written in Go : « docker », a system of software image building (infrastucture as code). The binaries are really lightweight (it does not produce bytecode, but executable files, the source must be compiled when switching of platform)

Here is an example of code made to resolve a challenge on a very popular platform of code challenges :
The principle of this code is to know how much nodes are needed in a tree to store several telephone numbers (what is the minimum numbers of digits needed to store a list of telephone numbers).
Here is the solution below, in Go (you can use it for your own needs if you find something interesting inside) :


package main

import "fmt"

type Tree struct {
Value uint8 //uint8 = char
Children []* Tree
}

func countNodes (aTree Tree) int {
if aTree.Children == nil {
return 1
}
sum := 1
for _,element := range aTree.Children {
sum += countNodes (*element)
}
return sum
}

func addTelephone (aTree* Tree, telephone string) {
var thisNode *Tree
telephoneSuffix := telephone
thisNode = aTree
for len(telephoneSuffix) > 0 { //len can be strlen or length of an array
if (*thisNode).Children == nil {
(*thisNode).Children = make([]*Tree,0)
}
var foundChild * Tree
for _,element := range (*thisNode).Children {
if element.Value == telephoneSuffix [0] {
foundChild = element
}
}
if (foundChild != nil) {
thisNode = foundChild
telephoneSuffix = telephoneSuffix[1:len(telephoneSuffix)] //substring or subarray
continue
}

newTree := new(Tree)
newTree.Value = telephoneSuffix[0]

newChildren := append ((*thisNode).Children, newTree)
(*thisNode).Children=newChildren

thisNode = newTree
telephoneSuffix = telephoneSuffix[1:len(telephoneSuffix)]
}
}

/**
* Auto-generated code below aims at helping you parse
* the standard input according to the problem statement.
**/

func main() {
var N int
var TheTree *Tree
fmt.Scan(&N)

TheTree = &Tree{0, nil}
for i := 0; i < N; i++ {
var telephone string
fmt.Scan(&telephone)
addTelephone(TheTree, telephone)
}

count := countNodes (*TheTree) - 1

fmt.Println(count) // The number of elements (referencing a number) stored in the structure.
}

Of course the solution is simple, but we have to get used to the syntax. Off you GO then.

8bit-ator

Sur mon repository github soundtransform, je crois avoir obtenu (par accident) un convertisseur musique vers 8bit.

J’étais en train de chercher comment remodeler un son en le sous échantillonnant pour en supprimer ses pics et ses bruits parasites. En écoutant le résultat de ma transformation, j’ai eu l’étrange impression d’écouter du son de console NES.

Voici le son avant : Tiefschwarz – On Up
Voici le son après : 8bitschwarz – On Up

Rien de bien neuf… sauf…

Finalement, je suis incapable de mettre à jour le blog. Devenu trop exigeant envers son contenu, j’en suis réduit à signaler toutes les fins du mois que je ne l’oublie pas.

Qu’ai je fait de beau ce mois-ci ?
J’ai tenté un rendu HD de mon ancien modèle de theodolite en stéréoscopie sur mon ordinateur. Ça a fait 2 semaines de rendu non-stop sur un i5. C’est effectivement de la 3D, mais c’est cher payé. (http://www.youtube.com/watch?v=Xy4eNSSAc1g)

Sur le plan prog, j’ai appris à utiliser AspectJ. Pour éviter d’avoir des méthodes comme celle-ci :
String method1 (String a, int b) {
log.info (this.getClass (), "début methode method1 (" + a + ", " + b)");
//...code
log.info (this.getClass (), "fin methode method1 (" + a + ", " + b)");
}

faites ceci :

before () : pointcut (within mon.package) {
log.info ("début de la méthode " + thisJointPoint.getTarget () + "." + thisJointPoint.getMethod ()");
}

after () : pointcut (within mon.package) {
log.info ("fin de la méthode " + thisJointPoint.getTarget () + "." + thisJointPoint.getMethod ()");
}

Le weaver AspectJ va recompiler toutes vos classes pour passer par cet intermédiaire, et cela ne nécessitera aucun effort de votre part.
Pour jouer avec sous eclipse, allez voir cette page : http://www.eclipse.org/aspectj/

Sinon, je tente le GWT. Depuis la liberation des données RATP me vint une idée d’appli… je reste discret là dessus pour l’instant…ratp