Des tableaux dans une classe
Fermé
micro_geek
Messages postés
3
Date d'inscription
vendredi 18 janvier 2019
Statut
Membre
Dernière intervention
18 janvier 2019
-
18 janv. 2019 à 05:42
titour - 19 janv. 2019 à 19:24
titour - 19 janv. 2019 à 19:24
A voir également:
- À l’aide des tableaux ci-dessous, trouvez le mot dont le code ascii est le suivant : 61 64 6d 69 73 73 69 6f 6e
- À l'aide des tableaux ci-dessous, trouvez le mot dont le code ascii est le suivant : 61 64 6d 69 73 73 69 6f 6e - Guide
- Comment trouver le mot de passe wifi sur son téléphone - Guide
- Winrar 64 bits windows 10 - Télécharger - Compression & Décompression
- Le mode suivi des modifications - Guide
- Comment déverrouiller un téléphone quand on a oublié le code - Guide
5 réponses
Utilisateur anonyme
18 janv. 2019 à 08:24
18 janv. 2019 à 08:24
Bonjour
Je ne connais pas Ruby, mais comme les 10 questions précédentes n’ont pas reçues de réponses, il y a fort à parier que la tienne n’en aurait pas eu non plus.
J’emets une hypothèse qui est vraie dans d’autres langages: le passage de paramètres de ton constructeur est fait par référence (éventuellement en pointeur, mais je n’y crois pas, ruby est sensé être simple à coder)
Dans tous les cas, si tu avais déjà codé avec des langages où le passage par référence existe soit par défaut (Les VB sauf VB.Net par exemple) soit par défaut selon le type (VB.net, C# par exemple) tu y aurais pensé.
Je vais dinc t’expliquer les passages de paramètres.
D’abord, on va survoler le fonctionnemt des variables et de la mémoire.
Quand tu crées une variable, tu utilises 2 emplacements de mémoire.
Dans l’un est stocké la données, cet emplacement est petit quand il s’agit d’un boolean et très grand quand il s’agit d’un texte de 50000 caractères.
Dans l’autre sont stockés les infos relatives à la variable elle-même, son nom, qui l’a créé, oú se trouve sa donnée etc... Cet emplacement est petit.
Quand on passe un paramètre à une méthode, un constructeur ou simplement que l’on fait a = b, le second emplacement est dupliqué.
Par contre le premier ça dépend.
A vérifier de ton côté si ruby travaille par référence, parfois , ou pas du tout.
Je ne connais pas Ruby, mais comme les 10 questions précédentes n’ont pas reçues de réponses, il y a fort à parier que la tienne n’en aurait pas eu non plus.
J’emets une hypothèse qui est vraie dans d’autres langages: le passage de paramètres de ton constructeur est fait par référence (éventuellement en pointeur, mais je n’y crois pas, ruby est sensé être simple à coder)
Je commence à programmer en rubyOk, mais ça ne dit pas si tu commences à programmer tout court.
Dans tous les cas, si tu avais déjà codé avec des langages où le passage par référence existe soit par défaut (Les VB sauf VB.Net par exemple) soit par défaut selon le type (VB.net, C# par exemple) tu y aurais pensé.
Je vais dinc t’expliquer les passages de paramètres.
D’abord, on va survoler le fonctionnemt des variables et de la mémoire.
Quand tu crées une variable, tu utilises 2 emplacements de mémoire.
Dans l’un est stocké la données, cet emplacement est petit quand il s’agit d’un boolean et très grand quand il s’agit d’un texte de 50000 caractères.
Dans l’autre sont stockés les infos relatives à la variable elle-même, son nom, qui l’a créé, oú se trouve sa donnée etc... Cet emplacement est petit.
Quand on passe un paramètre à une méthode, un constructeur ou simplement que l’on fait a = b, le second emplacement est dupliqué.
Par contre le premier ça dépend.
- Si c’est un passage par valeur, la donnée est entièrement copiée dans un nouvel emplacement, quand on travaille sur la donnée, celle d’origine n’est pas affectée. C’est gourmand en mémoire et « long » à exécuter.
- Si c’est un passage par référence, la nouvelle variable pointe sur le même emplacement de mémoire que la première, toute modification se voit forcément depuis les 2 variables puisqu’elles sont associées à la même donnée
A vérifier de ton côté si ruby travaille par référence, parfois , ou pas du tout.
micro_geek
Messages postés
3
Date d'inscription
vendredi 18 janvier 2019
Statut
Membre
Dernière intervention
18 janvier 2019
18 janv. 2019 à 10:52
18 janv. 2019 à 10:52
Merci beaucoup, Whismeril.
Non, je ne viens pas vraiment d'un autre langage, mais j'en ai parfois survolé certains...
Je comprends ce que tu veux dire : lors de l'appel de la fonction de construction de 'b' j'appelle une fonction de 'a' donc les deux objets pointent au même endroit. ( si j'ai bien saisi )
J'espérais que ce soit quelque chose de simple, mais il semble que ça me dépasse largement.
Je vais tenter de revoir la structure de mon code...
Non, je ne viens pas vraiment d'un autre langage, mais j'en ai parfois survolé certains...
Je comprends ce que tu veux dire : lors de l'appel de la fonction de construction de 'b' j'appelle une fonction de 'a' donc les deux objets pointent au même endroit. ( si j'ai bien saisi )
J'espérais que ce soit quelque chose de simple, mais il semble que ça me dépasse largement.
Je vais tenter de revoir la structure de mon code...
Utilisateur anonyme
18 janv. 2019 à 12:35
18 janv. 2019 à 12:35
lors de l'appel de la fonction de construction de 'b' j'appelle une fonction de 'a’La terminologie n’est pas bonne mais c’est ça.
Lors de l’appel de la méthode de construction de b tu appelles une propriété de a. Là c’est avec les termes « normés » de l’objet. La déclinaison en ruby peut être différente. On voit par exemple Procédure pour une méthode qui ne retourne pas de résultat et Fonction pour celle qui retourne un résultat.
J’ai cherché rapidement sur le net, je n’ai pas trouvé si un tableau est bien passé par référence et comment forcer le passage par valeur. Ça se fait dans les autres langages, y’a pas de raison que ça n’existe pas en ruby.
Bonjour.
Un Array est passé par référence, cela se teste en 3 secondes avec l'interpréteur ruby (irb).
Il faut donc utiliser la méthode clone des objets, mais comme préciser, clone ne copie pas en profondeur les objets, il y a la technique d'utiliser marshal si on a besoin de faire une copie en profondeur, mais pour un Array contenant une liste d'entiers, clone est suffisant.
L'interpréteur ruby facilite l'exécution de petits tests, et fournit une documentation sur les objets en tapant help.
Un Array est passé par référence, cela se teste en 3 secondes avec l'interpréteur ruby (irb).
diplo@bibi:~$ irb irb(main):001:0> ar = 1, 2, 3 => [1, 2, 3] irb(main):002:0> ar2 = ar => [1, 2, 3] irb(main):003:0> ar.__id__ => 19279820 irb(main):004:0> ar2.__id__ => 19279820 irb(main):005:0> ar3 = ar.clone => [1, 2, 3] irb(main):006:0> ar3.__id__ => 19130860 irb(main):007:0> help Enter the method name you want to look up. You can use tab to autocomplete. Enter a blank line to exit. >> Array#clone = Array#clone (from ruby core) === Implementation from Object ------------------------------------------------------------------------------ obj.clone -> an_object ------------------------------------------------------------------------------ Produces a shallow copy of obj---the instance variables of obj are copied, but not the objects they reference. Copies the frozen and tainted state of obj. See also the discussion under Object#dup. class Klass attr_accessor :str end s1 = Klass.new #=> #<Klass:0x401b3a38> s1.str = "Hello" #=> "Hello" s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello"> s2.str[1,4] = "i" #=> "i" s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">" s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">" :
Il faut donc utiliser la méthode clone des objets, mais comme préciser, clone ne copie pas en profondeur les objets, il y a la technique d'utiliser marshal si on a besoin de faire une copie en profondeur, mais pour un Array contenant une liste d'entiers, clone est suffisant.
L'interpréteur ruby facilite l'exécution de petits tests, et fournit une documentation sur les objets en tapant help.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
micro_geek
Messages postés
3
Date d'inscription
vendredi 18 janvier 2019
Statut
Membre
Dernière intervention
18 janvier 2019
18 janv. 2019 à 19:27
18 janv. 2019 à 19:27
J'ai essayé d'utiliser '.clone', '.dup' et même '.dup.map { |e| e.dup }' mais ça devient rapidement très compliqué et je ne sais plus trop où j'en suis.
Je suppose que ce sont des methodes pour forcer le passage par valeur...
J'ai regardé du coté de la classe Marshal mais je n'ai pas du tout saisi comment m'en servir.
En fait, mon code complet ressemblerai plus à ça :
Dois-je tout revoir et éviter d'utiliser des tableaux ?
Je suppose que ce sont des methodes pour forcer le passage par valeur...
J'ai regardé du coté de la classe Marshal mais je n'ai pas du tout saisi comment m'en servir.
En fait, mon code complet ressemblerai plus à ça :
class OtherClass def list end class ListArray attr_accessor :arr def initialize arr @arr = arr end def putItem ... def getItem ... def cutList &bloc ... end a = ListArray.new obj1_other_class.list # obj2_other_class.list => [[1, 2], [3, 4], ... ] # [3, 4] est un item b = ListArray.new obj2_other_class.list a.putItem [5, 6] c = ListArray.new a.arr c.arr += b.arr c.arr[1][0] = 7 ...
Dois-je tout revoir et éviter d'utiliser des tableaux ?
Bonjour.
Marshal sert à sérialiser des objets, par ce principe cela produit obligatoirement une copie totale d'un objet.
Et non, n'abandonne pas les arrays, pour toi, la création d'une méthode retournant la copie en profondeur de ton tableau est suffisante.
Tu aurais même pu le faire avec clone si ton array est composé que d'arrays en utilisant une fonction récursive.
Par ex.
Marshal sert à sérialiser des objets, par ce principe cela produit obligatoirement une copie totale d'un objet.
irb(main):035:0> ar = [[0, 1, 2], [3, 4, 5]] => [[0, 1, 2], [3, 4, 5]] irb(main):036:0> ar2 = ar.clone => [[0, 1, 2], [3, 4, 5]] irb(main):037:0> ar3 = Marshal.load(Marshal.dump(ar)) => [[0, 1, 2], [3, 4, 5]] irb(main):038:0> ar[0][0] = 8 => 8 irb(main):039:0> ar2[0][0] => 8 irb(main):040:0> ar3[0][0] => 0
Et non, n'abandonne pas les arrays, pour toi, la création d'une méthode retournant la copie en profondeur de ton tableau est suffisante.
Tu aurais même pu le faire avec clone si ton array est composé que d'arrays en utilisant une fonction récursive.
Par ex.
ar = [[1, 2, 3], [[4, 5, 6], [7, 8, 9]], [10, 11, 12]] def deep_clone array ar_clone = [] array.each{|v| ar_clone << (v.class == Array ? deep_clone(v) : v)} ar_clone end ar2 = deep_clone ar ar[1][1][2] = 19 p ar p ar2