2010-11-10 11 views
2

Fondamentalement, j'ai déjà une instance d'un objet Ruby mais je veux mettre à jour toutes les variables d'instance que je peux yaml. Il y a une fonction to_yaml qui va déverser mon objet sur yaml. Je cherche quelque chose dans le sens inverse. Par exemple, my_obj.from_yaml (yaml_stuff) et que les variables d'instance de mise à jour yaml soient passées.Comment puis-je mettre à jour un objet Ruby déjà instancié avec YAML?

Aurais-je besoin, dans ma fonction from_yaml, d'utiliser YAML :: load et de copier chaque variable d'instance? Y at-il une fonction que je peux utiliser pour copier rapidement ces variables sans trop taper si c'est le cas?

Est-ce que la bibliothèque yaml de Ruby a déjà quelque chose où je peux lui passer l'objet et le yaml et ça va faire ce que je veux?

édition pour plus de clarté

Ceci est un objet simple qui va stocker et charger YAML très simple types compatibles tels que les chaînes et les entiers.

Ce que je fini par faire

Bien que je répondu à cette question que je voulais ajouter ce que je fini par faire, mon patch singe objet

class Object 

    def from_yaml(yml) 

    if (yml.nil?) 
     return 
    end 

    yml.instance_variables.each do |iv| 
     if (self.instance_variable_defined?(iv)) 
     self.instance_variable_set(iv, yml.instance_variable_get(iv)) 
     end 
    end 

    end 
end 

Répondre

1

Votre question n'est pas assez claire. De quelle classe parlez-vous? Quel genre de documents YAML? Vous ne pouvez pas avoir tout sérialisé vers et à partir de YAML. Supposons que votre objet possède simplement un ensemble de variables d'instance de types compatibles YAML simples, tels que des chaînes, des nombres et des symboles.

Dans ce cas, vous pouvez généralement, écrire méthode from_yaml, qui charger le fichier YAML dans un hachage de key->value paires, itérer et mettre à jour toutes les variables d'instance nommée key avec value. Est-ce que cela vous semble utile, et si c'est le cas, avez-vous besoin d'aide pour écrire une telle méthode?

Edit:

Il n'y a pas besoin pour vous de garder votre état d'objet dans un hachage - vous pouvez toujours utiliser Ivars et attr_accessors - il suffit d'ouvrir un nouveau module (par exemple YamlUpdateable), mettre en œuvre une méthode de from_yaml qui serait mettez à jour vos ivars à partir d'un hash désérialisé de YAML, et incluez le module dans la classe que vous voulez désérialiser de YAML.

+0

Désolé si je n'étais pas clair. Les membres d'objet sont constitués de types très simples compatibles avec YAML. Je ne savais pas si cette fonctionnalité existait déjà dans la bibliothèque de ruby's yaml ou si je devais faire quelque chose de spécial. On dirait que j'ai besoin de faire quelque chose de spécial. Il se peut que je doive poster cette question sous un autre angle, mais y a-t-il un avantage à stocker les données d'instance dans un hachage et à utiliser method_missing pour mettre à jour les données? Ensuite, je peux juste yaml dans et hors du hachage. – Justin

+0

J'aime ça. Je vous remercie! – Justin

1

Pour autant que je sache, il n'y a rien comme cela inclus avec la bibliothèque YAML elle-même; Il est principalement conçu pour le vidage et la lecture de données, et non pour le mettre à jour en mémoire et sur disque. Si vous envisagez de conserver les données en mémoire et sur disque synchronisées les unes avec les autres avec un minimum de tracas, avez-vous considéré une bibliothèque de persistance des données comme ActiveRecord ou Stone? Si vous êtes toujours intéressé par l'utilisation de la bibliothèque YAML, et en supposant que vous n'avez pas beaucoup de classes différentes à persister, il peut être logique d'écrire simplement une petite méthode "updater" qui met à jour un objet de cette classe. un objet similaire. Ou vous pouvez retravailler votre application pour vous assurer que vous pouvez simplement recharger tous les objets du YAML sans avoir à les mettre à jour (c'est-à-dire, vider les anciens objets et en créer de nouveaux).

L'autre option consiste à utiliser la métaprogrammation pour lire les propriétés d'un objet et les mettre à jour en conséquence, mais cela semble risqué et dangereux.

-1

Ce que vous cherchez est la commande merge.

// fetch yaml file 
yml = YAML.load_file("path/to/file.yml") 

// merge variables 
my_obj.merge(yml) 
+0

Il ne semble pas qu'il existe une fonction de fusion sur la classe d'objets. Il y en a un pour la classe de hachage cependant. – Justin