Ruby and :symbols

2019-05-26 14:32发布

问题:

I have just started using Ruby and I am reading "Programming Ruby 1.9 - The Pragmatic Programmer's Guide". I came across something called symbols, but as a PHP developer I don't understand what they do and what they are good for.

Can anyone help me out with this?

回答1:

It's useful to think of symbols in terms of "the thing called." In other words, :banana is referring to "the thing called banana." They're used extensively in Ruby, mostly as Hash (associative array) keys.

They really are similar to strings, but behind the scenes, very different. One key difference is that only one of a particular symbol exists in memory. So if you refer to :banana 10 times in your code, only one instance of :banana is created and they all refer to that one. This also implies they're immutable.



回答2:

Symbols are similar to string literals in the sense that share the same memory space, but it is important to remark they are not string equivalents.

In Ruby, when you type "this" and "this" you're using two different memory locations; by using symbols you'll use only one name during the program execution. So if you type :this in several places in your program, you'll be using only one.

From Symbol doc:

Symbol objects represent names and some strings inside the Ruby interpreter. They are generated using the :name and :"string" literals syntax, and by the various to_sym methods. The same Symbol object will be created for a given name or string for the duration of a program‘s execution, regardless of the context or meaning of that name. Thus if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.

So, you basically use it where you want to treat a string as a constant.

For instance, it is very common to use it with the attr_accessor method, to define getter/setter for an attribute.

class Person 
   attr_accessor :name 
end
p = Person.new
p.name= "Oscar"

But this would do the same:

class DontDoThis
   attr_accessor( "name" )
end
ddt = DontDoThis.new
ddt.name= "Dont do it"


回答3:

Think of a Symbol as a either:

  • A method name that you plan to use later
  • A constant / enumeration that you want to store and compare against

For example:

s = "FooBar"
length = s.send(:length)
>>> 6


回答4:

@AboutRuby has a good answer, using the terms "the thing called".

:banana is referring to "the thing called banana."

He notes that you can refer to :banana many times in the code and its the same object-- even in different scopes or off in some weird library. :banana is the thing called banana, whatever that might mean when you use it.

They are used as

  • keys to arrays, so you look up :banana you only have one entry. In most languages if these are Strings you run the risk of having multiple Strings in memory with the text "banana" and not having the code detect they are the same
  • method/proc names. Most people are familiar with how C distinguishes a method from its call with parentheses: my_method vs. my_method(). In Ruby, since parentheses are optional, these both indicate a call to that method. The symbol, however, is convenient to use as a standin for methods (even though there really is no relationship between a symbol and a method).
  • enums (and other constants). Since they don't change they exhibit many of the properties of these features from other languages.


标签: ruby symbols