4.3.3 les chaînes de caractères

Nous avons déjà rencontré les chaînes de caractères à multiples reprises. Rappelons juste qu’une chaîne de caractères est toute séquence de caractères entourée par des caractères apostrophe (). Si l’on désire y inclure le caractère délimiteur de chaîne, l’apostrophe, il faut le doubler, comme dans Transcript show: ’Jean disait: ’’Hallo’’’ qui affiche Jean disait: ’Hallo’ dans le Transcript. Tout autre caractère, y compris le caractère à la ligne est permis.

Les chaînes de caractères sont des instances de la classe String. L’instance la plus simple est la chaîne ’’, la chaîne vide. La classe String, étant une sous-classe de ArrayedCollection, comprend, en plus de ses propres messages, la majorité des messages des autres collections, et – surtout – le message de concatenation de deux collections: le message “,. Ci-dessous quelques exemples de transmissions de messages à des chaînes de caractères et le résultat de leur évaluation (précédé par le caractère “~”):

    calcul de la taille d’une chaîne de caractères:
’foobar’ size  ~ 6


calcul de la taille; notez bien que les doubles apostrophes ne comptent que comme un seul cararactère:
’Jean disait: ’’hello’’’ size  ~ 20


transformation de tout caractère en caractère majuscule:
’Squeak’ asUppercase  ~ ’SQUEAK’


recherche de la première occurrence d’une suite de chiffres et sa transformation en nombre entier:
’a32b’ asInteger  ~ 32
’a32b34c’ asInteger  ~ 32


extraction de tous les chiffres d’une chaîne et transformation de la chaîne de chiffres en nombre:
’a1b45c’ extractNumber  ~ 14525


extraction de tous les caractères alphabétiques d’une chaîne de caractères:
’a32b34c’ onlyLetters  ~ ’abc’


transformation d’une chaîne en nombre:
’32.45’ asNumber  ~ 32.45


opérations arithmétiques sur des chaînes de caractères composées de chiffres:
’123’ + ’3’  ~ ’126’
’123’ / ’3’  ~ ’41’
’124’ / ’3’  ~ ’(124/3)’

extraction, vers un tableau, de toutes les sous-chaînes séparées par des caractères «séparateurs» (caractère ASCII: 9, 10, 12, 13, 32)26 :
’Jean disait: ’’hello’’’ substrings
        ~ #(’Jean’ ’disait:’ ’’’hello’’’)


calcul de l’indice de la première occurrence d’un caractère:
’Jean disait: ’’hello’’’ indexOf: $h  ~ 15


calcul du nième caractère:
’Jean disait: ’’hello’’’ at: 15  ~ $h


remplacement du nième caractère par un autre:
’Jean disait: ’’hello’’’ at: 15 put: $H ; yourself27
        ~ ’Jean disait: ’’Hello’’’


comparaison lexicographique entre deux chaînes de caractères:
’Jean’ < ’Jeannette’  ~ true


recherche de toutes les sous-chaînes séparées par un caractère (ici le caractère $a):
’Jean disait: ’’hello’’’ findTokens: ’a’
        ~ an OrderedCollection(’Je’ ’n dis’ ’it: ’’hello’’’)


recherche de toutes les sous-chaînes séparées par un des caractères d’un ensemble (ici les caractères $a et $e):
’aha, tu n’’as pas t’’envole tout de suite’ findTokens: ’ae’
        ~ an OrderedCollection(’h’ ’, tu n’’’ ’s p’ ’s t’’’ ’nvol’ ’ tout d’ ’ suit’)


remplacement des {1}, {2} etc par le premier, deuxième, etc élément de l’argument:28
Transcript show:
     (’{2} nous sommes le {1}’
             format: {Date today . ’Ajourd’’hui’})
affichait, au jour du 18 mai 2005, dans le Transcript:
             ’Ajourd’hui nous sommes le 18 May 2005


test d’égalité:
’Jean’ copy = ’Jean’  ~ true


test d’identité:
’Jean’ copy == ’Jean’  ~ false
Un test d’égalité teste l’égalité structurelle entre deux objets. Un test d’identité teste si les deux objets sont physiquement les mêmes. La chaîne de caractères ’Jean’ est bien structurellement égale à toute autre chaîne ’Jean’ (les deux chaînes sont composées de la même suite de caractères). Par contre, il n’y a – a priori – aucune raison que deux chaînes, deux suites de caractères, réfèrent à un même objet physique.29

Ouvrez un explorateur de classes sur la classe String et examinez les différentes méthodes; afin de comprendre, comme toujours, construisez-vous des exemples de leur utilisation et testez-les.

Notons que dans l’exemple:

’Jean disait: ’’hello’’’ at: 15 put: $H ; yourself
la cascade se termine par le sélecteur yourself. Bien qu’il ressemble quelque part à self et super, yourself n’est pas une pseudo-variable. Une pseudo-variable peut être receveur d’un message. yourself est un message, défini dans la classe Object. Il est utilisé quand on veut qu’une transmission retourne le receveur.

Dans notre exemple, le message at:put: retournant le deuxième argument (le caractère $H), la cascade avec yourself force le retour du receveur de ce message, qui est clairement la chaîne de caractère ’Jean disait: ’’hello’’’. Puisque cette chaîne a été physiquement modifiée par le message at:put: en la chaîne ’Jean disait: ’’Hello’’’, c’est cette dernière chaîne de caractères qui est retournée par yourself. Nous ne pouvons pas utiliser ici la pseudo-variable self, puisque celle-ci se réfère au receveur du sélecteur de la méthode à l’intérieur de laquelle ce self a une occurrence. Ici nous ne sommes pas dans une méthode30.

Tout est très simple: chaque fois que vous voulez être sûr qu’une transmission retourne le receveur de cette transmission, vous pouvez le garantir en cascadant la transmission avec le message yourself.