1

Suppose in Ruby I have a = "value"; arr1 = [a, b, c]; and arr2 = [a, d, e];

Is there some reflective programming technique allowing me to say:

What are all the objects which have a reference to a.object_id?

and getting as an answer something like:

object_id:123123 (Array)

object_id:234234 (Array)

Redoman
  • 3,059
  • 3
  • 34
  • 62
  • 1
    Define what you mean by `referencing`. Your question is vague. – sawa May 13 '16 at 04:42
  • You want to know what objects are referencing a primitive string? Simple. none. If you want to track that, you'd have to amend the Array constructor to track. – vol7ron May 13 '16 at 04:43
  • There is no reference counting in Ruby, so the answer that you would ever be able to do this is very likely no. Ruby uses mark and sweep for GC, so there really is no reason to ever require knowledge of references in this sort of way. – photoionized May 13 '16 at 04:45
  • Maybe I did not use the right terms: what I mean I'd like to know if it's possible to know what objects are making use of a variable, given the variable name and specifically, in the case of an array, if one if its element is its variable name. But I'd like to do that not by iterating the array, but rather knowing that from the variable, through some kind of reflective code. – Redoman May 13 '16 at 04:48
  • For example, if an object has that as the value of its instance variable, it does not count as referencing, correct? – sawa May 13 '16 at 04:52
  • So if `obj = Object.new` and `obj.instance_variable_set(:@foo, var)`, then `obj` does not "refer to" or "make use of" `var` according to your definition, right? – sawa May 13 '16 at 05:29
  • @sawa my previous comment was wrong, I deleted it, and I'm typing it again here: what I am trying to do is: given variable name "var" and a specific value the variable it's pointing at (e.g. "i am the value"), I'd like to say: find me all objects containing a variable called "var" pointing at "I am the value". – Redoman May 13 '16 at 05:52
  • You are just changing the term from "**refer**" to "**make use of**" to "**contain**" to "**point at**", but the vagueness of the question hasn't changed. – sawa May 13 '16 at 06:16
  • @sawa, no, in the comment I deleted, in the last sentence I had wrongly typed "a" instead of "var" as for the variable name. I then specified this because I thought it could have misled you. You don't need to have such a prejudicial attitude. As I commented under mudasobwa answer, what I'd like to do is I'd like to say: "hey, 'var.object_id', in which other objects have you been used? And yeah, the variable name does not actually matter to that purpose. It only matters because I want to be able to find the object_id by saying "**var**.object_id". Clear now? – Redoman May 13 '16 at 07:29
  • Can you please edit the question to be clear without having to read any comments? We want the question to stand on its own. – Wayne Conrad May 13 '16 at 16:58
  • @WayneConrad sure and I totally agree. I apologize if my question was not clear since the beginning. Please see the updated version of it. – Redoman May 14 '16 at 07:25

1 Answers1

1

There is ObjectSpace, commonly used for this kind of queries. Please note, that the code above will produce a lot of garbage output in IRB/Pry since those introduce their own bindings etc.

#!/usr/bin/env ruby
a = 42 ; b,c,g,h = [nil]*4 ; arr1 = [a,b,c] ; arr2 = [g,h,a]
ObjectSpace.each_object(Array) do |arr|
  puts "#{arr.__id__}: #{arr.inspect}" if arr.include? a
end

#⇒ 12491500: [nil, nil, 42]
#⇒ 12491520: [42, nil, nil]

This code has a side effect: it actually checks whether an array includes a variable by value. That said, plain [42] will be counted as well and you are probably interested in making more sophisticated check inside select.

But generally speaking, the answer to the question “what to use to query the global object space” is that linked in the very beginning of my answer: ObjectSpace.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • That is ok, and I already knew, but supposing if I wanted to start from just "a" without going through ObjectSpace, is there a way to do it? – Redoman May 13 '16 at 05:12
  • Evidently no, The analogy might be: staying in the crowdy place can you count all people who’s currently starring at you? – Aleksei Matiushkin May 13 '16 at 05:26
  • I did not say I wanted to do that without using reflection at all, but just without going through Object Space. My question is more about questioning if in Ruby a way to say "hey, 'var.object_id', where have you been referenced from recently?" – Redoman May 13 '16 at 06:02
  • 1
    No, it is not possible. I can think of two main reasons: 1. some objects like atoms and frozen objects are _shared_ amongst many references and 2. maintaining a double linked graph of objects is very expensive. – Aleksei Matiushkin May 13 '16 at 07:25