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

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

http://onestepback.org/index.cgi/Tech/Ruby/SymbolsAreNotImmutableStrings.red

···

2005/12/28, Surgeon <biyokuantum@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?

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

slitt@troubleshooters.com

···

On Wednesday 28 December 2005 02:32 pm, Alex Knaub wrote:

2005/12/28, Surgeon <biyokuantum@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

Alex Knaub <aknaub@gmail.com> writes:

···

2005/12/28, Surgeon <biyokuantum@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

YS.

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... :wink:

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

···

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 <biyokuantum@gmail.com>:

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).

···

On Wed, 28 Dec 2005 19:47:16 -0000, Steve Litt <slitt@earthlink.net> wrote:

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

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

···

From: "Steve Litt" <slitt@earthlink.net>

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 :slight_smile:

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
slitt@troubleshooters.com

--
Johannes Friestad
johannes.friestad@gmail.com

Yohanes Santoso wrote:

Alex Knaub <aknaub@gmail.com> writes:

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

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

···

2005/12/28, Surgeon <biyokuantum@gmail.com>:

--

http://www.ruby-doc.org - Ruby Help & Documentation
Ruby Code & Style - 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

Yohanes Santoso wrote:

Alex Knaub <aknaub@gmail.com> writes:

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. 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

···

2005/12/28, Surgeon <biyokuantum@gmail.com>:

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

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. :slight_smile:

···

On Wed, 28 Dec 2005 20:00:13 -0000, James Edward Gray II <james@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... :wink:

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

>>> 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... :wink:

> 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.

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))

SteveT

Steve Litt

slitt@troubleshooters.com

···

On Wednesday 28 December 2005 03:00 pm, James Edward Gray II wrote:

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 <biyokuantum@gmail.com>:

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:

···

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.

   ---
    - 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

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

James Britt wrote:

···

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

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_UsingSymbolsForTheWrongReason.html

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 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... :wink:

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

···

--
-- Jim Weirich

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

James Britt <james_b@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.

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

···

On Dec 28, 2005, at 3:22 PM, Ross Bamford wrote:

On Wed, 28 Dec 2005 19:47:16 -0000, Steve Litt > <slitt@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'.

Eero Saynatkari <ruby-forum-reg@mailinator.com> writes:

Yohanes Santoso wrote:

Alex Knaub <aknaub@gmail.com> writes:

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.

···

2005/12/28, Surgeon <biyokuantum@gmail.com>:

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

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

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

···

On Dec 28, 2005, at 2:35 PM, Steve Litt wrote: