) Understanding Ruby Symbol

Source: Internet
Author: User

What is Symbol?

Ruby is a powerful object-oriented scripting language (the ruby version used in this article is 1.8.6). In Ruby, symbol represents a "name", such as a string name and an identifier name. To create a symbol object, add a colon Before the name or string:

Create a symbol object

: foo
: test
 

: "Abc"
: "I am a boy"
 

You may ask, the string is the string, why do you still have the name of the string? This is because in Ruby a string is also an object, a String object. No matter its structure or operation and Symbol object are different. In Ruby, each object has a unique object identifier (Object Identifier), you can get an object identifier through the object_id method. Let's take a look at the difference between Symbol objects and String objects:

Ruby object identifier

irb (main): 001: 0> puts: foo.object_id
327458
=> nil
irb (main): 002: 0> puts: foo.object_id
327458
=> nil
irb (main): 003: 0> puts: "foo" .object_id
327458
=> nil
irb (main): 004: 0> puts "foo" .object_id
24303850
=> nil
irb (main): 005: 0> puts "foo" .object_id
24300010
=> nil
irb (main): 006: 0> puts "foo" .object_id
24296170
=> nil
 

It can be seen that: foo (or: "foo") in the first three lines of the statement are the same Symbol object, its object id is 327458, and the string "foo" in the last three lines are different objects, its object The id is 24303850, 24300010, 24296170 in order.

Visible, each String object is different, even if they contain the same string content; and for Symbol objects, a name (string content) uniquely determines a Symbol object.

It is worth noting that the string creating the Symbol object cannot contain the '\ 0' character, while the String object is possible.

Illegal Symbol string

irb (main): 001: 0>: "fo \ 0o"
SyntaxError: compile error
(irb): 1: symbol cannot contain '\ 0'
        from (irb): 1
irb (main): 002: 0>: "foo \ 0"
SyntaxError: compile error
(irb): 2: symbol cannot contain '\ 0'
        from (irb): 2
irb (main): 003: 0> puts "foo \ 0" .object_id
24305140
=> nil
irb (main): 004: 0> puts "fo \ 0o" .object_id
24301000
=> nil
irb (main): 005: 0>
 

In addition to the general string, you can also use operators (such as +,-, *, /), variables, constants, methods and even the name of the class to create Symbol objects, for example: + is a legal Symbol. In fact, the names of operators and variables in Ruby are handled as Symbols themselves. For example, when you define an instance variable, Ruby will automatically create a Symbol object, for example, @test corresponds to: @test.

Symbol of instance variable

class Test
 attr_accessor: test
end
 

This class defines an instance variable @test with read and write methods. In fact, Ruby creates two Symbols, one is the instance variable symbol: @test and the other is: test. What if the string object "test" is used as a parameter? Or, two symbols will still be created,: test and: @test, why would you also create: test? This is related to the Ruby implementation (at least in Ruby 1.8.6).

Note that the symbols corresponding to the class variable @@ test and the instance variable @test are obviously different. Remember: the same name, the same Symbol.

Same name, same symbol

class Test
  puts: Test.object_id
  Test = 10
  puts: Test.object_id
  
  def Test
    puts: Test.object_id
  end
end

Test.new.Test
operation result

224298
224298
224298
 

Different names, different symbols

class Test
  puts: Test.object_id

  @@ test = 10
  puts: @@ test.object_id
  def test
    puts: test.object_id
    @test = 10
    puts: @ test.object_id

  end
end

t = Test.new
t.test
operation result

224298
288068
79858
288108
 

In the first example, the class name, constant name, and method name are all Test, so the corresponding Symbol objects are all: Test. Don't worry, Ruby makes a good distinction between what it means in different contexts. Of course, this is not a good programming style, but it is still helpful for understanding Ruby's Symbol: Symbol represents a name, nothing more.

Symbol object once defined will always exist until the program execution exit. All Symbol objects are stored in the symbol table inside Ruby. You can get all Symbol objects defined in the current Ruby program through the class method Symbol.all_symbols, which returns an array of Symbol objects. Since there are many symbols, you can dump them to a file to view them.

all_symbols method

irb (main): 001: 0> Symbol.all_symbols.size
=> 4047
irb (main): 002: 0> Symbol.all_symbols [0..9]
=> [: @level_notifier,: ppx,: msg_dn,: version,: secs,: @user,: pos,: socketpair,
 : TkENSURE,: HTTPAccepted]
irb (main): 003: 0> File.open ("sym", "w") do | file | file.puts Symbol.all_symbols end
=> nil
 

Symbol and String

Symbol objects and String objects are completely different things, and the object identifier clearly illustrates this. In addition, we can also distinguish between the methods of the two objects. Looking at the Ruby library reference, you will find that the String class has a lot of methods, including the Mixed-in method (a method in Ruby obtained by including other modules to achieve the effect of multiple inheritance), class methods and instance methods; and Symbol The class has only one class method all_symbols and 7 instance methods. For example, you can use the [] = method to change the content of string, while symbol does not:

[] = Method comparison

irb (main): 001: 0> s = "test"
=> "test"
irb (main): 002: 0> s [0] = '1'
=> "1"
irb (main): 003: 0> puts s
1est
=> nil
irb (main): 004: 0> sym =: test
=>: test
irb (main): 005: 0> sym [0] = 1
NoMethodError: undefined method `[] = 'for: test: Symbol
        from (irb): 5
irb (main): 006: 0>
 

Although Symbol and String are different objects, they are closely related. Ruby provides methods to convert between Symbol and String. Convert Symbol to String, use to_s or id2name method to convert Symbol to a String object:

Symbol to String

irb (main): 001: 0>: test.id2name
=> "test"
irb (main): 002: 0>: test.to_s
=> "test"
irb (main): 003: 0>: "I am a boy" .to_s
=> "I am a boy"


Note that each String object is unique, so multiple calls to a Symbol will produce multiple String objects.

String is converted to Symbol. In addition to adding a colon in front of the string, you can also use the to_sym or intern method to convert String to Symbol. If the Symbol already exists, return it directly.

String to Symbol

irb (main): 001: 0> var1 = "test" .to_sym
=>: test
irb (main): 002: 0> var2 = "test" .intern
=>: test
irb (main): 003: 0> var1 == var2
=> true
irb (main): 004: 0>
 

Use Symbol

As mentioned earlier, Symbol has been used internally in Ruby, such as various names in Ruby programs. Symbols are essentially things in the Ruby symbol table. Using Symbol to process names can reduce Ruby memory consumption and increase execution speed, as we will see in the next article.

So what does Symbol do to us? Of course it is also memory. The overhead of using String is too large, because each String is an object. Consider the previous example. Ruby creates a String object every time a string appears.

Generally speaking, when you face the choice of String or Symbol, you can refer to the following standards:

If you use the content of a string, this content may change
If you use a fixed name or identifier, use Symbol
So when will we use the name? Many times, such as enumeration values, keywords (hash table keywords, method parameters), etc .; as the key of the hash table, the hash table is the most widely used symbol.

In Ruby, a hash is similar to an array. A hash table is a collection of key / value pairs, except that its key value range is wider and can be any object, such as a regular expression. But usually we will take meaningful keys, such as String, Symbol.

The following hash table represents a collection of machines classified by city.

An example of a hash table

hosts {
       'beijing' => 'machine1',
       'shanghai' => 'machine2',
       'guangzhou' => 'machine3',
       'tianjin' => 'machine4',
       'shenzhen' => 'machine5'
}


If you want to refer to beijing's machine, use hosts ['beijing']. But if our program frequently refers to the value in the hash table, this is not good, because Ruby generates a String object for each string reference, and the accumulated overhead is quite large.

We can use Symbol at all, because for these keys, we use the name only, for example the following hosts [: beijing]
 

Use Symbol as the key

hosts = {
: Beijing => 'machine1',
: Shanghai => 'machine2',
: Guangzhou => 'machine3',
: Tianjin=> 'Machine4',
: Shenzhen => 'machine5'
}
 

Hash parameters

Usually the number and order of the parameters of the function we define are hard-coded. When calling the function, make sure that the number and order of the parameters match. Sometimes this is inconvenient. Using hash parameters can solve this problem. This method is widely used in ROR, as you may have seen, Symbol and Hash are everywhere. such as:

Method call using hash parameters

link_to 'Show',: action => 'show',: id => product

add_column: products,: price,: decimal,
: precision => 8,: scale => 2,: default => 0
The method of using hash parameters can be defined as follows, the first half is fixed parameters, the latter is variable parameters, or simply use hash parameters:

Hash parameters

def my_method (para1,…, options = {})
#your code
end

def my_method (options = {})
#your code
end
 

If you want to set some default parameters and allow the caller to change these parameters, you can use the hash object's merge! Method, hsh.merge! (Other_hash). This method adds the contents of other_hash to hsh. If other_hash and hsh have duplicate keys, the value of key in other_hash overrides the value of the corresponding key in hsh.

Method definition-use default parameters

class Test
 def my_method (opts = {})
  default_opts = {: arg1 => 10,: arg2 => "abc"}
  default_opts.merge! (opts)
  default_opts.each {| key, value | puts "# {key} is # {value}"}
 end
end

t = Test.new
t.my_method: arg1 => 5,: arg3 => "def"
operation result

arg1 is 5
arg2 is abc
arg3 is def
 

 

 

Note: This article is transferred from: http://www.ibm.com/developerworks/cn/opensource/os-cn-rubysbl/, for more information, please visit the source of the article, this article is for learning purposes only.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.