Hash? But variables?

S

Soichi Ishida

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
 
S

Stu

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=3D[1,2,3]

you would get 2 by accessing via

a[1] (index starts at zero)

as a hash it could be written

a=3D{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 =3D>
and moves the colon to the other side of the key.

I hope I didn't confuse you more.
 
R

Robert Klemme

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

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

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

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

Not exactly. Here's the difference:

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

Also:

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

And, more importantly:

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

whereas

irb(main):013:0> a =3D (1..4).map { "water" }
=3D> ["water", "water", "water", "water"]
irb(main):014:0> a.map {|o| o.object_id}
=3D> [135636242, 135636228, 135636214, 135636200]
irb(main):015:0> a.map {|o| o.object_id}.uniq
=3D> [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

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

Soichi Ishida

Thanks for all of you.

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

Thanks again.

soichi
 
S

Stu

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

Soichi Ishida

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

Thanks everyone!

soichi
 
S

Su Zhang

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

Mike Stephens

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top