2013-07-19 61 views
0

我的代碼在class_eval部分有一個#符號。這對我來說是陌生的,這是什麼意思?#符號的含義

class Class 
    def attr_accessor_with_history(attr_name) 
    attr_name = attr_name.to_s # make sure it's a string 
    attr_reader attr_name # create the attribute's getter 
    attr_reader attr_name+"_history" # create bar_history getter 
    class_eval %Q{ 
def #{attr_name}=(attr_name) 
@#{attr_name} = attr_name 
@#{attr_name}_history = [nil] if @#{attr_name}_history.nil? 
@#{attr_name}_history << attr_name 
end 
} 
    end 
end 

回答

2
def #{attr_name}=(attr_name) 
@#{attr_name} = attr_name 
@#{attr_name}_history = [nil] if @#{attr_name}_history.nil? 
@#{attr_name}_history << attr_name 
end 

如果attr_name變量,其中等於讓我們說,"params"。這實際上會變成這樣:

def params=(attr_name) 
@params = attr_name 
@params_history = [nil] if @params_history.nil? 
@params_history << attr_name 
end 

爲什麼會發生這種情況?由於某些稱爲字符串插值。如果在字符串中寫入#{something},則something將被評估並在該字符串內被替換。

爲什麼上面的代碼工作,即使它不是在一個字符串?

答案是,因爲它!

紅寶石爲您提供了不同的方式來做事,並有一些文字的替代語法,即是這樣說:%w{one two three}其中{}可以是任何分隔符,只要你使用相同或相應的關閉一個。所以它可能是%w\one two three\%w[one two three],它們都會工作。

那一個,%w是數組,%Q是用於雙引號字符串。如果你想看到所有的人,我建議你先看看這個:http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html

現在,在代碼

class Class 
    def attr_accessor_with_history(attr_name) 
    attr_name = attr_name.to_s # make sure it's a string 
    attr_reader attr_name # create the attribute's getter 
    attr_reader attr_name+"_history" # create bar_history getter 
    class_eval %Q{ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # STRING BEGINS 
def #{attr_name}=(attr_name) 
@#{attr_name} = attr_name 
@#{attr_name}_history = [nil] if @#{attr_name}_history.nil? 
@#{attr_name}_history << attr_name 
end 
} <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # STRING ENDS 
    end 
end 

我們可以看到字符串插值整個部分是%Q{ }內。這意味着整個塊是一個大的雙引號字符串。這就是爲什麼在將字符串發送到eval之前,字符串插值將成功完成它的工作。

+0

太棒了!謝謝:) – Howarto

+0

沒有問題,隊友。很高興你明白了。 – Doodad

2

爲什麼下面的代碼已得到#在class_eval?

這是字符串插值。

一個例子:

x = 12 
puts %Q{ the numer is #{x} } 
# >> the numer is 12 

%Q Here

這是雙引號字符串替代方案,當你在一個string.Instead必須把反斜槓前面的更引號字符他們。

+1

http://kconrails.com/2010/12/08/ruby-string-interpolation/ –

4

此功能稱爲字符串插值。它的有效作用是將#{attr_name}替換爲attr_name的實際值。您發佈的代碼顯示了其中一個用例 - 當您想在運行時使用具有通用名稱的變量時。

然後用使用甚至更多的時候情況是這樣的:

您可以使用字符串這樣:"Hello, #{name}!"#{name}將在這裏被自動替換 - 這是非常方便的功能。一個語法糖。

但需要注意的代碼%Q - 這些將下面的代碼爲字符串,並隨後傳遞到class_eval並在那裏執行。查看更多關於它的信息here。沒有它,它當然是行不通的。

+2

值得一提的是'%Q'也在做什麼我想,因爲如果它錯過了,剩下的代碼看起來就像奇怪的Ruby那裏插值可以發生在任何地方,這可能是一個混亂的點 –