2012-07-17 68 views
4

顯然,Ruby可以讓一個代碼塊用一個符號返回一個實例變量的值。試想一下:使用符號來訪問實例變量?

class Person 
    attr_accessor :fn 
end 

def give(n,&b) 
    i=0 
    while(i<n) 
     aa = Person.new 
     aa.fn = "name #{i}" 
     i=i+1 
     puts b.call(aa) 
    end 
end 

現在,無論是give(5, &:fn)give(5) {|x| x.fn}

name 0 
name 1 
name 2 
name 3 
name 4 
=> nil 

但什麼是&:fn究竟意味着什麼?我知道這個符號可以一個Proc轉換成塊如

bb = Proc.new {|x| x.fn} 
give(5, &bb) 

那麼,是什麼符號:fn是什麼意思?我在哪裏可以看到像這樣的使用文檔?我們可以使用符號來訪問實例變量,如說person:newperson[:new]

+0

'person [:new]'將用於訪問散列,其中密鑰是符號 – 2012-07-17 19:32:57

+0

@KassymDorsel,謝謝。我知道散列的情況,但在這裏它是一個類的對象,'&:fn'中的符號訪問實例變量。 – highBandWidth 2012-07-17 19:37:34

+0

&符號將實際上將對象轉換爲'Proc',而':fn'則表示符號,'&:fn'等價於'&(:fn.to_proc)' – 2012-07-17 19:37:39

回答

4

簡單。陳述

attr_accessor :fn 

沒有定義某種特殊的實例變量的東西。它聲明(約)這種形式的兩種方法:

def fn 
    @fn 
end 
def fn=(v) 
    @fn=v 
end 

Ruby的「語法」 &:fn是一個符號,&嘗試操作轉換爲一個PROC。你猜怎麼着? Symbol執行to_proc。猜猜這看起來像:

def to_proc 
    Proc.new {|obj| obj.__send__(self)} 
end 

捕捉self,這是象徵:fn,其中,上調用,告訴obj執行方法fn,它返回實例變量的值。

編輯:回答問題的第二部分,不,是。用你說的語法,不。但是您可以使用BasicObject#__send__的符號調用方法,並且您可以使用而不是attr_accessorObject#instance_variable_get一樣的實例變量。