Ruby 学习笔记 Symbol

来源:互联网 发布:js 获取页面内容 编辑:程序博客网 时间:2024/06/07 00:36
 

Ruby 学习笔记 Symbol

Symbol ruby中是由一个标示符前面加一个冒号(:)组成的。从程序员的角度说它不是字符串,不是变量,不是常量,他仅是个名字,它的值是它自己。从解释器的角度说,它是一个指向一个symbol table的指针,这个symbol table是一个ruby内部所有标识符组成的列表。Symbol是唯一的。两个内容相同的字符串"string""string"ruby中有不同的object_id ,但是:string:string有同一个object_id

例如下面的代码:

puts( :helloworld.equal?( :helloworld ) )    #=> true 

puts( "helloworld".equal?( "helloworld" ) )  #=> false 

puts( 1.equal?( 1 ) )        #=> true 

Symbol可以作为参数传给一个方法,也可以用在case语句中。

Symbol的唯一性,不会因变量的可见性而改变。看下面的例子:

module One 

     class Fred 

     end 

     $f1 = :Fred 

end 

    

module Two 

     Fred = 1 

     $f2 = :Fred 

end 

 

def Fred() 

end 

 

$f3 = :Fred 

这个例子中有三个全局变量$f1,$f2,$f3被赋值相同的Symbol fred,虽然在各自的可见区内有不同的含义,但是三个全局变量确实有相同的object_id

一个更全面的例子:

module One 

   class Fred 

   end 

   $f1 = :Fred 

   def self.evalFred( aSymbol ) 

      puts( eval( aSymbol.id2name ) )    

   end 

end 

 

module Two 

   Fred = 1 

   $f2 = :Fred 

   def self.evalFred( aSymbol ) 

      puts( eval( aSymbol.id2name ) )       

   end 

end 

 

def Fred() 

   puts( "hello from the Fred method" ) 

end 

 

$f3 = :Fred 

 

One::evalFred( $f1 )     #=> displays the module::class name: One::Fred  

Two::evalFred( $f2 )      #=> displays the Fred constant value: 1 

method($f3).call         #=> calls Fred method: displays: 

                  #            hello from the Fred method” 

上面的例子,把三个相同的Symbol传给三个不同的方法,得到的实际结果是:Symbol保留了他们在原可见区内含义。

上面的例子中同样注意到有两个方法:evalid2nameId2nameSymbol类的一个方法,它返回一个symbol的名字或一个与symbol相关的字符串(英语原文是:It  returns  the  name  or  string  corresponding  to  the  symbol )。to_s方法可以做相同的事情。Eval是一个内核级的方法,它能计算字符串中表达式的值。看下面的例子:

x=2

puts(eval(:x.to_s)) #输出2

puts(eval(:x.id2name))  #输出2

:x.id2name会返回x,而eval计算出x的值是2

取得一个方法的symbol,然后把symbol传给一个叫method的方法,再调用一个叫call的特殊方法,如下面的形式:

method(:amethod).call("") 

我们可以用上面的形式调用一个方法。

继续看下面的例子:

def amethod(val)

puts("I say "<<val)

end

this_is_a_method_name=method(:amethod)

puts(this_is_a_method_name)

puts( "#{this_is_a_method_name.class}")

this_is_a_method_name.call("hello ")

method(:amethod)返回一个Method类的对象,所以puts(this_is_a_method_name)就输出#<Method: Object#amethod>puts( "#{this_is_a_method_name.class}")输出Method。此时调用this_is_a_method_name.call("hello ")就相当于调用了amethod("hello")

 

(学习资料是ruby安装程序中的book of ruby)

原创粉丝点击