【问题标题】:unless defined? is not working in my code [duplicate]除非定义?在我的代码中不起作用[重复]
【发布时间】:2015-11-05 05:03:29
【问题描述】:

我期待的是以下 sn-p:

var2 = "Not Empty" unless defined? var2

返回“Not Empty”,但我得到了 nil。对为什么会发生这种情况有任何见解吗?

【问题讨论】:

  • 投反对票的人请解释他为什么这样做。
  • 那是我,我不是“他”。在这行代码之前没有上下文可以知道var2 是(或不是)什么。为什么你期望它返回“Not Empty”?
  • @ShahrozShaikh 所描述的行为发生在之前未定义 var2 的任何上下文中。如果你把上面的代码单独放在一个 Ruby 文件中,它会完全按照 @ShahrozShaikh 所说的那样做。看一看,莫名其妙:ideone.com/ihm2Pt
  • 我在 ruby​​-lang.org 上没有看到关于此发现的未解决问题。谁想开一个?如果没有其他接受者,我很高兴。我会在报告中引用这个问题。

标签: ruby local-variables


【解决方案1】:

defined? 方法将返回:

nil => 无法识别表达式

上面sn -p的问题是局部变量的作用域。 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"

【讨论】:

  • unless 不是范围门,实际上,如果您将其写出来(如我的回答),则该变量在end 之后可用。此外,如果您执行other_local_var = "initialized" unless defined? local_var,则变量other_local_var 随后可用!仅当您尝试将未初始化的变量设置为单列检查时。
  • @mwp 我同意这条线other_local_var = "initialized" unless defined? 。如果结构具有与块相同的行为,则为内联。因此,当您将上述代码映射到块结构时,例如:unless defined? local_var local_var = "initialized" end。那么您可以清楚地看到 local_var scope/life_cycle 仅在块中。在该块之外,分配的值不再存在。
  • @KhAmmad:你错了。在 if/unless 块中初始化的变量在块之后仍然存在。看:ideone.com/OpWtlQ
  • 谢谢你的纠正。
【解决方案2】:

如果您想确定变量是否为nil,请尝试var2 = "Not Empty" if var2.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 的惯用方式称为“nil 守卫”,如下所示:

var2 ||= "Not Empty"

【讨论】:

  • 这也返回 nil 并且没有澄清 OP 的疑问
  • 啊,我的表达被否定了。现在修好了。但同意它没有澄清疑问。
  • 任何其他解决方案?
  • 如果var2 在此表达式之前为零,则var2 在此表达式之后将为“非空”。这不是你想要完成的吗?不要将表达式的返回值与存储(或未存储)到var2 的值混淆。
  • 这被否决了,因为它没有回答问题。 OP 询问为什么存在这种行为(当 val2 以前没有被定义时,notval2 以前被设置为 nil 时)。您的回答建议改用 nil?,甚至没有尝试解释 OP 看到的行为。
猜你喜欢
  • 2013-11-30
  • 2023-03-06
  • 2018-05-29
  • 1970-01-01
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
  • 1970-01-01
  • 2018-12-09
相关资源
最近更新 更多