2015-11-05 26 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

任何其他解决方案? –

相关问题