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/