程式扎記: [ Ruby Gossip ] Basic : 內建型態與操作 - 符號型態

標籤

2014年10月8日 星期三

[ Ruby Gossip ] Basic : 內建型態與操作 - 符號型態

Source From Here
你可以使用 :name 方式建立Symbol實例。例如:
>> :a
=> :a
>> :a.class
=> Symbol

Ruby 以 Symbol 實例代表程式中使用到的符號象徵,像是變數名稱、方法名稱、類別名稱、模組名稱等,如果你使用某個物件的 methods 方法,可以取得S ymbol 實例組成的陣列。例如取得字串的方法清單:


可以使用Symbol.all_symbols取得目前程式中所有Symbol實例清單,這是一份很長的內容。例如以Ruby 1.9.2 p290,在irb中取得的清單長度是3519。先前談過,變數名稱、方法名稱、類別名稱、模組名稱等都是一種符號象徵,當你建立了一個變數名稱、方法名稱、類別名稱、模組名稱,那麼在 Symbol.all_symbols 就會有個Symbol實例來代表它:
>> Symbol.all_symbols.size
=> 3519
>> abc = 10
=> 10
>> Symbol.all_symbols.size
=> 3520
>> def some; end
=> nil
>> Symbol.all_symbols.size
=> 3521
>> class Other; end
=> nil
>> Symbol.all_symbols.size
=> 3522

變數名稱、方法名稱、類別名稱、模組名稱等都是一種符號象徵,都會有個 Symbol 實例來代表,反過來說,你也可以使用 Symbol實 例來代表你想表示的對象。例如想得知某個字串上是否有 upcase 方法,可以如下:
>> "".methods.include? :upcase
=> true

例如,陣列上有個 reduce 方法,可以指定程式區塊,對逐一移出陣列的元素進行某些動作,第一個區塊參數是程式區塊傳回值,預設為 0,每次移出陣列的值會作為第二個區塊參數。例如想要對陣列中的值加總,可以如下:
>> [1, 2, 3, 4, 5].reduce { |sum, element|
?> sum + element
>> }
=> 15

{}的區塊寫法與do..end是幾乎相同的意義,慣例中,在一行中可寫完的區塊可使用{},有傳回值的時候也可使用 {},do..end則通常用於具有邊際效應的程式區塊。

實際上,若你只是對傳入的兩個區塊參數進行相加,可以指定:+,這代表著使用+方法:
>> [1, 2, 3, 4, 5].reduce(:+)
15

名稱是一種符號,字串撰寫名稱,可以使用字串的 to_sym 方法從字串取得Symbol實例,事實上,許多接受Symbol作為引數的方法,也接受字串:
>> "+".to_sym
=> :+
>> "+".to_sym.class
=> Symbol

許多初學者因此搞不清楚字串與 Symbol 的差別,正如先前所談,程式語意上,名稱只是一種符號,字串是用來撰寫名稱,如果就程式執行來說,Symbol 實例是不可變動的Immutable,而且整個程式中,Symbol實例是唯一的Unique),但字串則沒有這兩個特性。例如:
>> x = "123"
=> "123"
>> x.to_sym.object_id
=> 2044
>> x << "456"
=> "123456"
>> x
=> "123456"
>> x.to_sym.object_id
=> 2044 // 即使 x 的值變動了, x 的 symbol id 依舊不變.
>> "123".object_id
=> 20334732
>> "123".object_id
=> 20182656
>> :a.object_id
=> 332744
>> :a.object_id
=> 332744


沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!