简体   繁体   中英

How to create a similar Ruby method using symbol?

I have been reading a Ruby book where I encountered below code to describe symbols

def walk(direction)
  if direction == :north
    # ...
  end
end

I tried and failed to create a similar method ( where a comparison is made against a symbol such as

direction == :north

because most of the time I have seen symbols being used something like param[:name] , so in my code I tried :north = 1 or :favourite = 'ruby' but got syntax error.

Is it really possible to have such a comparison using a symbol alone (without hash) ie instead of

if "ruby" == param[:name]
end

if "ruby" == :name
end

I am not sure if I have expressed the question clearly, if not I shall try and reword it.

I see a misunderstanding of what symbols are and what is their purpose.

if direction == :north

In this line, direction is a variable (it can hold any value) and :north is a value (it can be assigned to variables).

Trying to do this:

:north = 1

is like trying to do

2 = 1

Which doesn't make sense, of course.

Symbols are rather like identifiers, or a special version of strings.

With strings, you can have

str1 = 'SYM'

and

str2 = 'symbol'
str2 = str2[0,3].upcase

and now there are two identical strings in different places in memory. Ruby has to compare all the characters to evaluate str1 == str2 .

However symbols are unique - you can't do character manipulation on them, and if you have

sym1 = :SYM
sym2 = :SYM

then it takes only a single comparison to test their equality. It demonstrates this clearly if we look at the object IDs for the strings and the symbols

puts str2.object_id
puts str1.object_id

puts sym1.object_id
puts sym2.object_id

puts str1.to_sym.object_id
puts str2.to_sym.object_id

output

22098264
22098228
203780
203780
203780
203780

So the two strings have different object IDs, whereas the two symbols are, in fact, the same object. Even converting the two strings to symbols gives the same object ID, so there is only one :SYM .

Because symbols are values , it makes no sense to write something like :north = 1 as it is like writing 'north' = 1 .

Comparing strings to symbols, like 'north' = :north will always return false , because they are different classes of object.

param[:name] works only because you can index a hash with any object . (You can say param[Object.new] = 1 .) It's different from writing either param['name'] (indexing the hash by a literal string) or param[name] (indexing the hash by the contents of variable name ).

Does this answer your question?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM