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保留了他们在原可见区内含义。
上面的例子中同样注意到有两个方法:eval和id2name。Id2name和Symbol类的一个方法,它返回一个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)