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之前,字符串插值將成功完成它的工作。
太棒了!謝謝:) – Howarto
沒有問題,隊友。很高興你明白了。 – Doodad