From: Ryan Pavlik Date: 2003-01-20T12:12:25+09:00 Subject: Symbols: More Functionality Wanted I've been discussing this for a bit on #ruby-lang on OPN (or freenode or whatever), and am going to post it here, per suggestion. Basically, the Symbol class should have more useful functionality. One should not have to do the following: @a = 1 str = "@a" val = eval(str) Especially when we've got a perfectly wonderful Symbol class which is not only there, but used internally for just this purpose. I'd like to see the following: @a = 1 sym = :@a val = sym.binding # Or whatever... pick your favorite name ;) More importantly: @a = 1 sym = :@a sym.bind(2) p @a # => 2 This has multiple advantages: * It's more efficient. * eval() sucks anyway. :-) * It allows rebinding variables dynamically * Symbols become useful in ruby code * All the internal calls are already there... like rb_ivar_set, rb_ivar_get, and these all take IDs (which can be taken directly from the symbol) In case you don't feel this is actually necessary functionality: a "real-world" case of this is persistant objects. Before serializing, each instance variable that contains a reference to another persistant object needs replaced with a temporary reference, so a deep copy doesn't happen when it gets restored. If the deep copy happens, the variables aren't referencing the "actual" object, so the system breaks. This is trivial to do, given the above extension to Symbol: 1. Grab a list of instance variables 2. Check each one to see if it's persistant 3. If so, replace it with a TempRef object 4. If this is an Enumerable, walk through each item doing the same. _Without_ the above functionality, one must resort to eval(), writing C modules, or rewriting Marshal---each of which is an ugly solution, which defeats the point of some preexisting part of ruby. Many of you have are familiar with Lisp, as well, and I'm sure can come up with other handy uses for symbol manipulation. Some additional thoughts: * This should be tied to Binding, so you can get a symbol in a binding. This seems natural, to me: sym = :@a sym.bind(object[, binding]) * Kernel::instance_variables could usefully return a list of symbols, instead of strings, further aiding in efficiency. -- Ryan Pavlik "Maniacal supervillain exit stage right."