Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Altri mondi - RPG e DS

60 views
Skip to first unread message

Jax

unread,
Oct 1, 2001, 4:10:07 AM10/1/01
to
Premessa: dopo parecchio tempo di programmazione Delphi, sono passato ad
AS/400 per necessità, e ho programmato in RPG... due linguaggi
diametralmente opposti, ma ovviamente certe volte viene spontaneo fare
paragoni o cercare metodi per fare le cose che un linguaggio può fare e
l'altro no... una di queste è la gestione delle DS (Data Structure).

Essenzialmente in RPG una DS è intesa come un record in Pascal, cioè una
definizione di tipi dati eterogenei che possono essere trattati sia
unicamente che separatamente.

Il bello però è che se noi abbiamo una "DS1" formata da:
campo1 - 6 alfanumerico
campo2 - 3.0 numerico
campo3 - 20 alfanumerico

in RPG si può fare un'operazione MOVE da una qualsiasi stringa alfanumerica
di qualsiasi dimensione a una DS di questo tipo, e poi potremo riferirci
alle variabili per campo... esempio:
MOVE 'ABCDEF1234567890GHILMNO' DS1
avremo che
campo1 = 'ABCDEF'
campo2 = 123
campo3 = '4567890GHILMNO '

e vi assicuro che è davvero una cosa utilissima.

Vengo finalmente al dunque: come fareste voi ad implementare questa cosa in
Delphi?
Secondo me sarebbe una cosa che semplificherebbe tantissime cose.

Se volete scrivermi: gare...@mindless.com

Jax


Paolo Pedrielli

unread,
Oct 1, 2001, 6:28:45 AM10/1/01
to
Guarda non ne ho idea, comunque posso dirti che anche il COBOL aveva questo
tipo di funzionamento, e concordo con te che è una cosa utilissima in vari
casi.
Oltretutto in COBOL c'era la REDEFINES che ti permetteva di vedere un certo
insieme di byte in N modi diversi, ad esempio:
CFISCALE CHAR(16)
potevi anche ridefinirlo e vederlo come
PIVA CHAR(11)
FILL CHAR(5)
questo era ancora più comodo.
Scusa se non ti rispondo, però mi hai fatto tornare in mente i vecchi
tempi....

Ciao
Paolo Pedrielli
Sintesi S.r.l.
EMail: pao...@sintesi.com --- Web: http://www.sintesi.com

"Jax" <rispo...@newsgroup.grazie> ha scritto nel messaggio
news:zxVt7.20753$C15.2...@news.infostrada.it...

Sam Sahara

unread,
Oct 1, 2001, 11:18:29 AM10/1/01
to
Ci sono diverse tecniche per implenetare in delphi il casting tra tipi (così
si chiama quello che hai descritto). Si tratta però di tecniche piuttosto
inusuali, in quanto allontanano dal controllo stretto sui tipi che è tipico
del pascal: Jeff Duntemann faceva rientrare queste tecniche tra le "magie"
del pascal.
1) record variante.
data una struttura record così definita:
TVarRec = record
case integer of
0 : fInt : integer;
1 : fStr : string[25];
3 : fPtr : pointer;
5 : fFloat : real;
end;

si può scrivere la seguente routine:

procedure TMainForm.MasksDance;
var
VarRec : TVarRec;
I : integer;
S : string[25];
R : real;
begin
FillChar(VarRec, SizeOf(VarRec), ''); // inizializza il record variante
VarRec.fStr := 'Sarò un intero, poi un reale, poi di nuovo una stringa, ma
un''altra stringa';
Edit1.Text := IntToStr(VarRec.fInt);
Edit2.Text := FloatToStr(VarRec.fFloat);
Edit3.Text := string(VarRec.fPtr^); // attenzione a questa istruzione: si
tratta di un casting.
end;

Come si vede, il record VarRec è stato prima 'ripulito', poi il campo
stringa è stato riempito con una frase. Dopodicchè il contenuto dello spazio
di memoria occupato da VarRec è stato successivamente letto dal compilatore
*come se fosse* un intero, poi un reale, infine un puntatore.
In realtà il record variante è una struttura dati la cui dimensione è uguale
alla dimensione del suo campo più 'ingombrante' (nel caso di TVarRec i 26
byte del campo stringa); Leggere gli altri campi significa semplicemente
dire al compilatore di leggere quello che c'è nel record variante come se
fosse del tipo del campo preso in considerazione.
Il tipico uso del record variante era, nel pascal, la lettura/scrittura dei
registri della CPU. In delphi il tipo Variant altro non è che un record
variante un pò più sofisticato. Ma non a caso Borland mette in guardia da un
uso eccessivo di quel tipo di dato.

2) casting tra tipi.
Si può anche costringere esplicitamente il compilatore a leggere un dato di
un certo tipo come se fosse di un altro tipo. Si possono cioè scrivere
istruzioni di questo tipo:
var
I : integer;
R : Real;
S1, S2 : string;
begin
I := 13256;
R := real(I);
Edit1.Text := FloatToStr(R);
S1 := shortstring(I);
S2 := IntToStr(I)
Edit2.Text := S1;
Edit3.Text := S2; // notare la differenza
end;

Esattamente così (salva la necessità di debug). In altre parole la locazione
di memoria occupata da un intero viene letta dal compilatore *come se fosse*
un reale e poi una stringa.

Per concludere: in pascal (e quindi in delphi) i tipi definiscono la
dimensione di una locazione di memoria, mentre le variabili stabiliscono la
allocazione fisica di uno spazio dati di quella data dimensione. Quello che
si trova ad un certo segmento e ad un certo offset è semplicemente una
sequenza di 0 e di 1: sarà il programmatore a stabilire che quella sequenza
andrà considerata come se fosse un intero, o un puntatore, o qualunque altra
cosa.

Una ultima annotazione: queste tecniche (associate all'uso dei puntatori
generici, come nell'ultima riga del primo esempio) in pascal per DOS
venivano considerate "extreme programming", e utilizzate con grande
circospezione. In ambiente windows, invece, sono considerate il punto di
partenza per una tecnica di programmazione appena decente.


--
Sam Sahara
sa...@iol.it
http://samsahara.cjb.net

Jax <rispo...@newsgroup.grazie> wrote in message
zxVt7.20753$C15.2...@news.infostrada.it...
>...


> Il bello però è che se noi abbiamo una "DS1" formata da:
> campo1 - 6 alfanumerico
> campo2 - 3.0 numerico
> campo3 - 20 alfanumerico
>
> in RPG si può fare un'operazione MOVE da una qualsiasi stringa
alfanumerica
> di qualsiasi dimensione a una DS di questo tipo, e poi potremo riferirci
> alle variabili per campo... esempio:
> MOVE 'ABCDEF1234567890GHILMNO' DS1
> avremo che
> campo1 = 'ABCDEF'
> campo2 = 123
> campo3 = '4567890GHILMNO '
>

> e vi assicuro che è davvero una cosa utilissima....


Solid Snake IT

unread,
Oct 1, 2001, 3:38:18 PM10/1/01
to
Mah, concordo con te che č tanto bello quanto incapibile soprattutto se
penso a quanto tempo ci ho perso facendo un'utility di import dalle tabelle
AS (ANTA200F per l'esattezza - ACG) utilizzando le DS a seconda del tipo di
"tabellina" mi trovato.
Cmq se io dovessi cercare di risolvere il problema farei una cosa del genere
(ps: non l'ho provato, penso che si possa fare!):

supponi di avere un tipo record di questo genere:

Tmiorec = record
nome: string[20];
eta: smallint;
provincia: string[4];
end;


function MiaMove(aString: string; var amiorec: Tmiorec);
var vI: integer;
begin
vI := 1;
amiorec.nome := copy(astring,vI,sizeof(amiorec.nome));
vI := vI + sizeof(amiorec.nome);
amiorec.eta := strtoint(copy(astring,vI,sizeof(amiorec.eta)));
ecc...
ecc...
end;

Magari non ho capito il tuo problema...oppure questa funzione non č
esattamente quello che volevi...

saluti
--
ciao

Solid Snake IT
"Nemo mortalium omnibus horis sapit" (Plinio il VECCHIO)


Jax

unread,
Oct 1, 2001, 3:45:49 PM10/1/01
to
"Sam Sahara" <sa...@iol.it> ha scritto nel messaggio
news:9P%t7.23490$C15.2...@news.infostrada.it...

> Ci sono diverse tecniche per implenetare in delphi il casting tra tipi (così
> si chiama quello che hai descritto). Si tratta però di tecniche piuttosto
> inusuali, in quanto allontanano dal controllo stretto sui tipi che è tipico
> del pascal: Jeff Duntemann faceva rientrare queste tecniche tra le "magie"
> del pascal.
> 1) record variante.
> STRASNIP
Molto molto interessante, anche se effettivamente non semplicissimo...

> 2) casting tra tipi.
Questo lo conoscevo già e in molti casi è abbastanza utile, anche se con le 2000
funzioni di conversione già pronte non è che li si usa poi tantissimo (il più
usato credo sia PChar(string) per passare i parametri alle API :))

> circospezione. In ambiente windows, invece, sono considerate il punto di
> partenza per una tecnica di programmazione appena decente.

Addirittura? Io invece le considero un po' inutili e pericolose, infatti tento
di starne alla larga quando posso... non so perché, ma non mi piacciono queste
forzature.

Jax


Emilio Panozzo

unread,
Oct 1, 2001, 3:55:46 PM10/1/01
to

"Jax"

> [cut]


> in RPG si può fare un'operazione MOVE da una qualsiasi stringa
alfanumerica
> di qualsiasi dimensione a una DS di questo tipo, e poi potremo riferirci
> alle variabili per campo... esempio:
> MOVE 'ABCDEF1234567890GHILMNO' DS1
> avremo che
> campo1 = 'ABCDEF'
> campo2 = 123
> campo3 = '4567890GHILMNO '
>
> e vi assicuro che è davvero una cosa utilissima.
>

Ho lavorato prima in RPG ed ho usato le DS poi sono passato al Clipper e poi
a Delphi
(transitando un attimo attraverso Visual Object e molto di sfuggita Visual
Basic)

Delle Data Structure non sento assolutamente la mancanza!

E' un buon sistema di lavorare quando sei costretto a fare i salti mortali,
che ti evita una capriola.

Se ci pensi solo un attimo puoi fare la stessa cosa con la funzione copy e
le eventuali dovute conversioni di tipo.
Tuttavia se ti sforzi di avere i dati puliti e separati già alla fonte (e
quasi sempre si può) poi vivi più tranquillo che,
se per caso qualcosa va storto, hai potuto farti tutti i controlli
necessari.

Tutto questo "secondo me".

Ciao.

--
Emilio Panozzo
mailto: emip...@tin.it


Sam Sahara

unread,
Oct 2, 2001, 4:31:24 AM10/2/01
to
Jax <gare...@libero.it> wrote in message
NJ3u7.1782$0Y2.5...@news.infostrada.it...
> > 2) casting tra tipi....
> ...Questo lo conoscevo già e in molti casi è abbastanza utile, anche se

con le 2000
> funzioni di conversione già pronte non è che li si usa poi tantissimo (il
più
> usato credo sia PChar(string) per passare i parametri alle API :))...

Attenzione, perchè non sempre è la stessa cosa. Una funzione di conversione
salva il *valore logico* di una variabile di un tipo in una variabile di un
altro tipo, il casting legge un *valore fisico* (cioè il contenuto della
locazione di memoria) secondo un tipo di dato diverso da quello originario.
Ad es:
var
S1, S2 : string;
I : integer;
begin
I1 := 1972;

S1 := StrToInt(I); // conversione da intero a stringa
Label1.Caption := Concat('Il valore logico di I è: ', S1);

S2 := shortstring(I); // casting di una stringa su un intero
Label2.Caption := Concat('Il valore fisico nella locazione di I è
rappresentabile, come se fosse una stringa, così : ', S2);
end;

Come si vede la stessa variabile intera I viene presa in considerazione
prima per il suo valore logico (che viene poi restituito in una stringa),
poi per il suo valore fisico (ovvero il contenuto della locazione di
memoria). Questo valore fisico viene quindi letto in S2 *come se fosse una
stringa*. Che si tratti di cose diverse lo dimostra il diverso output
(visualizzato nelle label).
In delphi uno dei tipici usi del casting è la scrittura di event handler
generici. Ad es.

procedure TMainForm.Button1Click(Sender : TObject);
begin
if (Sender is TButton) then
TButton(Sender).Caption := 'Clicked!'; // casting di TButton su un
generico oggetto
// codifiche alternative possono essere
// with (Sender as TButton) do Caption := 'Clicked!;
// (Sender as TButton).Caption := 'Clicked!;
end;

Ora, nel corpo del codice appena visto non si fa riferimento ad alcun Button
particolare per cui, ammettendo che sulla form dove è posto il Button1 di
cui sopra ci siano altri 10 TButton, l'event handler appena visto può essere
scritto una sola volta e poi direttamente collegato ad ognuno dei TButton a
design time, per mezzo dell'object inspector. Tutte le codifiche elencate
mostrano dei sofisticati esempi di casting, possibili solo in delphi (non in
pascal), che offrono la gestione del meccanismo del casting con l'utile
accessorio della gestione degli errori da parte della VCL.

Queste argomentazioni dimostrano, a monte, una cosa di cui sono sempre stato
convinto: per essere un decente programmatore delphi è necessario avere un
solido e sperimentato background pascal.

0 new messages