2015-11-05 61 views
1

工作,我期待下面的代碼片段:除非定義?是不是在我的代碼

var2 = "Not Empty" unless defined? var2 

重返「非空」,但我得到了零。深入瞭解爲什麼會發生這種情況?

+0

一個誰已經下來投它,請解釋他爲什麼這樣做。 –

+1

那就是我,我不是'他'。在這行代碼之前沒有上下文知道'var2'是(或不是)。你爲什麼期望它返回「不空」? – sevenseacat

+0

@ShahrozShaikh描述的行爲發生在'var2'之前沒有被定義的任何上下文中。如果你將上面的代碼本身放在一個Ruby文件中,它就是@ShahrozShaikh所說的那樣。看一看,這很令人費解:http://ideone.com/ihm2Pt –

回答

2

defined?方法將返回:

=>表達不可識別

在上述代碼段的問題是局部變量的範圍。 Its end on the line where you using it。要了解更多關於本地變量,請檢查:local_variable

pry(main)> p "local_var is not initialized" unless defined? local_var 
=> "loca_var is not initialized" 

,但如果你這樣做:

pry(main)> local_var = "initialized" unless defined? local_var 
=> nil 

local_var仍然nil,因爲這行之後其範圍的結束,所以無論怎樣分配都白費了。

解決方案:如果您希望此行爲,然後用這一個,我會建議:

local_var ||= "initialized" 
+1

'除非'不是範圍門,事實上如果你把它寫出來(就像在我的回答中那樣),這個變量在'end'之後是可用的。另外,如果你做'other_local_var =「初始化」,除非定義? local_var',變量'other_local_var'隨後可用!只有當你試圖設置未被初始化的變量在一個班輪中被檢查。 – mwp

+0

@mwp我同意這行'other_local_var =「初始化」除非定義? '。如果結構具有與塊相同的行爲,則爲聯機。因此,例如,當你將上面的代碼映射到塊結構時:'除非定義? local_var local_var =「已初始化」 end'。那麼你可以清楚地看到** local_var ** scope/life_cycle只在該塊中。在該塊之外,不存在已分配的值。 –

+0

@KhAmmad:你錯了。在塊之後,一個在'if' /'unless'塊中初始化的變量仍然存在。看:http://ideone.com/OpWtlQ –

0

嘗試var2 = "Not Empty" if var2.nil?如果你想弄清楚變量是否是nil或不是。 defined?很少用於不同目的(見下文)。

irb(main):009:0> var2 = nil 
=> nil 
irb(main):010:0> var2 = "Not Empty" if var2.nil? 
=> "Not Empty" 
irb(main):011:0> var2 
=> "Not Empty" 
irb(main):012:0> var2 = 'foo' 
=> "foo" 
irb(main):013:0> var2 = "Not Empty" if var2.nil? 
=> nil 
irb(main):014:0> var2 
=> "foo" 

如果你不能確定一個變量是否已經更被宣佈,您可以使用以下語法:

if defined?(var2).nil? 
    var2 = "Not Empty" 
end 

(它不工作,都在一個因爲一些奇怪的原因,正如@Jordan所指出的,但是這個工作起來。)

但是,這種慣用的Ruby方式來做到這一點,一般來說,被稱爲「零後衛」和如下所示:

var2 ||= "Not Empty" 
+1

這也返回'無',並沒有澄清OP的懷疑 – ray

+1

啊,我的表達被否定。現在修復。但同意它沒有澄清疑問。 – mwp

+0

任何其他解決方案? –