Symbol class for a newbie, I'm just not getting it. :-(

“some_identifier” vs “:some_identifier”?

I’m just not getting the Symbol type. What does this buy me? When would I want
to use it? What is it analogous to in another language?

I understand how to use the colon with attr_accessor through rote memorization;
but I don’t really understand it. :frowning:

Can someone provide a very simple example of its proper use and advantages?

Thanks very much for your patience,
Christopher

Christopher J. Meisenzahl CPS, CSTE
Senior Software Testing Consultant
Spherion
christopher.j.meisenzahl@citicorp.com

As far as I understand(from using the C API), it is just they way Ruby
represents method names internally, not something you should really
worry about, just use it with methods that require a symbol.

In practice, it buys you nothing.

···

christopher.j.meisenzahl@citicorp.com wrote:

“some_identifier” vs “:some_identifier”?

I’m just not getting the Symbol type. What does this buy me? When would I want
to use it? What is it analogous to in another language?

I’m just not getting the Symbol type.

Symbols are very much like strings, but with some important differences.
When you construct two strings with the same contents, e.g.

 s1 = "Hello"
 s2 = "Hello"

it is true that the strings are equivalent, i.e. both of these
expressions:

 s1 == s2
 s1.eql? s2

are true. But s1 and s2 don’t refer to the same string object, i.e.

 s1.equal? s2

is not true. In other words, you’ve got two little blobs of memory
storing the same data. Sometimes, that’s what you intended, but in a lot
of cases – especially where you’re using strings as constants – it’s a
waste.

That’s where symbols come in. When you construct a symbol object it
creates a unique entry in an (internal) symbol table for this string
that all future symbol reference will refer to. In other words,

 s1 = :Hello
 s2 = :Hello
 s1 == s2      # this is still true
 s1.eql? s2    # so is this
 s1.equal? s2  # this is now also true

What does this buy me? When would I want to use it?

If nothing else, it may help to reduce the amount of string allocation,
deallocation, etc. in your programs. For example, if I wrote the
following snippet in Ruby:

 allUsers.each do |userName|
   if userName == "Christopher"
     # found a match
   end
 end

Ruby would (presumably) allocate a new (temporary) string object, with
the contents “Christopher”, for each pass through the loop. It would
also perform that many character-by-character string comparisons. For a
lot of user names, that’s going to be slow. In contrast, this bit of code:

 allUsers.each do |userName|
   if userName.intern == :Christopher
     # found a match
   end
 end

would run significantly faster since the “Christopher” symbol gets added
to the symbol table once and subsequent references just point to that
entry. Also, since Symbol objects mainly consist of an index into the
symbol table, comparing symbols is very fast – as fast as comparing two
integer values to each other. This code could be made even faster if the
“allUsers” array stored symbols directly instead of storing strings, but
you get the idea.

What is it analogous to in another language?

I think symbols probably got popular with LISP (where they’re called
“atoms”, and are one of the basic data types). I remember that Python
supported this idea (often called “interning” strings) via an intern()
function. C and C++ don’t have any (standard) equivalent.

Hope this helps,

Lyle

···

christopher.j.meisenzahl@citicorp.com wrote:

Hi,

“some_identifier” vs “:some_identifier”?

I’m just not getting the Symbol type. What does this buy me? When would I want
to use it? What is it analogous to in another language?

I understand how to use the colon with attr_accessor through rote memorization;
but I don’t really understand it. :frowning:

Can someone provide a very simple example of its proper use and advantages?

Here’s a recent thread on the subject…
http://groups.google.com/groups?threadm=F5bQ30ITd1U4qECJ9O500008e6a%40hotmail.com&rnum=2

I personally like symbols for certain kinds of constants in my
code. For ex:

hat.add_relation(:synonym, “chapeau”)
hat.add_relation(:has_part, “brim”)
hat.add_relation(:kind_of, “clothing”)

Others have pointed out that using symbols thusly allows me to
misspell my constants without Ruby catching my mistakes… But
this doesn’t seem to bother me. :slight_smile:

Hope this helps,

Bill

···

From: christopher.j.meisenzahl@citicorp.com

There’s a section in the FAQ in this. Search for “symbol” at
http://www.rubygarden.org/iowa/faqtotum

Gavin

···

----- Original Message -----
From: christopher.j.meisenzahl@citicorp.com

“some_identifier” vs “:some_identifier”?

If nothing else, it may help to reduce the amount of string allocation,
deallocation, etc. in your programs. For example, if I wrote the following
snippet in Ruby:

 allUsers.each do |userName|
   if userName == "Christopher"
     # found a match
   end
 end

Ruby would (presumably) allocate a new (temporary) string object, with the
contents “Christopher”, for each pass through the loop. It would also
perform that many character-by-character string comparisons. For a lot of
user names, that’s going to be slow. In contrast, this bit of code:

 allUsers.each do |userName|
   if userName.intern == :Christopher
     # found a match
   end
 end

would run significantly faster since the “Christopher” symbol gets added
to the symbol table once and subsequent references just point to that
entry.

But wouldn’t doing that intern each time in the loop hurt you more? I tested
the above idea with this code:

– cut here ----------------------------------------------------------------
require “profile”

def string_test( a )
a.each do |s|
if s == “MMM”
# Do nothing
end
end
end

def symbol_test( a )
a.each do |s|
if s.intern == :MMM
# Do nothing
end
end
end

a = ( “AAA” … “ZZZ” ).collect

string_test( a )
symbol_test( a )
– cut here ----------------------------------------------------------------

and found that the symbol comparison test was slower:

···

,----

0.00 26.11 0.00 1 0.00 13620.00 Object#symbol_test
0.00 26.11 0.00 1 0.00 7460.00 Object#string_test
`----

   Also, since Symbol objects mainly consist of an index into the

symbol table, comparing symbols is very fast – as fast as comparing two
integer values to each other. This code could be made even faster if the
“allUsers” array stored symbols directly instead of storing strings, but
you get the idea.

That does make a difference but it doesn’t seem to be a very significant
gain, not as significant as the above paragraph might suggest:

– cut here ----------------------------------------------------------------
require “profile”

def string_test( a )
a.each do |s|
if s == “MMM”
# Do nothing
end
end
end

def symbol_test( a )
a.each do |s|
if s == :MMM
# Do nothing
end
end
end

a = ( “AAA” … “ZZZ” ).collect
s = a.collect {|s| s.intern }

string_test( a )
symbol_test( s )
– cut here ----------------------------------------------------------------

Giving:

,----

0.00 29.43 0.00 1 0.00 7860.00 Object#symbol_test
0.00 29.43 0.00 1 0.00 8080.00 Object#string_test
`----

Am I missing something here?


Dave Pearson
http://www.davep.org/