[Classic ASP] Improving split function

Coming from the JavaScript world, I’m used to split function working as follow :

"".split(",")
> Array [ "" ]

It’s basic JavaScript. Take an empty string, try to split it on a delimiter, it will return an array containing just one element : an empty string. It’s exactly what you expect from the function, always return an array. Like it should be in every programming language.

A few weeks ago, I had to deal with split function in ASP Classic. Calling the function is a bit different, but that’s not a big deal :

split("foo,bar", ",")

The function works fine in almost every cases. But it has an unexpected behaviour when you use it on an empty string. Let’s try it :

Dim array
array = split("", ",")
'-- Expect array to contain one element
UBound(array) '-- Returns -1. Wait! What?
array(0)      '-- Guess what: Internal server error

That’s a problem. The split function does not return an array containing an empty string when you try to split an empty string, it just returns an array with nothing in it – hence UBound returning -1.

When you are aware of this particularity, it’s easier to write your code. Since I personally prefer a JavaScript-like split function, I decided to write a betterSplit function doing the job as I wanted :

'-- Improve Split to work as expected
Function betterSplit(str, delimiter)
  Dim ar
  ar = Split(str, delimiter)

  '-- UBound
  '-- < 0 if empty string
  '-- = 0 if no delimiter in string
  If UBound(ar) <= 0 Then
    ReDim ar(0)
    ar(0) = str
  End If

  betterSplit = ar
End Function

As a matter of fact, I find this function much better than the original split function as it always returns an array even when using an empty string as a parameter.

Performance entre compute et move

 WORKING-STORAGE SECTION.
 01 WORKING-VAR.
    05 W-TAU-3-6         PIC S9(3)V9(6) COMP-3.
    05  W-TAU-2-5        PIC S9(2)V9(5).
    05 W-CPT             PIC 9(09).

 PROCEDURE DIVISION.
    move 123,123456       to W-TAU-3-6
    move 12,12345         to W-TAU-2-5

    perform until W-CPT = 999999999
*      compute W-TAU-3-6 = W-TAU-2-5
       move W-TAU-2-5     to W-TAU-3-6
       add 1              to W-CPT
    end-perform

Aujourd’hui, j’ai voulu savoir ce qui est le mieux à utiliser entre un compute et un move pour renseigner un champ. J’ai donc exécuter le petit bout de code si dessus.
Résultats :

Temps d’exécution Temps CPU
Move 45.49 1,814
35.9 1,81
1.05.83 1,818
Compute 49.44 2,429
38.66 2,421
1.16.26 2,441

Après 3 exécutions de chaque on distingue bien que le compute mange beaucoup plus de CPU que le move pour le même résultat (Ici environ 1/4 de plus). Conclusion, utiliser les compute seulement en cas de calcul et non pour renseigner une variable.

Mise à jour après un second test qui met sur un pied d’égalité le compute et le move (2.500 Temps CPU pour les deux) :

compute W-TAU-2-5 = W-TAU-3-6
move W-TAU-3-6 to W-TAU-2-5

Dans le cas où l’on met une zone plus grande dans une zone plus petite le compute et le move on les mêmes performances, avec une petite préférence personnelle pour le compute qui évite quelques Warning dans ce cas bien précis.

Manipulations de données simples

Des cas simples, toujours bon à avoir sous la main, ou ici plus particulièrement sous les yeux et à portée d’internet !
Dans cet article je vais parler de quelques bases de manipulations de données en Cobol:

 WORKING-STORAGE SECTION.
    01 WORKING-VAR.
       05 W-SOLDMOYEN-15-2 PIC S9(15)V9(2) COMP-3.
       05 W-SOLDMOYEN-17   PIC S9(17) COMP-3.

 PROCEDURE DIVISION.
    display 'Variables non renseignées :'
    display '15-2 :' W-SOLDMOYEN-15-2
    display '17 :'   W-SOLDMOYEN-17

    move 12,34 to W-SOLDMOYEN-15-2
    move 1234 to W-SOLDMOYEN-17
    display 'Variables renseignées :'
    display '15-2 :' W-SOLDMOYEN-15-2
    display '17 :'   W-SOLDMOYEN-17

    move W-SOLDMOYEN-15-2 to W-SOLDMOYEN-17
    display 'Variables après passage de 15-2 à 17 :'
    display '15-2 :' W-SOLDMOYEN-15-2
    display '17 :'   W-SOLDMOYEN-17

    compute W-SOLDMOYEN-17 = W-SOLDMOYEN-15-2 * 100
    display 'Variables après multiplic. de 15-2 par 100 à 17 :'
    display '15-2 :' W-SOLDMOYEN-15-2
    display '17 :'   W-SOLDMOYEN-17

    * Les deux techniques suivantes marchent :
    move  W-SOLDMOYEN-17  to W-SOLDMOYEN-15-2 
    * ... laquelle des deux est la meilleure ?
    compute W-SOLDMOYEN-15-2 = W-SOLDMOYEN-17
    display 'Variables après passage de 17 à 15-2 :'
    display '15-2 :' W-SOLDMOYEN-15-2
    display '17 :'   W-SOLDMOYEN-17

    move 12345678901234567 to W-SOLDMOYEN-17
    compute W-SOLDMOYEN-15-2 = W-SOLDMOYEN-17
    display 'Variable 15-2 après compute de 12345678901234567 :'
    display '15-2 :' W-SOLDMOYEN-15-2
    display '17 :'   W-SOLDMOYEN-17

Ce qui nous donne en sortie :

Variables non renseignées :
15-2 :00000000000000000
17   :00000000000000000
Variables renseignées :
15-2 :00000000000001234
17   :00000000000001234
Variables après passage de 15-2 à 17 :
15-2 :00000000000001234
17   :00000000000000012
Variables après multiplic. de 15-2 par 100 à 17 :
15-2 :00000000000001234
17   :00000000000001234
Variables après passage de 17 à 15-2 :
15-2 :00000000000123400
17   :00000000000001234
Variable 15-2 après compute de 12345678901234567 :
15-2 :34567890123456700
17   :12345678901234567 

Voilà pour les manipulations du jour, le but étant de retrouver facilement quelles actions donne quels résultats en étant sûr des données et ne pas avoir à retaper un cas de test ou de faire des displays abusifs ;)

Enabling code coverage : in Sonar, from Jenkins, with Maven, using Jacoco.

Let’s assume a few think before we begin.

  • SonarQube is installed somewhere and works.
  • The task « Invoke Standalone Sonar Analysis » is available in Jenkins.
  • Your project is using Maven so it has a pom.xml.

To begin, we’ll add configuration in our pom.xml.

<properties>
  <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
  <sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
  <sonar.language>java</sonar.language>
</properties>

We’re using JUnit to run tests.

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
</dependencies>

Continuer la lecture de « Enabling code coverage : in Sonar, from Jenkins, with Maven, using Jacoco. »

[NPM] Wrong python executable at install

In case you get an error similar to this when trying to npm install :

Error: Python executable "python" is v3.4.2, which is not supported by gyp.

You should tell npm which executable to use with the following command:

npm config set python python2

If you are on ArchLinux, you’re likely to encounter this problem since the default python is python3. Fortunately, it’s easy to fix.