Steve Litt wrote: > On Thursday 05 January 2006 02:25 am, Dave Howell wrote: > >>I was actually doing really well until the strange discussion involving >>throwing constants into the mix showed up, so I'm ignoring that. >> >>Steve's Newby Guide was excellent, if overly-complicated. >> >>Extremely useful item (I think from Gregory, but I'm not sure): >> >> attr_accessor "liquids", "solids" >> >>as effective and functional as >> >> attr_accessor :liquids, :solids > > That's true, but only because attr_accessor can convert the Strings it is passed to Symbols. Internally, it's using Symbols. > Yeah, that was quite a breakthrough for me too. I coded it to prove it to > myself, and from that moment on I found that I knew when to use Symbols, and > what I could accomplish by using them. > > >>So Steve, or anybody, I've learned that I can :mysymbol.to_i and I get >>an integer back. OK, I give up. What possible use do I have for this >>zany parlor trick? I'll hazard a guess that, as a "normal" programmer, >>not doing system-level stuff, not extending Ruby, not trying to do >>something dense and clever and incomprehensible...I don't. > Pretty much true. The point is that Symbols exist in pretty much any language - they're part of the normal process of parsing a program. Any C compiler will contain a definition of a type very like Symbol, and will use it for indexing variables, functions and so on. It doesn't make it into the compiled program, though. In Ruby, you can access the data structures created by the interpreter, and it is natural to do so via the Symbol type it uses in them. It is not essential - it can all be implicit as with >> attr_accessor "liquids" but the symbols exist, so why hide them from the programmer? As to why you would want to use Symbol#to_i, there is basically one reason for using it - as an array index. def initialize; @values_array = []; end def get_value( sym ) @values_array[sym.to_i] end def set_value( sym, obj ) @values_array[sym.to_i] = obj end That's only an optimisation over def initialize; @values_map = {}; end def get_value( str ) @values_map[str] end def set_value( str, obj ) @values_map[str] = obj end but it is an optimisation, and potentially a significant one, which is why Symbols are used internally instead of strings in the first place. Of course, if you wanted to do the above, and symbols didn't exist, you could implement them yourself in 30 lines. Again, Symbol is not there because you need it - it's there because Ruby needs it, and you can use it if you want. class Cymbal @@byname = Hash.new @@nexti = 0 def initialize( name ) # not thread-safe - needs a mutex. @name = name @c_id = @@nexti @@nexti+=1 @@byname[name] = self end def Cymbal.get( name ) @@byname[ name ] || new( name ) end def Cymbal.all_cymbals @@byname.values end def to_s ; @name ; end def to_i ; @c_id ; end private_class_method :new end The only difference between cym1 = :Gas and cym2 = Cymbal.get("Gas") is that the Symbol object :Gas is created as ruby parses the cym1 line, but the Cymbal object is only created when ruby executes the cym2 line. This doesn't change the real semantics, though you can prove it by playing with Symbol#all_symbols: s1 = Symbol.all_symbols if nil :aardvark end s2 = Symbol.all_symbols s2 - s1 => [:aardvark, :s2] > > Steve Litt > http://www.troubleshooters.com > slitt / troubleshooters.com > -- Andrew McGuinness http://anomalyuk.blogspot.com/