Hash? But variables?

Hi. I am a little confused with the use of ":" like,

hash = { :water => 'wet', :fire => 'hot' }
puts hash[:fire] # Prints: hot

in constructing the hash in this example, ":water" is the key for "wet".
I understand that. But what is the difference between "water" and
":water"?

I am guessing that ":water" works as a variable...but not quite sure.

Sorry if this is a too elementary question.

soichi

···

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

try,

  :water = 1

···

On Thu, Dec 9, 2010 at 4:08 PM, Soichi Ishida <soujiro0725+rubyforum@gmail.com> wrote:

I am guessing that ":water" works as a variable...but not quite sure.

It's actually a very good question. hashes are like arrays with non
numerical tags.

but instead of referring to the list as list[0] or list [2] you refer
to it as list[:element]

It's like having a readable array which also retains the speed.

for example of you have an array such as

a=[1,2,3]

you would get 2 by accessing via

a[1] (index starts at zero)

as a hash it could be written

a={one: 1, two: 2, three: 3}

then to access 2 we can do

a[:two]

instead of

a[1]

btw I used the shorthand version of hash creation which drops the =>
and moves the colon to the other side of the key.

I hope I didn't confuse you more.

···

On Thu, Dec 9, 2010 at 2:08 AM, Soichi Ishida <soujiro0725+rubyforum@gmail.com> wrote:

Hi. I am a little confused with the use of ":" like,

hash = { :water => 'wet', :fire => 'hot' }
puts hash[:fire] # Prints: hot

in constructing the hash in this example, ":water" is the key for "wet".
I understand that. But what is the difference between "water" and
":water"?

I am guessing that ":water" works as a variable...but not quite sure.

Sorry if this is a too elementary question.

soichi

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

Not exactly. Here's the difference:

irb(main):001:0> :water.class
=> Symbol
irb(main):002:0> "water".class
=> String

Also:

irb(main):003:0> :water == "water"
=> false
irb(main):004:0> "water" == :water
=> false
irb(main):005:0> :water.eql? "water"
=> false

And, more importantly:

irb(main):010:0> a = (1..4).map { :water }
=> [:water, :water, :water, :water]
irb(main):011:0> a.map {|o| o.object_id}
=> [247864, 247864, 247864, 247864]
irb(main):012:0> a.map {|o| o.object_id}.uniq
=> [247864]

whereas

irb(main):013:0> a = (1..4).map { "water" }
=> ["water", "water", "water", "water"]
irb(main):014:0> a.map {|o| o.object_id}
=> [135636242, 135636228, 135636214, 135636200]
irb(main):015:0> a.map {|o| o.object_id}.uniq
=> [135636242, 135636228, 135636214, 135636200]

In other words: the sequence :water always returns the same Symbol
instance while the sequence "water" (and 'water' also) create a new
instance all the time. If you have a limited set of Hash keys the
symbol is more appropriate because it is more efficient. If the
number of keys is large and changes often better use String (e.g. when
reading them from some external source).

Kind regards

robert

···

On Thu, Dec 9, 2010 at 9:08 AM, Soichi Ishida <soujiro0725+rubyforum@gmail.com> wrote:

Hi. I am a little confused with the use of ":" like,

hash = { :water => 'wet', :fire => 'hot' }
puts hash[:fire] # Prints: hot

in constructing the hash in this example, ":water" is the key for "wet".
I understand that. But what is the difference between "water" and
":water"?

I am guessing that ":water" works as a variable...but not quite sure.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Thanks for all of you.

I think I am getting it, although I will need to practice to fully
understand it.

Thanks again.

soichi

···

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

symbol and string...
This is much deeper than I thought.

Thanks everyone!

soichi

···

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

Just another addition to the facts above:

Symbols are Ruby's implementation of string interning or pooling, where
all the distinct symbols, each of which being immutable, are "interned"
in a constant pool. This mechanism brings better performance (both in
time
and space) of string comparison and reduces memory usage, but also
increases the time to create strings.

···

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

One way of describing symbols is they are constants whose value is their
name.

As far as your example is concerned, the two options give you rather the
same effect. Most likely "water" is held as an object of type string
whereas :water is held as an entry in a symbol table. Quite possibly one
is more efficient that the other (either faster or taking less space)
but Ruby is not supposed to be a language that worries about such things
(it's supposed to be human oriented), and I'm not convinced you could
rely on that in all implementations.

···

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

I wanted to add that you should think of a hash as an accocated array.

your keys can be "strings" or :symbols

symbols are easier to read and are faster as they refer to an integer
value inside the interpreter.

hashes can hold any fundamental, complex or abstract data type and
object including other hashes.