Hi -- On Mon, 5 Dec 2005 gwtmp01 / mac.com wrote: > When I was first learning Ruby, symbols were a bit of a mystery. > I understand them now, and in hindsight, I don't really understand > why they were so confusing. In teaching other people about Ruby and > in reading ruby-talk it is quite clear that symbols are an early > stumbling block for learning Ruby. I'd take an educated guess that > people learning Rails (or any other Ruby framework) struggle with > trying to understand if symbols are a magic feature of the framework > or the language or something else. > > My question to the list is, why? What is it about Symbols that > creates such confusion? I'm getting ready to prepare a two-hour > "Intro to Ruby" seminar and I'd like to find an approach to Symbols > that cuts through the confusion. I've seen Symbol confusion in the following forms: 1. Confusion between Symbol objects and symbols in the sense of identifiers in a Ruby program. This code: x = 1 may result in :x being put in the symbol table, but the x in that expression is not a Symbol object. I don't think this distinction is always clear to people. 2. Overuse of symbols. This kind of thing: methods.each do |m| something.send(m.intern) end is almost certainly pointless, in terms of efficiency. I think symbols have a kind of mystique -- as if there's something sort of sloppy or substandard or laughably high-level about using strings where you could use symbols. In fact, the methods that take strings or symbols as arguments are usually well-engineered to handle either. 3. Over-emphasis on the symbol table and its meaning. Maybe I under-emphasize it in my own thinking... but I've never seen any practical reason to think of symbols in terms of a table, even if one exists internally. I can't call to mind any case where the data structures involved in the interpreter's handling of symbols would make any difference to me. All I need to know is that symbols are immediate, immutable, and fast. I'm not campaigning against understanding the interpreter. But from the user side -- which is where we are when we use Ruby -- symbols are still an abstraction. When I do "send(:meth)", I'm not manipulating the symbol table *as* a table. The table-ness is an implementation detail. Symbol objects are part of Ruby. 4. Conflation of symbols and methods. Sort of along the same lines: :meth is no closer to the method you get when you do method(:meth) than "meth" is. It may be closer internally, but in practical terms, it isn't. You can't do: :meth += "2" and change the name of "meth" to "meth2". The symbol is the ending point, not the starting point. > One thought that I've had is that Ruby's reflection capabilities expose > the names of various internal structures (classes, methods, modules, > constants) in a way that is quite foreign to many programmers. For > example, in C you don't have any runtime access to the symbol table so > you would never see a value that could be mapped to a function like > 'printf', 'scanf', or 'main' unless the programmer took the trouble to > construct an explicit symbol table (mapping strings to function > pointers, for example). An explicit table isn't much of a mystery. To my knowledge there's no programmatic access to the underlying symbol table in Ruby. (Am I wrong about this? Have I missed all the table-manipulating fun? :-) > When you switch to a language like Ruby, Smalltalk, and certainly the > entire family of Lisp languages you are now in an environment where the > data structures of the language runtime are exposed to the programmer. > For a while, the novice will struggle because their mental model of > a runtime environment just doesn't match their new reality and symbols > just happen to be the bridge between the two worlds. One of the first > features of Ruby that many people learn are the 'attr*' methods. Right > off the bat, the novice is exposed to the mappings from strings to > symbols to methods. Again, I think that from the programmer's perspective, you can map from strings to methods just as easily: attr_reader :a attr_reader "a" attr_reader :a.to_s attr_reader "a".to_sym Obviously the first one is the common case, and the first two are the only useful ones. But conceptually, I think of strings and symbols, in such cases, as equidistant from the underlying method -- except for the hint that symbols are faster. David __ David A. Black dblack / wobblini.net "Ruby for Rails", forthcoming from Manning Publications, April 2006!