[Core] Function save
trigram30-Jan-2011/15:29:26+1:00
J'ai une question toujours très bête concernant les fonctionnalités de base de REBOL :

>> ? save
USAGE:
    SAVE where value /header header-data /bmp /png /all

DESCRIPTION:
     Saves a value or a block to a file or url.
     SAVE is a native value.

ARGUMENTS:
     where -- Where to save it. (Type: file url binary)
     value -- Value to save. (Type: any)

REFINEMENTS:
     /header -- Save it with a header
         header-data -- Header block or object (Type: block object)
     /bmp -- Save in .BMP format
     /png -- Save in .PNG format
     /all -- Save in serialized format


On peut dans le paramètre where indiqué une URL.
Mais comment cela fonctionne-t-il ?

Ensuite, dans les refinments on peut indiquer /all. Il est indiqué "Save in serialized format", qu'est-ce que l'on entend par serialiser ?

D'avance merci pour votre aide.
RebKodeur30-Jan-2011/22:18:48+1:00
save %"/C/Mes Documents/RepertoireY/" "blabla"

Sérialiser est le dump d'un object, donc normalement un objet complet peut être sauvegardé dans un fichier. Il faudrait tester en refaisant un load read pour voir ce qui marche vraiment..

A l'époque j'avais créé mon propre serialiser et mon unserialiser..
trigram30-Jan-2011/23:52:36+1:00
Il faut que je fasse des tests.
Par je suis intrigué sur la partie save sur une url!. A quoi est-ce que cela correspond ?

Par ailleurs, peut-on connaître le nom de l'objet ?
Je créé un objet task et ensuite j'instancie task1 a parir de task. Je voudrai récupérer le littéral task1.
Associé à save je pourrai sauvegarder l'objet instancié.
coccinelle31-Jan-2011/8:21+1:00
Easy-soccer utilise la forme sérialisé de Rebol pour communiquer entre les applications, ça marche bien.

Je l'emploie avec mold/all et ça simplifie le travail car un simple load permet d'avoir une reconstruction à l'identique des éléments sauvés.

Ce qui se passe avec un save sur un url dépend du protocol. Avec http, cela doit faire un POST ou un PUT, je ne sais pas. si c'est FTP, cela fait un file transfert selon ce protocol. Si c'est SMTP, cela envoie la chose via un message.
Didec31-Jan-2011/10:50:39+1:00
Le raffinement /all correspond au mold/all qui va sauver certaines valeurs sous une forme dites littérale. Par exemple 'none devient : #[none]
trigram31-Jan-2011/22:41:36+1:00
Et comment fait-on pour recharger ce que l'on a sauvegardé avec save ?

task: make object! [
  save*: get in system/words 'save
  list: copy []
  add: funct [t [block!]] [
    append list t
  ]
  save: does [
    save*/all %task1.r self
  ]
  run: does [
    do list
  ]  
]

task1: make task []
task1/add [a: 0 a: a + 1]
task1/add [print a]
task1/save
task1/run


Si je veux recharger dans un autre REBOL le fichier %task1.r, comment faire ?

Par ailleurs, je souhaiterai optimiser la fonction save en sauvegardant avec le nom de l'objet instancié, en l'occurence task1. Comment faire ?
Didec1-Feb-2011/11:14:17+1:00
Tu ne peux pas récupérer le nom de l'objet depuis lui-même (self) parceque l'objet ne se connait pas de l'intérieur.

Pour faire ce genre de chose il faut concevoir une sorte de sur-objet ou des fonctions implémentant les fonctionnalités que tu souhaite (stockage de son nom, méthode load et save à ta sauce) et t'en servir à la place des fonctions de base.
guest21-Feb-2011/15:09:21+1:00
Ou tu peux stocker l'attribut nom à l'intérieur même de l'objet et utiliser ton propre constructeur à la place de make.

;-- le proto de task
task: context [
name: none
...
]

;-- le constructeur qui remplace la fonction make
new: func ['name* proto spec][get set in set name* make proto spec 'name to-word name*]

;-- exemple

>> new task1: task []
>> ?? task1
task1: make object! [
name: 'task1
]
trigram4-Feb-2011/22:36:15+1:00
Comment fait-on pour recharger ?
J'ai mon fichier %task1.r qui contient mon objet task1 créé.
Mais je veux le recharger dans un autre interpreteur REBOL, je ne sais comment faire pour réinstancier l'objet.
Faut-il créer tout le code dans %task1.r et juste faire un do %task1.r ?
Ou peut-on faire un load dans objet task1 ?
RebKodeur5-Feb-2011/13:55:03+1:00
task1: load read %task1.r
trigram7-Feb-2011/17:15:23+1:00
Toujours dans mes essais, j'ai une erreur que je ne comprends pas...

REBOL [
]

task: make object! [
  save*: get in system/words 'save
  task-file: copy ""
  list: copy []
  add: funct [t [block!]] [
    append list t
  ]
  save: does [
    save*/all task-file self
  ]
  run: does [
    do list
  ]
]

create-task: funct [_task _task-list [block!]] [
  t: make task [task-file: to-file join mold/only _task ".r"]
  if not none? _task-list [t/add _task-list]
  t/save
  set _task t
]


REBOL [
]
do %task.r
create-task [task1] [print "Task1" b: 1 b: b + 1 print b]
create-task [task2] [print "Task2" c: 2 print c]
task3: load read %task2.r
task3/run
halt


Et le résultat :

** Script Error: list has no value
** Where: run
** Near: do list
>>


Et je ne comprends car :

>> ?? task1
task1: make object! [
    save*: native
    task-file: %task1.r
    list: [print "Task1" b: 1 b: b + 1 print b]
    add: func [t [block!]][
        append list t
    ]
    save: func [][
        save*/all task-file self
    ]
    run: func [][
        do list
    ]
]
>> ?? task2
task2: make object! [
    save*: native
    task-file: %task2.r
    list: [print "Task2" c: 2 print c]
    add: func [t [block!]][
        append list t
    ]
    save: func [][
        save*/all task-file self
    ]
    run: func [][
        do list
    ]
]
>> ?? task3
task3: make object! [
    save*: 'native
    task-file: %task2.r
    list: [print "Task2" c: 2 print c]
    add: func [t [block!]][
        append list t
    ]
    save: func [][
        save*/all task-file self
    ]
    run: func [][
        do list
    ]
]
>> task3/list
== [print "Task2" c: 2 print c]
>> do task3/list
Task2
2


Pourquoi est-ce que le task3/run ne fonctionne pas ?
RebKodeur8-Feb-2011/10:00:14+1:00
Oui même erreur pour moi.
Cela doit être un problème de binding, car print mold task3/list produit qqch, mais pas un appel depuis l'intérieur de la classe.

J'ai un peu de peine avec le binding..
Didec8-Feb-2011/12:19:35+1:00
Réponse de Dockimbel sur Altme :
utiliser 'save au lieu de 'save/all et faire "do load" au chargement !

Reste à comprendre pourquoi la forme serialisée (save/all) ne marche pas !?
trigram8-Feb-2011/15:08:23+1:00
Bon, j'ai un peu de mal.

et faire "do load" au chargement !

???
coccinelle8-Feb-2011/15:50:50+1:00
Non, un do %... est suffisant.

/all est parfait pour les objets passifs, c'est à dire ceux qui ne sont que de simple structure/container de données que l'on veux sauver et recharger, ou transmettre via un protocol quelconque.

/all est même impératif lorsqu'un block contient des objets.

Par contre, ça ne fonctionne pas dans ton cas car le contexte n'est pas reconstruit.
trigram17-Feb-2011/10:26:42+1:00
Qui peut m'aider à écrire la fonction ?

load-task: funct [_task-file] [
...
]


J'ai un peu de mal...
Didec17-Feb-2011/10:50:53+1:00
Allez, un exemple complet, tu adaptera à tes besoins :
Rebol []

make-obj: func [
	"Créé un objet en sauvant son nom dedans."
	'name "Nom de l'objet à créer."
	obj "Objet de base à instancier."
	spec "extension de l'objet de base."
] [
	set name make obj append reduce [to-set-word 'obj-name to-string name] spec
]


save-obj: func [
	"Sauvegarde un objet selon son propre nom."
	'obj "Objet à sauvegarder."
	/local name
] [
	name: any [all [word? obj  object? get obj  get in get obj 'obj-name] join "objet" random 10000]
	save to-file join name ".r" get obj
]

load-obj: func [
	"Recharge un objet et l'intanci selon son propre nom s'il en a un."
	file "Nom du fichier à charger."
	/bindto "Spécifier le contexte où binder la liste de l'objet chargé."
	ctx "Nom de l'objet (contexte) ou binder la liste de l'objet chargé."
	/local obj
] [
	if exists? file [
		obj: do load file
		if all [in obj 'obj-name  set to-word get in obj 'obj-name obj] [
			if all [bindto  object! ctx] [bind obj/list ctx]
		]
	]
	obj
]

task: make object! [
  list: copy []
  add: funct [
  	"Ajoute à la liste."
  	t [block!] "Elément ou code à ajouter la liste."
  	/bindto "Spécifier le contexte où binder la liste de l'objet créé."
	ctx "Nom de l'objet (contexte) ou binder la liste de l'objet créé."
  ] [
    append list t
	if all [bindto  object! ctx] [bind list ctx]
	list
  ]
  save: does [
    save-obj self
  ]
  run: does [
    do list
  ]  
]

; exemple de base
make-obj task1 task []
task1/add [a: 0 a: a + 1]
task1/add [print a]
task1/run

task1/save
task1: none

load-obj %task1.r
task1/run


; exemple avec binding au chargement
toto: context [
	b: 10
]

make-obj task2 task []
task2/add/bindto [b: b + 1 print b] toto
task2/run

task2/save
task2: none

load-obj/bindto %task2.r toto
task2/run
halt

Login required to Post.


Powered by RebelBB and REBOL 2.7.8.4.2