Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What is the difference between :foo and "foo" ?

24 views
Skip to first unread message

Surgeon

unread,
Dec 28, 2005, 2:23:09 PM12/28/05
to
Hi,

I am a Ruby newbie. I wish I didn't post such a simple question here
but I had to.
What is the difference between :foo (a keyword) and "foo"(a string).
Can they be used interchangeably? Are they fundamentally same and is
the only difference performance?

Thanks in advance

Alex Knaub

unread,
Dec 28, 2005, 2:32:43 PM12/28/05
to

Steve Litt

unread,
Dec 28, 2005, 2:47:16 PM12/28/05
to

The preceding URL tells me unequivically that symbols aren't strings, but
really doesn't tell me too much about what they are, other than what,
names???

I still don't understand why it's

attr_reader :fname, :lname

instead of

attr_reader @fname, @lname

How does attr_reader know that :fname corresponds to @fname. Seems like magic
to me.

SteveT

Steve Litt
http://www.troubleshooters.com
sl...@troubleshooters.com


James Edward Gray II

unread,
Dec 28, 2005, 3:00:13 PM12/28/05
to
On Dec 28, 2005, at 1:47 PM, Steve Litt wrote:

> On Wednesday 28 December 2005 02:32 pm, Alex Knaub wrote:
>> 2005/12/28, Surgeon <biyok...@gmail.com>:
>>> Hi,
>>>
>>> I am a Ruby newbie. I wish I didn't post such a simple question here
>>> but I had to.
>>> What is the difference between :foo (a keyword) and "foo"(a string).
>>> Can they be used interchangeably? Are they fundamentally same and is
>>> the only difference performance?
>>
>> http://onestepback.org/index.cgi/Tech/Ruby/
>> SymbolsAreNotImmutableStrings.re
>> d
>
> The preceding URL tells me unequivically that symbols aren't
> strings, but
> really doesn't tell me too much about what they are, other than what,
> names???

As one of the people guilty of saying what that article says we
shouldn't, I better try to get back in Jim's good graces by answering
this one... ;)

> I still don't understand why it's
>
> attr_reader :fname, :lname
>
> instead of
>
> attr_reader @fname, @lname
>
> How does attr_reader know that :fname corresponds to @fname. Seems
> like magic
> to me.

Attributes of a class logically correspond to instance variables in
many cases, don't you think? Ruby's just making that assumption for
you.

When I see:

some_call @my_variable

I expect what is held inside of @my_variable to get passed to
some_call(), not the variable name itself. What you describe would
be the opposite and that would surely surprise a lot of people.

Furthermore, Symbols are commonly used to refer to method names (as
Ruby uses them for this internally). That's really what we are doing
here, creating new methods by name, so it's a good fit.

Hope that makes some sense.

James Edward Gray II


Ross Bamford

unread,
Dec 28, 2005, 3:14:48 PM12/28/05
to
On Wed, 28 Dec 2005 19:47:16 -0000, Steve Litt <sl...@earthlink.net> wrote:

>> http://onestepback.org/index.cgi/Tech/Ruby/SymbolsAreNotImmutableStrings.re
>> d
>
> The preceding URL tells me unequivically that symbols aren't strings, but
> really doesn't tell me too much about what they are, other than what,
> names???
>

I agree with Jim (obviously ;)) that describing symbols as immutable
strings isn't ideal, but it did help me break away from the idea that they
worked on some kind of internal voodoo. An object with a name seems a good
way to put it - maybe 'an object that is a name, by which it can be
referenced anywhere'.

So :foo is just the name, 'foo', as an object. A singleton object. Kind of
like the literal '4' - wherever you use that literal, you'll get the same
instance of Fixnum (incidentally, with object_id 9), whether you mean four
loops, or four bananas, since four is four the same one will do.

> I still don't understand why it's
>
> attr_reader :fname, :lname
>
> instead of
>
> attr_reader @fname, @lname
>
> How does attr_reader know that :fname corresponds to @fname. Seems like
> magic
> to me.
>

You're looking at it backwards. You give attr_reader a name (or several).
It then takes those names, and just creates methods with each one. There's
no connection between the symbols, and the methods - it's just like
passing in a string (which you can actually do instead) except that,
instead of creating a new string with the characters 'lname' or whatever,
it just grabs the single symbol with that name, or makes it if it doesn't
already exist. It saves memory, and is better on performance in many types
of system. The reader method accesses an instance variable, again named
from the symbol, and it gets created automatically at startup.

So the symbol just gives you the name - it's up to you to supply the
context (like 'an attribute reader with this name' above).

--
Ross Bamford - ro...@roscopeco.remove.co.uk

Ross Bamford

unread,
Dec 28, 2005, 3:22:17 PM12/28/05
to
On Wed, 28 Dec 2005 20:00:13 -0000, James Edward Gray II
<ja...@grayproductions.net> wrote:

> On Dec 28, 2005, at 1:47 PM, Steve Litt wrote:
>
>> On Wednesday 28 December 2005 02:32 pm, Alex Knaub wrote:
>>>
>>> http://onestepback.org/index.cgi/Tech/Ruby/
>>> SymbolsAreNotImmutableStrings.re
>>> d
>>
>> The preceding URL tells me unequivically that symbols aren't strings,
>> but
>> really doesn't tell me too much about what they are, other than what,
>> names???
>
> As one of the people guilty of saying what that article says we
> shouldn't, I better try to get back in Jim's good graces by answering
> this one... ;)
>

I still think it's a useful description, at least for those of us coming
from Java. In fact it was reading one of your 'priors' that set me on the
road to understanding a bit more - I couldn't get away from the internal
connotations of the word 'Symbol' until I read that.

I still really think of symbols as an immutable _representation of_ a
string. Although it's not entirely accurate it suits me I think. I am
liking the Object with name thing the more I think about it. Or 'a name
referenced by name'. Or whatever. :)

Yohanes Santoso

unread,
Dec 28, 2005, 3:25:37 PM12/28/05
to
Alex Knaub <akn...@gmail.com> writes:

What a coincidence. Seems like Jim and I finally had enough of people
conflating symbols and immutable strings on the same day.

http://microjet.ath.cx/WebWiki/2005.12.27_UsingSymbolsForTheWrongReason.html

YS.


Bill Kelly

unread,
Dec 28, 2005, 3:26:51 PM12/28/05
to
From: "Steve Litt" <sl...@earthlink.net>

>
> I still don't understand why it's
>
> attr_reader :fname, :lname
>
> instead of
>
> attr_reader @fname, @lname
>
> How does attr_reader know that :fname corresponds to @fname. Seems like magic
> to me.

If this helps, attr_reader itself isn't magic or special Ruby syntax,
it's just a method that defines helper-methods for you, using whatever
names you provide it. The symbols :fname, :lname above are just
interpreted by attr_reader as names of methods we are asking it to
define, and names of corresponding instance variables we want it to
access. (Note that: attr_reader "fname", "lname" also works - it's
less convenient to type than the symbol equivalents.)

I think there are more elegant ways to do this, but here's one way we
could define our own attr_reader:

def my_attr_reader(*list_of_attr_names)
list_of_attr_names.each do |name|
eval <<-ENDFUNC
def #{name}
@#{name}
end
ENDFUNC
end
end

class Foo
my_attr_reader :foo, :bar
def initialize
@foo = 123
@bar = 456
end
end

f = Foo.new
puts f.foo, f.bar

# the above program outputs:
123
456


So you can see my_attr_reader is just taking a list of "names",
which we conveniently specify as symbols (but we could also
specify as strings, if we wanted.) Then my_attr_reader just
proceeds to use eval to define methods with the requested name,
accessing the corresponding instance variable. (Again, there
are probably more elegant ways to do this than using eval; it's
just one way.)


Hope this helps,

Regards,

Bill

Steve Litt

unread,
Dec 28, 2005, 3:35:54 PM12/28/05
to

Oh, I get it!!!

In see itwould be some_call(&@my_variable), and in ruby it's
some_call(:my_variable). One thing -- why not some_call(:@my_variable)?


> What you describe would
> be the opposite and that would surely surprise a lot of people.
>
> Furthermore, Symbols are commonly used to refer to method names (as
> Ruby uses them for this internally). That's really what we are doing
> here, creating new methods by name, so it's a good fit.

Ah ha! That's why I need to pass callback routines entry and exit that occur
in object cb, like this:

walker = Walker.new(node, cb.method(:entry), cb.method(:exit))

James Edward Gray II

unread,
Dec 28, 2005, 3:48:03 PM12/28/05
to
On Dec 28, 2005, at 2:35 PM, Steve Litt wrote:

> One thing -- why not some_call(:@my_variable)?

This is a fair question I've asked myself once or twice. Ruby seems
to change it's mind on this sometimes too:

>> class MyClass
>> def initialize( var )
>> @var = var
>> end
>> attr_reader :var # I guess we're talking about the method here
(no @)
>> def fetch( name )
>> instance_variable_get("@#{name}") # but we need the @ now
>> end
>> end
=> nil
>> ex = MyClass.new(123)
=> #<MyClass:0x32565c @var=123>
>> ex.var
=> 123
>> ex.fetch(:var)
=> 123

James Edward Gray II


Johannes Friestad

unread,
Dec 28, 2005, 3:50:23 PM12/28/05
to
attr_reader :fname, :lname (attr_reader "fname", "lname" works too)
knows how to map the names because that's what an attribute is: A
read-only attribute 'foo' will have a getter method named 'foo' and an
instance variable '@foo'. It's a common enough convention, used in
other languages as well. (In Java, it would be a method 'getFoo()' and
an instance variable 'foo'.)

The difference between symbols and strings:

A string is a sequence of characters. You can append to a string,
parse it, split it, iterate over characters or lines and so forth. Two
strings containing the same character sequence (say "abc" and "abc")
are equal, but not necessarily the same object.
Strings can be basically any character or byte sequence, like the
contents of a text or binary file. Strings are local and are garbage
collected when they are no longer referred to, like other objects.

A symbol is atomic, immutable and unique: It cannot be parsed or
modified, and all references to a symbol with a given name (say :abc)
refers to the same object.
Symbols tend to be short, simple names, like a single word with no
whitespace. Symbols are global, and hang around quite a bit longer
than strings normally do, often until the end of the program.

Symbols are (or can be) quicker for hash lookup, since it is
sufficient to compare object identity to find whether two symbols are
the same, while strings must be compared character by character. You
are unlikely to notice the difference unless your program uses hashes
heavily.

So they are not fundamentally the same. But there are a some cases
where they can be used interchangeably, like naming an attribute or as
hash key.

Reasons for using symbols instead of strings are mostly based on
convention. Personally, I use them basically because I save a
keystroke in typing them :)

Does this make it any clearer?

johannes

> The preceding URL tells me unequivically that symbols aren't strings, but
> really doesn't tell me too much about what they are, other than what,
> names???
>
> I still don't understand why it's
>
> attr_reader :fname, :lname
>
> instead of
>
> attr_reader @fname, @lname
>
> How does attr_reader know that :fname corresponds to @fname. Seems like magic
> to me.
>
> SteveT
>
> Steve Litt
> http://www.troubleshooters.com
> sl...@troubleshooters.com
>
>


--
Johannes Friestad
johannes...@gmail.com


Austin Ziegler

unread,
Dec 28, 2005, 3:51:03 PM12/28/05
to
On 28/12/05, Steve Litt <sl...@earthlink.net> wrote:
> Oh, I get it!!!
> In see itwould be some_call(&@my_variable), and in ruby it's
> some_call(:my_variable). One thing -- why not some_call(:@my_variable)?

No.

There is nothing even remotely close in C, C++, or Java.

In Ruby, it's *not* some_call(:my_variable), it's some_call(:my_name).

When you do:

attr_accessor :my_name

You do NOT get a @my_name variable. You get two methods: Foo#my_name
and Foo#my_name= -- that's it. Consider:

>> class Foo
>> attr_accessor :bar
>> end
=> nil
>> baz = Foo.new
=> #<Foo:0x2d8aea8>

Note. Thus far, there's no instance variable @bar on the Foo instance baz.

>> Foo.instance_methods(false)
=> ["bar", "bar="]

There's our instance methods.

>> baz.bar = 32
=> 32
>> baz
=> #<Foo:0x2d8aea8 @bar=32>

Now that we've called Foo#bar= on the baz instance of Foo class, baz
finally has a @bar instance variable. But not a moment before, unless
we instantiate such an instance variable prior to the call of
Foo#bar=.

So :bar is a name (Symbol) used to refer to the name :bar. It is used
by attr_accessor to create two methods that also operate on a
like-named instance variable. But :bar doesn't refer to a variable,
which is precisely why it isn't :@bar -- you're not creating a
variable @bar, you're creating instance methods #bar and #bar= that
happen to work on @bar in the instance.

-austin
--
Austin Ziegler * halos...@gmail.com
* Alternate: aus...@halostatue.ca


Johannes Friestad

unread,
Dec 28, 2005, 4:12:24 PM12/28/05
to
Depends on the call.
In the case of attr_*, it's because you're naming the attribute, not
the methods or the variable. The convention (and the code behind
attr_*) will do the expansion.
In instance_variable_get(...), you are explicitly looking for a
variable, and naturally supply the variable name.
In both cases, the symbol is just a name. What we are naming depends
on the context.

jf

ara.t....@noaa.gov

unread,
Dec 28, 2005, 4:17:32 PM12/28/05
to
On Thu, 29 Dec 2005, Johannes Friestad wrote:


> Symbols are (or can be) quicker for hash lookup, since it is sufficient to
> compare object identity to find whether two symbols are the same, while
> strings must be compared character by character. You are unlikely to notice
> the difference unless your program uses hashes heavily.

i see this claim all the time but never data supporting it, all my test
programs have shown the opposite to be true. see

http://groups.google.com/group/comp.lang.ruby/browse_frm/thread/c881186317ef8d33/e20e6e93c99b9924?q=symbol+string+hash+speed+howard&rnum=1#e20e6e93c99b9924

for some sample code.

running that sample code with the latest ruby (1.8.4) shows the gap has
narrowed, but strings are still beating symbols on my box:

---
- Symbol:
max: "0.0019838809967041"
avg: "0.0000033428150346"
min: "0.0000019073486328"
- String:
max: "0.0019280910491943"
avg: "0.0000037288846215"
min: "0.0000019073486328"

also, don't forget that symbols are __never__ freed.


this is a severe memory leak:

loop{ Time::now.to_f.to_s.intern }

this is not

loop{ Time::now.to_f.to_s }


strings certainly play nicer with yaml as well.

regards.

-a
--
===============================================================================
| ara [dot] t [dot] howard [at] noaa [dot] gov
| all happiness comes from the desire for others to be happy. all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================


a.rb


Johannes Friestad

unread,
Dec 28, 2005, 4:38:27 PM12/28/05
to
That's where the 'can be' part comes in :)
The point is that symbols support quicker lookup by their nature.
Whether they are quicker in practice will depend on the
implementation. From the timings you give, it looks like symbol lookup
is implemented by converting the symbol to a string and doing string
lookup. Which is obviously not quicker :)

My data were from a Common Lisp implementation, where symbols were
quicker in practice as well.
Sorry, didn't know about the Ruby implementation. Thanks for the info.


jf

James Britt

unread,
Dec 28, 2005, 4:41:48 PM12/28/05
to


Question: Would using a constant be equally suitable for expressing
intention, and (possibly) less error-prone?

# Assume ConstUtils.next_value
# ensures unique values
HOST = ConstUtils.next_value
PORT = ConstUtils.next_value

foo1 = {
HOST => 'localhost',
PORT => 80
}

A downside to using symbols as constants is that this will not raise any
exceptions:


foo1 = {
:hots => 'localhost',
:prt => 80
}

But a typo in a constant will.


James
--

http://www.ruby-doc.org - Ruby Help & Documentation
http://www.artima.com/rubycs/ - Ruby Code & Style: Writers wanted
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools


ara.t....@noaa.gov

unread,
Dec 28, 2005, 4:51:29 PM12/28/05
to
On Thu, 29 Dec 2005, Johannes Friestad wrote:

> That's where the 'can be' part comes in :)
> The point is that symbols support quicker lookup by their nature.
> Whether they are quicker in practice will depend on the
> implementation. From the timings you give, it looks like symbol lookup
> is implemented by converting the symbol to a string and doing string
> lookup. Which is obviously not quicker :)

i never consider that as an impl - i bet your right though... time for me to
read the source.

cheers.

Simon Kröger

unread,
Dec 28, 2005, 4:56:47 PM12/28/05
to

I'm all with you, you may even use

HOST = :host
PORT = :port

instead of ConstUtils.next_value, but anybody else will tell you
to use modul tests to find your errors instead of letting the
interpreter find them.

(Agreed, sharp knifes are better than dull ones, but even if all
you need is a spoon?)

cheers

Simon

Johannes Friestad

unread,
Dec 28, 2005, 5:00:08 PM12/28/05
to
> Question: Would using a constant be equally suitable for expressing
> intention, and (possibly) less error-prone?

I agree. But there's no law against using both:

HOST = :host
PORT = :port

foo1 = {
HOST => 'localhost',
PORT => 80
}

which is equally safe, simpler to read, doesn't need the ConstUtil,
and automagically gives a constant with a readable string value.

jf

> > What a coincidence. Seems like Jim and I finally had enough of people
> > conflating symbols and immutable strings on the same day.
> >

> > http://microjet.ath.cx/WebWiki/2005.12.27_UsingSymbolsForTheWrongReasonhtml

Jim Weirich

unread,
Dec 28, 2005, 5:12:57 PM12/28/05
to
ara wrote:
> i see this claim all the time but never data supporting it, all my test
> programs have shown the opposite to be true.

My benchmark shows symbols to have a slight edge. I've attached my
benchmark at the end for review. (Benchmarks are tricky ... sometimes
you don't measure what you think you are measuring).

$ ruby string_symbol_time.rb
Strings Filling
14.080000 0.090000 14.170000 ( 14.406058)
Strings Fetching
4.320000 0.030000 4.350000 ( 4.355025)

Symbols Filling
12.300000 0.030000 12.330000 ( 12.561648)
Symbols Fetching
3.370000 0.030000 3.400000 ( 3.461109)

> also, don't forget that symbols are __never__ freed.

True, but when used properly, this is rarely a concern. If they are
used as programmer names for things, then the number of symbols is
finite and not likely to grow and consume memory as the program runs.

If however, you are dynamically creating symbols by interning strings, I
would suggest you review your use of symbols and consider using strings
instead.

--
-- Jim Weirich

-------------------------------------------------------------------
#!/usr/bin/env ruby

require 'benchmark'

SIZE = 100
N = 10000

def make_str_keys
(1..SIZE).collect { |i| "key#{i}" }
end

def make_sym_keys(strs)
strs.collect { |s| s.intern }
end

def populate(keys)
result = {}
keys.each_with_index do |k, i|
result[k] = i
end
result
end

def fetch(keys, hash)
keys.each do |key| hash[key] end
end

strs = make_str_keys
syms = make_sym_keys(strs)

str_hash = populate(strs)
sym_hash = populate(syms)

puts "Strings Filling"
puts Benchmark.measure {
N.times do
populate(strs)
end
}

puts "Strings Fetching"
puts Benchmark.measure {
N.times do
fetch(strs, str_hash)
end
}

puts
puts "Symbols Filling"
puts Benchmark.measure {
N.times do
populate(syms)
end
}

puts "Symbols Fetching"
puts Benchmark.measure {
N.times do
fetch(syms, sym_hash)
end
}

--
Posted via http://www.ruby-forum.com/.


Jim Weirich

unread,
Dec 28, 2005, 5:15:36 PM12/28/05
to
James Gray wrote:
> As one of the people guilty of saying what that article says we
> shouldn't, I better try to get back in Jim's good graces by answering
> this one... ;)

James, you have never been out of my good graces (despite how you
describe symbols) :)

--
-- Jim Weirich

Dan Diebolt

unread,
Dec 28, 2005, 5:18:54 PM12/28/05
to
How about devoting the next Ruby Quiz to coming up with the best-of-class examples, self paced-tutorial and documentation to settle the :symbol vs "string" issue? At some point you have to ask yourself are the explanations given so far to inquiring users adequate. The fact that this question keeps coming up must be seen as evidence that there is something lacking in the explanations previously given. At a minimum all the explanations give so far should be edited up into a FAQ entry that the experts can agree upon. Just my two cents.
6.1 What does :var mean? A colon followed by a name generates an integer(Fixnum) called a symbol which corresponds one to one with the identifier. "var".intern gives the same integer as :var, but the ``:'' form will create a local symbol if it doesn't already exist. The routines "catch", "throw", "autoload", and so on, require a string or a symbol as an argument. "method_missing", "method_added" and "singleton_method_added" (and others) require a symbol. The fact that a symbol springs into existence the first time it is referenced is sometimes used to assign unique values to constants: NORTH = :NORTH
SOUTH = :SOUTH
EAST = :EAST
WEST = :WEST

http://www.rubycentral.com/faq/rubyfaqall.html#s6


---------------------------------
Yahoo! for Good - Make a difference this year.

Yohanes Santoso

unread,
Dec 28, 2005, 5:21:14 PM12/28/05
to
James Britt <jam...@neurogami.com> writes:

> Question: Would using a constant be equally suitable for expressing
> intention, and (possibly) less error-prone?

I would say that if your language does not provide a means for you to
define your own identifier, then it would be acceptable.

But this seems pointless in ruby.


> # Assume ConstUtils.next_value
> # ensures unique values
> HOST = ConstUtils.next_value
> PORT = ConstUtils.next_value

For discussion simplicity sake, I'd just assume next_value returning
integers.

>
> foo1 = {
> HOST => 'localhost',
> PORT => 80
> }

p foo1 ==> {32=>"localhost", 238=>80}

That makes debugging difficult. Since the value of HOST/PORT is
volatile (it could change depending on how next_value generates the
integers, and also if you, say, insert 'DOMAIN =
ConstUtils.next_value' between HOST and PORT assignments),
understanding past debugging outputs(e.g., in a log file) would be
harder as well.

> A downside to using symbols as constants is that this will not raise
> any exceptions:
>
>
> foo1 = {
> :hots => 'localhost',
> :prt => 80
> }

True, typos are such a hard error to prevent. Fortunately, there are
ways around that.


<example>
module ConfigIdentifiers
[:host, :port].each{|x| const_set(x.to_s.upcase, x)}
end

include ConfigIdentifiers


foo1 = { HOST => 'localhost', PORT => 80}

</example>

is a solution.

But my experience as someone who has made many typos such as that (and
still is making them) is my test cases usually catch them and those
that manage to elude are easily identified (and corrected) manually.


YS.


ara.t....@noaa.gov

unread,
Dec 28, 2005, 5:24:57 PM12/28/05
to
On Thu, 29 Dec 2005, Dan Diebolt wrote:


> NORTH = :NORTH
> SOUTH = :SOUTH
> EAST = :EAST
> WEST = :WEST


%w( NORTH SOUTH EAST WEST ).each{|c| const_set c, c}

;-)

Jim Weirich

unread,
Dec 28, 2005, 5:30:44 PM12/28/05
to
Jim Weirich wrote:
>> also, don't forget that symbols are __never__ freed.
>
> True, but when used properly, this is rarely a concern. If they are
> used as programmer names for things, then the number of symbols is
> finite and not likely to grow and consume memory as the program runs.

Here I am replying to my own posting, but I think this point could use
some elaboration.

Why are symbols not garbage collected? Because a symbol represents a
mapping from a string name to a unique object. Anytime in the execution
of the program, if that name is used for a symbol, the original symbol
object must be returned. If the symbol is garbage collected, then a
later reference to the symbol name will return a different object.
That's generally frowned upon (although I don't really see the harm. If
the original symbol was GC'ed, nobody cared what the original object was
anyways. But that's the way it works).

This might be one area where the "Symbol isa immutable string" meme
might be doing some real harm. We if think of symbols as strings, then
we tend to build symbols dynamically like we do strings. This is when
the memory leak" problem of symbols becomes a problem.

Here's a rule of thumb ... if a programmer never sees the symbol name in
the code base, then you probably should be using a string rather than a
symbol.

I'm not sure if this helped, or just muddied the water more.

--
-- Jim Weirich

James Britt

unread,
Dec 28, 2005, 6:33:27 PM12/28/05
to
Johannes Friestad wrote:
..

>
> HOST = :host
> PORT = :port
> foo1 = {
> HOST => 'localhost',
> PORT => 80
> }
>
> which is equally safe, simpler to read, doesn't need the ConstUtil,
> and automagically gives a constant with a readable string value.
>

My hack was a quicky to flesh out the example. After sending it I
thought about assigning symbols. My main point was that if one mistypes
a symbol name, Ruby doesn't care. Unit tests should catch this, but
using constants might just help things along because of the immediate
error. And it might more clearly express intent.

gwt...@mac.com

unread,
Dec 28, 2005, 6:36:32 PM12/28/05
to

On Dec 28, 2005, at 3:22 PM, Ross Bamford wrote:
> On Wed, 28 Dec 2005 19:47:16 -0000, Steve Litt
> <sl...@earthlink.net> wrote:
>> The preceding URL tells me unequivically that symbols aren't
>> strings, but
>> really doesn't tell me too much about what they are, other than what,
>> names???
>
> An object with a name seems a good way to put it - maybe 'an object
> that is a name, by which it can be referenced anywhere'.

At the new_haven.rb December meeting, I gave a short presentation on
Symbols
versus Strings. I described Symbols as:

Named numbers, you pick the name, Ruby picks the number

The number that Ruby picks is effectively an index into an internal
table
with some bit shifting and masking to encode the index into a 32-bit
Ruby
reference value.

The internal table gets new entries when a symbol literal is parsed
or when String#to_sym is called.


Gary Wright

Mauricio Fernandez

unread,
Dec 28, 2005, 7:24:25 PM12/28/05
to
On Thu, Dec 29, 2005 at 07:30:44AM +0900, Jim Weirich wrote:
> Jim Weirich wrote:
> Why are symbols not garbage collected? Because a symbol represents a
> mapping from a string name to a unique object. Anytime in the execution
> of the program, if that name is used for a symbol, the original symbol
> object must be returned. If the symbol is garbage collected, then a
> later reference to the symbol name will return a different object.
> That's generally frowned upon (although I don't really see the harm. If
> the original symbol was GC'ed, nobody cared what the original object was
> anyways. But that's the way it works).

Keep in mind that symbols are immediate values backed by
the global_symbols table (actually global_symbols.tbl and
global_symbols.rev, for the name => id and id => name associations
respectively). Since the lower bits encode information like ID_LOCAL,
ID_INSTANCE, etc., symbol values cannot point to the appropriate entry
in global_symbols the same way VALUEs for normal objects point to RVALUE
slots in the object heaps. [1]

During the mark phase, the stack must be scanned for references to live
objects. It's easy to verify if an unsigned (long) long seems to point
to an object, by seeing if the address falls into the area occupied by
some heap and actually corresponds to a slot. In order to mark symbol entries
in global_symbols, a lookup in global_symbols.rev would be needed for each
word in the stack. I conjecture that this would be relatively expensive, but
there are probably better reasons for the current behavior (it's too late to
read the sources in detail though :)...

[1] Even if those bits were not used, another level of indirection would
be needed due to the way the hash table works.

--
Mauricio Fernandez


Mauricio Fernandez

unread,
Dec 28, 2005, 8:12:24 PM12/28/05
to
On Thu, Dec 29, 2005 at 06:51:29AM +0900, ara.t....@noaa.gov wrote:
> On Thu, 29 Dec 2005, Johannes Friestad wrote:
> >That's where the 'can be' part comes in :)
> >The point is that symbols support quicker lookup by their nature.
> >Whether they are quicker in practice will depend on the
> >implementation. From the timings you give, it looks like symbol lookup
> >is implemented by converting the symbol to a string and doing string
> >lookup. Which is obviously not quicker :)
>
> i never consider that as an impl - i bet your right though... time for me to
> read the source.

I think :sym.hash uses the method definition from Kernel (inherited through
Object) and :sym.eql?(:foo) would also reuse the existing definition.

[see C code at the bottom]

So there's seemingly no reason for symbol hashing/comparison not to be
faster than for strings. The benchmarks you linked to, as well as Jim's,
use relatively short strings, but one can exaggerate the effect:


# >> Strings Filling
# >> 5.800000 0.000000 5.800000 ( 6.302649)
# >> Strings Fetching
# >> 3.120000 0.010000 3.130000 ( 3.404679)
# >>
# >> Symbols Filling
# >> 2.120000 0.000000 2.120000 ( 2.326393)
# >> Symbols Fetching
# >> 0.640000 0.000000 0.640000 ( 0.700178)


#!/usr/bin/env ruby

require 'benchmark'

SIZE = 100
N = 10000

RUBY_VERSION # => "1.8.4"

def make_str_keys
(1..SIZE).collect { |i| "long key" * i}
end


rb_define_method(rb_mKernel, "hash", rb_obj_id, 0);
..

VALUE
rb_obj_id(VALUE obj)
{
if (SPECIAL_CONST_P(obj)) {
return LONG2NUM((long)obj);
}
return (VALUE)((long)obj|FIXNUM_FLAG);
}


rb_define_method(rb_mKernel, "eql?", rb_obj_equal, 1);
..

static VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
if (obj1 == obj2) return Qtrue;
return Qfalse;
}

--
Mauricio Fernandez


Eero Saynatkari

unread,
Dec 28, 2005, 8:44:18 PM12/28/05
to

While, technically speaking, both of you are absolutely and
undeniably correct (with one correction: Symbols are not Strings),
such a conflation is the best way to get someone over the
initial confusion. As this thread quite well demonstrates,
a definition for Symbols is quite difficult to come up with.

To paraphrase fifteen thousand fourty-three mediocre
comedians over the last three centuries:

"A Symbol is like a word, a sentence, a phrase, a
description or, perhaps, a name. Except sometimes."

> YS.


E

Johannes Friestad

unread,
Dec 28, 2005, 9:25:51 PM12/28/05
to
> On Thu, 29 Dec 2005, Johannes Friestad wrote:
>
>
> > Symbols are (or can be) quicker for hash lookup, since it is sufficient to
> > compare object identity to find whether two symbols are the same, while
> > strings must be compared character by character. You are unlikely to notice
> > the difference unless your program uses hashes heavily.
>
> i see this claim all the time but never data supporting it, all my test
> programs have shown the opposite to be true.
>

Along with Jim and Mauricio, my tests indicate that symbols are
consistently quicker, even on short strings.

Here's my benchmark
-------
def bmark_string_symb
require 'benchmark'
strings, symbols=[], []
n, m=100, 1000
hash={}
n.times {|x| strings<<strings<<x.to_s+"key"}
strings.each {|s| symbols<<s.to_sym}
# initialize hash
strings.each {|s| hash[s]=1}
symbols.each {|s| hash[s]=1}
Benchmark.bm(10) do |b|
b.report("string set") { m.times {|x| strings.each {|s| hash[s]=x}}}
b.report("symbol set") { m.times {|x| symbols.each {|s| hash[s]=x}}}
b.report("string get") { m.times {|x| strings.each {|s| hash[s]}}}
b.report("symbol get") { m.times {|x| symbols.each {|s| hash[s]}}}
end
end
-------

and here are some results:
-------
irb(main):080:0> bmark_string_symb
user system total real
string set 0.219000 0.016000 0.235000 ( 0.235000)
symbol set 0.141000 0.000000 0.141000 ( 0.141000)
string get 0.078000 0.000000 0.078000 ( 0.078000)
symbol get 0.047000 0.000000 0.047000 ( 0.047000)
=> true
=> true
irb(main):083:0> bmark_string_symb
user system total real
string set 0.234000 0.000000 0.234000 ( 0.235000)
symbol set 0.063000 0.000000 0.063000 ( 0.062000)
string get 0.078000 0.000000 0.078000 ( 0.078000)
symbol get 0.047000 0.000000 0.047000 ( 0.047000)
=> true
-------


There's a fair amount of variation, but symbols appear to behave as
expected (quicker on average), meaning that my guess that symbol
lookup in hashes was done on the basis of their string value was
wrong.
I guess I should learn to refrain from speculating until I've checked closer :)

jf


Devin Mullins

unread,
Dec 28, 2005, 9:31:22 PM12/28/05
to
Jim Weirich wrote:

>I'm not sure if this helped, or just muddied the water more.
>
>

When I first was trying to learn about symbols, attempts to explain
their "intentions" (as names of things, for example), rather than to
explain what they are, just muddied the water for me. Sure, give me some
advice on when and when not to use them, but also, tell me what they
are, so I can decide for myself:
- Like a string, but:
- Object-level equality, so :foo.equal?(:foo) and not 'foo'.equal?('foo')
- That means, with strings, if you say 'foo' 5 times in the code, you're
creating 5 string objects, whereas with symbols, you're only creating one.
- Share many properties with Fixnum (both being "immediate")--
immutable, no singleton classes, object equality, not picked up by
ObjectSpace.each_object...
- Not garbage collected.
- Looks cooler -- by using a different syntax, you can give some visual
distinction between your keys and your values, for instance.

(Also, Johannes Friestad's explanation was pretty good, IMO.)

Devin

Rich Morin

unread,
Dec 28, 2005, 9:50:51 PM12/28/05
to
At 11:31 AM +0900 12/29/05, Devin Mullins wrote:
> - That means, with strings, if you say 'foo' 5 times in the code, you're
> creating 5 string objects, whereas with symbols, you're only creating one.

I can understand this as a possible implementation, but I
really wonder about the follow-on statement that I've seen,
saying that this can cause memory leaks. If I define a
string and then discard it, shouldn't it be GCed?

-r
--
email: r...@cfcl.com; phone: +1 650-873-7841
http://www.cfcl.com - Canta Forda Computer Laboratory
http://www.cfcl.com/Meta - The FreeBSD Browser, Meta Project, etc.


Johannes Friestad

unread,
Dec 28, 2005, 9:53:09 PM12/28/05
to
BTW: Ruby version 1.8.2, Win XP Pro, Pentium M 2.0 GHz

jf

> and here are some results:

> ...


ara.t....@noaa.gov

unread,
Dec 28, 2005, 10:10:56 PM12/28/05
to
On Thu, 29 Dec 2005, Johannes Friestad wrote:

> On 12/28/05, ara.t....@noaa.gov <ara.t....@noaa.gov> wrote:
>> On Thu, 29 Dec 2005, Johannes Friestad wrote:
>>
>>
>>> Symbols are (or can be) quicker for hash lookup, since it is sufficient to
>>> compare object identity to find whether two symbols are the same, while
>>> strings must be compared character by character. You are unlikely to notice
>>> the difference unless your program uses hashes heavily.
>>
>> i see this claim all the time but never data supporting it, all my test
>> programs have shown the opposite to be true.
>>
>
> Along with Jim and Mauricio, my tests indicate that symbols are
> consistently quicker, even on short strings.

<snip test>

that way well be true now. however, if you look at my test it goes to some
lengths to make the test a little more 'real-world':

- creats a large (2 ** 13) hash
- poplate using a semi-random distribution
- selects keys for lookup in a semi-random distribution
- fork for each test to isolate tests somewhat
- disable GC for each test
- runs each test 4 times

in anycase, all i'm driving at is that a pretty heavy duty test (not saying
mine is that test) is required to eliminate the differences data distribution,
gc, and system load have on the results. in particular i can see how a linear
distribution might have a huge effect - seeing as symbols are essentially
numbers and hash more predictably whereas making the jump from '9999' to
'10000' is likely to land in quite a different bucket.

it's nonetheless very interesting to see some tests though.

i use both btw. ;-)

ara.t....@noaa.gov

unread,
Dec 28, 2005, 10:32:31 PM12/28/05
to
On Thu, 29 Dec 2005, Johannes Friestad wrote:

> BTW: Ruby version 1.8.2, Win XP Pro, Pentium M 2.0 GHz

your test did show symbols being faster on my (linux - 2g cpu, 2g ram) machine
too btw...


but this slightly modified version shows strings being a tiny bit faster:

harp:~ > cat a.rb
require 'benchmark'

n = 2 ** 16
string_hash, symbol_hash = {}, {}

Benchmark.bm(10) do |b|
b.report("string set"){ n.times{|x| string_hash[rand.to_s.freeze] = rand}}
end
Benchmark.bm(10) do |b|
b.report("symbol set"){ n.times{|x| symbol_hash[rand.to_s.intern] = rand}}
end

string_keys = string_hash.keys.sort_by{ rand }
symbol_keys = symbol_hash.keys.sort_by{ rand }

Benchmark.bm(10) do |b|
b.report("string get"){ string_keys.each{|k| string_hash[k]}}
end
Benchmark.bm(10) do |b|
b.report("symbol get"){ symbol_keys.each{|k| symbol_hash[k]}}
end

harp:~ > ./build/ruby-1.8.4/ruby ./a.rb
user system total real
string set 0.470000 0.000000 0.470000 ( 0.471459)
user system total real
symbol set 0.640000 0.020000 0.660000 ( 0.661556)
user system total real
string get 0.100000 0.000000 0.100000 ( 0.101498)
user system total real
symbol get 0.080000 0.000000 0.080000 ( 0.077205)


i think all we are showing here is that there aren't good reasons for one over
the other. but that's good to i supose - since people certainly seem to have
preferences.

cheers.

James Edward Gray II

unread,
Dec 28, 2005, 10:43:25 PM12/28/05
to
On Dec 28, 2005, at 4:18 PM, Dan Diebolt wrote:

> How about devoting the next Ruby Quiz to coming up with the best-of-
> class examples, self paced-tutorial and documentation to settle
> the :symbol vs "string" issue?

Hmm, smells like work and documentation combined. Two evils in one
quiz. ;)

I suspect that would make for an unpopular topic.

James Edward Gray II


Devin Mullins

unread,
Dec 28, 2005, 11:11:50 PM12/28/05
to
Devin Mullins wrote:

> When I first was trying to learn about symbols, attempts to explain
> their "intentions" (as names of things, for example), rather than to
> explain what they are, just muddied the water for me. Sure, give me
> some advice on when and when not to use them, but also, tell me what
> they are, so I can decide for myself:
> - Like a string, but:
> - Object-level equality, so :foo.equal?(:foo) and not 'foo'.equal?('foo')
> - That means, with strings, if you say 'foo' 5 times in the code,
> you're creating 5 string objects, whereas with symbols, you're only
> creating one.
> - Share many properties with Fixnum (both being "immediate")--
> immutable, no singleton classes, object equality, not picked up by
> ObjectSpace.each_object...
> - Not garbage collected.
> - Looks cooler -- by using a different syntax, you can give some
> visual distinction between your keys and your values, for instance.

- Lacking all those cool String methods like #gsub and #[]

so... nothing like a string.

Yeah, I dunno, the "some named thing" was just a little iffy. The
PickAxe was especially annoying in this respect by trying to imply that
a symbol was the name of a method, variable, or class, specifically.
Maybe I'm just ranting about that.

Sorry for the mess,
Devin

Jim Weirich

unread,
Dec 29, 2005, 12:22:55 AM12/29/05
to
ara wrote:
> but this slightly modified version shows strings being a tiny bit
> faster:

The difference is that your version measures more than just hash access
speed. It also includes string and symbol creation times. In
particular, to create a symbol, you must first create a string, so you
have twice as many object creations when using symbols.

--
-- Jim Weirich

Surgeon

unread,
Dec 29, 2005, 3:02:06 AM12/29/05
to

Oh, so many replies to my poor question! What a wonderful community!

Ron M

unread,
Dec 29, 2005, 5:43:56 AM12/29/05
to
ara.t....@noaa.gov wrote:
>
> also, don't forget that symbols are __never__ freed.
> this is a severe memory leak:
>
> loop{ Time::now.to_f.to_s.intern }

I still wonder if the lack of garbage collection of symbols
is merely a weakness in the current implementation, or something
that's part of the Ruby language.

Note that most lisps and javas can garbage collect
symbols and interned strings.


If it's just an implementation misfeature I'd love to
see that limitation go away in YARV.

Notes:
*1 http://community.schemewiki.org/?scheme-faq-language "Most Schemes
do perform garbage-collection of symbols, since otherwise programs
using string->symbol to dynamically create symbols would consume
ever increasing amounts of memory even if the created symbols are
no longer being used."

*2 http://mindprod.com/jgloss/interned.html "In the early JDKs, any
string you interned could never be garbage collected because the
JVM had to keep a reference to in its Hashtable so it could
check each incoming string to see if it already had it in the
pool. With JDK 1.2 came weak references. Now unused interned
strings will be garbage collected."


Steve Litt

unread,
Dec 29, 2005, 8:40:21 AM12/29/05
to
On Thursday 29 December 2005 03:03 am, Surgeon wrote:
> Oh, so many replies to my poor question! What a wonderful community!

I think it's because A LOT of us were wondering the same thing. In general,
RUBY conforms beautifully to Eric Raymond's "Rule of Least Surprise". IMHO
symbols are an exception.

Tell you the truth, I still don't understand, but at least now I have some
theorys thanks to the thread you started. Thank you for that.

SteveT

Steve Litt
http://www.troubleshooters.com
sl...@troubleshooters.com


Yohanes Santoso

unread,
Dec 29, 2005, 9:37:59 AM12/29/05
to
Eero Saynatkari <ruby-fo...@mailinator.com> writes:

> Yohanes Santoso wrote:
>> Alex Knaub <akn...@gmail.com> writes:
>>
>>> 2005/12/28, Surgeon <biyok...@gmail.com>:
>>>> Hi,
>>>>
>>>> I am a Ruby newbie. I wish I didn't post such a simple question here
>>>> but I had to.
>>>> What is the difference between :foo (a keyword) and "foo"(a string).
>>>> Can they be used interchangeably? Are they fundamentally same and is
>>>> the only difference performance?
>>>
>>> http://onestepback.org/index.cgi/Tech/Ruby/SymbolsAreNotImmutableStrings.red
>>
>> What a coincidence. Seems like Jim and I finally had enough of people
>> conflating symbols and immutable strings on the same day.
>>
>> http://microjet.ath.cx/WebWiki/2005.12.27_UsingSymbolsForTheWrongReason.html
>
> While, technically speaking, both of you are absolutely and
> undeniably correct (with one correction: Symbols are not Strings),
> such a conflation is the best way to get someone over the
> initial confusion.

The initial confusion is simply part of the learning curve rubyists
must go through along with learning that 'everything' is an
object. Dumbing down the situation can bring unexpected result:

Since we are around Christmas, I'm going to use Santa Claus as an
example. To prevent the initial confusion of children finding presents
magically appearing before Christmas tree, parents resort to such
outlandish notion that that is the work of a joyful guy who has never
heard of razor in a red jumper suit and riding reinders-pulled sleigh
around the world in one night.

Some children outgrew that notion. Some don't. Those that don't would
either sulk for a long time about the demise of such a joyful guy, or
start to think their parents are liars and spend the next untold years
of their life learning enough Math and Physics to prove that it is
impossible for a guy like Santa Claus to visit all children in one
night.

> As this thread quite well demonstrates,
> a definition for Symbols is quite difficult to come up with.

A formal definition is difficult to formulate correctly, but what CLHS
has is good enough:

"Symbols are used for their object identity to name various entities
in Common Lisp, including (but not limited to) linguistic entities
such as variables and functions." --
http://www.lisp.org/HyperSpec/Body/syscla_symbol.html#symbol

It is just a way to name/identify things. In RL, you name/identify
that collection of atoms 'bird', and another collection of atoms
'cow'. In ruby, you name/identify an object 'host', and another object
'port'. Just as you name parts of collection of atom that you named
'bird' 'wings', 'legs', 'feathers', etc., you name parts of a
Hashtable that you named 'ServerConfig' 'host', 'port'.

Just as one does not dumbed down "'everything' is an object in ruby",
which is a powerful ability, one should not dumbed down "symbols are
user-defined identifiers". It's just parts of learning curve.

dbl...@wobblini.net

unread,
Dec 29, 2005, 10:16:25 AM12/29/05
to
Hi --

On Thu, 29 Dec 2005, Steve Litt wrote:

> On Thursday 29 December 2005 03:03 am, Surgeon wrote:
>> Oh, so many replies to my poor question! What a wonderful community!
>
> I think it's because A LOT of us were wondering the same thing. In general,
> RUBY conforms beautifully to Eric Raymond's "Rule of Least Surprise". IMHO

s/RUBY/Ruby/ :-) In Ruby, P[olicy]OLS refers to what does or does not
surprise Matz.

> symbols are an exception.

A little surprise is OK. As Yohanes says, it's part of the learning
curve -- and Ruby does have a learning curve, even though it's
relatively gentle. The language has to be "allowed" to do things in a
way that are not identical to what programmers of other languages
expect. Otherwise its existence would serve no purpose.

Just out of curiosity: can you describe how symbols would work if
they weren't surprising?


David

--
David A. Black
dbl...@wobblini.net

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black


Steve Litt

unread,
Dec 29, 2005, 10:45:30 AM12/29/05
to
On Thursday 29 December 2005 10:16 am, dbl...@wobblini.net wrote:
> Hi --
>
> On Thu, 29 Dec 2005, Steve Litt wrote:
> > On Thursday 29 December 2005 03:03 am, Surgeon wrote:
> >> Oh, so many replies to my poor question! What a wonderful community!
> >
> > I think it's because A LOT of us were wondering the same thing. In
> > general, RUBY conforms beautifully to Eric Raymond's "Rule of Least
> > Surprise". IMHO
>
> s/RUBY/Ruby/ :-) In Ruby, P[olicy]OLS refers to what does or does not
> surprise Matz.
>
> > symbols are an exception.
>
> A little surprise is OK. As Yohanes says, it's part of the learning
> curve -- and Ruby does have a learning curve, even though it's
> relatively gentle. The language has to be "allowed" to do things in a
> way that are not identical to what programmers of other languages
> expect. Otherwise its existence would serve no purpose.
>
> Just out of curiosity: can you describe how symbols would work if
> they weren't surprising?

They wouldn't exist, or they wouldn't be called symbols. If I'm referring to
an instance instead of a value, I could call it &variable as in C, or I could
call it :variable, but in that case I'd call it a reference, not a symbol.

Personally, I think of the referencing and dereferencing in C as being
unsurprising. C has plenty of surprises, but referencing and dereferencing is
not one.

From what I understand, symbols are used for things other than naming
objects/variables. In such cases, it would be less surprising if they had a
different syntax than the ones that name objects.

A little surprise is OK. The subtle differnces of do/end and {/} in blocks is
a little surprise. But in my opinion, symbols and their uses is a blizzard on
the equator type surprise.

The fact that symbols cause so much more confusion than most other Ruby
facilities is an indicator. AFAIK there has been no good documentation on
symbols. When I mean good, I mean like the thoughts that have gone into this
thread -- thoughts valuable to the person who doesn't yet know symbols by
instinct, at which time the documentation is moot anyway.

dbl...@wobblini.net

unread,
Dec 29, 2005, 11:04:06 AM12/29/05
to
Hi --

On Fri, 30 Dec 2005, Steve Litt wrote:

> On Thursday 29 December 2005 10:16 am, dbl...@wobblini.net wrote:
>>
>> Just out of curiosity: can you describe how symbols would work if
>> they weren't surprising?
>
> They wouldn't exist, or they wouldn't be called symbols. If I'm referring to
> an instance instead of a value, I could call it &variable as in C, or I could
> call it :variable, but in that case I'd call it a reference, not a symbol.

But it's not a reference; it's an object, of class Symbol. If you do:

s = :sym

then the variable s holds a reference to the object :sym, just as when
you do:

a = []

a holds a reference to that array.

> Personally, I think of the referencing and dereferencing in C as being
> unsurprising. C has plenty of surprises, but referencing and dereferencing is
> not one.

Referencing and related things are so completely different as between
Ruby and C, though. They really don't map onto each other at all.

>> From what I understand, symbols are used for things other than naming
> objects/variables. In such cases, it would be less surprising if they had a
> different syntax than the ones that name objects.

They do; they have a literal constructor (:sym). That's always a
symbol first and foremost; and if there happens to be a method called
"sym", there may be some contexts in which you can use a symbol to
refer to it, but that's only because something is implemented to do
that (such as: obj.method(:sym)).

I think one important key to understanding symbol objects is their
immediacy. When you see :sym, it's very similar to seeing an integer.
It *is* the object. What gets done with the object, or what methods
do or do not know how to use it to pry out methods or other things, is
secondary.

James Edward Gray II

unread,
Dec 29, 2005, 11:08:40 AM12/29/05
to
On Dec 29, 2005, at 9:45 AM, Steve Litt wrote:

> On Thursday 29 December 2005 10:16 am, dbl...@wobblini.net wrote:
>>
>> Just out of curiosity: can you describe how symbols would work if
>> they weren't surprising?
>
> They wouldn't exist, or they wouldn't be called symbols. If I'm
> referring to
> an instance instead of a value, I could call it &variable as in C,
> or I could
> call it :variable, but in that case I'd call it a reference, not a
> symbol.

You are still confused. <laughs>

Symbols are nothing like references. They would be much closer to
enums, if you want a C-ish comparison.

James Edward Gray II


Kirk Haines

unread,
Dec 29, 2005, 11:20:56 AM12/29/05
to
On Thursday 29 December 2005 8:45 am, Steve Litt wrote:

> They wouldn't exist, or they wouldn't be called symbols. If I'm referring
> to an instance instead of a value, I could call it &variable as in C, or I
> could call it :variable, but in that case I'd call it a reference, not a
> symbol.

It's not a reference. Symbols are much simpler than that. Really. They are
just an integer with some sequence of characters to represent it, all wrapped
up in an object.

:foo has nothing to do with a variable named @foo, or a method named foo() or
anything else. It's just the characters "foo" associated with an integer.
That association lasts for the life of the Ruby interpreter process.

That's all there is to it. They are _simple_ constructs. My hunch is that
the confusion for people new to the language is simply that they are trying
to map them to something more complex than Symbols really are, and they don't
happen to find any clear, concise, handy documentation to explain them.


Kirk Haines


Austin Ziegler

unread,
Dec 29, 2005, 11:30:29 AM12/29/05
to

Chad Perrin

unread,
Dec 29, 2005, 11:50:14 AM12/29/05
to
On Thu, Dec 29, 2005 at 11:37:59PM +0900, Yohanes Santoso wrote:
>
> > As this thread quite well demonstrates,
> > a definition for Symbols is quite difficult to come up with.
>
> A formal definition is difficult to formulate correctly, but what CLHS
> has is good enough:
>
> "Symbols are used for their object identity to name various entities
> in Common Lisp, including (but not limited to) linguistic entities
> such as variables and functions." --
> http://www.lisp.org/HyperSpec/Body/syscla_symbol.html#symbol

Ever since this discussion started, I've wondered if there was some
relationship between Ruby symbols and Lisp symbols. This is the first
thing I've seen that seemed to indicate that, though. Prior to this
quote you provided, everything that has been said in this discussion of
Ruby symbols has seemed to indicate that there is zero relationship
between the two.

So tell me: Is a Ruby symbol basically just an object oriented
implementation of the Lisp concept of a symbol? If that's the case,
what's up with all this tripe about "a symbol is just a name" and so on?
I get the distinct impression that either there's no real relationship
between Ruby symbols and Lisp symbols, or else all the people trying to
explain Ruby symbols don't much know what they're talking about.


>
> It is just a way to name/identify things. In RL, you name/identify
> that collection of atoms 'bird', and another collection of atoms
> 'cow'. In ruby, you name/identify an object 'host', and another object
> 'port'. Just as you name parts of collection of atom that you named
> 'bird' 'wings', 'legs', 'feathers', etc., you name parts of a
> Hashtable that you named 'ServerConfig' 'host', 'port'.

Until you mentioned the hash table in that paragraph, it didn't make any
sense at all. I think these analogies are doing a disservice to people
trying to get a read on what a symbol is in Ruby. You might as well go
back to trying to explain OOP with truck analogies, which never worked
worth a damn for explaining the concept either, if you are going to do
that. It's impressively frustrating trying to make heads or tails of
this discussion of Ruby symbols: people are full of analogies and
categorical statements that don't really explain anything, but there
isn't a whole lot of substance to it.

If you tell me that Ruby symbols are basically just Lisp symbols,
implemented in an OOP way by way of a symbol class, I think I could
probably come up with a succinct and clear explanation of what a Ruby
symbol is that would remove a lot of the ambiguity, but so far I still
don't know if that's what a Ruby symbol actually is.


>
> Just as one does not dumbed down "'everything' is an object in ruby",
> which is a powerful ability, one should not dumbed down "symbols are
> user-defined identifiers". It's just parts of learning curve.

Dumb down? No, never. Try explaining it, though. Identifier for what?
While you're at it, define "identifier" within this context.

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

"Real ugliness is not harsh-looking syntax, but having to
build programs out of the wrong concepts." - Paul Graham


Jonathan Simms

unread,
Dec 29, 2005, 11:51:31 AM12/29/05
to

On Dec 29, 2005, at 12:22 AM, Jim Weirich wrote:

> ara wrote:
>> but this slightly modified version shows strings being a tiny bit
>> faster:
>
> The difference is that your version measures more than just hash
> access
> speed. It also includes string and symbol creation times. In
> particular, to create a symbol, you must first create a string, so you
> have twice as many object creations when using symbols.
>

This version (I believe) shows that by using a string literal, you're
paying for the creation of a string object with each invocation, whereas
by using a symbol, you only pay for the interning once, but on each
subsequent usage, you're using a reference to a singleton.


slyphon@willie ~ $ cat /tmp/bmrk.rb
#!/usr/bin/env ruby

require 'benchmark'

n = 1_000_000
string_hash, symbol_hash = {}, {}


Benchmark.bm(10) do |b|
b.report("string set"){ n.times{|x| string_hash["foo"] = rand}}
end
Benchmark.bm(10) do |b|
b.report("symbol set"){ n.times{|x| symbol_hash[:foo] = rand}}
end


slyphon@willie ~ $ ruby /tmp/bmrk.rb
user system total real
string set 1.270000 0.000000 1.270000 ( 1.274019)
user system total real
symbol set 0.880000 0.000000 0.880000 ( 0.877080)
slyphon@willie ~ $


- Jonathan Simms


Steve Litt

unread,
Dec 29, 2005, 12:08:33 PM12/29/05
to
On Thursday 29 December 2005 11:20 am, Kirk Haines wrote:
> On Thursday 29 December 2005 8:45 am, Steve Litt wrote:
> > They wouldn't exist, or they wouldn't be called symbols. If I'm referring
> > to an instance instead of a value, I could call it &variable as in C, or
> > I could call it :variable, but in that case I'd call it a reference, not
> > a symbol.
>
> It's not a reference. Symbols are much simpler than that. Really. They
> are just an integer with some sequence of characters to represent it, all
> wrapped up in an object.

OK, let me see if I'm correctly understanding you.

:wilbur is an object. That object has two properties, which one could call, in
generic and not Ruby terms, a key and a value. The key is an integer. The
value is "wilbur". Neither the key nor the value can be changed during the
execution of the program. When we write:

attr_accessor :wilbur

what really happens is that the function attr_accessor() takes symbol :wilbur
as an argument, tacks on a @ to the string's value in order to make the true
class variable @wilbur, and then writes a tiny get and set functions whose
names are wilbur, such that:

my_object.wilbur = 22
puts my_object.wilbur

So my initial comment that it seemed like magic is true only to the extent
that the "magic" performed by attr_accessor is to create the set and get
methods with the same name as the symbol that is its argument.

Do I understand what you're saying?

Thanks

Edward Faulkner

unread,
Dec 29, 2005, 12:09:40 PM12/29/05
to
On Fri, Dec 30, 2005 at 01:50:14AM +0900, Chad Perrin wrote:
> If you tell me that Ruby symbols are basically just Lisp symbols,
> implemented in an OOP way by way of a symbol class, I think I could
> probably come up with a succinct and clear explanation of what a Ruby
> symbol is that would remove a lot of the ambiguity, but so far I still
> don't know if that's what a Ruby symbol actually is.

Yes, I think Ruby symbols and Lisp symbols are the same thing. The
issue is just slightly obscured because Ruby glosses over the Lisp
concept of "quote" by building the quote syntax directly into the
symbol-literal syntax. :mysymbol means the same thing as Lisp's
'mysymbol, except the whole thing is treated as a single literal
token, instead of parsing to (quote mysymbol).

signature.asc

Steve Litt

unread,
Dec 29, 2005, 12:13:09 PM12/29/05
to
> > a symbol.
>
> http://www.oreillynet.com/ruby/blog/2005/12/symbols_strings_methods_and_va.
>html

Thanks Austin,

I *think* that article brought me closer to understanding. Armed with your
article and all the other responses, I replied to Kirk Haines' post with my
interpretation of what you all were saying.

By the way, your article is obviously needed, and you should probably refine
it as time goes on. The fact that we had so many responses that at least in
part contradicted each other indicates to me that symbols are perhaps the
most surprising element of Ruby, which is otherwise not a surprising language
at all.

Thanks for the great blog entry.

A LeDonne

unread,
Dec 29, 2005, 12:13:17 PM12/29/05
to
On 12/29/05, Austin Ziegler <halos...@gmail.com> wrote:
<snip>
> What
> makes Symbols "special" in the current implementation is that a Symbol
> is created for every named item.
>
> >> olds = Symbol.all_symbols; nil
> nil
> >> quuxl = 0
> 0
> >> Symbol.all_symbols - olds
> [:quuxl]
>
> But as I stated in the blog entry I posted above, the Symbol is just a
> name. What gives a Symbol its power is the thing that uses it, such as
> attr_accessor. Symbols are names. No more, no less.
>
> Really, I think that people create the confusion for themselves,
> expecting them to be more than they are.
>
> -austin

I think that the same thing that "makes symbols 'special' in the
current implementation" is what creates confusion for people.

I know that the idea that the "thingy" in the symbol table is the same
"thingy" represented by an immediate object that has a literal
representation seemed very voodoo/black magic to me at first, coming
from languages where the symbol table is a hidden, reserved, internal
sort of structure. From the outside, Symbols look like they were
invented solely to facilitate meta-programming, which is why they have
all the "name" conceptual baggage attached.

In other words, to a non-Rubyist, a natural question to ask is, "If
you didn't need easy access to names in or destined for the symbol
table, would Symbol objects exist in Ruby?" (Probably followed by "And
why do you need access to names in the symbol table, anyway?")

-A


Chad Perrin

unread,
Dec 29, 2005, 12:22:39 PM12/29/05
to

Thank you.

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

print substr("Just another Perl hacker", 0, -2);


James Edward Gray II

unread,
Dec 29, 2005, 1:03:41 PM12/29/05
to
On Dec 29, 2005, at 11:08 AM, Steve Litt wrote:

> When we write:
>
> attr_accessor :wilbur
>
> what really happens is that the function attr_accessor() takes
> symbol :wilbur
> as an argument, tacks on a @ to the string's value in order to make
> the true
> class variable @wilbur,

That's an instance variable, not a class variable.

As Austin taught us yesterday, it doesn't make the variable either,
just some methods.

> and then writes a tiny get and set functions whose
> names are wilbur, such that:
>
> my_object.wilbur = 22
> puts my_object.wilbur
>
> So my initial comment that it seemed like magic is true only to the
> extent
> that the "magic" performed by attr_accessor is to create the set
> and get
> methods with the same name as the symbol that is its argument.

"Magic" to me is the tricky stuff and I don't see any of that here.
We just told it the name for a method we wanted. You could easily
code a pure Ruby replacement for the attr* methods, so it's really
just a shortcut with Ruby doing some work for you. No magic there.

James Edward Gray II


Kirk Haines

unread,
Dec 29, 2005, 1:11:44 PM12/29/05
to
On Thursday 29 December 2005 10:08 am, Steve Litt wrote:

> OK, let me see if I'm correctly understanding you.

Yep!

> what really happens is that the function attr_accessor() takes symbol
> :wilbur as an argument, tacks on a @ to the string's value in order to make
> the true class variable @wilbur, and then writes a tiny get and set
> functions whose names are wilbur, such that:
>
> my_object.wilbur = 22
> puts my_object.wilbur
>
> So my initial comment that it seemed like magic is true only to the extent
> that the "magic" performed by attr_accessor is to create the set and get
> methods with the same name as the symbol that is its argument.
>
> Do I understand what you're saying?

That is exactly what happens.

And because that is what happens, one can write attr_accessor-like methods
oneself, if there is something additional/different that you want to have
happen. The symbol is just a tool.


Kirk Haines


Austin Ziegler

unread,
Dec 29, 2005, 1:19:33 PM12/29/05
to
On 29/12/05, Steve Litt <sl...@earthlink.net> wrote:
> On Thursday 29 December 2005 11:20 am, Kirk Haines wrote:
>> On Thursday 29 December 2005 8:45 am, Steve Litt wrote:
>>> They wouldn't exist, or they wouldn't be called symbols. If I'm
>>> referring to an instance instead of a value, I could call it
>>> &variable as in C, or I could call it :variable, but in that case
>>> I'd call it a reference, not a symbol.
>> It's not a reference. Symbols are much simpler than that. Really.
>> They are just an integer with some sequence of characters to
>> represent it, all wrapped up in an object.
> OK, let me see if I'm correctly understanding you.
>
> :wilbur is an object. That object has two properties, which one could
> call, in generic and not Ruby terms, a key and a value. The key is an
> integer. The value is "wilbur". Neither the key nor the value can be
> changed during the execution of the program. When we write:

No. :wilbur is an object. It has *one* property, itself. You can ask for
integer or string representations, but :wilbur's value is :wilbur and
there will only ever be one :wilbur.

> attr_accessor :wilbur
>
> what really happens is that the function attr_accessor() takes symbol
> :wilbur as an argument, tacks on a @ to the string's value in order to
> make the true class variable @wilbur, and then writes a tiny get and
> set functions whose names are wilbur, such that:

Sort of. In the link that I posted for you earlier, you'll note that I
wrote an accessor generator (md5_accessor) which can be used to create
accessors that deal with variables named completely differently than the
accessors.

The method Module#attr_accessor will take the symbol and use it as a
name to create accessors (#wilbur and #wilbur=) that *coincidentally*
work on a variable of the same name. It doesn't *create* that variable.

> my_object.wilbur = 22
> puts my_object.wilbur
>
> So my initial comment that it seemed like magic is true only to the
> extent that the "magic" performed by attr_accessor is to create the
> set and get methods with the same name as the symbol that is its
> argument.

You are correct in this last. The "magic" is in attr_accessor, not in
the Symbol. The Symbol is just a name.

-austin
--
Austin Ziegler * halos...@gmail.com
* Alternate: aus...@halostatue.ca


Yohanes Santoso

unread,
Dec 29, 2005, 3:07:35 PM12/29/05
to
Chad Perrin <per...@apotheon.com> writes:

> Prior to this quote you provided, everything that has been said in
> this discussion of Ruby symbols has seemed to indicate that there is
> zero relationship between the two.

The first line of my journal (third post in this thread) already
mentions "The concept of symbols have been popular among the lisp
community...".

So, there is not zero relationship between the two. Before coming to
ruby, I was already familiar with elisp and dabled some in CL. A quick
reading of the then scampy documentation of ruby Symbol revealed that
they are just different implementations of the same concept. But they
are not the same. ruby's symbol is CL&elips symbol minus attributes
(symbol value, property list, etc.)

> So tell me: Is a Ruby symbol basically just an object oriented
> implementation of the Lisp concept of a symbol?

Yes: different implementations of the same concept. No: CL&elisp's
Symbol has more functionalities.

> If that's the case, what's up with all this tripe about "a symbol is
> just a name" and so on?

Because it's true? Because there are people who don't have lisp
background who are not familiar with what symbol is? Because there are
people who thinks symbols are magical thingie?

> I think these analogies are doing a disservice to people trying to
> get a read on what a symbol is in Ruby.

This is true for all analogies. Different people are receptive to
different analogies. This simply means you are not receptive to the
analogy I made.

> people are full of analogies and categorical statements
> that don't really explain anything

The basic message has always been clear: symbol is a mean for you, the
programmer, to name/identify entities. But somehow, people are having
difficulty understanding this and asked for more explanations. This is
when analogies and categorical statements came in.

>> Just as one does not dumbed down "'everything' is an object in ruby",
>> which is a powerful ability, one should not dumbed down "symbols are
>> user-defined identifiers". It's just parts of learning curve.
>
> Dumb down? No, never. Try explaining it, though.

As this and many other previous threads about symbol have shown,
explaining the concept of symbol is not easy.

> While you're at it, define "identifier" within this context.

To help people understanding the meaning of 'identifier', I've been
mentioning it together with 'name': 'name/identify' as in "It is just


a way to name/identify things".

In any case, there is only one definition of identifier so context
should not influence the meaning of it:

From WordNet (r) 2.0 (August 2003) [wn]:

identifier
n : a symbol that establishes the identity of the one bearing it


YS.


Johannes Friestad

unread,
Dec 29, 2005, 3:44:23 PM12/29/05
to
On 12/29/05, Chad Perrin <per...@apotheon.com> wrote:
> Ever since this discussion started, I've wondered if there was some
> relationship between Ruby symbols and Lisp symbols..

> So tell me: Is a Ruby symbol basically just an object oriented
> implementation of the Lisp concept of a symbol?

Yes, the concept of a symbol in Ruby is the same as in Lisp. Just as
similar as the concepts for integers, strings, arrays and other basic
constructs.

I think the confusion comes from two areas:

1) Not many languages has 'symbol' as a distinct data type. Java has
interned strings, which are pretty close to symbols for most practical
purposes (symbols are atomic, immutable and unique, Java interned
strings are just immutable and unique), but they are not a separate
datatype.

2) It is not immediately obvious why symbols are useful. Numbers and
arrays/lists are easily explained as representing numbers and 'a
construct to hold multiple values', but there is no such simple
explanation for symbols. Not that I know of, anyway.

jf


dbl...@wobblini.net

unread,
Dec 29, 2005, 4:56:13 PM12/29/05
to
Hi --

On Fri, 30 Dec 2005, dbl...@wobblini.net wrote:

> Hi --
>
> On Fri, 30 Dec 2005, Steve Litt wrote:
>
>> On Thursday 29 December 2005 10:16 am, dbl...@wobblini.net wrote:
>>>
>>> Just out of curiosity: can you describe how symbols would work if
>>> they weren't surprising?
>>
>> They wouldn't exist, or they wouldn't be called symbols. If I'm referring
>> to
>> an instance instead of a value, I could call it &variable as in C, or I
>> could
>> call it :variable, but in that case I'd call it a reference, not a symbol.
>
> But it's not a reference; it's an object, of class Symbol. If you do:
>
> s = :sym
>
> then the variable s holds a reference to the object :sym, just as when
> you do:
>
> a = []
>
> a holds a reference to that array.

This assertion by me seems to have been mercifully ignored in
subsequent discussion :-) Actually, s = :sym doesn't produce a
reference to :sym; rather, s has the actual/immediate value :sym.
Anyway, the main (obscured) point was that symbols are not references.

> I think one important key to understanding symbol objects is their
> immediacy. When you see :sym, it's very similar to seeing an integer.
> It *is* the object. What gets done with the object, or what methods
> do or do not know how to use it to pry out methods or other things, is
> secondary.

Here's where the s = :sym example should have been, since otherwise
I'm really talking about the literal constructor, which wasn't (i.e.,
shouldn't have been) the main point.

Anyway, I just wanted to ungarble that post a little :-)

Steve Litt

unread,
Dec 29, 2005, 6:35:31 PM12/29/05
to
On Thursday 29 December 2005 01:03 pm, James Edward Gray II wrote:
[clip]

> > class variable @wilbur,
>
> That's an instance variable, not a class variable.

I knew that :-) Skipping from Perl to C to C++ to Python to Ruby, I sometimes
forget the terminology.


>
> As Austin taught us yesterday, it doesn't make the variable either,
> just some methods.

My understanding of Ruby is the getters and setters it makes make the
variable, because the setter sets @wilber to its argument.

Eero Saynatkari

unread,
Dec 29, 2005, 6:42:51 PM12/29/05
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2005.12.30 08:35, Steve Litt <sl...@earthlink.net> wrote:
> On Thursday 29 December 2005 01:03 pm, James Edward Gray II wrote:
> [clip]
> > > class variable @wilbur,
> >
> > That's an instance variable, not a class variable.
>
> I knew that :-) Skipping from Perl to C to C++ to Python to Ruby, I sometimes
> forget the terminology.
> >
> > As Austin taught us yesterday, it doesn't make the variable either,
> > just some methods.
>
> My understanding of Ruby is the getters and setters it makes make the
> variable, because the setter sets @wilber to its argument.

The instance variable is not created by the attr_* statement,
however. Only if you call obj.attribute = something will it
be created (unless you create it in #initialize or something).

irb(main):001:0> class Foo
irb(main):002:1> attr_accessor 'bar'
irb(main):003:1> end
=> nil
irb(main):004:0> f = Foo.new
=> #<Foo:0xb7de9be8>
irb(main):005:0> f.inspect
=> "#<Foo:0xb7de9be8>"
irb(main):006:0> f.bar = 5
=> 5
irb(main):007:0> f.inspect
=> "#<Foo:0xb7de9be8 @bar=5>" # <-- This here
irb(main):008:0>

> SteveT


E
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFDtH2ZxvA1l6h+MUMRAudYAKCRQTHp/6p70j83waz8y3r56i4mwACeNkAW
5rX3d6mtf9XMuGZlu+zyk/U=
=ogE8
-----END PGP SIGNATURE-----

Chad Perrin

unread,
Dec 29, 2005, 7:36:18 PM12/29/05
to
On Fri, Dec 30, 2005 at 05:07:35AM +0900, Yohanes Santoso wrote:
> Chad Perrin <per...@apotheon.com> writes:
>
> > If that's the case, what's up with all this tripe about "a symbol is
> > just a name" and so on?
>
> Because it's true? Because there are people who don't have lisp
> background who are not familiar with what symbol is? Because there are
> people who thinks symbols are magical thingie?

It's not really true, though, considering what a symbol is (according to
my current understanding). A symbol is an element of a hash table that
is often used as a name, and it is an (anonymous? not sure how to
qualify that) object. Calling it a "name" seems to be confusing common
use with actual nature, or premature explanation of an abstract way of
thinking about it, depending on how you mean "it is a name" when you say
it. Either way, it seems to be getting the cart before the horse.


>
> > I think these analogies are doing a disservice to people trying to
> > get a read on what a symbol is in Ruby.
>
> This is true for all analogies. Different people are receptive to
> different analogies. This simply means you are not receptive to the
> analogy I made.

I think it's probably more useful to start by describing the actual
functional nature of a symbol, then start in with the analogies if that
doesn't make a lightbulb go on in the person's head.


>
> > people are full of analogies and categorical statements
> > that don't really explain anything
>
> The basic message has always been clear: symbol is a mean for you, the
> programmer, to name/identify entities. But somehow, people are having
> difficulty understanding this and asked for more explanations. This is
> when analogies and categorical statements came in.

"A means for you, the programmer, to name/identify entities" is not a
description of what a symbol *is* so much as a description of how you
can use it. It seems awfully odd to me that everything else in the
language tends to get described in terms of what it actually is under
the hood, then starts getting analogies only if the target of the
explanation doesn't get it, while for some reason nobody starts an
explanation of symbols that way in Ruby.

For example: while saying that a method is "a verb" does help one to
"get" how verbs are used in the language, nobody really knows what a
method is until it's explained that it's a mini-algorithm whose
definition is part of a class definition, accessible by way of instances
thereof. As such, someone always starts explaining what a method is
under the hood pretty quickly when trying to get the point of a method
across in teaching OOP. With symbols, though, I keep seeing bland
assertions that a symbol is "just a name", or "a name that is an
object", or something like that, without any explanation of what a
symbol actually does behind the scenes.

I seem to have missed the blog post that mentioned the relationship to
Lisp methods, but even that didn't really address the matter as clearly
as I would have expected.


>
> > While you're at it, define "identifier" within this context.
>
> To help people understanding the meaning of 'identifier', I've been
> mentioning it together with 'name': 'name/identify' as in "It is just
> a way to name/identify things".
>
> In any case, there is only one definition of identifier so context
> should not influence the meaning of it:
>
> >From WordNet (r) 2.0 (August 2003) [wn]:
>
> identifier
> n : a symbol that establishes the identity of the one bearing it

. . which, unfortunately, in no way explains what one does with a
"symbol" in a programming context in a helpful way.

A symbol is an element (or a reference to an element, though I hesitate
to use the term "reference" with its programming contextual baggage) in
a hash table. A hash table is, in short, a list maintained "by the
language" rather than by the user. From the programmer's point of view,
this list essentially has only values, not keys, though from the
language's point of view it most certainly has keys. This is primarily
useful for applying names to things, thus the common assertion that "a
symbol is a name".

Is that close, or have I missed something?

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

"A script is what you give the actors. A program
is what you give the audience." - Larry Wall


Chad Perrin

unread,
Dec 29, 2005, 9:36:04 PM12/29/05
to
On Fri, Dec 30, 2005 at 10:42:33AM +0900, Eero Saynatkari wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 2005.12.30 09:36, Chad Perrin <per...@apotheon.com> wrote:
> >
> > It's not really true, though, considering what a symbol is (according to
> > my current understanding). A symbol is an element of a hash table that
> > is often used as a name, and it is an (anonymous? not sure how to
> > qualify that) object. Calling it a "name" seems to be confusing common
> > use with actual nature, or premature explanation of an abstract way of
> > thinking about it, depending on how you mean "it is a name" when you say
> > it. Either way, it seems to be getting the cart before the horse.
>
> Nope, Symbols have nothing to do with Hashes. They are often used
> as Hash keys because they are descriptive: h[:foo] is better than
> h[1] if one wants to convey some meaning with the key. In other
> languages, you might use a string instead of a Symbol (and you
> can, of course, do so in ruby as well: h['foo']).

Apparently, a more significant distinction needs to be made between a
"hash table" in the symbol sense of the term and a "hash" in the sense
of an associative array.

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

unix virus: If you're using a unixlike OS, please forward
this to 20 others and erase your system partition.


Devin Mullins

unread,
Dec 29, 2005, 9:36:06 PM12/29/05
to
Austin Ziegler wrote:

>The Symbol is just a name.
>
>

Er... a thing that /has/ a name. (That being, Symbol#to_s.)

A symbol's just a thing. :apple == :apple. :apple.to_s == "apple".
:apple.to_i == 23417. The end.*

AFAIK, you *can* use a String to do all the things you would do with a
Symbol (i.e. identify things)+, but using Symbols is more fun! (More
performant, possibly, for the purpose of static identifiers, and a
little less line noise, when used as the key to a hash, for example.
Plus, if you're using a text editor with syntax highlighting, they'll
show up a different color, which is fun.)

Devin
* Though I'm not a very good one, I'm a mathematician at heart, so I
like to define things by their properties.
+ This is because all the builtin methods that are meant to take a
Symbol as a parameter tend to call its #== or #eql? or #hash or #to_s
method (the properties of which String mimicks, to an isomorphism), or
allow a String to be passed in its place (as is the case with attr_*, e.g.).

Chad Perrin

unread,
Dec 29, 2005, 9:38:21 PM12/29/05
to
On Fri, Dec 30, 2005 at 10:46:23AM +0900, Eero Saynatkari wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 2005.12.30 06:56, dbl...@wobblini.net wrote:
> >
> > This assertion by me seems to have been mercifully ignored in
> > subsequent discussion :-) Actually, s = :sym doesn't produce a
> > reference to :sym; rather, s has the actual/immediate value :sym.
> > Anyway, the main (obscured) point was that symbols are not references.
>
> This is another bad aspect of Symbol explanations. Sooner or later
> someone mentions 'immediate values' or 'internal symbol tables'.
> While accurate (and in some cases, useful knowledge), these are a
> big source of confusion and not in any way helpful to understanding
> the fairly trivial function of Symbols :/

I disagree. If the underlying semantic mechanism of a symbol isn't
understood, symbols won't be understood.

Devin Mullins

unread,
Dec 29, 2005, 10:26:08 PM12/29/05
to
Devin Mullins wrote:

> Austin Ziegler wrote:
>
>> The Symbol is just a name.
>
> Er... a thing that /has/ a name. (That being, Symbol#to_s.)

OK, well, I RTFA, and sorry for blatantly contradicting what was an
intentional choice of words (and not, as I had thought, a slip-up)
without reason. Anyways, to quote you:

>No. :wilbur is an object. It has *one* property, itself. You can ask for
>integer or string representations, but :wilbur's value is :wilbur and
>there will only ever be one :wilbur.
>

Calling it a "name" is just another analogy. Its name is its String
representation, just as Module#name == Module#to_s (for non-singletons).
Rather, :jazz is :jazz is :jazz. There is no reducing it to other concepts.

Devin
Yeah, I know, total 540.

J. Ryan Sobol

unread,
Dec 29, 2005, 11:40:43 PM12/29/05
to
To whom who asked this question, open your console / terminal and type:

ri Symbol

Then type:

ri String

~ ryan ~


Yohanes Santoso

unread,
Dec 30, 2005, 12:10:09 AM12/30/05
to
Chad Perrin <per...@apotheon.com> writes:

> On Fri, Dec 30, 2005 at 05:07:35AM +0900, Yohanes Santoso wrote:
>> Chad Perrin <per...@apotheon.com> writes:
>>
>> > If that's the case, what's up with all this tripe about "a symbol is
>> > just a name" and so on?
>>
>> Because it's true? Because there are people who don't have lisp
>> background who are not familiar with what symbol is? Because there are
>> people who thinks symbols are magical thingie?
>

> Calling it a "name" seems to be confusing common use with actual
> nature, or premature explanation of an abstract way of thinking
> about it, depending on how you mean "it is a name" when you say it.

Well, what can I say? Symbol is really meant to represent a
name/identifier.

Let's stop with analogies since obviously we are not
analogy-compatible, and get on with the concretes.

What is 1? A way to represent the number one. You said a way, what
others are there? 0x1, \001, "1". However, one does not use "1" to
represent the number one even if one doesn't plan to do any arithmetic
operations on that number because that representation is
ambiguous. Does he mean "1" as in number one or as in the character
"1"?

What is :server? A way to represent the name/identifier
``server``. What others are there? "server" is another one. But it is
also ambigious. Does he mean the name/identifier ``server`` or the
character sequence "s","e","r","v","e","r"?

I can see no way to describe 1 without involving number. Similarly, I
can see no way to describe :server without involving
name/identifier. Perhaps you can.

> "A means for you, the programmer, to name/identify entities" is not a
> description of what a symbol *is* so much as a description of how you
> can use it.

I really am not sure what you are saying there. That sentence
describes what a symbol is. That sentence does not describe/prescribe
how to use it.

Here, let me paraphrase my sentence: "[Symbol is] a means for you, the
programmer, to [represent the] name/identit[y] of entities". Did I
manage to preserve the meaning? Let's do word substitution. "Number
is a means for you, the programmer, to represent numbers". In no way
am I describing/prescribing how to use instances of Number.

> object", or something like that, without any explanation of what a
> symbol actually does behind the scenes.

This is precisely the kind of explanation that I objected when
explaining what a symbol is to a newcomer. Any explanation that refer
to the implementation is doomed to be short-lived. There are many ways
to implement the class Symbol and the concept of symbol.

Do you explain what number does behind the scenes to someone asking
'What is a number?' Do you explain that ruby maps number less than
2^31-1 directly to native integer format? Quick question, then: does
this still hold on a 64-bit machine? How about in ruby 2.0? Will
Number behave differently and is used to represent different thing
there simply because what goes on behind the scene has changed?

If one is interested in how something is implemented in a specific
environment, one should ask for that (and there are posts in this
thread dwelving into how Symbol is implemented in current ruby VM).

In any case, if someone can give me a description of what 1 is without
involving number, then I'll show you a description of what symbol is
without involving name/identifier.

YS.

Devin Mullins

unread,
Dec 30, 2005, 12:25:50 AM12/30/05
to
For the heck of it, I decided to come up with my own Symbol analogy.
Caveat reader:

A symbol is a bubble. In Ruby-land, there is this ever-present *ether*
wherein lies an abundance of bubbles.

<picture of a bunch of bubbles, each with a symbol literal inside --
feel free to Gimp it into existence -- here's a starter kit:
http://www.scrapbookerie.com/images/autocollants/Sticko-Bubbles.jpg>

Every symbol you could ever want is out there, in the ether, bubbling
along. For every name, there is a single bubble. For every bubble, there
is a single name.

When you assign +x = :mr_t+, as with all variable assignments, you're
pointing x to the :mr_t object. Here, you're pointing at that bubble
that the Ruby interpreter recognizes as :mr_t. For plausability reasons,
the Ruby interpreter blows the :mr_t bubble the first time you mention
its name, but for your sake, you can assume that the :mr_t bubble has
always existed and always will exist -- it's just there, floating in the
ether, waiting to be pointed to.

So from that description right there, we already know one thing we can
do with bubbles--er, Symbols--determine equality. Are these two
variables pointing to the same bubble? Find me the Hash value whose
associated key is this bubble I'm pointing to right now. For programming
convenience, these bubbles have names associated with them, but as far
as your code is concerned, they're just bubbles. This is the magic
behind {:server => 'localhost', :port => 80}, etc.

The other (principal) thing you can do with a bubble--eh, Symbol--is
find out its name at runtime (thanks to #to_s or #id2name). Thus,
attr_accessor :mcklellan is born. I'm passing along a pointer to the
:mcklellan bubble. attr_accessor follows the pointer, talks to that
bubble, asks it what its name is, and uses that information to define
some methods. Here, :mcklellan is just used as a fancy shorthand for
'mcklellan'. (It happens to be one I like, but I digress...)

So, uh, yeah. That's it. The End.

Ha, yeah, so that description is probably more unsettling than settling,
but maybe it'll plant a seed of wisdom, or whatnot. Plus, I can rest
easy, now that I've solved everybody's problems.

Devin
Did I really just digress into "The End"?

Austin Ziegler

unread,
Dec 30, 2005, 12:45:55 AM12/30/05
to
On 29/12/05, Devin Mullins <twi...@comcast.net> wrote:
> Austin Ziegler wrote:
> >The Symbol is just a name.
> Er... a thing that /has/ a name. (That being, Symbol#to_s.)

No, I think that the essential property of a Symbol is that it is an
object that is a name:

keep = Symbol.all_symbols
quuxl = nil
puts Symbol.all_symbols - keep

You'll see that :quuxl is there. You can get a string representation
of that name (:quuxl.to_s) or an integer representation of that name
(:quuxl.to_i), but the canonical representation of that name is the
Symbol itself (:quuxl). Sure, you could get pedantically
philosophical, but the you'd be saying that 1 really isn't the number,
it's a thing that represents a quantity of one.

For all practical purposes, Symbols are atomic in the sense that they
are themselves. Who *cares* how it's actually represented in the
implementation? That can change. The fundamental nature of a Symbol is
that :quuxl will always be :quuxl and never anything else. Consider
these two IRB sessions:

irb(main):001:0> :bar.to_i
=> 23417
irb(main):002:0> :quuxl.to_i
=> 23425
irb(main):003:0>

irb(main):001:0> :quuxl.to_i
=> 23417
irb(main):002:0> :bar.to_i
=> 23425
irb(main):003:0>

A Symbol, like a number, is immediate and is identified by itself.

Devin Mullins

unread,
Dec 30, 2005, 1:01:34 AM12/30/05
to
Heh, one of my emails to the list got eaten (by a grue?). Let's try this
again:

Devin Mullins wrote:

> Austin Ziegler wrote:
>
>> The Symbol is just a name.
>
> Er... a thing that /has/ a name. (That being, Symbol#to_s.)

OK, well, I RTFA, and sorry for blatantly contradicting what was an

intentional choice of words (and not, as I had thought, a slip-up)
without reason. Anyways, to quote you:

> No. :wilbur is an object. It has *one* property, itself. You can ask for


> integer or string representations, but :wilbur's value is :wilbur and
> there will only ever be one :wilbur.

Calling it a "name" is just another analogy. Its name is its String

Chad Perrin

unread,
Dec 30, 2005, 1:57:53 AM12/30/05
to
On Fri, Dec 30, 2005 at 02:10:09PM +0900, Yohanes Santoso wrote:
> Chad Perrin <per...@apotheon.com> writes:
>
> What is 1? A way to represent the number one. You said a way, what
> others are there? 0x1, \001, "1". However, one does not use "1" to
> represent the number one even if one doesn't plan to do any arithmetic
> operations on that number because that representation is
> ambiguous. Does he mean "1" as in number one or as in the character
> "1"?

Then why not simply say:

:symbol is to "symbol" as 1 is to "1"

That would get the point across far more clearly than saying "A symbol
is just a name," especially since strings can be names (from another
perspective), and since variables are "names" in another sense of the
term, and so on. Saying it's "a name" doesn't explain jack, as far as I
can tell.

Being vague doesn't help.


>
> > "A means for you, the programmer, to name/identify entities" is not a
> > description of what a symbol *is* so much as a description of how you
> > can use it.
>
> I really am not sure what you are saying there. That sentence
> describes what a symbol is. That sentence does not describe/prescribe
> how to use it.

Let's take a look at that sentence's structure and meaning:

A [something] is a means [. . .] to [do something].

Gee, looks like a description of how one uses it. A symbol is a means
to name/identify entities. A screwdriver is a means to turn screws. A
mug is a means to transport coffee. By the same token, however,
telekinesis is a means to turn screws, as is a centrifuge if you really
want to put screws into one, for some definition of "turn". Also, a
hose, a Folger's can, and an eighteen wheeler might be a means for
transporting coffee. It's vague and, ultimately, useless for getting
the point across, that point being: What *is* it?

A screwdriver is a handle affixed to a metal shaft with a bit on the end
that serves as the interface for the screw -- the torque point, if you
will. A mug is a drinking vessel that is ideally suited to beverages
such as coffee, allow you to transport the hot beverage from the coffee
pot to your lips after it has been prepared and poured.

For someone who doesn't already know what a mug or screwdriver actually
is, the mere description of what each is a means to do is far too vague
to actually impart much understanding.


>
> > object", or something like that, without any explanation of what a
> > symbol actually does behind the scenes.
>
> This is precisely the kind of explanation that I objected when
> explaining what a symbol is to a newcomer. Any explanation that refer
> to the implementation is doomed to be short-lived. There are many ways
> to implement the class Symbol and the concept of symbol.

It may be doomed to be short lived, but without some kind of example
that is recognizable, the prospective student is more likely than not to
learn very little of anything.


>
> Do you explain what number does behind the scenes to someone asking
> 'What is a number?' Do you explain that ruby maps number less than
> 2^31-1 directly to native integer format? Quick question, then: does
> this still hold on a 64-bit machine? How about in ruby 2.0? Will
> Number behave differently and is used to represent different thing
> there simply because what goes on behind the scene has changed?

Unlike symbols, numbers are pretty well understood, particularly for
someone coming from another programming language (any language except
the original, archetypal "lisp", pre-implementation, involves numbers).
Symbols are another matter entirely.

The problem with most of the descriptions of symbols I've seen is that
they try to define symbols in terms of themselves to people who don't
already understand those terms. A framistan is a thing. Whee. That
taught me nothin'.

This approach to explaining symbols is equivalent to trying to teach
object oriented programming with nothing more than the statement that
"an object is a thing". Okay, great. What kind of thing? What are all
these terms like "method/message" and "class" and "instance" and so on?
There are entire college courses devoted (almost) solely to imparting a
rudimentary understanding of what an "object" is and how it is used.
Why can't someone come up with a better explanation of a symbol than the
five-word sentences that are so common here?

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

"Real ugliness is not harsh-looking syntax, but having to

Chad Perrin

unread,
Dec 30, 2005, 2:10:27 AM12/30/05
to
On Fri, Dec 30, 2005 at 01:36:05PM +0900, Eero Saynatkari wrote:

0. :symbol is to "symbol" as 1 is to "1"
Insofar as it is accurate to say that an integer is an atomic
numeral, it is likewise accurate to say that a symbol is an
atomic string, or so it seems to me.
>
> 1. Symbols are values.
> :foo is like 'foo' or 2 or f = FooObject.new
>
> 2. Symbols are used to name, describe or label things.
> cd_drive_type = :dvd_rom
> socks = my_closet[:sock_drawer]
>
> 3. Common usages.
> object.send :method_name, parameter # Could use 'method_name'
> attr_accessor :property1, :property2 # Could use 'property1' etc.
>
> 4. Implementation details.

Am I wrong?

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

print substr("Just another Perl hacker", 0, -2);


gwt...@mac.com

unread,
Dec 30, 2005, 2:19:31 AM12/30/05
to

On Dec 30, 2005, at 12:45 AM, Austin Ziegler wrote:
> Sure, you could get pedantically
> philosophical, but the you'd be saying that 1 really isn't the number,
> it's a thing that represents a quantity of one.

But 1 (as in the ascii character code 49) is *not* the number/object
one.
And the reference value that the Ruby parser constructs when it sees
the ascii character code 49 is also *not* the number/object one.

I don't think it is possible to have a coherent discussion of Ruby
semantics without clearly and consistently differentiating between
an object, a reference to an object, and an identifier that is
bound to a reference to the object. In particular, the semantics
of assignment/equality/identity can't be fully explained without
carefully distinguishing between these ideas.

Yes it sounds very pedantic but the devil is in the details.

Gary Wright

Chad Perrin

unread,
Dec 30, 2005, 2:44:55 AM12/30/05
to
On Fri, Dec 30, 2005 at 01:42:39PM +0900, gwt...@mac.com wrote:
>
> I think one of the hardest things to explain/comprehend
> about symbols is that the *only* semantics associated
> with a symbol is that there is a one to one mapping from a symbol
> object to a sequence of characters. It is this isomorphism that
> is the useful (and *only*) property of symbols.

If you want a useful introductory description of symbols for someone
that hasn't encountered them before, the above is the only part of your
previous email that is taking steps in that direction.

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

print substr("Just another Perl hacker", 0, -2);


Chad Perrin

unread,
Dec 30, 2005, 2:56:51 AM12/30/05
to
On Fri, Dec 30, 2005 at 03:01:34PM +0900, Devin Mullins wrote:
>
> Calling it a "name" is just another analogy. Its name is its String
> representation, just as Module#name == Module#to_s (for non-singletons).
> Rather, :jazz is :jazz is :jazz. There is no reducing it to other concepts.

That's something I've been trying to get across in other emails, but I
don't think I've done a very good job. Thus, using the "symbol is just
a name" analogy doesn't actually explain what a symbol *is*. Analogies
are essentially useless without the technically correct explanation for
them to illustrate.

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

This sig for rent: a Signify v1.14 production from http://www.debian.org/


gwt...@mac.com

unread,
Dec 30, 2005, 3:17:43 AM12/30/05
to

On Dec 30, 2005, at 2:44 AM, Chad Perrin wrote:

> On Fri, Dec 30, 2005 at 01:42:39PM +0900, gwt...@mac.com wrote:
>>
>> I think one of the hardest things to explain/comprehend
>> about symbols is that the *only* semantics associated
>> with a symbol is that there is a one to one mapping from a symbol
>> object to a sequence of characters. It is this isomorphism that
>> is the useful (and *only*) property of symbols.
>
> If you want a useful introductory description of symbols for someone
> that hasn't encountered them before, the above is the only part of
> your
> previous email that is taking steps in that direction.

I wasn't trying to produce a useful introductory description
of symbols. Nor do I really think that first paragraph would be all
that appropriate for that purpose. 'Isomorphism' isn't exactly in
common use.

Gary Wright


Gregory Brown

unread,
Dec 30, 2005, 3:18:46 AM12/30/05
to
On 12/30/05, Chad Perrin <per...@apotheon.com> wrote:

> That's something I've been trying to get across in other emails, but I
> don't think I've done a very good job. Thus, using the "symbol is just
> a name" analogy doesn't actually explain what a symbol *is*. Analogies
> are essentially useless without the technically correct explanation for
> them to illustrate.
>

You know. I'm tired of hearing about how incorrect everyone is and
how they haven't found a solution that meets your needs. It's frankly
becoming insulting.

kill-filed.


Chad Perrin

unread,
Dec 30, 2005, 3:37:34 AM12/30/05
to

Sorry. I didn't mean to suggest that you must intend to produce a
useful introduction. I guess I wasn't clear. I was just saying that
*if* "you" (for some definition of "you") wanted to produce such an
introduction, that one part of your message seemed to be a step in the
right direction. The language wasn't particularly accessible (as you
point out), but the concepts were, and didn't require a firm grounding
in Ruby to understand them.

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

unix virus: If you're using a unixlike OS, please forward

Chad Perrin

unread,
Dec 30, 2005, 3:38:24 AM12/30/05
to
On Fri, Dec 30, 2005 at 05:18:46PM +0900, Gregory Brown wrote:
> You know. I'm tired of hearing about how incorrect everyone is and
> how they haven't found a solution that meets your needs. It's frankly
> becoming insulting.
>
> kill-filed.

hallelujah

--
Chad Perrin [ CCD CopyWrite | http://ccd.apotheon.org ]

"A script is what you give the actors. A program

Johannes Friestad

unread,
Dec 30, 2005, 5:04:27 AM12/30/05
to
On 12/30/05, Chad Perrin <per...@apotheon.com> wrote:
> 0. :symbol is to "symbol" as 1 is to "1"
> Insofar as it is accurate to say that an integer is an atomic
> numeral, it is likewise accurate to say that a symbol is an
> atomic string, or so it seems to me.
..
> Am I wrong?
>

No, you're right.
The string "123" is a character sequence, and can be picked apart
character by character. The integer 123 is atomic - it cannot be
picked apart on the object level.
Likewise, the string "abc" is a character sequence, and can be picked
apart. The symbol :abc is atomic.

A further similarity between (fixnum) integers and symbols is that
there will always be only one object representing the integer 123, and
only one object representing the symbol :abc. Strings are basically
byte arrays, there can be several strings containing the same
elements.

So I guess you can say that symbols gives a fixnum-style atomic
representation of any given string.

jf


Christian Neukirchen

unread,
Dec 30, 2005, 8:06:37 AM12/30/05
to
Steve Litt <sl...@earthlink.net> writes:

> By the way, your article is obviously needed, and you should probably refine
> it as time goes on. The fact that we had so many responses that at least in
> part contradicted each other indicates to me that symbols are perhaps the
> most surprising element of Ruby, which is otherwise not a surprising language
> at all.

That just means you didn't dig deep enough into Ruby (yet). ;-)

> SteveT
--
Christian Neukirchen <chneuk...@gmail.com> http://chneukirchen.org


Malte Milatz

unread,
Dec 30, 2005, 8:05:48 AM12/30/05
to
dblack:

> Actually, s = :sym doesn't produce a reference to :sym;
> rather, s has the actual/immediate value :sym. Anyway, the main (obscured)
> point was that symbols are not references.

My understanding of things so far was that :sym and 3 are immediate values,
and after writing
a, b = :sym, 3
a is a reference to :sym and b is a reference to 3.

Have I been wrong all the time?

Malte

Ross Bamford

unread,
Dec 30, 2005, 8:22:23 AM12/30/05
to
On Fri, 30 Dec 2005 13:05:48 -0000, Malte Milatz <mal...@gmx-topmail.de>
wrote:

I wonder that too. What about:

a, b = :sym, :sym

I guess a and b hold separate references to the same object, much as if I
did

a, b = 4, 4

That was the basis for my mentioning literal fixnums earlier in the ':foo
and "foo"' thread, but now I wonder if I'm in fact wrong (again ;)).

Basically I suppose I'm confused about assignment by value or reference. I
though Ruby was pass by reference, with references passed by value, no
matter what?

--
Ross Bamford - ro...@roscopeco.remove.co.uk

Steve Litt

unread,
Dec 30, 2005, 9:56:31 AM12/30/05
to
On Thursday 29 December 2005 07:36 pm, Chad Perrin wrote:
> On Fri, Dec 30, 2005 at 05:07:35AM +0900, Yohanes Santoso wrote:
> > Chad Perrin <per...@apotheon.com> writes:
> > > If that's the case, what's up with all this tripe about "a symbol is
> > > just a name" and so on?
> >
> > Because it's true? Because there are people who don't have lisp
> > background who are not familiar with what symbol is? Because there are
> > people who thinks symbols are magical thingie?
>
> It's not really true, though, considering what a symbol is (according to
> my current understanding). A symbol is an element of a hash table that
> is often used as a name, and it is an (anonymous? not sure how to
> qualify that) object. Calling it a "name" seems to be confusing common
> use with actual nature, or premature explanation of an abstract way of
> thinking about it, depending on how you mean "it is a name" when you say
> it. Either way, it seems to be getting the cart before the horse.

And now you have identified the crux of all the misunderstanding (and I think
"misunderstanding" is the right word, given that tens of people smarter than
me disagree with each other on how to describe a symbol).

Long time Rubyists, people with heavy CS studies, and people who have
experience in languages with symbols (LISP, I guess) tend to talk more about
how it's implemented, while programmers (probably without CS degrees)
migrating from languages not containing symbols are more interested in what
it does than how it's implemented.

I asked if it's an object with 2 attributes, an integer key and a string
value. Someone says no, it's an object with one attribute that can be seen 2
ways, a string or an integer. From my point of view, he's saying the same
thing. I was describing what it can do for me, he was describing something
truer to the implementation, but when actually using the little bugger either
explanation will lead to correct programming, at least if I understand it
correctly (and I think I now understand it correctly, at least correctly
enough to know how and when to use a symbol).

One thing I know for sure -- the length and bredth of this thread indicates
for sure that Ruby symbols need much better documentation. Austin Ziegler has
made an excellent start. I volunteer to give input from an imigrant from Perl
land (and C, C++, and about a dozen others but not lisp) whose BS degree is
in Electrical Engineering and whose computer programming classes were limited
to the very practical stuff they taught at Santa Monica Community College.

dbl...@wobblini.net

unread,
Dec 30, 2005, 10:19:07 AM12/30/05
to
Hi --

On Fri, 30 Dec 2005, Eero Saynatkari wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>

>> On Fri, 30 Dec 2005, dbl...@wobblini.net wrote:
>>
>> This assertion by me seems to have been mercifully ignored in

>> subsequent discussion :-) Actually, s = :sym doesn't produce a


>> reference to :sym; rather, s has the actual/immediate value :sym.
>> Anyway, the main (obscured) point was that symbols are not references.
>

> This is another bad aspect of Symbol explanations. Sooner or later
> someone mentions 'immediate values' or 'internal symbol tables'.
> While accurate (and in some cases, useful knowledge), these are a
> big source of confusion and not in any way helpful to understanding
> the fairly trivial function of Symbols :/

"Immediate value" is not a useless or arcane notion. (And I did *not*
mention the internal symbol table :-) In fact, understanding that
some variable assignments result in variables that hold immediate
values, and others result in variables that hold references, is quite
important, if you want to understand, for example, the whole lack of
post-increment operator thing (i.e., the fact that, given x = 1, x++
and 1++ are the same expression, etc.).

I agree that part of the problem with people understanding Symbols is
the tendency to expect, and look for, more than is there -- but I'd
maintain that to understand Ruby identifiers fully, you really need to
be aware of the (not terribly difficult) notion of immediate values
vs. references.


David

--
David A. Black
dbl...@wobblini.net

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black


Steve Litt

unread,
Dec 30, 2005, 10:35:11 AM12/30/05
to
On Friday 30 December 2005 08:06 am, Christian Neukirchen wrote:
> Steve Litt <sl...@earthlink.net> writes:
> > By the way, your article is obviously needed, and you should probably
> > refine it as time goes on. The fact that we had so many responses that at
> > least in part contradicted each other indicates to me that symbols are
> > perhaps the most surprising element of Ruby, which is otherwise not a
> > surprising language at all.
>
> That just means you didn't dig deep enough into Ruby (yet). ;-)

Then neither did the 20+ other people, some long time Ruby users, who couldn't
put forth an explanation clear enough to settle the issue amongst the
majority.

With all the controversy, including some piping to a killfile, the issue isn't
*my* depth of digging, it's either *everyone's* depth of digging, or it's an
issue of :symbols being a particularly surprising element of Ruby. I haven't
heard this level of disagreement about blocks, methods, iterators and the
like. Heck, for two cents I'll document it myself!

Austin Ziegler

unread,
Dec 30, 2005, 10:55:55 AM12/30/05
to
On 30/12/05, Steve Litt <sl...@earthlink.net> wrote:
> Long time Rubyists, people with heavy CS studies, and people who have
> experience in languages with symbols (LISP, I guess) tend to talk more
> about how it's implemented, while programmers (probably without CS
> degrees) migrating from languages not containing symbols are more
> interested in what it does than how it's implemented.

And what I've been trying to get across, Steve, is that Symbols don't
actually *do* anything. Nothing. Zero. Zip. ABSOLUTELY NADA! They're
names with the special property that the name uniquely identifies the
object. :wilbur always identifies :wilbur.

> I asked if it's an object with 2 attributes, an integer key and a
> string value. Someone says no, it's an object with one attribute that
> can be seen 2 ways, a string or an integer. From my point of view,
> he's saying the same thing.

Then you didn't understand the answer if you saw them as the same. What
I said (rephrasing; I'm too lazy to look up what I really said) is
essentially that a Symbol has one value: itself. If you will, its name.

puts :wilbur.inspect # => :wilbur

You can *convert* a Symbol to a string:

puts :wilbur.to_s # => wilbur

You can *convert* a Symbol to an integer value:

puts :wilbur.to_i # => 23569 !! This value can change !!

But both #to_s and #to_i are conversions, not attributes of the Symbol.
The Symbol's only attribute is ... itself. Just like a Fixnum's only
attribute is ... itself.

puts 1.inspect # => 1

Look at what Symbol.instance_methods(false) returns:

["inspect", "to_int", "===", "to_s", "to_sym", "to_i", "id2name"]

Symbol doesn't otherwise provide any methods not provided by Object (or
Kernel), and most of those listed above are conversion methods.

[...]

Hopefully that's a bit clearer. It's not that different from Perl
barewords.

Steve Litt

unread,
Dec 30, 2005, 11:06:05 AM12/30/05
to
On Friday 30 December 2005 10:55 am, Austin Ziegler wrote:
>It's not that different from Perl
> barewords.

I plead ignorance on Perl barewords. I use "use strict" every time.

Christian Neukirchen

unread,
Dec 30, 2005, 12:42:35 PM12/30/05
to
Steve Litt <sl...@earthlink.net> writes:

Oh, I'm sorry. I think you got me wrong. I was refering to the "most
suprising element" for you. There are mystic parts of ruby that are
far more suprising. Personally, I don't know why people have such big
problems with Symbol, and I'll probably not ever understand. Just
take them for granted and use them.

Christer Nilsson

unread,
Dec 30, 2005, 1:00:51 PM12/30/05
to
Amazing!

This is the 98th comment in this thread! Longest in december.
If we go further we have to discuss on the transistor level...

Christer

--
Posted via http://www.ruby-forum.com/.


Gregory Brown

unread,
Dec 30, 2005, 1:04:26 PM12/30/05
to
On 12/30/05, Christian Neukirchen <chneuk...@gmail.com> wrote:

> Personally, I don't know why people have such big
> problems with Symbol, and I'll probably not ever understand. Just
> take them for granted and use them.

Amen!

Sorry if this has already been posted but Kevin Clark gives a good
explanation of Ruby Symbols in his article _Understanding Ruby
Symbols_

http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols

Now i'm not sure that this has enough detail for the pedantic* but he
certainly makes the case for USING symbols.

Hope this helps shed some light, as this thread is getting painfully long.

-Greg

* seriously we should find a new word, search the archive for this
week to see what I mean!
On the lighter sides of things... I've searched for new ways to call
each other or ourselves pedantic, which hopefully the erudites among
us will pick apart :)

abstruse, academic, arid, didactic, doctrinaire, donnish, dry, dull,
egotistic, erudite, formal, fussy, hairsplitting, learned, nitpicking,
ostentatious, overnice, particular, pedagogic, pompous, precise,
priggish, punctilious, scholastic, schoolish, sententious, stilted


Christer Nilsson

unread,
Dec 30, 2005, 1:08:13 PM12/30/05
to
The original poster, Surgeon, wrote only two comments.
This is his second, sixty comments ago:

>Oh, so many replies to my poor question! What a wonderful community!

I guess, he was forgotten somewhere around five :-)

Next comment will be number 100!

gwt...@mac.com

unread,
Dec 30, 2005, 1:18:58 PM12/30/05
to

On Dec 30, 2005, at 1:08 PM, Christer Nilsson wrote:
> The original poster, Surgeon, wrote only two comments.
> This is his second, sixty comments ago:
>
>> Oh, so many replies to my poor question! What a wonderful community!
>
> I guess, he was forgotten somewhere around five :-)
>
> Next comment will be number 100!

Yikes. I hope we don't start behaving like the Slashdot community
where everyone races to post the message "this is the first message".

Gary "did I submit the 100th message?" Wright


Gregory Brown

unread,
Dec 30, 2005, 1:26:11 PM12/30/05
to
On 12/30/05, gwt...@mac.com <gwt...@mac.com> wrote:

> Gary "did I submit the 100th message?" Wright

Actually. Not according to ruby-forum. The message before yours was
the 100th :)

But nothin' wrong with being 101.

Gary Wright, Symbols 101. Hey, didn't you teach that class a couple
weeks ago? ;)

-Greg (102... i think)


Steve Litt

unread,
Dec 30, 2005, 2:51:22 PM12/30/05
to
On Friday 30 December 2005 10:35 am, Steve Litt wrote:
[clip]

> With all the controversy, including some piping to a killfile, the issue
> isn't *my* depth of digging, it's either *everyone's* depth of digging, or
> it's an issue of :symbols being a particularly surprising element of Ruby.
> I haven't heard this level of disagreement about blocks, methods, iterators
> and the like. Heck, for two cents I'll document it myself!
>
> SteveT

The Ruby Newbie Guide to Symbols is here:

http://www.troubleshooters.com/codecorn/ruby/symbols.htm

Austin Ziegler

unread,
Dec 30, 2005, 3:03:20 PM12/30/05
to
On 30/12/05, Steve Litt <sl...@earthlink.net> wrote:
> On Friday 30 December 2005 10:35 am, Steve Litt wrote:
> [clip]
> > With all the controversy, including some piping to a killfile, the issue
> > isn't *my* depth of digging, it's either *everyone's* depth of digging, or
> > it's an issue of :symbols being a particularly surprising element of Ruby.
> > I haven't heard this level of disagreement about blocks, methods, iterators
> > and the like. Heck, for two cents I'll document it myself!
> >
> > SteveT
>
> The Ruby Newbie Guide to Symbols is here:
>
> http://www.troubleshooters.com/codecorn/ruby/symbols.htm

Steve:

Please edit your guide, as it is *not* correct when it says:

A Ruby symbol is a thing that has both a number (integer) and a string.

This is not correct in any way. If you leave it as "A Ruby Symbol is a
thing", you're fine. But when you say that it "has" a number and a
string, you are incorrect. Symbols are not composed of the integer or
string values that you can convert Symbols to; they just are. The
value of a Symbol is not its String value or its Fixnum value, but
itself.

I strongly recommend rewriting your guide from that perspective,
because you are likely to greatly *increase* the confusion of newbies.
If you would like, I can see about possibly helping you edit this or
coauthor it such that it might become a useful article to be published
at Ruby Code & Style to explain where Symbols can be used and what
they are. Ultimately, though, trying to dig into the internals of
Symbols misses the point -- it's just something that represents
itself.

It is loading more messages.
0 new messages