7

Is there a way to access everything in the symbol table in Ruby? I want to be able to serialize or otherwise save the current state of a run of a program. To do this, it seems I need to be able to iterate over all the variables in scope.

Jonathan Tran
  • 15,214
  • 9
  • 60
  • 67
  • 1
    If you don't mind me asking,what are you using this for ? – Geo Feb 02 '09 at 19:03
  • I'm using it for this: http://stackoverflow.com/questions/199603/how-do-you-stringize-serialize-ruby-code Basically, no one answered my question good enough, so before offering bounty (which would make me lose rep), I thought I'd break it out into this sub-question and figure out the answer myself. – Jonathan Tran Feb 02 '09 at 22:27

3 Answers3

6

I think he comes from a perl background , and that he would like to obtain all the variables defined in a script and serialize them . This way , when he'll load the file , he'll get them back . I'm still searching about how to get a list of the variables , but serialization will be made using Marshal.dump and reading them back will be made with Marshal.load . I'll edit the post once I find out how to get a list of all defined variables .

EDIT : found it!

You can get a list of all variables by calling these methods :

local_variables
global_variables

And if you haven't already got your serialization code , I would suggest something like this:

  • create a class or a Struct instance that holds a variable name and the value of the variable and add them in an array :

local_variables.each {|var| my_array &lt&lt MyVarObject.new(var,eval(var)) } # eval is used to get the value of the variable

and then serialize the array :


data = Marshal.dump(my_array)
File.open("myfile.ser","w") do |file|
  file.puts data
end
Geo
  • 93,257
  • 117
  • 344
  • 520
  • Be careful: you have to initialize my_array outside the loop, and as a result it will be included when you iterate over local_variables. You should add "unless var == 'my_array'" just before the closing curly brace to ignore it. – Bkkbrad Feb 02 '09 at 23:53
5

If I have understood your question properly - that you would like to see all the symbols in your program then the following should do the trick:

puts Symbol.all_symbols.inspect

The “all_symbols” class method will return an Array of every Symbol currently in the program.

David Grayson
  • 84,103
  • 24
  • 152
  • 189
andHapp
  • 3,149
  • 2
  • 21
  • 20
  • Yes, this is true. Interestingly, it returns symbols that are not defined as well: `ZZZ` is not defined. `ZZZ;Symbol.all_symbols` includes `ZZZ`. – B Seven Jul 07 '15 at 00:26
  • @BSeven "Interestingly, it returns symbols that are not defined as well" It actually doesn't. The mere act of trying to call `ZZZ` is like calling `self.class.const_get(:ZZZ)` (where `self` is the [`main` object](https://stackoverflow.com/q/917811/3141234)). The `ZZZ` symbol is created in that process, even if the subsequent `const_get` fails. – Alexander Mar 17 '21 at 16:16
  • @BSeven I encountered a similar issue when trying to look up if a symbol already exists in the symbol table with `Symbol.all_symbols.include?(:foo)`. Naturally, the mere mentioning of `:foo` creates it, so that always evaluates to false. You can work around it with something like `Symbol.all_symbols.find { |sym| sym.to_s == "foo" }` – Alexander Mar 17 '21 at 16:17
0

I don't believe there is, but you could always use marshall dump/load.

Allyn
  • 20,271
  • 16
  • 57
  • 68