[url=http://ozmm.org/posts/return_early.html]Chris Wanstrath[/url]曾有一篇博文優化初始化變量和傳回值。下面是一些進一步的讨論:
原始的醜陋代碼如下:
def logger
unless @logger
@logger = Logger.new(STDOUT)
@logger.level = Logger::WARN
end
@logger
end
Chris'的改進:
def logger
return @logger if defined? @logger
@logger = Logger.new(STDOUT)
@logger.level = Logger::WARN
@logger
end
作者本人更傾向:
def logger
@logger || begin
@logger = Logger.new(STDOUT)
@logger.level = Logger::WARN
@logger
end
end
值得探讨的是,部落客的願意是希望用@logger ||=的方式表達,如果有一個構造函數傳回本身會看起來更漂亮。或者,在加上一個反射,如下:
def logger
@logger ||= default_logger
end
def default_logger
logger = Logger.new(STDOUT)
logger.level = Logger::WARN
logger
end
當然,如果你有更強的風格,也可寫成這樣:
def logger
@logger ||= Logger.new(STDOUT).tap {|l| l.level = Logger::WARN}
end
另外,defined? @logger 和if @logger并不一樣,如下:
[quote]>> defined?(@logger)
=> nil
>> @logger
=> nil
>> @logger = nil
=> nil
>> defined?(@logger)
=> "instance-variable"[/quote]
是以,當你試圖判斷@logger是否為nil的時候,defined?往往不是你需要的,要當心使用。