cerhu > comp.lang.* > comp.lang.ada

Blady (11/11/2019, 19h26)
Bonjour,

Je cherchais une procédure remplaçant un caractère par un autre dans une
chaine Unbounded_String. Je n'ai trouvé que pour un seul caractère de la
chaine :

procedure Replace_Element (Source : in out Unbounded_String;
Index : in Positive;
By : in Character);

Bon pour toute la chaine il suffit d'itérer...

Ah je met la main sur la procédure qui pourrait faire l'affaire :
procedure Translate (Source : in out Unbounded_String;
Mapping : in Maps.Character_Mapping_Function);

avec par exemple la fonction :
function Arobase_En_Espace (From : Character) return Character is
begin
if From = ' ' then
return '@';
else
return From;
end if;
end Arobase_En_Espace;

j'écris :
Translate (CH1, Arobase_En_Espace'Access);

Ok mais j'aimerais paramétrer le caractère à remplacer et celui de
remplacement :

procedure Translate
(Source : in out Unbounded_String;
De, Vers : Character)
is
function De_En_Vers (From : Character) return Character is
begin
if From = De then
return Vers;
else
return From;
end if;
end De_En_Vers;
begin
Translate (Source, De_En_Vers'Access);
end Translate;

Patatras :
essaitranslate.adb:23:26: subprogram must not be deeper than access type

Est-il possible de s'en sortir sans aller jusqu'à créer un paquetage
générique ou utiliser l'attribut Unrestricted_Access ?

Merci pour vos réponses, Pascal.
[..]
J-P. Rosen (12/11/2019, 08h32)
Le 11/11/2019 à 18:26, Blady a écrit :
[..]
>    begin
>       Translate (Source, De_En_Vers'Access);
>    end Translate;
> Patatras :
> essaitranslate.adb:23:26: subprogram must not be deeper than access type
> Est-il possible de s'en sortir sans aller jusqu'à créer un paquetage
> générique ou utiliser l'attribut Unrestricted_Access ?

Il suffit de mettre la fonction De_En_Vers à l'extérieur de Translate
(on ne peut pas passer une fonction locale à un pointeur dont le type
est global, sinon on pourrait appeler une fonction qui n'existe plus).

Ceci dit, le plus simple est d'appeler Translate avec une valeur du type
Character_Mapping.
Blady (15/11/2019, 23h10)
Le 12/11/2019 à 07:32, J-P. Rosen a écrit :
> Le 11/11/2019 à 18:26, Blady a écrit :
> Il suffit de mettre la fonction De_En_Vers à l'extérieur de Translate
> (on ne peut pas passer une fonction locale à un pointeur dont le type
> est global, sinon on pourrait appeler une fonction qui n'existe plus).
> Ceci dit, le plus simple est d'appeler Translate avec une valeur du type
> Character_Mapping.

Si je met De_En_Vers à l'extérieur de Translate je n'est plus d'accès à
ses paramètres De et Vers :-(
Il ne me vient pas de solution immédiate.
Je me demandais quelle pouvait être l'utilisation pratique de ce
Translate là (hormis le cas trivial d'une translation statique) qui me
semblait plus simple que celui-ci :

procedure Translate
(Source : in out Unbounded_String;
De, Vers : Character)
is
CM : constant Character_Mapping :=
To_Mapping (To_Sequence (To_Set (De)), To_Sequence (To_Set
(Vers)));
begin
Translate (Source, CM);
end Translate;

Cordialement, Pascal.
Blady (07/12/2019, 08h45)
Le 15/11/2019 à 22:10, Blady a écrit :
[..]
>    begin
>       Translate (Source, CM);
>    end Translate;


Une autre possibilité serait d'avoir des sous-programmes génériques
paramétrés par la fonction Character_Mapping_Function au lieu d'un
'Access, par exemple avec Translate:

generic
with function Character_Mapping_Function (From : Character)
return Character;
procedure Translate (Source : in out Unbounded_String);

procedure Translate2 (Source : in out Unbounded_String; De, Vers :
Character) is
function De_En_Vers (From : Character) return Character is
begin
if From = De then
return Vers;
else
return From;
end if;
end De_En_Vers;
procedure My_Translate is new Translate (De_En_Vers);
begin
My_Translate (Source);
end Translate2;

Cela me semble plus utilisable sous cette forme.
Serait-il possible d'ajouter cette forme dans Ada.Strings.Unbounded ?

Merci, Pascal.
J-P. Rosen (07/12/2019, 09h15)
Le 07/12/2019 à 07:45, Blady a écrit :
[..]
>          else
>             return From;
>          end if;
>       end De_En_Vers;
>       procedure My_Translate is new Translate (De_En_Vers);
>    begin
>       My_Translate (Source);
>    end Translate2;
> Cela me semble plus utilisable sous cette forme.

Personnellement, je préfère les génériques aux pointeurs sur
sous-programmes, en particulier parce qu'on n'a jamais de problème de
niveau d'accessibilité.

> Serait-il possible d'ajouter cette forme dans Ada.Strings.Unbounded ?

Il ne suffit pas d'avoir une bonne idée pour modifier un standard. Il
faut aussi montrer un besoin réel et important qui ne pourrait pas être
satisfait autrement.

Je crains que ce ne soit pas le cas ici...
Discussions similaires
Container Unbounded_String itérable ?

TRANSLATE !

xslt function translate()

translate


Fuseau horaire GMT +2. Il est actuellement 06h12. | Privacy Policy