03 - Open Source03g - Varie Open Source per IBM i

Harbour – Il ritorno di una leggenda

Last Updated on 26 Maggio 2021 by Roberto De Pedrini

Ciao a tutti amici appassionati di IBM i !
Oggi con questo articolo voglio parlarvi di un linguaggio di programmazione che tutti hanno in
mente come un lontano ricordo. Torniamo nel secolo scorso per la precisione tra gli anni 80 e 90, quando i PC cominciavano ad
avere piede. Le persone che hanno vissuto questo periodo possono subito ricordare del linguaggio di programmazione clipper!

Ogni volta che mi è capitato di parlare con qualcuno , la classica domanda che mi viene posta è “Tu quali linguaggi di programmazione conosci?” . Quando io rispondo RPG e VB.NET (usato maggiormente per lavoro). Ottengo come riscontro la classica frase:

“perché usi questi linguaggi di programmazione! sono ormai morti , usa le tue energie per studiare linguaggi più moderni come c#”.

Mentre se rispondo di conoscere il linguaggio clipper , la reazione è totalmente diversa e la maggior parte delle persone racconta della loro avventura con questo linguaggio. Oggi con questo articolo sul Blog di Faq400 , voglio annunciare apertamente che il Clipper non è mai tramontato e si è evoluto diventando Open source.

  • Harbour il nuovo clipper
    Il progetto oggi si chiama Harbour , questo progetto nasce ufficialmente dal 2000, Capitanato da Antonio Linares , si
    differenzia da altri progetti per via della sua natura libera e la filosofia del gioco di squadra che viene messa in gioco da tutti gli appassionati. Dietro Harbour non esiste nessun tipo di azienda che finanzia il progetto ma la forza di gruppi o singoli sviluppatori che danno supporto al linguaggio. Al momento nel mondo circa 10.000 persone usano questo linguaggio e lo integrano con nuove soluzioni o progetti già esistenti facendo evolvere e modernizzandolo al meglio (ad esempio ritroviamo come gli altri linguaggi il paradigma OOP di cui parleremo in articoli futuri e il ciclo FOR EACH).
    Tra alcuni progetti esistenti c’è da citare:
    HMG (libreria grafica principale per creare applicazioni winform).
    HBQT (progetto creato dalla base delle librerie QT 5 , per creare applicazioni GUI come C , ruby , python…).
    mod_harbour ( di questa libreria parleremo più avanti , e uno dei progetti piu recenti che estende l’uso di harbour su apache).
    TWEB (libreria basata su BOOTSTRAP, è un estensione per mod_harbour e offre la capacita di creare interfacce web con la classica sintassi del clipper).

altri progetti come ad esempio connettori dei database, libreria per la gestione di report delle stampanti zebra, pdf ecc.. fanno parte del nucleo di harbour (allocati nella cartella contrib) e si possono considerare elementi nativi del linguaggio.

  • HARBOUR simile a RPG

Ma arrivati qui molti potrebbero chiedersi… “a cosa può servire Harbour nel mondo IBM i?”
La prima cosa che accomuna i due linguaggi è la logica di programmazione. Entrambi fanno uso di
macro (ad esempio EVAL) e cicli per gestire i dati per singolo record.

Piccolo e classico esempio di ricerca in una tabella:

RPG--------------------------------------------------------------------
 Chain klst1 FILE01;
 If %found(FILE01);

     C#PDES=PDES;
 
 Endif;
-----------------------------------------------------------------------

HARBOUR----------------------------------------------------------------
 USE Customer NEW
 INDEX ON Customer->ID TO ID
 SEEK "Doe"
 IF FOUND()
 
      ? “Record found”
 
 ENDIF
-----------------------------------------------------------------------

come si può osservare la logica e quasi identica, l’unica differenza sta nel nome del comando (CHAIN per RPG – SEEK per HARBOUR) ma entrambi funzionano allo stesso modo.

La seconda somiglianza riguarda la compilazione. Harbour come RPG, viene compilato a basso livello. Questo vuol dire che, non abbiamo bisogno di macchine virtuali (come ad esempio .NET framework o JVM per JAVA) , ma l’intero codice viene immagazzinato nell’eseguibile rendendolo portatile pronto ad essere eseguito su qualsiasi sistema senza installare niente di aggiuntivo.

La terza somiglianza (probabilmente quella più importante) riguarda la gestione dei dati. Harbour come Clipper, poggia sui file con estensione DBF e senza fare uso di librerie esterne , si possono creare applicazioni autonome in maniera rapida.


La quarta somiglianza con RPG riguarda la retrocompatibilità del codice. Harbour come RPG, guarda molto alla conservazione del codice. Infatti se abbiamo codice clipper scritto piu di trentanni fa , possiamo ricompilarlo senza problemi a 32 o 64 bit e usarlo senza fare nessuna modifica nel codice.

  • Concetto ILE anche su HARBOUR
    La quinta e ultima somiglianza con RPG che va osservata più nello specifico, sta nella flessibilità di Harbour di integrare codice C all’interno del progetto e compilarlo insieme. Questo fa si che qualsiasi progetto o libreria scritta in c o c++ può essere adattata al linguaggio con il minimo sforzo.

Vediamo qualche esempio nello specifico:

integrazione delle funzioni c da file esterno

codice harbour---------------------------------------------------
// test.prg
PROCEDURE Main()
      CLEAR SCREEN
      ? "The result is: ", multiply( 58, 37 )
RETURN
-----------------------------------------------------------------
codice C---------------------------------------------------------
/* func.c */
#include "hbapi.h"
HB_FUNC(MULTIPLY) {
   unsigned int a,b,c;
   a=hb_parni(1);
   b=hb_parni(2);
   c=a*b;
   hb_retni(c);
}
-----------------------------------------------------------------

Come si può osservare da questo esempio, basta creare un file C e sfruttando la macro HB_FUNC() , la funzione diventa nativa di Harbour.

Sfruttando poi il preprocessore di harbour possiamo concatenare funzioni C con harbour e usarle direttamente nel file prg usando il comando #PRAGMA.

#define MAXLOOP 5
Function Main()
    local l_loop
    MyOutputDebugString("[Harbour] Starting Hello World")
    FOR l_loop := 1 to MAXLOOP
        ?"Hello Harbour " + alltrim(str(l_loop))
        IF l_loop == 3
           AltD() // Same as “SET STEP ON” of VFP
           ?"Paused Debugger"
        ENDIF
    END
    MyOutputDebugString("[Harbour] Completed Hello World")
RETURN nil
//CODICE C========================================
#pragma BEGINDUMP
#include <windows.h>
#include "hbapi.h"
HB_FUNC( MYOUTPUTDEBUGSTRING )
{
   OutputDebugString( hb_parc(1) )
;}
#pragma ENDDUMP
//CODICE C========================================
  • Punti di forza del linguaggio
    Ho voluto presentare Harbour alla community di faq400 perché può diventare uno strumento valido per semplificare lo sviluppo. Negli ultimi tempi per colpa di sistemi sempre più frammentati , dobbiamo fare ricorso a metodi abbastanza ostici per gestire dati provenienti da fonti diverse (DB2, MYSQL,POSTGRES…) , ma sfruttando le query interne di harbour possiamo caricare i dati su dei dbf virtuali e gestirli come se
    fossero dello stesso database.

Esempio di interazione tra due tabelle DB2 – MYSQL:

REQUEST SDDODBC,SDDMY, SQLMIX
ANNOUNCE RDDSYS
PROCEDURE Main()
   cls
#if defined( _HBSCRIPT_HBSHELL )
   rddRegister( "SQLBASE" )
   rddRegister( "SQLMIX" )
   hb_SDDMY_Register()
#endif
   rddSetDefault( "SQLMIX" )
   //connetto mysql
   IF rddInfo( RDDI_CONNECT, { "MYSQL", "mysql-rfam-public.ebi.ac.uk", "rfamro", , "Rfam",4497 } ) == 0
       ? "Unable connect to the server"
       RETURN
   ENDIF
   //prendo a carico il risultato
   use ("SELECT * FROM family") Alias famiglia new
   index on famiglia->rfam_acc to rfam_acc
   //mostro a video la tabella
   Browse()
   //connetto con as400
   IF rddInfo( RDDI_CONNECT, { "ODBC", "Driver={IBM i Access ODBC Driver};System=pub400.com;Uid=unetcorp;Pwd=QSYSNLS4$;" } ) == 0
      ? "Unable connect to the server"
      RETURN
   ENDIF
   //prendo a carico il risultato
   dbUseArea( .T., , "SELECT codart as rfam_acc FROM unetcorp1.art_mag", "art_mag")
   index on art_mag->rfam_acc to fam_acc
   //mostro a video la tabella
   Browse()
   
   //collego le due tabelle e mostro in questo caso l'output a video
   set RELATION to rfam_acc INTO famiglia
   DO WHILE ! famiglia->(EOF())
       list art_mag->rfam_acc,famiglia->description for art_mag->rfam_acc = famiglia->rfam_acc
       skip alias famiglia
   END DO
   dbCloseAll()
RETURN

Come si osserva in questo semplice esempio, possiamo richiamare due query con il comando USE. La tabella successivamente (come una sorta di vista logica) viene memorizzata in ram. In maniera indipendente e separata dal database possiamo creare indici locali su Harbour e Successivamente possiamo mettere in relazione le due tabelle, facendo come in questo caso una join per ottenere una lista di righe che hanno lo stesso codice ID.

  • Sintassi unica per la creazione di interfacce e report
    Un altro punto che va a favore di Harbour come il suo predecessore è la capacita di creare interfacce di ogni genere. Sfruttando le librerie che ci vengono messe a disposizione sfruttiamo la stessa sintassi nativa e semplice del linguaggio sia essa applicazione console oppure web.
Esempio di interfaccia console in harbour:
PROCEDURE Main ()
   CLS
   nScelta=1
   @ 09,08 TO 15,35 DOUBLE COLOR "rg+/n" 
   @ 10,10 PROMPT "1) Inserimento.........."
   @ 11,10 PROMPT "2) Modifica............."
   @ 12,10 PROMPT "3) Visualizzazione......"
   @ 13,10 PROMPT "4) Stampa..............."
   @ 14,10 PROMPT "5) Cancellazione........"
   MENU TO nScelta
RETURN
esempio di interfaccia winform classica (Creata con HMG):
#include "hmg.ch"
FUNCTION Main()
   DEFINE WINDOW Form_1 ;
    AT 90,90 ;
    WIDTH 400 ;
    HEIGHT 250 ;
    TITLE "Finestra di Giovanni" ;
    MAIN
    END WINDOW
  @ 20,20 LABEL testo1 ;
    PARENT Form_1 ;
    VALUE "First Name"
  @ 40,20 TEXTBOX name ;
    PARENT Form_1
  @ 20,150 LABEL testo2 ;
    PARENT Form_1 ;
    VALUE "Last Name"
  @ 40,150 TEXTBOX surname ; PARENT Form_1
  @ 90,150 TEXTBOX sum ;
    PARENT Form_1 ;
    WIDTH 200
  @ 85,20 BUTTON bottone ;
    PARENT Form_1 ;
    CAPTION "Merge the fields" ;
    WIDTH 120 ;
    ONCLICK merge()
    ACTIVATE WINDOW Form_1
RETURN NIL
FUNCTION merge()
    Form_1.sum.value := Form_1.name.value + Form_1.surname.value
RETURN NIL
Esempio di interfaccia web (creata con TWEB)
Function main()
   INIT FORM oForm
     ROWGROUP oForm
     BUTTON ;
      LABEL ' Scansiona C:' ;
      ICON '<i class="far fa-save"></i>';
      ACTION 'Load()';
      CLASS 'btn-secondary mybtnbar' ;
      GRID 12 OF oForm
   
      DEFINE BROWSE oBrw ID 'disksize' HEIGHT 500 DBLCLICK 'editRow' OF oFormADD oCol TO oBrw ID 'folder' HEADER 'Folder' ALIGN 'center'
         ADD oCol TO oBrw ID 'size' HEADER 'Size' SORT
      INIT BROWSE oBrw
   end oForm
RETURN 
  • Linguaggio compilato? Non solo!

Harbour oltre ad essere un linguaggio compilato, con gli aggiornamenti che si sono avuti da parte della community e la sua capacita’ di adattamento , riesce a creare programmi totalmente interpretati come python o semi-compilati come java.

Schema ridotto processo di utilizzo di harbour

In conclusione il Clipper non è morto ma continua a vivere grazie ad Harbour . Questo è certamente un vantaggio per gli utenti finali che possono ancora beneficiare di un linguaggio che, anche se dalla fine degli anni 90 lo ha visto cedere a linguaggi di nuova generazione, resta sempre attuale per la sua capacità di adattamento alle esigenze dell’utente finale che ben pochi linguaggi hanno. Questo articolo era solo un piccolo assaggio delle potenzialita di questo linguaggio e Seguiranno sul blog webinar con articoli di approfondimento per scoprire al meglio Harbour.

  • link esterni consigliati dalla community

Schema avanzato del processo di compilazione di harbour (gentilmente offerto dal sito harbour.wiki):

HarbourLanguageCompilationProcess_Rev_2020_01_22.png (3044×1477)

Gli esempi sono stati tratti dal sito del mio carissimo amico Giovanni Di Maria (http://www.elektrosoft.it)

link esterni:

GitHub – harbour/core: Portable, xBase compatible programming language and environment – link al progetto ufficiale

Harbour manual for beginners – part III (kresin.ru) – manuale su harbour con approfondimenti

Harbour Language Wiki Home – wiki di base con le istruzioni su come installare e configurare harbour

Harbour Users – Google Gruppi – gruppo ufficiale di supporto su harbour.

FiveTech Software tech support forums • View forum – FiveWin for Harbour/xHarbour (fivetechsupport.com) – forum ufficiale di supporto creato da Antonio Linares.

Viva Clipper ! | Notes of a Clipper Language Student (wordpress.com)

Related Posts
DB2 for i SQL – Stringhe – POSSTR-LOCATE-LOCATE_IN_STRING (IT)

Introduzione Spesso, nelle nostre applicazioni, abbiamo la necessità di lavorare con le stringhe di testo e l'SQL del DB2 può Read more

DB2 for i & SQL – FAQ & Howto (Part. 1) (IT)

Database DB2 e SQL ... forse lo strumento più potente e completo che abbiamo sulla piattaforma IBM i: ecco una Read more

Annuncio IBM i 7.4

Arriva direttamente con l'uovo di Pasqua questo annuncio IBM per le novità della versione IBM i 7.4, versione iNext secondo Read more

Generated Always Columns – Approfondimenti (IT)

Introduzione "Generated Always Column": sono colonne, campi, di una tabella il cui contenuto è controllato direttamente dal sistema ... e Read more

About author

Giorgio Caponera, appassionato sviluppatore del mondo IBM i, Fresh Face IBM nel 2019.

2 Comments

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *