Je joue avec .object_id
de Ruby et .object_id
remarqué que, dans plusieurs sessions séquentielles d’irb, j’ai les mêmes résultats:
false.object_id // 0 true.object_id // 2 nil.object_id // 4 100.object_id // 201
En fait, object_id de chaque entier semble être ((valeur * 2) + 1).
D’autre part, object_id d’une chaîne donnée n’est jamais le même après avoir quitté et relancé irb.
Cela soulève plusieurs questions pour moi:
object_id
s sont déterminés? Les autres sont-ils fondamentalement aléatoires? En utilisant la suggestion d’Andrew Grimm, j’ai essayé de découvrir d’autres objects “low id”, mais j’ai constaté que:
Dans l’IRM, object_id
d’un object est identique à la VALUE
qui représente l’object au niveau C. Pour la plupart des types d’objects, cette VALUE
est un pointeur vers un emplacement en mémoire où les données réelles de l’object sont stockées. Évidemment, cela sera différent lors de plusieurs exécutions, car cela ne dépend que de l’endroit où le système a décidé d’allouer la mémoire, et non de n’importe quelle propriété de l’object lui-même.
Cependant, pour des raisons de performances, true
, false
, nil
et Fixnum
s sont gérés spécialement. Pour ces objects, il n’y a pas vraiment de structure avec les données de l’object en mémoire. Toutes les données de l’object sont codées dans la VALUE
elle-même. Comme vous l’avez déjà compris, les valeurs pour false
, true
, nil
et tout Fixnum
i
sont respectivement 0
, 2
, 4
et i*2+1
.
La raison pour laquelle cela fonctionne est que sur tous les systèmes sur lesquels l’IRM s’exécute, 0
, 2
, 4
et i*2+1
ne sont jamais des adresses valides pour un object sur le tas.
Assigner Integer (value * 2) + 1
et non-entiers (x * 2)
est analogue au paradoxe de Hilbert du Grand Hotel , qui décrit comment affecter infiniment plus d’invités à un hôtel infini.
En ce qui concerne la recherche d’objects par leur identifiant, il existe ObjectSpace._id2ref(object_id)
. À moins que votre implémentation n’ait pas ObjectSpace.