0
我對ruby非常陌生,我只是花時間研究github中現有的ruby項目的模式。現在,我降落在twitter's ruby project,並注意到在其配置這些行:Ruby配置技巧
client = Twitter::REST::Client.new do |config|
config.consumer_key = "YOUR_CONSUMER_KEY"
config.consumer_secret = "YOUR_CONSUMER_SECRET"
config.access_token = "YOUR_ACCESS_TOKEN"
config.access_token_secret = "YOUR_ACCESS_SECRET"
end
在這種方法調用的declaration,我也注意到了這一點:
module Twitter
class Client
include Twitter::Utils
attr_accessor :access_token, :access_token_secret, :consumer_key, :consumer_secret, :proxy
def initialize(options = {})
options.each do |key, value|
instance_variable_set("@#{key}", value)
end
yield(self) if block_given?
end
...
現在,我做我的做法,我複製了相同的邏輯,但觀察「初始化」方法的內容。
module Main
class Sample
attr_accessor :hello, :foo
def initialize(options={})
yield(self) if block_given?
end
def test
@hello
end
end
end
,並呼籲它(同樣在Twitter上面的代碼怎麼做)
sample = Main::Sample.new do |config|
config.hello = "world"
config.foo = "bar"
end
puts "#{sample.hello} #{sample.foo}" # outputs => world bar
puts sample.test # outputs => world
現在,我的問題是,即使我沒有在我的這幾行代碼(見代碼塊從嘰嘰喳喳以上),在我的 「初始化」 的方法,
options.each do |key, value|
instance_variable_set("@#{key}", value)
end
代碼 puts "#{sample.hello} #{sample.foo}"
和puts sample.test
仍然正常工作。這是爲什麼?這個實例變量是如何真正設置的?
啊哈!我知道了。我懂了。所以原因是當我產生(self)'時,它實際上將實例傳遞給塊,這就是我能夠手動配置或賦值給他們的方式。我太傻了。無論如何,再次感謝人! – Aldee
您的風格實際上很安全且易於追蹤。是。我同意Twitter的實施實際上是鬆懈的。 – Aldee
在這樣的方法中,你會看到'yield(self)if(block_given?)'。這是一種模式,它可以回退正在進行中的對象,您可以在最終確定之前進行修改。當你在一個函數調用中構建一個對象時,這個函數會派上用場,你只需要調整它:'func(Thing.new {| t | t.name ='test'})''例如。 – tadman