rebol document

Annexe C1 - Changements

Ce document est la traduction française de l'Annexe C1 du User Guide de REBOL/Core,
qui concerne les changements intervenus sur les versions 2.3.0 à 2.5.6, et incluant
/View, /SDK, et /Command.

Contenu

1. Historique de la traduction
2. Core 2.5.6
2.1 Démarrage en ligne de commande (correctif pour les scripts CGI/shell)
2.2 "Quit" implicite
2.3 Erreur "Corrupt Datatype"
2.4 Correction de l'Aide (help vs native!)
2.5 Get sur none
2.6 Set-browser-path
2.7 DO en ligne de commande
2.8 Correction du bogue find/any
2.9 Usage de mold sur des noms vides de fichiers
3. Core 2.5.5
3.1 But de cette version
3.2 Nouvelle licence pour Core
3.3 Fichiers de démarrage (user.r et rebol.r)
3.4 Comment les scripts sont lancés
3.5 Caractère en fin de ligne de commande (CR)
3.6 Changements relatifs à la fonction secure
3.7 Raffinement mold/flat :
3.8 Troncature de l'index d'une série (lorsque son extrémité est dépassée)
3.9 AT sur les ports
3.10 Ajout des fonctions sixth à tenth
3.11 Lignes de plus de 4 Kb en mode direct/lines
3.12 DECODE-CGI et la gestion des noms CGI en double
3.13 Correction pour la fonction ALTER
3.14 Erreurs réseau avec la fonction TRY (net-error throw)
3.15 Extension des paths pour les répertoires FTP
3.16 STATS pour system/stats
3.17 Portée de la variable PURL
4. Core 2.5.3
4.1 Remerciements
4.2 Réécriture de la fonction MAKE-DIR
4.3 Nouvelles fonctions pour les bitsets : CLEAR, LENGTH?, EMPTY?
4.4 Changements dans la fonction SKIP
4.5 Tableaux initialisés avec des valeurs de type block!
4.6 Ajout du mot BREAK pour la fonction PARSE
4.7 Correction de la fonction OPEN sur les ports réseau
4.8 Correction du bogue sur les fonctions en cours de modification
4.9 CHANGE accepte des valeurs de type Any-type
4.10 Mettre en "unset" des variables objets (sur un exit)
4.11 Ajout de la fonction BUILD-MARKUP
4.12 Révision de la fonction BUILD-TAG
4.13 Révision de la fonction DECODE-CGI
4.14 Correction de la fonction UNPROTECT
4.15 Ajout à Core de la fonction ALTER
4.16 Protection du mot SYSTEM
4.17 Message d'erreur pour un mot sans contexte
4.18 Correction vis-à-vis de dates dans le futur
5. Core 2.5.2
5.1 Fonction CONSTRUCT, pour créer un objet
5.2 Changement pour la fonction LOAD (Important)
5.3 Modification et amélioration de HELP
5.4 Ajout de la fonction SUFFIX?
5.5 Ajout de la fonction SIGN?
5.6 Ajout de la fonction COMPONENT?
5.7 Mise à jour de la fonction SEND
5.8 Corrections diverses
5.8.1 TYPE? (utilisation dans parse)
5.8.2 MOLD/all
5.8.3 FTP
6. Core 2.5.1
6.1 Code source et valeurs none, true, etc.
6.2 Une évaluation moins agressive (Important !)
6.3 Insertion de blocs avec COMPOSE/ONLY
6.4 REMOVE-EACH - Un moyen pratique d'effacer les éléments d'une Série
6.5 ATTEMPT et la manipulation des Erreurs
6.6 Mise à jour de la fonction EXTRACT
6.7 SAVE en mémoire
6.8 Raffinements /subject et /attach pour la fonction SEND
6.9 Fonction DIFFERENCE pour les dates/heures
6.10 Ajout du PORT SYSTEM
7. Core 2.5.0
7.1 Nouvelle fonction SORT
7.1.1 Terminologie
7.1.2 Arguments
7.1.3 Comparateurs
7.1.4 Récupérer les listes de modes
7.1.5 Modes possibles
7.1.6 Utilisation des ressources fichier
7.1.7 Déterminer toutes les ressources
7.2 Accès au Port Série
7.2.1 Spécifier un port Série
7.2.2 Opérations
7.3 Objets
7.3.1 Make Object Object
7.3.2 Usage de third sur un objet
7.4 Changements pour mold et load
7.5 Changements sur File et Port
7.6 Changement dans les protocoles réseau (APOP, IMAP)
7.7 Changements pour les Séries
7.8 Changements relatifs aux fonctions Mathématiques
7.9 Changements pour la ligne de commande
7.10 Console
7.11 Contrôles
7.12 Interpréteur
7.13 Autres changements
8. Correction relatives à l'interpréteur
9. Corrections propres au réseau
10. Autres corrections (Fonction)
11. résumé des nouveautés dans la v. 2.3
12. résumé des améliorations dans la v.2.3
13. Synthèse des corrections en v.2.3
14. Nouvelles fonctions et nouveaux raffinements en v.2.3
14.1 Type de données Pair
14.2 Make-dir/deep
14.3 Unique
14.4 Does
14.5 Offset?
14.6 Load/markup
14.7 Repend
14.8 Replace/case
14.9 ??
14.10 To-pair
15. Améliorations dans la v.2.3
15.1 Parsing de blocs
15.2 Modification du handler POP
15.3 Usage de la touche Tabulation
15.4 Raffinement /next pour la fonction load
15.5 Fonction Query
15.6 Fonctions acceptant des valeurs de type pair!
15.7 Fonction Random
15.8 System/options/path
15.9 Fonction what
15.10 Fonctions if, any, et all
15.11 Help
16. Corrections dans la v2.3
16.1 Fonction split-path
16.2 Interruption d'une opération réseau
16.3 Trim/lines
16.4 Fonction to-word
16.5 Fonction to-block
17. Autres changements (provenant du document d'Addendum) dans la v.2.3

1. Historique de la traduction

Date

Version

Commentaires

Auteur

Email

lundi 26 septembre 2005 - 18:42

1.0.0

Traduction initiale

Philippe Le Goff

lp--legoff--free--fr

2. Core 2.5.6

Divers corrections ont été réalisées pour les releases des versions 2.5.6 de REBOL/SDK, REBOL/Command.

2.1 Démarrage en ligne de commande (correctif pour les scripts CGI/shell)

REBOL ne tient pas compte du caractère CR (Retour chariot ou Carriage Return) dans les fichiers scripts, mais un problème peut se produire si le caractère CR apparaît sur la ligne de commande qui lance REBOL, par exemple à la suite d'un transfert binaire d'un script CGI vers votre serveur Web Linux/Unix. REBOL afficherait l'aide en ligne (help). Ce problème a été corrigé.

2.2 "Quit" implicite

Tous les produits REBOL ont été corrigés, et fonctionnent de manière similaire vis-à-vis du bogue suivant : l'exécution d'un script se termine, sans qu'il y ait eu un "quit" explicite. A présent, le "quit" est forcé à la fin d'un script. Si vous voulez retourner à la console, mettez un "halt" dans votre script.

2.3 Erreur "Corrupt Datatype"

Dans certaines situations, REBOL plante à la fin d'un script avec une erreur "corrupt datatype". Ceci est dû aux améliorations faites dans la version 2.5.3, qui libèrent la mémoire des structures internes inutilisées. Le problème devrait seulement se produire lorsqu'un script nécessite un recyclage de la mémoire et n'inclut pas un "quit" ou un "halt" à sa fin. Ceci a été résolu.

2.4 Correction de l'Aide (help vs native!)

Les requêtes help sur des fonctions de type native! ont été corrigées (le mot native! a été restauré).

2.5 Get sur none

L'appel de get sur none est maintenant permis et retournera none.

print get none
none

Ceci facilite l'écriture de code afin de récupérer les valeurs d'un objet, lorsque le mot à l'intérieur d'un objet est manquant. Par exemple, le code ci-dessous ne produira plus à présent d'erreur, si le mot word n'est pas présent dans l'objet :

value: get in object 'word

Ceci simplifie le code par exemple pour le traitement des valeurs d'un formulaire avec l'objet CGI :

cgi: construct decode-cgi read-cgi
name: any [get in cgi 'name "par-défaut"]

Dans l'exemple ci-dessus, si la variable CGI name n'existe pas, la chaîne "par-défaut" sera utilisée. Aucune erreur ne se produit si le mot "name" est manquant dans l'objet CGI.

2.6 Set-browser-path

La fonction set-browser-path accepte à présente les noms de fichiers au format REBOL. Elle acceptera aussi une chaîne au format de votre système d'exploitation (lorsque un nom de fichier est fourni sous forme d'une chaîne). Vous pouvez aussi définir à none la fonction.
La fonction set-browser-path renvoie aussi son précédent paramétrage. Si vous souhaitez ne pas utiliser cette fonction (pour des raisons de sécurité), vous pouvez la définir à none ou utiliser unset :

set-browser-path: none

unset 'set-browser-path

2.7 DO en ligne de commande

L'option --do est traitée en ligne de commande. Cela permet de passer à partir de la ligne de commande du shell des expressions qui sont à exécuter .

Par exemple :

rebol --do "probe system/options/args"

Notez que --do est effectué à présent après l'évaluation des fichiers rebol.r et user.r (ce qui vous laisse la possibilité d'initialiser vos propres fonctions et valeurs) mais avant celle du script en ligne de commande.

L'option --do peut être utilisée pour définir des variables avant l'exécution de votre script. Par exemple :

rebol make-website.r --do "verbose: true"

devrait permettre de définir la variable verbose sur true au démarrage de l'exécution. Pour définir une variable par défaut dans le script, vous devriez utiliser un code comme celui-ci :

if not value? 'verbose [verbose: false]

2.8 Correction du bogue find/any

Une erreur importante a été remontée par rapport à l'usage de find avec le raffinement /any (et les caractères jokers). Dans certains cas, find/any renvoyait une chaîne de caractère valide, au lieu de none. Par exemple :

find/any next "abc" "d"

renvoyait "c". Le problème a été corrigé.

2.9 Usage de mold sur des noms vides de fichiers

L'usage de mold sur un nom vide de fichier produisait un code source qui ne pouvait pas être chargé. Dans de rares cas, un save conduisait à créer un fichier que load ne pouvait pas charger. A présent, un nom vide fichier est précédé de "%" pour éviter ce problème. Ceci corrige le problème dans mold, save et probe.

3. Core 2.5.5

3.1 But de cette version

Le principal but du lancement de la version 2.5.5 est de rapprocher le plus possible REBOL/Core et REBOL/SDK, et d'améliorer la compatibilité avec Mac OS X.

3.2 Nouvelle licence pour Core

La licence de REBOL/Core a été modifiée pour permettre un usage personnel, pour l'Éducation, ou Commercial libre de droits. Notez que ce changement concerne seulement REBOL/Core (et sera étendu à la prochaine version de REBOL/View), mais ne s'applique pas à REBOL/SDK, /Command, /IOS et d'autres produits REBOL commerciaux.

3.3 Fichiers de démarrage (user.r et rebol.r)

La béta v 2.5.4 n'évaluait plus les fichiers rebol.r et user.r. La version 2.5.5 les évaluent à nouveau, quoique d'une façon légèrement différente. Ceci ne devrait pas affecter vos programmes. L'ordre est à présent :

  1. Vérifier le répertoire courant en premier.
  2. Vérifier le répertoire system/options/home en second.

Ceci vous permet d'avoir un unique fichier rebol.r (et aussi user.r) qui est partagé par tous les utilisateurs sur des systèmes multi-utilisateurs.

3.4 Comment les scripts sont lancés

La méthode utilisée pour lancer les scripts a été modifiée.
Ce changement ne devrait pas avoir d'incidence sur vos programmes, mais il produira un message d'erreur plus pertinent pour les erreurs de scripts, en éliminant la ligne d'erreur qui fait référence au problème "Near do-boot". Cette ligne déroutait les nouveaux utilisateurs, car do-boot ne faisait pas partie de leur script.

3.5 Caractère en fin de ligne de commande (CR)

REBOL n'indique plus les informations que renvoie la commande usage, si un caractère CR est passé depuis une ligne de shell Unix, en ligne de commande.

Bien que les scripts REBOL gèrent ce caractère proprement (ASCII 13), certains systèmes d'exploitation passent ce caractère comme un argument en ligne de commande, ce qui provoque avec les anciennes versions de REBOL l'affichage de l'aide en ligne.

Par exemple, vous pourriez avoir un problème avec un script shell CGI débutant par :

#!/home/user/rebol -cs
REBOL [...]

que vous auriez écrit sur un système Windows et transféré vers Linux sans conversion des caractères de fin de lignes. Le problème a été corrigé.

3.6 Changements relatifs à la fonction secure

La béta 2.5.4 ne définissait plus secure avant d'exécuter les scripts (en d'autres termes, elle fonctionnait comme REBOL/Base). Avec la version v.2.5.5, la sécurité est à nouveau correctement définie, avec cependant un léger changement : vous pouvez à présent par défaut écrire dans le répertoire où se trouve le script. Par exemple, si vous lancez :

REBOL /home/test/script.r

REBOL démarrera avec les droits en écriture sur le répertoire /home/test.
Tous les autres répertoires seront définis en lecture (read) seulement (avec interrogation si une écriture est requise).

Ceci rend plus facile pour les utilisateurs l'écriture de scripts qui écrivent et mettent à jour des données locales, sans avoir besoin de fournir l'option -S de la ligne de commande, mais tout en protégeant le reste des fichiers.

Notez que l'option +S a aussi été modifiée. Auparavant, +S était équivalent à secure quit, qui était souvent peu utilisée car REBOL s'arrêtait dés qu'il avait essayé de lire les fichiers user.r et rebol.r. A présent, l'option +S signifie secure ask de sorte que son usage devient :

rebol +s script.r

et conduira à l'ouverture d'une fenêtre ou d'un prompt interrogeant l'utilisateur pour toutes les opérations en écriture/lecture pour les fichiers locaux ou en réseau. Un mode sécurisé donc, mais moins strict qu'auparavant.

De plus, l'option --secure devrait encore continuer à fonctionner :

rebol --secure allow script.r
rebol --secure ask script.r

3.7 Raffinement mold/flat :

La raffinement /flat de la fonction mold vous permet de générer du code et des données sans indentation de lignes, ce qui rend la chaîne de texte résultante plus compacte (d'où l'intérêt pour un envoi via le réseau, ou la compression des données, l'encapsulation etc.)

Par exemple :

blk: [
    name [
    first "Bob"
    last "Smith"
    ]
    options [
    colors [
        red
        green
        blue
    ]
    ]
]

print mold blk
[
    name [
    first "Bob"
    last "Smith"
    ]
    options [
    colors [
        red
        green
        blue
    ]
    ]
]
print mold/flat blk
[
name [
first "Bob"
last "Smith"
]
options [
colors [
red
green
blue
]
]
]

3.8 Troncature de l'index d'une série (lorsque son extrémité est dépassée)

La gestion du débordement de la fin d'une série a été modifiée. Dans les versions précédentes, faire référence à une série au delà de son extrémité (tail) provoquait une erreur :

>> a: "ABC"
"ABC"
>> b: next a
"BC"
>> clear a
""
>> insert b "X"
** Script Error: Out of range or past end
** Near: insert b "X"

Dans certaines circonstances, ce problème était difficile à détecter, car presque n'importe quelle référence à B causait une erreur.

>> tail? b
** Script Error: Out of range or past end
** Near: tail? b

A présent, la gestion de l'erreur "past end" a été assouplie. Pour de nombreuses fonctions, l'index de la série est à présent tronqué à l'extrémité courante de la série :

>> a: "ABC"
"ABC"
>> b: next a
"BC"
>> clear a
""
>> tail? b
true

3.9 AT sur les ports

La fonction at (similaire à la fonction skip) peut s'employer à présent avec le type de données (datatype) port!.

3.10 Ajout des fonctions sixth à tenth

Cinq nouvelles fonctions ordinales ont été rajoutées :

sixth
seventh
eighth
ninth
tenth

L'intérêt de ces fonctions devient évident si vous les utilisez pour récupérer des valeurs provenant d'une série (au lieu d'utiliser un objet) :

name-of: :first
age-of:  :second
date-of: :third
...
product-of: :ninth
...
if empty? product-of record [print "missing product"]

La ligne ci-dessus est plus lisible que celle-ci :

if empty? ninth record [print "missing product"]

Voici une petite fonction utile :

ordain: func [
    "Defines ordinal accessors (synonyms)."
    words [block!] /local ords
][
    ords: [first second third fourth fifth
    sixth seventh eighth ninth tenth]
    foreach word words [
    set word get first ords
    ords: next ords
    ]
]

L'exemple ci-dessus peut se simplifier à présent en :

ordain [name-of age-of date-of ... product-of]
...
if empty? product-of record [print "missing product"]

Question : voulez-vous que cette fonction ordain devienne une fonction à part entière du langage REBOL ? Dites-le nous via la page de Feedback.

3.11 Lignes de plus de 4 Kb en mode direct/lines

Les versions précédentes de REBOL n'étendaient pas correctement leur buffer interne pour les lignes de plus de 4 Kb avec les fichiers ouverts en mode direct/line.

De sorte que ces lignes de plus de 4 Kb (pas de caractères de fin de lignes pour plus de 4 Kb) n'étaient pas lues correctement et provoquait un "end-of-file". Ce problème a été corrigé dans cette version.

3.12 DECODE-CGI et la gestion des noms CGI en double

Du fait de l'emploi de plus en plus courant de REBOL pour des scripts CGI, nous avons amélioré la fonction decode-cgi pour lui permettre de manipuler des noms de champs en doublons.

Par exemple, les "checklists" utilisées dans les formulaires Web peuvent retourner plusieurs valeurs pour une unique variable. Maintenant, decode-cgi renvoie ces valeurs mutiples dans des blocs :

>> cgi-str: {name=bob&option=view&option=email&}
>> decode-cgi cgi-str
[name: "bob" option: ["view" "email"]]

3.13 Correction pour la fonction ALTER

Une sérieuse erreur dans la fonction alter (une fonction pour les ensembles de données, voir la référence dans le dictionnaire REBOL) provoque son dysfonctionnement. Le problème a été résolu.

3.14 Erreurs réseau avec la fonction TRY (net-error throw)

La fonction net-error utilisait throw pour les erreurs, plutôt que de laisser l'erreur se produire.
Ceci provoquait le fait que certains types d'erreurs réseau ne pouvaient pas être récupérées à un plus haut niveau comme en utilisant try. Cela signifiait que si vous utilisiez try sur des sections de votre code, certaines erreurs de réseau (comme pour un cas vu avec SMTP) pouvaient être renvoyées, ce qui alors forçait l'erreur à être affichée de bout en bout sur la console. C'était un problème pour les scripts SDK, et il a été corrigé.

3.15 Extension des paths pour les répertoires FTP

Lors de l'utilisation d'URLs FTP, il n'y avait pas de moyen simple de fournir un chemin complet à partir du répertoire racine.

Comme par exemple, si le répertoire de login était :

/home/luke/

mais que vous vouliez faire une référence à :

/var/log/

Dans cette nouvelle version, vous pouvez utiliser un double slash pour fournir le chemin absolu vers la racine :

read ftp://user:pass@host//var/log/messages

(Merci de nous signaler si vous avez un souci avec ce format )

3.16 STATS pour system/stats

La fonction stats est maintenant directement accessible. Vous n'avez plus à l'appeler avec system/stats. En plus, la fonction stats calcule plus précisément la quantité de mémoire utilisée.

3.17 Portée de la variable PURL

La variable PURL utilisée dans la fonction decode-url est maintenant une variable locale et non plus globale.

4. Core 2.5.3

4.1 Remerciements

Merci à ces contributeurs pour les retours, suggestions et solutions :

Andrew Martin
"Anton"
Cal Dixon 
Carl Sassenrath
Ernie van der Meer
Gregg Irwin
Ladislav Mecir
Maarten Koopmans
"Mr. Martin Mr. Saint"
Reichart Von Wolfsheild

Avons-nous oublié votre feedback ou apport pour corriger ou améliorer quelque chose ? Si oui, faites-en nous part sur :

http://www.rebol.com/feedback.html.

Il n'est pas toujours possible de caractériser tous les changements intervenus pour chaque nouvelle version, mais si vous trouvez un bogue, merci de nous le signaler et nous ferons le maximum pour le corriger.

Donnez nous un exemple court et reproductible du problème, et si vous avez la correction du problème, envoyez-la également. (vous verrez la correction mise en place plus vite dans ce cas).

4.2 Réécriture de la fonction MAKE-DIR

La fonction make-dir a été réécrite et fonctionne à présent correctement. De plus, elle a été améliorée pour ne plus causer d'erreur lorsque le répertoire spécifié existe déjà.

Utilisez la fonction exists? si vous avez besoin de vérifier l'existence du répertoire.

4.3 Nouvelles fonctions pour les bitsets : CLEAR, LENGTH?, EMPTY?

Trois nouvelles fonctions (actions) ont été ajoutées pour les bitsets :

  • La fonction clear remet rapidement tous les bits à zéro.
  • La fonction length? renvoie le nombre de bits dans le bitset (toujours un multiple de 8).
  • La fonction empty? renvoie true sur tous les bits définis, et false sinon. (Notez que la fonction empty? est la même fonction que tail?; donc par conséquent, tail? va avoir le même résultat, mais le mot n'a pas de signification pour les bitsets.)

Les bitsets sont utilisés pour leurs bonnes performances avec les tableaux logiques de caractères ou des hashs.

>> items: make bitset! 40
== make bitset! #{0000000000}
>> length? items
== 40
>> empty? items
== true
>> insert items 10
== make bitset! #{0004000000}
>> empty? items
== false
>> clear items
== make bitset! #{0000000000}
>> empty? items
== true
>> empty? negate items
== false

4.4 Changements dans la fonction SKIP

Il y a trois changements pour skip que vous devriez noter :

  • skip, à présent, manipule correctement les valeurs décimales d'offsets. Les valeurs sont tronquées à l'entier inférieur le plus proche.

(Notez que les nombres décimaux devraient être utilisés avec précaution car 1.99999 n'est pas 2.0 )

>> skip "abc" 1.9999999
== "bc"
>> skip "abc" 2.0
== "c"
  • skip peut avoir gérer un offset logique (logic offset). Cela rend cette fonction cohérente avec pick et at qui utilisaient des offsets logiques :
>> pick [red green] true
== red
>> skip [red green] true
== [red green]
>> at [red green] true
== [red green]
>> pick [red green] false
== green
>> skip [red green] false
== [green]
>> at [red green] false
== [green]

Pour les offsets logiques, skip est identique à at.

  • L'usage de skip avec le type de données image! permet de sauter des pixels, pas des octets RGBA. Ceci est cohérent avec at, pick, et poke. Si vous utilisez actuellement pick avec des images, ce changement affecte votre code.

4.5 Tableaux initialisés avec des valeurs de type block!

Si une valeur de type block! est fournie comme valeur initiale à la fonction array, chaque élément du tableau contiendra le bloc, et pas le contenu du bloc.

Si la valeur initiale est une série de type string!, block!, email!, url!, elle sera copiée dans chaque élément du tableau (ce qui induit que la valeur de chaque élément sera unique et non partagée).

Par exemple :

>> a: array/initial [2 3] [1 2]
== [[[1 2] [1 2] [1 2]] [[1 2] [1 2] [1 2]]]
>> append a/1/2 3
== [1 2 3]
>> a
== [[[1 2] [1 2 3] [1 2]] [[1 2] [1 2] [1 2]]]

4.6 Ajout du mot BREAK pour la fonction PARSE

Au sein de certains types de boucles de parsing comme any et some, il est parfois difficile d'écrire des règles qui clôturent la boucle. Ceci se produit principalement lors de l'utilisation de règles générales qui tentent de traiter "tous les autres cas" au sein de la boucle.

Par exemple, un code comme celui-ci :

parse item [
    any [
    "word" (print "got word")
    | copy value [to "abc" | to end]
        (print value)
    ]
]

finira par boucler indéfiniment, car la deuxième règle au sein de any sera toujours vérifiée, et la condition any ne se terminera jamais.

Pour résoudre cette situation, le mot break a été rajouté au dialecte parse. Il est simple d'emploi. Quand le mot break est rencontré au sein d'un bloc, l'analyse de ce bloc se termine immédiatement sans se soucier de la position courante du pointeur. Les expressions qui suivent break au sein du même bloc ne seront donc pas évaluées.

L'exemple précédent peut à présent être écrit :

parse item [
    any [
    "word" (print "got word")
    | copy value [to "abc" | to end]
        (print value) break
    ]
]

La boucle any sera terminée après la deuxième règle

En général, pour les blocs de règles avec any, vous pouvez ajouter la vérification d'une clause end, suivie par le mot break, comme dans cet exemple :

parse item [
    any [
      end break           ; <----  ici 
    | "word" (print "got word")
    | copy value [to "abc" | to end]
        (print value)
    ]
]

4.7 Correction de la fonction OPEN sur les ports réseau

Pour quelques versions de Windows32, et les ports réseau, la fonction open fonctionnait de manière incorrecte du fait d'une erreur renvoyée par la librairie winsock (documenté par Microsoft). Corrigé.

4.8 Correction du bogue sur les fonctions en cours de modification

Le bogue qui se produisait, lorsqu'on modifiait une valeur de fonction durant l'évaluation de ses arguments, a été corrigé. Par exemple, le code ci-dessous :

a: func [x] [print x]
b: func [] [a: 42]   
a b

ne produira plus un crash de REBOL.

Notez que modifier une fonction durant son évaluation peut produire des résultats bizarres, variables suivant les versions, et cette façon de faire devrait en général être évitée.

4.9 CHANGE accepte des valeurs de type Any-type

Pour être cohérent avec insert, la fonction change autorise une nouvelle valeur à être de type any-type!. Les utilisateurs devraient être attentifs au fait qu'un argument sans valeur conduira à exécuter change sur une valeur unset!, et qu'il n'y aura pas d'erreurs.

Par exemple :

>> a: [10]
== [10]
>> do [change a]      ; pas de valeur fournie
== []
>> probe a
[unset]
== [unset]

4.10 Mettre en "unset" des variables objets (sur un exit)

Si un exit se produit durant l'évaluation d'un objet, les variables non assignées qui n'auraient pas été copiées depuis l'objet parent seront non référencées. Corrige le bogue "end" où la première variable était définie sur un type de données end!.

>> probe make object! [exit a: b:]
== make object! [
    a: unset
    b: unset
]

4.11 Ajout de la fonction BUILD-MARKUP

La fonction a été inspirée par le concept EREBOL de Marteen Koopmans et Ernie van der Meer. Grossièrement, l'idée est que REBOL peut être un puissant outil de traitement (façon PHP) pour générer des pages Web et d'autres textes à balises.

La fonction build-markup a été rajoutée au langage pour prendre en compte cette capacité, et devenir une fonction standard dans chaque évolution de REBOL.
La fonction build-markup prend du texte à balises (ex. HTML) qui contient des items commencant par "<%" et se terminant avec "%>".

Elle évalue le code REBOL dans chaque item (comme s'il s'agissait d'un bloc REBOL), et le remplace par son résultat. N'importe quelle expression REBOL peut être placée dans ces balises.

Comme le langage PHP l'a montré, c'est une technique très utile et pratique.

Par exemple :

== build-markup "<%1 + 2%>"
>> "3"

== build-markup "<B><%1 + 2%></B>"
>> "<B>3</B>"

== build-markup "<%now%>"
>> "2-Aug-2002/18:01:46-7:00"

== build-markup "<B><%now%></B>"
>> "<B>2-Aug-2002/18:01:46-7:00</B>"

L'argument <%now%> passé à la fonction build-markup permet d'insérer la date et l'heure courante dans l'affichage.

Voici un court exemple qui génère une page Web depuis un modèle, ainsi qu'un nom et une adresse email.

template: {<HTML>
    <BODY>
    Hi <%name%>, your email is <i><%email%></i>.<P>
    </BODY>
    </HTML>
}

name: "Bob"
email: bob@example.com
page: build-markup template

N'oubliez pas les deux caractères "%" dans le tag. C'est une erreur courante.

En principe, la valeur renvoyée par le code entre balises "<%" "%>" est normalement passée à la fonction join pour l'affichage.

Vous pouvez aussi utiliser les fonctions form ou mold sur le résultat pour récupérer le genre de réponse qui vous convient. L'exemple ci-dessous charge une liste de fichiers depuis le répertoire courant et les affiche de trois manières différentes :

Input: "<PRE><%load %.%></PRE>"
Result: {<PRE>build-markup.rchanges.txt</PRE>}

Input: "<PRE><%form load %.%></PRE>"
Result: {<PRE>build-markup.r changes.txt</PRE>}

Input: "<PRE><%mold load %.%></PRE>"
Result: {<PRE>[%build-markup.r %changes.txt]</PRE>}

Si l'évaluation d'un tag ne renvoie pas de résultat (par exemple en utilisant du code tel que : print "test"), alors il n'y a aucune sortie affichée.
Dans ce cas, l'affichage de print sera fait vers le périphérique standard pour la sortie (output).

Input: {<NO-TEXT><%print "test"%></NO-TEXT>}
test
Result: "<NO-TEXT></NO-TEXT>"

La fonction build-tag peut être utilisée à l'intérieur du tag fourni pour transformer des valeurs REBOL en balises :

Input: {<%build-tag [font color "red"]%>}
Result: {<font color="red">}

Les tags "<%" "%>" permettent de définir et d'utiliser des variables de la même manière que n'importe script REBOL.

Par exemple, le code ci-dessous charge une liste de fichiers depuis le répertoire courant, sauve cette liste dans une variable, puis affiche deux noms de fichiers :

Input: "<PRE><%first files: load %.%></PRE>"
Result: {<PRE>build-markup.r</PRE>}

Input: "<PRE><%second files%></PRE>"
Result: {<PRE>changes.txt</PRE>}

Notez que les variables utilisées dans les tags sont toujours des variables globales.

Si une erreur se produit dans le tag, un message d'erreur apparaîtra au lieu du résultat du tag. Ceci vous permet de voir les erreurs depuis n'importe quel navigateur HTML.

Input: "<EXAMPLE><%cause error%></EXAMPLE>"
Result: {<EXAMPLE>***ERROR no-value in: cause error</EXAMPLE>}

Si vous ne voulez pas que les messages d'erreurs soient retournés, vous pouvez utiliser le raffinement /quiet. L'exemple précédent devrait renvoyer à présent :

Result: "<EXAMPLE></EXAMPLE>"

4.12 Révision de la fonction BUILD-TAG

La version précédente de build-tag générait des résultats manquant d'intérêt pour la plupart des cas.

Elle a été remplacée par une nouvelle fonction qui est une contribution d'Andrew Martin.

Cette fonction produit de meilleurs résultats, mais se comporte différemment de la précédente version de la fonction. Si vous utilisez actuellement build-tag, vous devrez sans doute modifier votre code.

In:  [input "checked" type "radio" name "Favourite" value "cat"]
Old: {<input="checked" type="radio" name="Favourite" value="cat">}
New: {<input checked type="radio" name="Favourite" value="cat">}

In:  [html xml:lang "en"]
Old: {<html="xml:lang"="en">}
New: {<html xml:lang="en">}

In:  [body text #FF80CC]
Old: {<body text="FF80CC">}
New: {<body text="#FF80CC">}

In:  [a href %Test%20File%20Space.txt]
Old: {<a href="Test File Space.txt">}
New: {<a href="Test%20File%20Space.txt">}

In:  [/html gibber %Froth.txt]
Old: {</html gibber="Froth.txt">}
New: "</html>"

In:  [?xml version "1.0" encoding "UTF-8"]
Old: {<?xml version="1.0" encoding="UTF-8">}
New: {<?xml version="1.0" encoding="UTF-8"?>}

In:  [html xmlns http://w3.org/xhtml xml:lang "en" lang "en"]
Old: {<html xmlns="http://w3.org/xhtml"="xml:lang"="en" lang="en">}
New: {<html xmlns="http://w3.org/xhtml" xml:lang="en" lang="en">}

In:  [html xmlns http://w3.org/xhtml/ xml:lang "en" lang "en"]
Old: {<html xmlns="http://w3.org/xhtml/"="xml:lang"="en" lang="en">}
New: {<html xmlns="http://w3.org/xhtml/" xml:lang="en" lang="en">}

4.13 Révision de la fonction DECODE-CGI

Plusieurs bogues ont été corrigés dans la fonction decode-cgi. En particulier, la fonction gère des affectations d'attributs vides. Voici quelques exemples :

Input:   "name=val1&amp;name=val2"
Decoded: [name: "val1" name: "val2"]

Input:   "name1=val1&amp;name2&amp;name3=&amp;name4=val3"
Decoded: [name1: "val1" name2: "" name3: "" name4: "val3"]

Input:   "name1="
Decoded: [name1: ""]

Input:   "name2&amp;"
Decoded: [name2: ""]

Input:   "name3=&amp;"
Decoded: [name3: ""]

Input:   "name4=val"
Decoded: [name4: "val"]

Input:   "name5=val&amp;"
Decoded: [name5: "val"]

La nouvelle fonction est basée aussi sur une contribution d'Andrew Martin. Merci à lui !

4.14 Correction de la fonction UNPROTECT

Tenter de déprotéger (unprotect) un bloc contenant n'importe quelle valeur autre qu'un mot provoquait un crash. A présent, les valeurs qui ne sont pas des mots sont ignorées.

4.15 Ajout à Core de la fonction ALTER

La fonction alter, seulement rencontrée dans View, est en fait d'intérêt général, et a été rajoutée dans toutes les versions de REBOL.

4.16 Protection du mot SYSTEM

Pour éviter aux débutants des erreurs accidentelles qui pourraient être difficiles à déboguer, les mots system et rebol sont à présent protégés. Si vous devez les modifiez, utilisez unprotect d'abord.

4.17 Message d'erreur pour un mot sans contexte

Le message d'erreur "word not defined in this context" a été modifié en "word has no context" pour indiquer que le mot n'a jamais été défini (plus précisément, n'a jamais été lié) dans le contexte d'un objet, d'une fonction ou dans l'environnement global.

4.18 Correction vis-à-vis de dates dans le futur

Ceci permet d'éviter un crash au démarrage causé par une erreur Microsoft Windows sur les fonctions temporelles, lorsqu'elles utilisent des dates système plus grandes que 2036.

5. Core 2.5.2

5.1 Fonction CONSTRUCT, pour créer un objet

Nous avons ajouté une fonction pour la création d'objet pour fournir un niveau plus élevé de sécurité pour des objets importés. La fonction est appelée : construct et elle fabrique de nouveaux objets, mais sans l'évaluation habituelle des spécifications de l'objet (comme cela est fait avec les fonctions make et context).

Lorsque construct est utilisée pour un objet, seuls les types littéraux sont acceptés. L'évaluation fonctionnelle n'est pas réalisée. Ceci permet d'importer directement des objets (comme ceux qui sont envoyés de sources non sûres comme le courrier électronique, une requête CGI, etc.) sans être impacté par des effets de bords "cachés", liés à du code exécutable.

La fonction construct s'utilise de la même façon que la fonction context :

obj: construct [
    name: "Fred"
    age: 27
    city: "Ukiah"
]

Mais aucune évaluation n'est faite. Ceci signifie que des spécifications d'objets telles que :

obj: construct [
    name: uppercase "Fred"
    age: 20 + 7
    time: now
]

ne retourneront pas leurs résultats évalués.

La fonction construct est pratique pour importer des objets externes. Par exemple, le chargement des paramétrages d'un fichier de préférences peut être fait avec :

prefs: construct load %prefs.r

De la même manière, vous pouvez utiliser construct pour charger une réponse CGI ou email.

Pour fournir un objet modèle qui va contenir des valeurs par défaut pour des variables, (comme cela peut se faire avec make), utilisez le raffinement /with. L'exemple ci-dessous utilise comme modèle un objet existant appelé standard-prefs.

prefs: construct/with load %prefs.r standard-prefs

La fonction construct réalisera une évaluation des mots true, false, none, on, et off, pour produire les valeurs ad-hoc. Les mots et les paths littéraux seront aussi évalués, pour produire les mots et paths respectifs. Par exemple :

obj: construct [
    a: true
    b: none
    c: 'word
]

la valeur obj/a devrait true (logical), obj/b devrait être none, et obj/c devrait être : word.

5.2 Changement pour la fonction LOAD (Important)

Les en-têtes de scripts sont à présent des objets créés par la fonction construct et ils ne sont dorénavant plus évalués. Cette modification induit un niveau de sécurité plus élevé quand la fonction load est utilisée pour charger des données REBOL. Ce changement devrait affecter très peu de scripts (seulement ceux dépendant de l'évaluation de variables d'en-tête, ils sont rares).

La fonction load peut être utilisée sans souci sans avoir besoin d'utiliser load/all pour contrôler un en-tête de script avant l'évaluation de celui-ci.

5.3 Modification et amélioration de HELP

La fonction help peut maintenant être utilisée pour explorer les champs d'un objet dans un format compréhensible. Par exemple, saisir cette ligne dans la console :

help system

produira ce résultat :

SYSTEM is an object of value:
   version         tuple!    1.0.4.3.1
   build           date!     1-May-2002/13:31:11-7:00
   product         word!     Link
   components      block!    length: 45
   words           object!   [unset! error! datatype! context! native
   license         string!   {REBOL End User License Agreement IMPORT
   options         object!   [home script path boot args do-arg link-
   user            object!   [name email home words]
   script          object!   [title header parent path args words]
   console         object!   [history keys prompt result escape busy 
   ports           object!   [input output echo system serial wait-li
   network         object!   [host host-address]
   schemes         object!   [default Finger Whois Daytime SMTP POP I
   error           object!   [throw note syntax script math access co
   standard        object!   [script port port-flags email face sound
   view            object!   [screen-face focal-face caret highlight-
   stats           native!   System statistics. Default is to return 
   locale          object!   [months days]
   user-license    object!   [name email id message]

Ceci fonctionne aussi pour d'autres types d'objets dont vos propres objets. Le code ci-dessous devrait afficher le contenu de l'objet text-face créé avec la fonction layout, de REBOL/View :

out: layout [text-face: text "test"]

help text-face

Les objets secondaires sont aussi affichés. Ils doivent être mentionnés sous forme de paths.

Par exemple pour voir l'objet options inclus dans l'objet system :

help system/options

Le résultat devrait ressembler à cela :

SYSTEM/OPTIONS is an object of value:
   home            file!     %/d/rebol/link/
   script          file!     %/d/rebol/link/ranch/utilities/console.r
   path            file!     %/d/rebol/link/ranch/
   boot            file!     %/d/rebol/link/rebol-link.exe
   args            none!     none
   do-arg          none!     none
   link-url        string!   "tcp://localhost:4028"
   server          none!     none
   quiet           logic!    true
   trace           logic!    false
   help            logic!    false
   install         logic!    false
   boot-flags      integer!  2064
   binary-base     integer!  16
   cgi             object!   [server-software server-name gateway-int

De plus, la fonction de recherche inhérente à help renvoie maintenant plus d'informations pour les correspondances trouvées. Si vous saisissez :

help "to-"

vous verrez maintenant :

Found these words:
   caret-to-offset native!   Returns the offset position relative to 
   offset-to-caret native!   Returns the offset in the face's text co
   to-binary       function! Converts to binary value.
   to-bitset       function! Converts to bitset value.
   to-block        function! Converts to block value.
   to-char         function! Converts to char value.
   to-date         function! Converts to date value.
   to-decimal      function! Converts to decimal value.
   to-email        function! Converts to email value.
   to-event        function! Converts to event value.
   to-file         function! Converts to file value.
   to-get-word     function! Converts to get-word value.
   to-hash         function! Converts to hash value.
   to-hex          native!   Converts an integer to a hex issue!.
   to-idate        function! Returns a standard Internet date string.
   to-image        function! Converts to image value.
   to-integer      function! Converts to integer value.
   to-issue        function! Converts to issue value.
   to-list         function! Converts to list value.
   to-lit-path     function! Converts to lit-path value.
   to-lit-word     function! Converts to lit-word value.
   to-local-file   native!   Converts a REBOL file path to the local 
   to-logic        function! Converts to logic value.
   to-money        function! Converts to money value.
   to-none         function! Converts to none value.
   to-pair         function! Converts to pair value.
   to-paren        function! Converts to paren value.
   to-path         function! Converts to path value.
   to-rebol-file   native!   Converts a local system file path to a R
   to-refinement   function! Converts to refinement value.
   to-set-path     function! Converts to set-path value.
   to-set-word     function! Converts to set-word value.
   to-string       function! Converts to string value.
   to-tag          function! Converts to tag value.
   to-time         function! Converts to time value.
   to-tuple        function! Converts to tuple value.
   to-url          function! Converts to url value.
   to-word         function! Converts to word value.

5.4 Ajout de la fonction SUFFIX?

La fonction suffix? est une fonction pratique qui renvoie l'extension d'un fichier ou d'une URL. Par exemple :

>> suffix? %into.txt
== %.txt
>> suffix? http://www.rebol.com/docs.html
== %.html
>> suffix? %test
== none
>> suffix? %test.it/file
== none

Cette fonction suffix? peut être utile lors de la sélection de fichiers depuis un répertoire. L'exemple ci-dessous permet de ne sélectionner que les fichiers html et htm :

foreach file load %. [
    if find [%.html %.htm] suffix? file [
    browse file
    ]
]

5.5 Ajout de la fonction SIGN?

La fonction sign? renvoie un entier positif, nul ou un entier négatif selon le signe de l'argument qui lui est fourni.

print sign? 1000
1
print sign? 0
0
print sign? -1000
-1

Le signe est retourné sous forme d'un entier ce qui permet de l'utiliser dans une multiplication :

new: 2000 * sign val

if size < 10 [xy: 10x20 * sign num]

5.6 Ajout de la fonction COMPONENT?

La fonction component? est une fonction permettant de vérifier l'existence d'un composant REBOL.

if component? 'crypt [print "Encryption available."]

if not component? 'sound [print "No sound."]

5.7 Mise à jour de la fonction SEND

La fonction send inclut maintenant un raffinement /show qui permet de montrer tous les destinataires (TO) dans l'en-tête. Par défaut, les destinataires ne sont normalement pas montrés.

send/show [bob@example.com fred@example.com] message

De plus, le champ FROM inclut le nom de l'expéditeur tout comme son adresse email. La chaîne mentionnée dans system/user/name est utilisée comme adresse "From". Par exemple, si :

system/user/name: "Fred Reboller"

alors, lorsque le courrier électronique sera envoyé, le champ FROM apparaîtra maintenant ainsi :

From: Fred Reboller <fred@example.com>

Si la valeur de system/user/name est none, le champ n'est pas utilisé.

Également, certains problèmes dans le raffinement /attach ont été corrigés.

Les courriers avec des pièces jointes sous la forme :

send/attach user content [[%file.txt "text message"]]

devraient être correctement émis. Voir les notes sur send ci-dessous pour plus d'information sur le raffinement /attach.

5.8 Corrections diverses

5.8.1 TYPE? (utilisation dans parse)

Correction du problème rapporté pour la fonction type? qui induisait une erreur de datatype dans la fonction parse. Maintenant, le code ci-dessous devrait fonctionner correctement :

parse [34] reduce [type? 34]
parse [34.5] reduce [type? 34.5]

5.8.2 MOLD/all

Correction du problème rencontré avec la fonction mold lorsque le raffinement /all est fourni.

load mold/all context [test: func [arg] [print arg]]

5.8.3 FTP

Deux corrections :

Lorsqu'on se connecte sur un serveur FTP basé sur Microsoft IIS, REBOL ne reconnaît pas correctement les dossiers. Ils sont bien marqués comme des répertoires (type 'directory), mais aucun symbole slash n'est ajouté à la fin du nom de fichier alors que c'est le cas avec d'autres types de serveurs FTP.

En FTP, les liens vers des fichiers peuvent maintenant être identifiés. Ils correspondent à des fichiers de type 'link. Merci à Cal et Reichart de Prolific.com pour leur contribution des corrections des bogues FTP.

6. Core 2.5.1

6.1 Code source et valeurs none, true, etc.

Afin de mieux supporter les valeurs persistantes entre save, mold, et load, un nouvel élément syntaxique a été rajouté à REBOL.

Dans le passé, la représentation dans le code source de valeurs comme none et true nécessitait une évaluation en vue de convertir ces mots en leurs valeurs. Par exemple :

load "none"

renvoyait le mot none, pas la valeur none. Ceci nécessitait que votre code puisse évaluer le résultat (avec do, reduce, ou try), ou de manuellement convertir le mot none avec un code comme celui-ci :

if value = 'none [value: none]

D'autre part, si vous stockiez des données REBOL en utilisant les fonctions mold ou save, lorsque vous récupériez ces données en retour, il était nécessaire soit de les évaluer (par exemple avec reduce), ou sinon d'ajouter des contrôles pour certains types de mots (comme indiqué avant).

Pour faciliter la gestion de cette situation avec les expressions littérales de none, true, false, et d'autres valeurs qui nécessitent une évaluation, une nouvelle forme syntaxique a été ajoutée au langage :

#[datatype value]

pour laquelle datatype indique le type de données, et value sa valeur. Pour des types de données simples comme none, true, et false, la forme raccourcie

#[word]

est aussi permise. Par exemple :

#[none]

exprime la valeur none, pas le mot none. Pareillement,

#[true]
#[false]

expriment les valeurs de true et false dans un code non évalué.

Les fonctions load, do et les autres fonctions de conversion ont été étendues pour accepter cette nouvelle syntaxe. L'exemple ci-dessous montre la différence :

block: load " none #[none] true #[true] "

foreach value block [print type? value]

word
none
word
logic

L'expression littérale d'objets REBOL est aussi permise avec ce nouveau format. Par exemple, l'expression non évaluée :

#[object! [name: "Fred" skill: #[true]]]

est équivalente à :

make object! [
    name: "Fred"
    skill: true
]

D'autre part, une forme persistante (réciprocité mold/load) d'objets est maintenant valable pour les programmeurs.

Pour créer ou sauvegarder du code source ou des données en utilisant ces expressions, les fonctions mold et save intègrent un nouveau raffinement appelé /all. Ce raffinement renverra le nouveau format #[...] pour les valeurs qui le nécessitent.

Par exemple :

mold/all reduce ["Example" true none time]

renvoie la chaîne :

["Example" #[true] #[none] 5-May-2002/9:08:04-7:00]

Pareillement, avec save/all, il est possible de sauvegarder l'expression précédente dans un fichier.

6.2 Une évaluation moins agressive (Important !)

Les variables ne sont plus évaluées de façon agressive.

Dans les précédentes versions de REBOL, les variables qui sont rattachées à des mots définis (set-words), parens, paths et autres types de données devaient être évaluées en référence à ces types. Ceci n'est plus le cas. Par exemple, dans les anciennes versions, si vous écriviez :

a: first [b/c/d]
print a

le résultat aurait été une évaluation de b/c/d. Cette évaluation posait problème, car il est plus courant de référencer ces données, que de les évaluer. Par exemple, il devrait être possible d'écrire :

data: ["test" A: mold/only (10 + 2.5)]

foreach value data [print value]

et de parcourir aisément les éléments du bloc comme de simples valeurs. Vous ne voudriez pas nécessairement que ces valeurs soient évaluées.

Ce changement dans l'évaluation a des conséquences importantes. Par exemple, il affecte n'importe quelle fonction qui spécifie des valeurs littérales dans ses arguments. Par exemple, pour le code :

f: func ['word] [print word]

le principe de REBOL pour définir l'argument littéral d'une fonction est d'accepter toujours l'argument comme une valeur littérale et de ne PLUS l'évaluer. Cependant, dans l'implémentation actuelle, une évaluation peut normalement se produire lorsque la variable a été référencée. (comme avec print dans l'exemple).

Par exemple, si vous écrivez :

f a/b/c

dans la fonction, la référence au mot word devrait provoquer l'évaluation du path. Donc, si vous faites référence trois fois à l'argument word, à chaque fois, il devrait être évalué.

Cette évaluation implicite et "agressive", bien qu'intéressante, n'était pas intuitive, et générait beaucoup de difficultés dans la recherche d'erreurs et l'interprétation des messages d'erreurs.

Considérez le cas où un item de type set-word! était fourni en argument :

f: func ['word] [print word]
f test:

le mot défini (test:) est alors évalué lorsque word apparaît (dans la ligne avec print) et il nécessite un argument. Le code produisait un message d'erreur disant que set nécessitait un argument. Pourtant, vous ne voyiez aucun "set" dans votre code. Cela ressemblait à un défaut de l'interpréteur, alors qu'en fait, il faisait précisément ce qui lui était demandé.

Quoique la majorité des programmes REBOL ne repose sur ce type d'évaluation, nous avons étudié cette situation. Ceci permet de clarifier la sémantique des arguments littéraux, mais cela signifie aussi que là où des programmes dépendent de l'évaluation d'arguments littéraux, ils ne le seront plus.

Cela peut conduire, de manière rare, à des problèmes dans votre code. (Par exemple dans le code source de REBOL, un seul cas de ce type existe).

6.3 Insertion de blocs avec COMPOSE/ONLY

A présent, la fonction compose possède un raffinement /only similaire au raffinement insert/only. Lorsque /only est fourni, les blocs à insérer le sont seulement en tant que blocs, et non pas avec les éléments du bloc (défaut). L'usage de la fonction reduce sur les blocs n'est pas nécessaire.

Par exemple :

>> block: [1 2 3]

>> compose [example (block)]
== [example 1 2 3]
>> compose [example (reduce [block])]
== [example [1 2 3]]
>> compose/only [example (block)]
== [example [1 2 3]]

6.4 REMOVE-EACH - Un moyen pratique d'effacer les éléments d'une Série

La nouvelle fonction remove-each fonctionne de manière similaire à foreach et efface successivement des valeurs dans une série, qui peut être de type string!, block!, etc.

Également, dans la plupart des cas, remove-each est plusieurs fois plus rapide qu'une boucle while, et que la fonction remove.

le format de remove-each est identique à celui de foreach excepté le fait qu'il utilise le résultat de l'expression du bloc pour déterminer ce qui doit être effacé.

Remove-each effectue une itération sur un ou plusieurs éléments d'une série et évalue un bloc à chaque fois. Si le bloc renvoie false ou none, rien ne se produit. Mais si le bloc renvoie n'importe quelle autre valeur, cet item ou les items sont enlevés.

remove-each value series [expression]

Notez qu'en plus de modifier une série, remove-each renvoie cette série en tant que résultat.

Voici un certain nombre d'exemples :

Pour ôter d'un bloc les nombres impairs :

>> blk: [1 22 333 43 58]
>> remove-each item blk [odd? item]
== [22 58]
>> probe blk
== [22 58]

Pour enlever d'un bloc fourni tous les nombres supérieurs à 10 :

>> blk: [3 4.5 20 34.5 6 50]
>> remove-each item blk [item > 10]
== [3 4.5 6]
>> probe blk
== [3 4.5 6]

Pour ôter tous les répertoires apparaissant dans le listing d'un répertoire :

>> dir: load %.
>> remove-each file dir [#"/" = last file]
== [%calculator.r %clock.r %console.r %find-file.r...]

Pour conserver seulement les répertoires dans le listing :

remove-each file load %. [#"/" <> last file]

Pour enlever seulement les fichiers .doc du listing

remove-each file load %. [not suffix? ".doc"]

Tout comme foreach, remove-each peut opérer sur plusieurs éléments d'une série (et se déplacer éventuellement par saut (skip) pour récupérer le jeu suivant d'éléments) :

remove-each [val1 val2 val3] series [expression]

Voici un exemple de bloc structuré qui utilise plusieurs valeurs :

blk: [
    1 "use it"
    2 "rebol"
    3 "great fun"
    4 "the amazing bol"
]

remove-each [num str] blk [odd? num]

remove-each [num str] blk [not find str "bol]

Remove-each peut aussi enlever les caractères d'une chaîne

>>  str: "rebol is fun to use"

>>  remove-each chr str [chr = #"e"]
== "rbol is fun to us"
>>  remove-each chr str [find "uno " chr]
== "rblisfts"

6.5 ATTEMPT et la manipulation des Erreurs

La fonction attempt est un raccourci pour le code REBOL suivant :

error? try [block]

Le format pour attempt est :

attempt [block]

La fonction attempt est pratique dans les cas où soit vous ne vous souciez pas des erreurs pouvant se produire, soit vous voulez juste déclencher des actions simples selon l'erreur rencontrée.

attempt [make-dir %fred]

La fonction attempt renvoie le résultat du bloc si aucune erreur ne se produit. Si une erreur se produit, par contre, none est retournée.

Dans la ligne :

value: attempt [load %data]

la variable value sera à none si le fichier %data ne peut être chargé (par ex. s'il n'existe pas ou contient une erreur).

Ceci vous permet d'écrire des conditions dans votre code, comme ceci :

if not value: attempt [load %data] [alert "Problem"]

ou, encore plus simple :

value: any [attempt [load %data] 1234]

Dans cette ligne, si le fichier ne peut être chargé, alors value prend la valeur 1234.

6.6 Mise à jour de la fonction EXTRACT

La fonction extract inclut à présent le raffinement /index qui vous permet de spécifier quelle "colonne" vous souhaitez extraire. Par exemple :

data: [
    10 "fred" 1.2
    20 "bob" 2.3
    30 "ed" 4.5
]

>> probe extract/index data 3 2
== ["fred" "bob" "ed"]

Ici, c'est la deuxième colonne qui a été extraite.

Si le raffinement /index n'est pas fourni, alors c'est par défaut la première colonne qui est récupérée.

De plus, la fonction extract a été corrigée pour extraire correctement les blocs d'une série de blocs.

6.7 SAVE en mémoire

La fonction save peut maintenant écrire son résultat en mémoire. C'est assez utile, car cette fonction contient des raffinements pour formater son résultat, qui ne sont trouvés nulle part ailleurs.

Pour utiliser save et écrire en mémoire, vous devrez indiquez une valeur binaire plutôt qu'un nom de fichier. Par exemple :

bin: make binary! 20000 ; (auto expansion si besoin)

image: load %fred.gif

save/png bin image

A présent la variable binaire bin contient l'image image au format PNG . Il n'est pas nécessaire de l'écrire dans un fichier et de le relire par la suite.

6.8 Raffinements /subject et /attach pour la fonction SEND

La fonction send utilisée pour l'envoi de mail a été améliorée pour pouvoir facilement indiquer une ligne pour le sujet du mail, avec le raffinement /subject. C'est un raccourci pratique.
Par exemple :

letter: read %letter.txt

send/subject luke@rebol.com letter "Here it is!"

L'exemple précédent enverra le texte de la lettre (du fichier letter.txt) avec la ligne de sujet spécifiée. Si le raffinement /subject n'est pas fourni, alors la première ligne de letter sera utilisée comme sujet.

De plus, la fonction send autorise à présent l'attachement de fichiers en pièce jointes, en utilisant le raffinement /attach. Un ou plusieurs fichiers peuvent être joints. Les fichier spécifiés peuvent être lus en local sur le disque ou fournis en tant que noms de fichiers, ou sous forme de données.

Les formats possibles sont :

send/attach user letter file

send/attach user letter [file1 file2 ...]

send/attach user letter [[%filename data] ...]

Vous pouvez aussi combiner les deux derniers formats.

Des exemples d'usage pour les pièces jointes :

user: luke@rebol.com
letter: read %letter.txt

send/attach user letter %example.r

send/attach user letter [%file1.txt %file2.jpg]

send/attach user letter compose/deep [
    [%options.txt (mold system/options)]
]

6.9 Fonction DIFFERENCE pour les dates/heures

La fonction difference permet à présent de calculer les écarts entre deux valeurs de date/heures.

>> difference now 1-jan-2000
== 20561:20:26

En principe, lorsque vous soustrayez des dates, le résultat est un nombre de jours, pas des heures :

>> now - 1-jan-2000
== 856

6.10 Ajout du PORT SYSTEM

Le composant REBOL System Port a été rajouté. Ce composant permet un accès direct à diverses possibilités spécifiques à votre système d'exploitation. Par exemple, avec le port system, il est possible de capturer les signaux sous Unix et Linux, et d'effectuer un arrêt contrôlé. Sous Win32, le port peut être utilisé pour accéder aux événements (win-messages).

D'autres d'informations sur le composant System Port seront fournies dans un document à part.

7. Core 2.5.0

7.1 Nouvelle fonction SORT

Plusieurs modifications et améliorations ont été faites sur la fonction sort pour accroître ses fonctionnalités, comme le tri inversé, hiérarchique (avec tri sur plusieurs champs), un tri sur une partie seulement d'une série, un tri permettant aux items "égaux" de ne pas être permutés durant le tri, et la possibilité de spécifier plus facilement des critères de tri (sans l'assistance d'une fonction de comparaison dédiée).

La nouvelle fonction sort présente une compatibilité ascendante complète avec l'ancienne.

7.1.1 Terminologie

 Enregistrementun simple item logique dans la série à trier. Habituellement, un caractère si la série est un chaîne de caractères, ou une valeur si la série est un bloc. Si le raffinement /skip est utilisé, alors un enregistrement consiste en un ensemble de plusieurs éléments consécutifs dans la série.
 Champune partie d'un enregistrement. Avec le raffinement /skip et une longueur de saut égale à n éléments, un champ est un élément sur n dans l'enregistrement. Si le raffinement /skip n'est pas utilisé et que la série à trier est un bloc qui contient des sous-blocs, alors un champ est un élément d'un sous-bloc (PAS le sous-bloc complet). Ceci permet de trier des éléments dans des blocs. Dans tous les autres cas, un champ est identique à un enregistrement (chaque enregistrement a exactement un seul champ).
 Offset du champun entier spécifiant la position d'un champ dans un enregistrement. Pour un enregistrement, consistant en n champs, l'offset peut donc varier entre 1 et n.

7.1.2 Arguments

En plus aux séries à trier, la nouvelle fonction sort accepte les raffinements suivants. Un nouveau comportement est marqué avec : [NOUVEAU].

 /caseTri sensible à la casse des caractères. Ce raffinement a uniquement un effet sur les champs de type chaînes ou caractères.
 /skip sizeTraite la série comme une suite d'enregistrements de taille fixe. La variable size est de type integer!.
 /allUtilisée en combinaison avec le raffinement /skip. [NOUVEAU] Par défaut, seul un champ unique dans un enregistrement est utilisé pour une comparaison. Si le raffinement /all est utilisé, alors tous les champs dans un enregistrement sont utilisés pour la comparaison.
 /compare comparatorSpécifie un comparateur particulier. Ce peut être un offset de champ (type integer! [NOUVEAU]), une fonction de comparaison, ou un bloc [NOUVEAU]. Voir ci-dessous.
 /reverseTri inversé. [NOUVEAU]
 /part sizeTri sur une partie seulement d'une série. (identique dans son usage au raffinement /part des fonctions copy ou change [NOUVEAU]).

7.1.3 Comparateurs

Le tri est effectué en comparant et en permutant des éléments, des comparateurs fournissant l'ordre de tri. Les comparateurs suivants sont admis :

  • Aucun comparateur (pas de raffinement /compare) :
    Dans ce cas, le premier champ dans chaque enregistrement est utilisé pour la comparaison. Si le raffinement /all est utilisé, alors tous les champs dans chaque enregistrement sont utilisés pour la comparaison. Les raffinements /case et /reverse marchent normalement.
  • Offset de champ (integer!) [NOUVEAU].
    Spécifie le champ à utiliser pour la comparaison. Si le raffinement /all est utilisé, alors le champ spécifié est le premier champ à utiliser, et tous les champs qui suivent sont aussi utilisés. Les raffinements /case et /reverse marchent normalement.
  • Fonction
    Une fonction appelée lors du tri pour comparer deux enregistrements. Les enregistrements sont passés en arguments à la fonction, et la fonction doit retourner -1,0 ou 1, si le premier enregistrement est plus petit, égal ou plus grand que le second enregistrement, respectivement. [NOUVEAU] Pour garder une compatibilité ascendante, la fonction peut renvoyer true ou false, où true indique que le premier enregistrement est plus petit ou égal au second, et false indique que le premier enregistrement est plus grand que le second. Le raffinement /case est ignoré. Le raffinement /reverse fonctionne normalement (inversion du sens de comparaison pour la fonction). Si la raffinement /skip est utilisé, alors l'argument passé à la fonction de comparaison est seulement le premier champ dans l'enregistrement, pas l'enregistrement complet. Ceci pour garder une compatibilité ascendante avec l'ancienne fonction sort. Afin de passer un enregistrement complet, dans un bloc, utilisez le raffinement /all.
  • Bloc [NOUVEAU].
    Un dialecte pour effectuer une comparaison, qui précise le type de comparaison dans les détails. Voir ci-dessous.

Raffinements pour la comparaison :

Les items suivants peuvent apparaître dans un bloc de comparaison :

 Offset de champ (integer!)spécifie la position suivante du champ à comparer. Les champs sont comparés dans l'ordre indiqué.
 reverse (word!)Inverse par la suite la comparaison pour tous les champs spécifiés.
 forward (word!)Définit la comparaison pour tous les champs spécifiés dans le sens normal (opposé à reverse).
 case (word!)rend la comparaison sensible à la casse pour tous les champs spécifiés par la suite.
 no-case (word!)rend la comparaison insensible à la casse pour tous les champs spécifiés par la suite.(opposé de case).
 to (word!) offset champ (integer!)Indique un éventail de champs à comparer, par exemple [1 to 5] compare les champs 1 à 5.

Avec des blocs pour la comparaison, les raffinements /all, /case et /reverse voient leur comportements se modifier légèrement : /all revient à aller "au max-field" (jusqu'au dernier champ) à la fin du bloc , c'est-à-dire que lorsque la fin du bloc de comparaison est atteinte, la comparaison se poursuit jusqu'à ce que la fin de l'enregistrement soit atteinte. Le raffinement /case spécifie le mode par défaut (jusqu'à ce que les mots case ou no-case soient rencontrés), c'est-à-dire : sensible à la casse. Dans le cas contraire, la comparaison est insensible à la casse. Le raffinement /reverse inverse complément la liste résultante, et est indépendante des mots reverse/forward dans le bloc de comparaison.

Examples

a: [10 "Smith" "Larry" 20 "Smith" "Joe" 80 "Brown" "Harry" 50 "Wood" "Jim"]

sort/skip a 3     ; sorts on the first field (number)
[10 "Smith" "Larry" 20 "Smith" "Joe" 50 "Wood" "Jim" 80 "Brown" "Harry"]
sort/skip/compare a 3 2     ; sorts on the second field (last name)
[80 "Brown" "Harry" 10 "Smith" "Larry" 20 "Smith" "Joe" 50 "Wood" "Jim"]
sort/skip/compare/all a 3 2  
; sorts on the second field and following fields (last name and first name)
[80 "Brown" "Harry" 20 "Smith" "Joe" 10 "Smith" "Larry" 50 "Wood" "Jim"]
sort/skip/reverse a 3     ; sorts on the first field (number), in reverse
[80 "Brown" "Harry" 50 "Wood" "Jim" 20 "Smith" "Joe" 10 "Smith" "Larry"]
sort/skip/compare a 3 [2 reverse 3]
; sorts on the last name forward, and the first name in reverse
[80 "Brown" "Harry" 10 "Smith" "Larry" 20 "Smith" "Joe" 50 "Wood" "Jim"]

6.2 Modes des fichier

Les fonctions get-modes et set-modes ont été rajoutées pour les ports file et network.

 get-modesretourne les modes en cours pour un port ouvert
 set-modesmodifie les modes d'un port ouvert

La fonction get-modes possède la syntaxe suivante :

get-modes: native [
    {Return mode settings for a port}
    target [file! url! block! port!]
    modes [word! block!]
]

le bloc qui doit être passé en argument consiste en des mots définissant les modes pour lesquels on veut connaître l'état.

Chaque mot correspond à un mode. La fonction get-modes renvoie un bloc qui contient des paires de valeurs : le nom du mode et la valeur du paramétrage courant du mode.

Exemple:

>> get-modes someport [direct binary]
== [direct: true binary: false]

indique que le port someport est ouvert en mode direct et non binaire, c'est-à-dire en mode texte.

Il est aussi possible de donner en argument uniquement un mot, pour lequel get-modes va renvoyer la valeur directement, sans passer par un bloc du type [nom: valeur].

Exemple:

>> get-modes someport 'binary
== false

Une autre manière est de fournir en argument un bloc de paires noms-valeurs, dans le même format que celui renvoyé par get-modes. Dans ce cas, les valeurs (dans l'exemple ci-dessous, elles sont à none) sont ignorées.

Exemple:

>> get-modes someport [direct: none binary: none] == [direct: true binary: false]

La fonction set-modes possède la syntaxe suivante :

set-modes: native [
    {Change mode settings for a port}
    target [file! url! block! port!]
    modes [block!]
]

Le bloc passé en argument est composé de paires noms-valeurs décrivant les modes à changer. Un bloc renvoyé par la fonction get-modes peut être fourni en argument à la fonction set-modes.

La fonction set-modes renvoie le port qui lui est passé en argument.

Exemple:

>> set-modes someport [direct: false binary: false]

Le bloc accepté par set-modes est actuellement un bloc qui peut permettre une instanciation et une initialisation multiple :

Exemple:

>> set-modes someport [direct: binary: false]

7.1.4 Récupérer les listes de modes

La fonction get-modes supporte quelques modes un peu "spéciaux", qui ne renvoient pas les paramétrages du mode pour un port spécifique, mais plutôt un jeu de modes qui sont applicables pour un fichier (ou un répertoire, une socket, etc.) Ce sont les "file-modes", "copy-modes", "network-modes" et "port-modes". Si certains de ces modes sont spécifiés dans une requête get-modes, alors la réponse sera un bloc contenant les modes possibles pour le port, sur le système courant.

>> get-modes somefileordir 'port-modes
== [direct binary lines no-wait (...etc...) ]

>> get-modes somefileordir 'file-modes
== [file-note creation-date archived script (...etc...) ]

>> get-modes someudpsocket 'network-modes
== [broadcast multicast-groups type-of-service]

L'exemple ci-dessus est valable pour un Amiga.

Notez que le bloc renvoyé pour l'une ou l'autre des ces requêtes spéciales est identique pour tous les fichiers et répertoires au sein du système de fichiers (et pour toutes les sockets dans un "scheme", comme tcp, udp), mais il peut être différent par plate-forme et sans doute par systèmes de fichiers et "schemes", mais pas par fichiers ou sockets.

L'objet de ces fonctions et de ces modes spéciaux est de fournir un mécanisme pour obtenir la liste des modes supportés, pas d'obtenir les paramètres courants d'un mode.

Pour obtenir les paramètres courants d'un port, le bloc renvoyé par get-modes (qui permet de lister les modes possibles) doit être fourni à la fonction get-modes (donc deux appels de cette fonction), comme dans l'exemple :

>> get-modes somefileordir get-modes somefileordir 'file-modes
== [file-note: "cool graphics" creation-date: 1-Jan-2000 
    archived: true script: false]

La différence entre "file-modes" et "copy-modes" est :

 file-modesrenvoie tous les modes de l'élément sur lequel il s'applique (typiquement un fichier) sans tenir compte de comment il a été ouvert.
 copy-modesidentique à file-modes, mais renvoie seulement les modes qui sont sans danger pour la copie, par exemple qui devraient être inclus dans un appel set-modes lors de la création d'un nouveau fichier, pour créer un clone exact d'un fichier existant. Si une plate-forme fournit des propriétés de fichiers qui sont dangereux pour la copie, ou qui sont nécessairement variables sur des copies de fichiers (ex.: les inodes Unix), alors ces modes devraient apparaître dans le bloc retourné avec files-modes, mais pas avec copy-modes.

Dupliquer toutes les propriétés du fichier file1 vers le fichier file2 peut être fait avec la ligne suivante :

>> set-modes file2 get-modes file1 get-modes file1 'copy-modes

7.1.5 Modes possibles

File-modes

  • status-change-date, modification-date, access-date, backup-date, creation-date : une date REBOL. Modification-date est valable sur toutes plate-formes. status-change-date est valable sur Unix. Access-date est valable sur Unix et Windows. Creation-date est valable sur Windows et MacOS. Backup-date est valable sur MacOS. Tous les modes fonctionnent avec get-modes et set-modes, sauf modification-date et access-date qui ne sont pas définissables pour Elate.
  • owner-name, group-name: une chaîne de caractères REBOL (nom utilisateur/groupe ). Valable pour Unix. owner-id, group-id: un entier REBOL (id utilisateur/groupe). Valable pour Unix et AmigaOS (>=V39). owner-read, owner-write, owner-delete, owner-execute, group-read, group-write, group-delete, group-execute, world-read, world-write, world-delete, world-execute : une valeur logique REBOL. Tous les modes -read, -write and -execute modes sont valables pour Unix , BeOS, QNX et Elate. owner-read, owner-write, owner-execute et owner-delete sont valables en AmigaOS. Tous les modes group- et world- sont valables en AmigaOS >=V39. owner-write est aussi valable en Windows (mappé sur l'inverse de l'octet pour Windows "read-only").
  • comment : une chaîne de caractères REBOL (le commentaire du fichier). Valable en AmigaOS seulement.
  • script, archived, system, hidden, hold, pure : une valeur logique REBOL (flags supplémentaires). Script, hold et pure sont valables en AmigaOS seulement. Archived est valable en AmigaOS et Windows. System et hidden sont valables sous Windows seulement.
  • type, creator: une chaîne de caractères REBOL. Valables en MacOS uniquement.

Les plate-formes qui autorisent seulement une unique date pour un fichier l'exportent via l'item "modification-date". Pareillement, les plate-formes qui ne supportent pas les modes d'accès multi-utilisateurs fournissent les modes possibles pour l'accès aux fichiers via owner-read/write/delete/execute.

Port-modes

read, write, binary, lines, no-wait, direct : une valeur logique REBOL. Binary, lines et no-wait peuvent être définies.

Network-modes

  • broadcast : une valeur logique REBOL. UDP uniquement. Mettre cette valeur à true permet d'envoyer en broadcast depuis une socket. Toutes plate-formes sauf BeOS.
  • multicast-groups : un bloc de blocs REBOL. UDP uniquement, décrit quels groupes une socket a touché en multicast. Chaque sous-bloc consiste en deux adresses IP (tuples) : le groupe de multicast et l'adresse IP de l'interface sur laquelle le groupe de multicast a été atteint. Typiquement valable en MacOS, Windows, la plupart des plate-formes Unix, QNX et AmigaOS (uniquement Miami/MiamiDx). L'accessibilité est déterminée en fonctionnement et varie selon la version de l'OS et celle de la pile TCP/IP.
  • type-of-service : un nombre entier REBOL. UDP et TCP. C'est la valeur sur 8 octets du champ "TOS" dans les en-têtes IP. Les valeurs typiques sont 0 (défaut), 2 (minimise la latence), 4 (améliore l'accessibilité), 8 (maximise le débit), et 16 (minimise la latence), mais l'interprétation de ce champ est propre à la pile TCP/IP et aux routeurs intermédaires, elle n'est pas imposée par REBOL. Toutes plate-formes exceptées BeOS.
  • keep-alive : une valeur logique REBOL. TCP uniquement. Définir cette valeur à true force TCP à émettre des paquets "keep-alive" après un certain temps d'inactivité (typiquement 4 heures). Toutes plate-formes exceptées BeOS.
  • receive-buffer-size, send-buffer-size : un nombre entier REBOL. UDP et TCP. Taille du buffer pour l'émission et la réception dans la pile TCP/IP. Les valeurs et l'éventail possible varient énormément selon la plate-forme. Principalement utilisé pour UDP. Augmenter ces valeurs n'améliore PAS les performances. Toutes plate-formes exceptées BeOS.
  • multicast-interface : une chaîne de caractère REBOL. UDP uniquement. L'interface par défaut à utiliser pour le multicasting. Plate-formes identiques à celles pour multicast-groups.
  • multicast-ttl : un nombre entier REBOL. UDP uniquement. La valeur de "time-to-live" (distance de propagation maximale) des multicasts. Plate-formes identiques à celles pour multicast-groups.
  • multicast-loopback : une valeur logique REBOL. UDP uniquement. Si cette valeur est à true, l'envoi en multicast est en local (loopback). Plate-formes identiques à celles pour multicast-groups.
  • no-delay : une valeur logique REBOL. TCP uniquement. Désactive l'algorithme de Nagle. La plupart des protocoles fonctionnent mieux si cette valeur est à false. Elle devrait uniquement être à true si le protocole est interactif ET relié à des événements précis combinés avec des temporisations. (ex. X11). Toutes plate-formes exceptées BeOS.
  • interfaces : un bloc d'objets REBOL. Chaque objet représente une interface réseau et contient actuellement les champs suivants : "name": nom de l'interface (sur certaines plate-formes, c'est un nom idiot). "address": l'adresse IP locale. "netmask": masque de sous-réseau. "broadcast": addresse de broadcast. "remote-address": adresse IP distante pour la connexion point-à-point. "flags": un bloc de mots décrivant les propriétés de l'interface, les mots actuellement supportés sont : "broadcast" (l'interface supporte le broadcasting), "multicast" (l'interface supporte le multicasting), "loopback" (l'interface est l'interface de loopback) et "point-to-point" (l'interface est une interface point-à-point, le contraire d'une interface "multi-drop"). Certaines valeurs peuvent être à none (ex. : "remote-address" sur une interface multi-drop). Avec Windows, toutes les interfaces apparaissent comme des interfaces multi-drop (PPP inclus), avec des masques de réseau idiots. Valable pour toutes plate-formes, exceptées BeOS, Elate, WinCE. Non définissable.

7.1.6 Utilisation des ressources fichier

Le raffinement /custom pour les fonctions read, open et write permet d'accéder à différentes ressources d'un fichier. (actuellement pour MacOS uniquement).

open/custom %myfile [fork "name"] ; Specify which fork to open.

La ressource spécifiée "name" définit quelle ressource ouvrir.

Si aucune ressource n'est spécifiée (pas de spécification pour fork dans le bloc en argument ou la valeur none au lieu de "name"), alors pour les plate-formes non Mac, le fichier est ouvert normalement. Pour Mac, la ressource est ouverte. Si le raffinement /new est utilisé, alors la taille du fichier est remise à zéro octets. (Note : ce comportement a été modifié depuis Core 2.3. Auparavant, open/new sur Macintosh remettait seulement à zéro la taille des données, et il n'y avait pas de moyens d'effacer la taille de la ressource. ) Si une ressource est spécifiée par son nom, alors elle est ouverte. Si le raffinement /new est utilisé, alors la taille de la ressource demandée est mise à zéro octets. Si la ressource n'existe pas (ou pour les accès en écriture, ne peut être créée) sur la plate-forme courante, une erreur est retournée. Les plate-formes non-Mac possèdent uniquement une seule ressource "data". Les plate-formes Mac ont deux ressources, nommées "data" et "ressource".

7.1.7 Déterminer toutes les ressources

Ceci est fait en utilisant le mécanisme des modes, de façon à trouver tous les modes supportés : L'exemple ci-dessous est valable pour Mac.

>> get-modes somefile 'forks
== ["data" "resource"]

Pour les autres plate-formes, le résultat retourné serait seulement ["data"].

7.2 Accès au Port Série

Ce paragraphe décrit la création et l'usage des ports de communication série avec REBOL. Les ports série sont supportés depuis la version 2.3, mais n'étaient pas documentés.

7.2.1 Spécifier un port Série

Les ports série sont créés de la même manière que d'autres ports avec REBOL. Le nom du "scheme" pour les ports série est "serial". Les URLs sont encodés avec les différents champs séparés par le symbole slash. Par exemple :

port: open serial://port1/9600/8/none/1

L'ordre des valeurs dans l'URL d'un scheme serial, n'est pas important, le type de champ peut être déterminé par le contenu. (Notez que vous pouvez aussi utiliser la fonction make sur un objet port plutôt qu'une URL, pour spécifier un port série.)

La spécification d'un port série peut inclure le numéro du périphérique, la vitesse de communication, le nombre de bits de données, la parité et le nombre de bits de stop. Ces informations peuvent être spécifiées directement en affectant les champs appropriés dans la définition d'un objet port, ou via la création d'une URL contenant ces informations. Si un champ n'est pas défini, une valeur par défaut sera prise pour ce champ.

Les paramètres par défaut pour les ports série sont :

device: port1
speed: 9600
data-bits: 8
parity: none
stop-bits: 1

Au sein de la spécification du port, les divers paramètres sont stockés dans les champs suivants de l'objet :

host:           périphérique
speed:          vitesse
data-bits:      bits de data 
parity:         parité
stop-bits:      bits de stop

Le spécification du portN (ex. port1) est une référence indirecte au périphérique de communication. Il fait référence au Niéme périphérique défini dans le bloc system/ports/serial.

Ce bloc est initialisé par défaut selon ce que le système utilise, et peut être modifié via le fichier user.r pour refléter les conditions locales. Par exemple, avec Windows, le bloc pourrait être défini ainsi :

system/ports/serial: [ com1 com2 ]

ou, si COM1 est utilisé par la souris, ce pourrait être juste :

system/ports/serial: [ com2 ]

Sur les système de type Unix, le bloc pourrait être :

system/ports/serial: [ ttyS0 ttyS1 ]

ou, si le premier périphérique devait correspondre à COM2 :

system/ports/serial: [ ttyS1 ttyS0 ]

Ainsi, les ports peuvent être définis de manière indépendante du type de machine, tandis que la définition propre à la machine peut être contrôlée en utilisant le bloc system/ports/serial.

7.2.2 Opérations

Les ports séries sont toujours ouverts en mode direct (direct port) tout comme peuvent l'être la console et les ports réseau.

Ils devraient être ouverts soit avec open/string (par défaut) ou open/binary.

Ils sont par défaut ouvert en mode asynchrone, mais peuvent être rendus synchrone en utilisant le raffinement /wait.

En fonctionnement asynchrone, toute tentative de copier des données provenant du port renverra none, si aucune donnée n'est présente.

En mode synchrone, la copie est une action bloquante, tant qu'aucune donnée n'est présente.

Les données peuvent être écrites dans le port en utilisant la fonction native insert. Les données peuvent aussi être lues avec les fonctions pick, first ou copy et leurs raffinements habituels. Comme pour les autres types de ports, en mode direct, les fonctions remove, clear, change et find ne sont pas supportées.

La fonction update peut être utilisée pour modifier les paramètres du port. Par exemple, pour changer la vitesse après qu'une connexion initiale ait été établie, vous auriez juste à faire :

ser-port: open serial://9600
ser-port/speed: 2400
update ser-port

Modifier le numéro de périphérique ou system/ports/serial, puis appeler update ne devrait pas avoir d'effet. Une fois que le port a été ouvert avec un périphérique particulier, le périphérique ne peut être changé.

Il y a deux champs supplémentaires pour le port qui ne peuvent être définis via l'URL, mais peuvent être spécifiés dans le bloc de spécification du port, ou modifiés manuellement.

Le champ rts-cts spécifie si le mécanisme de réservation du média doit être utilisé sur le port. Par défaut, ce champ est sur on. Pour changer cette valeur :

ser-port/rts-cts: off
update ser-port

Une valeur de time-out peut être spécifiée en modifiant le champ timeout dans la spécification du port. La valeur de time-out s'applique uniquement sur les ports séries qui ont été ouverts avec le raffinement /wait (NdT : donc en synchrone, pour ceux qui suivent). Lorsque le time-out expire, une erreur de time-out est générée pour le port.

Pour définir la valeur du time-out, faites :

ser-port/timeout: 10        ; 10 secondes de timeout

Les ports séries fonctionnent correctement avec la fonction wait.

7.3 Objets

  • Ajout de l'objet system/locale.
    Les noms des mois et des jours sont couramment utilisés. Les jours de la semaine sont des chaînes à part dans system/locale/days et les noms des mois sont des chaînes dans system/locale/months.
>> probe system/locale
make object! [
    months: [
    "January" "February" "March" "April" "May" "June"
    "July" "August" "September" "October" "November" "December"
    ]
    days: [
    "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sunday"
    ]
]
  • Ajout de la fonction context pour faire un raccourci de : make object!.
  • Vous pouvez à présent utilisez query sur un objet. La fonction query renverra un bloc contenant les champs d'un objet qui ont été modifiés depuis sa création ou depuis le précédent appel de query/clear. La fonction query renvoie none si rien n'a été modifié. Query/clear effacera le statut "modifié" de tous les champs dans un objet.
  • Les objets acceptent des valeurs logiques (logic!) comme arguments pour un choix (pour être cohérent avec les blocs).

7.3.1 Make Object Object

Maintenant, vous pouvez faire un objet à partir de deux autres : un objet modèle (template object) et un objet de spécification (spec object). Lorsque vous réalisez un objet à partir de deux autres, les mots partagés à la fois par l'objet modèle et l'objet de spécification prennent leurs valeurs à partir de ce dernier. Ceci induit quelques différences dans le comportement, car l'approche est lexicale via l'objet template, et par définition, via l'objet spec.

7.3.2 Usage de third sur un objet

Vous pouvez utiliser third sur un objet afin de récupérer un bloc de paires variables-valeurs relatives à l'objet :

z: make object! [a: 99 b: does [a + 1]]
t: third z
== [a: 99 b: func [][a + 1]]

Le bloc renvoyé par la fonction third est comme un bloc de spécification, cependant les mots qui y sont définis sont liés à leur objet. Ce bloc est comme un cliché des valeurs de l'objet à un moment donné. Vous pouvez aussi utiliser le bloc renvoyé par third pour définir les valeurs de l'objet :

set first t 199     ; "first t" correspond à "a:", donc ici a: 199
z/b                 ;  on appelle la méthode b de l'objet
== 200

7.4 Changements pour mold et load

  • La fonction mold avec son raffinement /only ne produit pas le retour [] le plus extérieur dans la chaîne résultante.
  • L'usage de mold sur un bloc récursif ou un objet affichera [...] pour la seconde instance de l'élément. De sorte que vous pouvez maintenant faire un print mold system !
  • Les chaînes de plus de 50 caractères contenant des caractères "{" non appariés sont maintenant rechargeables.
  • Ajout du raffinement /all à la fonction load. L'appel de load/all sur un script n'évalue plus l'en-tête REBOL. Load/all renvoie toujours un bloc.
  • load/next/header renvoie un bloc avec l'en-tête (header) évalué suivi par le reste du script sous forme d'une chaîne.
  • Le chargement de script avec des caractères de contrôle supérieurs à CTRL-Z (hex 1C et plus) est maintenant possible.
  • Ajout du champ header/content. Lorsque ce champ est à true, le code source du script peut être consulté avec system/script/header/content (évaluation avec DO) ou depuis l'objet header (lorsque le script est chargé avec load/header ou load/next/header). Cela permet à votre script d'accéder à des données qui sont incluses en lui (comme le format de l'archive REBOL, RIP).

Combinaisons des raffinements pour la fonction LOAD :

LOAD/raffinement

Évaluation de l'en-tête ?

Retourne

load

oui

renvoie le script (donnée). Si le fichier contient une valeur unique (comme 1234), alors c'est juste cette valeur qui est renvoyée. Si il y a plusieurs valeurs, alors c'est un bloc qui est renvoyé.

load/next

non

[first-val { reste du script }] -- renvoie une valeur suivie par une chaîne. Ce raffinement permet d'analyser (parser) les fichiers REBOL, une valeur à la fois.

load/next/header

oui

[header-obj { reste du script } ] -- idem load/next mais inclut l'objet header évalué.

load/header

oui

[header-obj { reste du script } ] -- renvoie le script, avec l'en-tête (header) REBOL comme première valeur.

load/all

no

[tout le script] -- renvoie le script, toujours sous forme de bloc, même s'il contient une seule valeur (très pratique dans les cas où vous voulez toujours utiliser un bloc pour vos datas, même en cas de valeur unique).

load/next/all

no

[first-val { reste du script }]

" "

load/header/all

oui

[header-obj reste du script]

load/next/header/all

oui

[header-obj {rest of script}]

Le raffinement /all sera ignoré si d'autres raffinements sont présents.

7.5 Changements sur File et Port

Ajout d'un mode asynchrone pour le protocole DNS pour Unix et Windows. Par exemple : open dns:///async, puis insert/wait/copy.

  • Support de l'HTTP asynchrone. Vous pouvez faire une requête avec open/direct/no-wait et utilisez wait et copy pour recevoir les datas au fur et à mesure qu'elles arrivent.
  • wait [0 port] renvoie à présent le port s'il n'y a des datas, et none sinon.
  • Ajout d'un raffinement wait/all, qui conduit la fonction wait à renvoyer en résultat un bloc de tous les ports ayant des datas.
  • Le raffinement /no-wait permet l'ouverture d'un port en mode non bloquant.
  • copy sur un port non bloquant renvoie une chaîne vide à moins que la fin du port ait été atteinte, auquel cas, none est renvoyé.
  • wait supporte à présent les handlers (http, tcp etc.) en mode /direct.
  • Ajout d'un champ awake dans les spécifications de port et dans l'objet root-protocol pour spécifier un bloc ou une fonction à appeler quand la fonction wait est sur le point d'être réveillée, activée. Utilisé pour implémenter un processus en tâche de fond.
  • wait fonctionne correctement sur les ports en mode /lines qui ont été ouverts sans le raffinement /with.
  • Les fonctions to-local-file et to-rebol-file peuvent être utilisées pour la conversion de paths depuis et vers le format local de votre système d'exploitation.
  • Ajout des champs local-port, remote-ip et remote-port pour les spécifications de ports afin d'avoir des valeurs indépendantes de la création du port.
  • make-dir/deep permet la création de tous les répertoires nécessaires dans une arborescence complexe (long path).
  • connected? est native pour la plupart des plate-formes.
  • Correction d'une affection incorrecte pour port-id
  • Correction d'un bogue qui évite aux sockets UDP en état "listen" de répondre aux paquets de diverses origines.
  • split-path a été modifiée pour séparer correctement le chemin (path) de la cible (target) dans un chemin de fichier.

7.6 Changement dans les protocoles réseau (APOP, IMAP)

  • Ajout de l'authentification pour pop:// (APOP) qui n'envoie plus le mot de passe en clair à un serveur.
  • Ajout du protocole imap:// . Le format des URLs et le comportement URL est identique à pop://, avec en plus des formats d'URLs supplémentaires comme mentionné dans la RFC 2192.
  • Correction de send lorsque le raffinement /header (mais pas l'adresse FROM) est donné.
  • Correction de do-send pour modifier les lignes d'un courrier électronique ayant uniquement un "." de façon à avoir deux points.(bogue sur courrier)

7.7 Changements pour les Séries

  • Les type de données hash! et list! permettent à présent des opérations plus complètes, cohérentes, sérieuses et rapides.
  • Les fonctions select, find, union, intersect, exclude, difference, et unique acceptent un raffinement /skip pour délimiter des données d'une certaine taille.
  • unique accepte le raffinement /case
  • La fonction to-binary appliquée sur des tuples utilise à présent des valeurs de tuples au lieu de fabriquer un tuple.
  • La fonction join sur des valeurs binaires n'utilise plus des chaînes de caractères et un appel à form, mais des valeurs binaires.
  • find permet de fonctionner sur tous les types de fonctions correctement.
  • find/reverse fonctionne avec des bitsets.
  • Correction de pick vis-à-vis de son usage avec des objets ou des fonctions et un nombre négatif.
  • Correction d'un bogue dans la fonction enbase qui faisait que des caractères invalides pouvaient être insérés dans une chaîne encodée en base 64.
  • Suppression du raffinement /only pour la fonction difference (exclude est équivalent).
  • minimum-of et maximum-of pour les series. Vous pouvez utiliser minimum-of et maximum-of sur un argument unique de type série pour récupérer respectivement la plus petite ou la plus grande valeur contenue dans la série.
minimum-of reduce [pi .099 10 * 100]
== [0.099 1000]
maximum-of reduce [pi .099 10 * 100]
== [1000]

7.8 Changements relatifs aux fonctions Mathématiques

  • Ajout de checksum/secure et random/secure, qui produisent respectivement une checksum et des nombres aléatoires cryptés.
  • Ajout de checksum/hash et checksum/method (identique à checksum/secure, mais avec choix possible d'algorithmes : 'md5 or 'sha1), et de checksum/key (calcule le "digest message"). MD5 a été ajouté en tant que méthode de cryptage.
  • Correction un bogue portant sur les soustraction des mois avec des valeurs de type date!
  • Les valeurs de type time! peuvent être converties en nombres entiers et décimaux.
  • now/precise fournit une meilleure précision sur l'heure. Pratique pour les événements et temporisations.

7.9 Changements pour la ligne de commande

  • Le démarrage de REBOL en ligne de commande autorise à présent "--" pour signaler la fin de options de démarrage. Les éléments restants sur la ligne de commande sont des arguments à passer au script REBOL. Cela permet à REBOL de démarrer sans appel à un script, mais avec un passage d'arguments.
  • En démarrant à partir de la ligne de commande, on a : system/script/args qui contient une chaîne de caractères comprenant tous les arguments, et system/options/args qui est un bloc où les éléments sont les arguments.
  • Tous les items qui suivent la spécification d'un script sont considérés comme des arguments. REBOL travaille maintenant avec un nombre arbitraire d'arguments en ligne de commande (pas de taille fixe).

7.10 Console

  • Avec la touche "tabulation", il est possible de compléter autant que possible les mots ou les chemins de fichiers.
  • Ajout d'un code de réinitialisation propre pour la console, pour les cas où REBOL est relancé après un CTRL-Z suivi par "fg" (foreground, pour Unix et les shells).
  • L'auto-complétion sur un nom de fichier est maintenant insensible à la casse pour les systèmes d'exploitation qui n'y sont pas sensibles (Windows, AmigaOS, etc.) L'écran peut à présent être effacé au premier item affiché à la console, pas au message d'accueil.

7.11 Contrôles

  • L'usage de break dans le premier bloc de while provoque une sortie de la boucle.
  • catch et throw ont été améliorées.
  • foreach renvoie une valeur correcte pour des séries vides.

7.12 Interpréteur

  • La vitesse pour le "binding" a été fortement améliorée pour les mots "top-level".
  • Extension imprécise corrigées pour de nombreux cas (fonction use).

7.13 Autres changements

  • Ajout d'une fonction has pour définir un raccourci afin de définir des fonctions ayant des variables locales, mais aucun argument.
  • Correction de la fonction confirm pour tracer les erreurs dans le cas d'une mauvaise sélection.

8. Correction relatives à l'interpréteur

Les problèmes internes suivants ont été revus :

  • Amélioration des Séries : de meilleures performances et la résolution de problème de mémoire ont été obtenues, d'où des gains très importants en vitesse pour certains usages. Ce changement augmente la réactivité de mold et save de plusieurs ordres de grandeurs.
  • La comparaison avec des datas lit-path! fonctionne correctement.
  • Correction d'un bogue concernant le fuseau horaire pour des comparaisons de dates.
  • Gestion des arguments en ligne de commande avec "--"
  • La touche TAB (tabulation) permet de compléter les mots en console.
  • Les numéros de version des composants ont été rajoutés au message d'accueil (boot).
  • Le nombre maximum de mots globaux a été porté à 8000.
  • Correction d'un crash potentiel liés aux valeurs de type hash! (recyclage et agrandissement)
  • Correction d'un crash potentiel lors du recyclage d'un port ouvert ou non référencé.
  • Suppression d'un port et fermeture dans un ordre correct

9. Corrections propres au réseau

Les corrections suivantes ont été faites pour la partie réseau :

  • DNS - Unix uniquement : correction d'un blocage quand un processus DNS (assistant) s'arrête de façon inattendue.
  • DNS - Unix only: un processus DNS ne reste pas l'état de "zombie" si le processus principal est supprimé (kill).
  • FTP - Résolution d'un confit avec le proxy generic.
  • FTP - autorise plus de code retours pour la commande CWD
  • HTTP - ajout de l'authentification pour un proxy
  • HTTP - méthode POST, conversion des changements de ligne corrigée
  • HTTP - correction de l'envoi lorsque le nom d'hôte dans l'en-tête n'a pas mis à jour
  • POP - utilise APOP si port/algorithm est défini à 'apop (solution de contournement d'un bogue pour quelques serveurs POP).
  • TCP - pour Windows seulement : Les sockets TCP en écoute (listen) n'admettent plus plusieurs listeners sur le même port. Solution de contournement pour SO_REUSEADDR dans la pile Windows TCP/IP.

10. Autres corrections (Fonction)

Les corrections sur les fonctions natives ou non comprennent :

  • compress/decompress - les offsets pour les séries sont maintenant possibles
  • debase - crash potentiel corrigé
  • debase - les offsets pour les séries sont maintenant possibles
  • find - quand on utilise un biset avec des caractères supérieurs à 127
  • find/match/case - corrigé
  • load/markup - crash potentiel corrigé
  • make - crash potentiel avec make object! object! corrigé
  • make-dir/deep - bogue corrigé
  • set-modes - correction relative aux dates de fichiers si aucune valeur de temps n'est fournie.
  • sort - crash potentiel fixé et manipulation des hashs
  • union, intersect, etc. - les offsets pour les séries sont maintenant possibles en deuxième argument

11. résumé des nouveautés dans la v. 2.3

La liste suivante donne un résumé des nouveautés dans REBOL/Core 2.3:

  • raffinement load/markup - renvoie un bloc de balises et de textes
  • fonction repend - usage de reduce avant append
  • replace/case - permet des remplacements sensible à la casse
  • fonction ?? - impression d'information
  • fonction to-pair - transforme diverses valeurs en une de type pair!
  • datatype pair! - nouveau datatype pour représenter les vecteurs et coordonnées
  • fonction offset? - renvoie l'offset entre deux positions de séries
  • fonction does - raccourci pour créer des fonctions sans argument
  • fonction unique - renvoie une série où les doublons ont été supprimés
  • fonctions qui acceptent pair! - beaucoup de fonctions existantes acceptent à présent le type de données pair!
  • raffinement make-dir/deep - permet la création des répertoires dans une arborescence complexe

12. résumé des améliorations dans la v.2.3

La liste suivante montre le résumé des améliorations apportées aux fonctions existantes et aux objets globaux dans REBOL/Core 2.3:

  • fonction help - l'information est formatée différemment. L'aide peut à présent permettre des recherches dans la documentation interne (ex. fonctions).
  • http user-agent - L'agent Http permet de définir à présent le http-user-agent
  • retour value/selector - renvoie la valeur définie, pas la valeur consolidée
  • fonction random - peut à présent s'employer avec des valeurs négatives et des tuples
  • system/options/path - indique le répertoire dans lequel se trouve le script REBOL en cours d'exécution
  • fonction what - modification de la façon dont les fonctions sont listées; elles sont triées maintenant
  • build-tag - accepte un plus grand éventail de valeurs
  • parse - pour analyser les blocs et les chaînes
  • fonctions if, any et all - la valeur de retour "false" est modifiée en "none"
  • agent (handler) pop - contient des informations sur la taille des messages
  • and, or, xor - and, or, et xor peuvent utiliser le type binary!. Le binaire résultant sera aussi long que le plus long des deux arguments binaires. Les opérations utilisent l'offset des valeurs binaires pour déterminer où démarrer.
  • fonctions acceptant pair! - beaucoup de fonctions existantes acceptent à présent les valeurs pair!
  • fonction query - modifiée pour permettre de vérifier dans les objets les mots qui ont été changés.
  • load/next - le comportement a été modifié par rapport aux en-têtes de scripts (header)
  • touche tabulation - l'auto-complétion a été changée pour afficher une liste de possibilités lorsque la touche est appuyée deux fois.

13. Synthèse des corrections en v.2.3

La liste suivante indique un résumé des corrections incorporées dans REBOL/Core v.2.3 :

  • fonction to-block - corrigée pour permettre un fonctionnement correct sur les valeurs lit-path!
  • fonction to-word - corrigée pour permettre de convertir correctement des valeurs set-word! en valeurs word!
  • trim/lines - corrigée, enlève tous les espaces
  • Réseau - une opération réseau en cours peut à présent être interrompue avec la touche Escape
  • fonction split-path - corrigée, le plus petit niveau de path est découpé correctement

14. Nouvelles fonctions et nouveaux raffinements en v.2.3

Les fonctions et raffinements suivants sont incorporés dans la version 2.3 de REBOL/Core :

14.1 Type de données Pair

Les pairs sont des données utilisées pour décrire les coordonnées (x, y) d'un point. Ce type de données est couramment utilisé pour décrire des objets graphiques et leurs positions à l'écran, les tailles, etc. Le type de donnée pair! consiste en deux valeurs séparées par un "x" minuscule ou majuscule comme dans 10x20.

Exemple : A: 10x20, définit A comme une valeur de type pair! avec des coordonnées x=10, et y=20. Ces valeurs peuvent être récupérées individuellement en utilisant les raffinements /x et /y comme dans : print A/x qui afficherait la valeur 10.

14.2 Make-dir/deep

L'usage du raffinement /deep avec la fonction make-dir permet de forcer la création des répertoires mentionnés dans un chemin, fourni en argument, mais qui n'existent pas encore.

L'exemple suivant utilise make-dir/deep pour créer une longue arborescence :

probe dir? %/c/abc
false
make-dir/deep %/c/abc/def/ghi/jkl/mno/pqr/stu/vwx/yz/
probe dir? %/c/abc
true
probe dir? %/c/abc/def/ghi/jkl/mno/pqr/stu/vwx/yz/
true

Si make-dir/deep échoue, tous les répertoires créés avant l'erreur seront effacés.

14.3 Unique

La fonction unique accepte en argument une série et renvoie une autre série. Le résultat est une copie de l'argument sans les éventuels doublons.

Voici quelques exemples qui illustrent le comportement de cette fonction :

probe unique "abcabcabc"
"abc"
probe unique [1 2 3 3 2 1 2 3 1]
[1 2 3]

Le raffinement /case peut être utilisé avec la fonction unique pour rendre cette fonction sensible à la casse (minuscules/majuscules).

14.4 Does

Does permet de créer des fonctions qui ne nécessitent pas d'arguments ou de mots locaux.

Par exemple :

get-script-dir: does [probe system/options/path]
probe get-script-dir
%/usr/local/rebol/

14.5 Offset?

La fonction offset? prend deux séries en argument et renvoie l'écart entre leurs deux index.

L'exemple suivant montre l'usage de offset? sur la même série :

colors: ["red" "green" "blue" "yellow" "orange"]
colors-2: skip colors 3
probe offset? colors colors-2
3

L'exemple ci-dessous illustre l'usage d'offset? avec deux séries :

str: "abcdef"
blk: skip [a b c d e f] 4
[e f]
probe offset? str blk
4

14.6 Load/markup

L'utilisation du raffinement /markup sur la fonction load force l'argument (chaîne, fichier ou URL) à être traité comme du texte avec des balises. (les fichiers et les URLs sont enregistrés d'abord comme des chaînes de caractères par load). Toutes les balises trouvées dans l'argument par load/markup seront transformées en valeurs de type tag! et le reste laissé en tant que chaînes. Le résultat de load/markup est un bloc de plusieurs valeurs de type tag! et string!.

L'exemple suivant montre le comportement de load/markup :

probe load/markup {<head> 123 abc <head>}
[<head> { 123 abc  } </head>]

14.7 Repend

La fonction repend est une sorte de raccourci pour "reduce append". Repend prend deux arguments. Le premier est une série. Le second argument est passé à la fonction reduce puis le résultat à la fonction append, qui l'ajoute au premier argument.

Voici quelques exemples avec repend :

a: "AA" b: "BB" c: "CC"
probe repend [] [a b c]
["AA" "BB" "CC"]
probe repend "" [a b c]
"AABBCC"

14.8 Replace/case

La fonction replace possède à présent un raffinement /case qui la rend sensible à la casse. Par défaut, la fonction replace n'est pas sensible à la casse.

Cet exemple illustre l'action de replace sur un bloc sans le raffinement /case :

probe replace/all [A a B b A a B b] 'A 'C
[C C B b C C B b]

Et celui-ci illustre l'usage de replace sur un bloc avec le raffinement /case :

probe replace/all/case [A a B b A a B b] 'A 'C
[C a B b C a B b]

Cet exemple montre replace agissant sur une chaîne sans le raffinement /case :

probe replace/all "ABCabcDEFdefABCabcDEFdef" "abc" "xxx"
"xxxxxxDEFdefxxxxxxDEFdef"

Et ici avec /case :

probe replace/all/case "ABCabcDEFdefABCabcDEFdef" "abc" "xxx"
"ABCxxxDEFdefABCxxxDEFdef"

14.9 ??

La fonction ?? accepte un argument de n'importe quel datatype. Afin d'aider au déboguage, si un mot est fourni à ??, alors ce mot est affiché avec sa valeur.

Comme pour probe, ?? renvoie la valeur (non évaluée) de son argument de sorte que ?? peut être utilisée de façon transparente sur des expressions REBOL.

Lorsque ?? est utilisée directement sur une valeur qui n'est pas un mot, la valeur est affichée et ?? retourne la valeur non évaluée.

L'exemple suivant montre l'usage de ?? sur un bloc défini par le mot blk :

blk: ["a" block 'of [values]]
?? blk
blk: ["a" block 'of [values]

L'exemple suivant illustre le fonctionnement de ?? sur un mot définissant une fonction :

?? probe
probe: func [
    {Prints a molded, unevaluated value and returns the same value.}
    value
][
    print mold :value :value
]

L'exemple ci-dessous montre ?? opérant sur une valeur qui n'est pas un mot :

?? 12:30pm
12:30

14.10 To-pair

La fonction to-pair accepte un argument de n'importe quel type. To-pair essaye de transformer l'argument fourni en une valeur de type pair!.

L'exemple suivant montre le fonctionnement de to-pair avec un bloc :

probe to-pair [11 11]
11x11

L'exemple ci-dessous montre to-pair avec un argument string! :

probe to-pair "11x11"
11x11

15. Améliorations dans la v.2.3

15.1 Parsing de blocs

Avec REBOL/Core 2.3, la fonction parse peut être utilisée sur des blocs. La capacité qu'a REBOL de créer des dialectes est améliorée grâce à cette possibilité d'utiliser des blocs. Voir le chapitre du Guide Utilisateur pour l'utilisation de parse avec des blocs.

15.2 Modification du handler POP

L'agent mail POP a été amélioré pour conserver la taille totale des messages et les tailles de chaque message. La taille totale des messages peut être trouvée sous la forme d'un nombre entier (représentant des octets) dans le champ total-size de l'objet locals du port POP. Les tailles respectives de chacun des messages sont stockés sous la forme d'un bloc de numéros de message et tailles en octets dans l'objet locals du port, dans le champ sizes.

Exemples :

Taille totale de tous les messages dans une connexion POP :

pop: open pop://login:pass@mail.site.com/
size: probe pop/locals/total-size
735907
print join to-integer size / 1024 "K"
718K

Tailles respectives de chaque message :

pop: open pop://login:pass@mail.site.com/
sizes: pop/locals/sizes
foreach [mesg-num size] sizes [
    print [
    "Message" mesg-num "is" join to-integer size / 1024 "K"
    ]
]
Message 1 is 2K
Message 2 is 2K
Message 4 is 1K
Message 5 is 9K
Message 6 is 1K
Message 7 is 678K
Message 8 is 1K

15.3 Usage de la touche Tabulation

L'auto-complétion via la touche TAB dans la console REBOL a été étendue pour qu'en pressant deux fois cette touche, une liste de choix possibles soit affichée.

Pour voir le comportement de cette fonctionnalité, saisissez fun en ligne de commande et ensuite appuyez sur la touche TAB. Le mot fun va être complété en "func". Un autre appui sur la touche TAB montrera les items suivants :

function!  function?

func et function sont les choix possibles pour le mot saisi.

15.4 Raffinement /next pour la fonction load

Le comportement du raffinement /next a été modifié. Load/next n'omet plus l'en-tête du script REBOL. Pour charger l'en-tête du script en tant qu'objet en utilisant le raffinement /next, incluez le raffinement /header.

Exemples :

Sauvegarder un simple script dans un fichier %simple.r:

save %simple.r [
    REBOL [
    title: "simple"
    file:  %simple.r
    ]
    print "simple script"
]

Utilisation de load/next sur le script:

script: probe load/next %simple.r
[
    REBOL { [
    title: "simple"
    file: %simple.r
]
print "simple script"}]
probe load/next second script
[[
    title: "simple"
    file: %simple.r
    ] {
print "simple script"}]

Utilisation de load/next/header sur le script :

script: probe load/next/header %simple.r
[
    make object! [
    Title: "simple"
    Date: none
    Name: none
    Version: none
    File: %simple.r
    Home: none
    Author: none
    Owner: none
    Rights: none
    Needs: none
    Tabs: none
    Usage: none
    Purpose: none
    Comment: none
    History: none
    Language: none
    ] {
print "simple script"}]
probe load/next second script
[
    print { "simple script"}
]

15.5 Fonction Query

La fonction query accepte maintenant les objets, et renvoie un bloc des mots modifiés dans cet objet ou sinon none. Le bloc retourné dans ce cas contient les mots qui ont été modifiés depuis la création de l'objet ou depuis la dernière appel de query/clear sur l'objet. Les mots retournés dans le bloc sont liés (binding) au contexte de l'objet. En utilisant query, les modifications sur un objet peuvent être suivies.

L'exemple suivant illustre l'emploi de query sur des objets :

Définition d'un objet :

obj: make object! [
    field-one: "string"
    field-two: 123
    field-three: 11:11:01
]

L'utilisation de query sur l'objet obj immédiatement après que l'objet ait été créé renverra none :

probe query obj
none

Usage de query après avoir modifié un champ dans l'objet obj :

obj/field-two: 456
obj/field-three: 12:12:02
mod: query obj
probe mod
[field-two field-three]
probe get mod/1
456
probe get mod/2
12:12:02

La fonction query a renvoyé un bloc constitué des mots modifiés et liés à obj.

Utilisez query/clear pour réinitialiser le statut "modifié" de l'objet.

L'exemple suivant démontre cet effacement de l'état des champs dans obj :

query/clear obj
probe query obj
none

Ici, none a été renvoyé car le statut "modifié" a été effacé en utilisant query/clear.

15.6 Fonctions acceptant des valeurs de type pair!

Voici une liste de fonctions qui ont été modifiées pour accepter les valeurs de type pair! :

Addition : + et add

probe 12x12 + 12x12
24x24
probe add 11x11 11
22x22

Soustraction : - et subtract

probe 24x24 - 12x20
12x4
probe subtract 24x24 12
12x12

Multiplication : * et multiply

probe 12x12 * 12x12
144x144
probe multiply 12x12 24
288x288

Division : / et divide

probe 12x12 / 2x4
6x3
probe divide 24x24 4
6x6

Reste : // et remainder

probe 24x24 // 5x3
4x0
probe remainder 24x24 10
4x4

Minimum : min et minimum

probe min 12x12 12x11
12x11
probe minimum 23x24 24x24
23x24

Maximum : max et maximum

probe max 12x12 12x11
12x12
probe maximum 23x24 24x24
24x24

Fonction negate

probe negate 12x12
-12x-12
probe negate 12x0
-12x0

Valeur absolue : abs et absolute

probe abs -12x-24
12x24
probe absolute -12x24
12x24

Fonction zero?

probe zero? 12x0
false
probe zero? 0x0
true

Fonctions pick, first et second

probe pick 24x12 1
24
probe pick 24x12 2
12
probe pick 24x12 3 ; n'importe quelle valeur au delà de 2 renvoie none
none
probe first 24x12
24
probe second 24x12
12

Fonctions reverse

probe reverse 12x24
24x12

15.7 Fonction Random

La fonction random accepte maintenant des valeurs négatives. Quand une valeur négative est utilisée, la fonction random renvoie un nombre compris entre -1 et cette valeur négative.

Exemples:

loop 5 [print random -5]
-5
-5
-3
-3
-5
loop 5 [print random -$5]
-$4.00
-$5.00
-$3.00
-$5.00
-$3.00

15.8 System/options/path

Le mot path a été rajouté à l'objet system/options. System/options/path est le répertoire depuis lequel est exécuté le script REBOL en cours.
Exemple :

print system/options/path
/C/REBOL/

15.9 Fonction what

La fonction what sort par ordre alphabétique la liste des fonctions définies.

15.10 Fonctions if, any, et all

Les fonctions if, any et all renvoie à présent none en guise de valeur "d'échec" là où elles renvoyaient autrefois false.

Voici quelques exemples de la nouvelle valeur de retour :

val: 10
probe if val = 100 [print "matched"]
none
val: 10
probe any [val = 100 val = 1000 val = 10000]
none
set [val1 val2 val3] [10 100 2000]
probe all [val1 = 10 val2 = 100 val3 = 1000]
none

15.11 Help

Utilisez la fonction help pour récupérer la description les arguments, et les raffinements pour toutes les fonctions, ou pour inspecter d'autres valeurs REBOL.
Saisissez help dans la console, et un nom de fonction :

>> help cosine
USAGE:
    COSINE value /radians
DESCRIPTION:
     Returns the trigonometric cosine in degrees.
     COSINE is a native value.
ARGUMENTS:
     value -- (Type: number)
REFINEMENTS:
     /radians -- Value is specified in radians.

La fonction help peut aussi être utilisée pour rechercher des informations internes.

Voici un exemple d'usage d'help avec un mot :

>> help path
Found these words:
    clean-path     (function)
    inst-path      (object)
    lit-path!      (datatype)
    lit-path?      (action)
    make-dir-path  (function)
    path!          (datatype)
    path?          (action)
    set-path!      (datatype)
    set-path?      (action)
    split-path     (function)
    to-lit-path    (function)
    to-path        (function)
    to-set-path    (function)

16. Corrections dans la v2.3

Voici les corrections faites depuis la version 2.3.

16.1 Fonction split-path

En découpant un path très court comme %. ou %/, la seconde valeur renvoyée dans le bloc de résultat sera none. Si un fichier apparaît dans le path, la première valeur sera le répertoire courant (%./) et la seconde valeur sera le fichier lui-même (%file).

Voici quelques exemples dans l'utilisation de split-path :

probe split-path %.
[%./ none]
probe split-path %./
[%./ none]
probe split-path %/
[%/ none]
probe split-path %file.txt
[%./ %file.txt]

16.2 Interruption d'une opération réseau

Une opération réseau en cours peut à présent être interrompue en pressant la touche Escape (Esc). Une exception notoire à ce fonctionnement est la version BeOS de REBOL pour laquelle, actuellement, une opération réseau en cours ne peut être interrompue par ce moyen.

16.3 Trim/lines

L'usage de trim/lines permet d'ôter tous les espaces et assimilés (whitespaces) dans une chaîne, de compresser toutes les occurrences multiples d'espaces blancs en espaces uniques.

L'exemple suivant montre le comportement de trim/lines :

str: {
    line one
    line two
    line five
    line eight
}
probe trim/lines str
"line one line two line five line eight"

16.4 Fonction to-word

La fonction to-word accepte maintenant des valeurs de type set-word! en argument.

Voici une illustration de ce comportement :

probe to-word first [data: "string of data"]
data
probe type? to-word first [data: "string of data"]
word!

16.5 Fonction to-block

Lorsque qu'un chemin littéral est fourni en argument à to-block, le bloc qui est renvoyé par la fonction contient les composants du chemin sous forme de mots.

L'exemple suivant présente l'utilisation de to-block avec un argument de type lit-path! :

probe to-block 'system/options/path
[system options path]

17. Autres changements (provenant du document d'Addendum) dans la v.2.3

  • REBOL 2.3 a une option supplémentaire +q (non-quiet) en ligne de commande
  • Difference est renommée exclude, quoique difference est conservée comme synonyme pour exclude
  • If a un nouveau raffinement /else.
  • Parse accepte à présent des séries au lieu de juste une chaîne
  • Trace possède un nouveau raffinement /function qui permet de tracer les appels aux fonctions
  • slash et backslash sont des valeurs pré-définies
  • dirize est une fonction qui transforme un non de fichier en répertoire
  • append a un nouveau raffinement /only, qui se comporte comme dans insert/only
  • L'objet system contient un bloc components pour de futurs ajouts
  • L'objet system contient à présent l'item user/home qui précise le chemin indiqué dans la variable d'environnement $HOME
  • Ces champs ont été rajoutés aux ports : localip, localservice, remoteservice, lastremoteservice, direction, key, strength, algorithm, block-chaining, init-vector. Certains de ces champs sont nécessaires pour des raisons de sécurité d'autres produits REBOL.
  • Par défaut, il est possible d'écrire dans system/options/home/public/.
  • Les datatypes suivants existent dans REBOL/core 2.3 quoique certains ne soient pas utilisables : event! library! struct! routine! image!
  • Quand un path est utilisé pour définir une valeur d'une type de données scalaire, il la place dans le scalaire qui a été employé dans le path : date/minute: 1, à présent date/minute renverra 1
  • Maintenant, read %/ ou load %/ retourne les partitions sur Win32 et Amiga.
  • L'usage de mold sur un objet où un champ référence un mot littéral ('word) est à présent correct.
  • Les ports UDP en mode listen fonctionnent correctement.
  • Des informations ont été ajoutées pour le fonction copy vis-à-vis de l'utilisation des ports UDP.
  • Les scripts peuvent maintenant indiquer la version et le produit requis pour leur exécution dans le champ needs de l'en-tête (header) REBOL.
  • La fonction random autorise maintenant l'usage des tuples.
  • poke appliquée sur un tuple ne manipule que des valeurs entre 0 et 255.
print poke 1.2.3.4 2 10      ; tuple index-de-la-position valeur-nouvelle
1.10.3.4
  • Une nouvelle fonction native (connected?) essaye de déterminer si l'ordinateur est connectée à Internet.
  • Les fonctions suivantes présentes dans REBOL 2.3 ont été désactivées : free browse launch




Updated 15-Apr-2005 - Copyright REBOL Technologies - Formatted with MakeDoc2 - Translation by Philippe Le Goff

REBOL.com Documents Manual Dictionary Library Feedback