【问题标题】:Set Ruby variable if it is not already defined如果尚未定义,请设置 Ruby 变量
【发布时间】:2011-07-12 21:33:49
【问题描述】:

在 Ruby 中,如何将变量设置为未定义的某个值,如果已定义则保留当前值?

【问题讨论】:

  • 通过“定义”,您的意思是“它存在于当前范围内”还是“它不是== nil”?
  • @zetetic: "它存在于当前范围内"

标签: ruby variables set


【解决方案1】:

虽然x ||= value 是一种表示“如果 x 包含一个虚假值,包括 nil(在此构造中隐含 if x 未定义,因为它出现在赋值),给 x 赋值”,它就是这么做的。

大致等同于以下内容。 (但是,x ||= value 不会像此代码那样抛出 NameError可能,并且它总是会为 x 分配一个值,因为此代码不会 - 重点是查看 x ||= value对于 x 中的 any falsey 值(包括“默认”nil 值)同样适用):

if !x
  x = value
end  

要查看变量是否真正没有被赋值,使用defined?方法:

>> defined? z
=> nil                                                                  
>> z = nil                                                              
=> nil                                                                  
>> defined? z                                                           
=> "local-variable"                                                     
>> defined? @z                                                          
=> nil                                                                  
>> @z = nil                                                             
=> nil                                                                  
>> defined? @z                                                          
=> "instance-variable" 

但是,在几乎所有情况中,使用defined? 是代码异味。小心使用电源。做明智的事情:在尝试使用变量之前给它们值:)

编码愉快。

【讨论】:

  • 如果未定义变量,||= 是什么使它不会抛出 NameError?那是内置在运算符中的吗?是否有其他运营商以这种方式工作?
  • @jrdioko "Magic" ;) 实际上,它与出现在赋值左侧的x 有关——如果尚未分配值也没关系(它将“默认”为nil)。例如,z = z.nil? # => true 即使当前未定义 z
  • @pst 我猜是“定义?”方法只是比找出“NameError:未定义的局部变量或方法”更优雅的选择所以真正的答案是当你的程序出错时你会知道你是否还没有定义一个变量。
  • 是的,如果您将变量设置为 true/false 会更好
  • @Dmitri @Codeglot 确实如此。最优雅的方法是编写代码不会导致NameError! (并通过良好的测试覆盖率进行了验证);-)
【解决方案2】:
@variable ||= "set value if not set"

所以false 变量将被覆盖

> @test = true 
 => true 
> @test ||= "test"
 => true 
> @test 
 => nil 
> @test ||= "test"
 => "test" 
> @test = false 
 => false 
> @test ||= "test"
 => "test" 

【讨论】:

  • 然而,它可以设置为假值。因此,这只是大致正确的。
  • 你能解释一下它是如何工作的(以及如何处理错误值)吗?
  • > @test 应该是> @test = nil
  • TIL:如果没有名为 'owner' 的键,这不适用于像 bodyParams['owner'] ||= '' 这样的哈希值。它会给你一个IndexError。为此,请在此处查看stackoverflow.com/a/39549523/1025430
【解决方案3】:

由于您没有指定什么样的变量:

v = v
v ||= 1

虽然不建议对局部变量执行此操作。

编辑:事实上 v=v 是不需要的

【讨论】:

  • 然而,它可以设置为假值。因此,这只是大致正确的。
  • irb(main):007:0> v = v => nil // irb(main):008:0> v.class => NilClass // 与将其初始化为 v = 相同无
  • @Dmitri 不,不一样,如果 v 有值,它不会改变。这就是重点。
【解决方案4】:

如果变量没有定义(声明?)它不存在,如果它被声明了那么你知道你是如何初始化它的,对吧?

通常,如果我只需要一个我还不知道其用途的变量——我知道它永远不会用作布尔值——我通过将其值设置为 nil 来初始化它.然后你可以很容易地测试它是否在以后被更改了

x = nil


some code


if x do 
[code that will only run if x has changed]
end

就是这样。

【讨论】:

  • 然而,它可以设置为假值。因此,这只是大致正确的。
  • 确实如此,@pst 如果预期值是布尔值,我不会使用这种技术。
【解决方案5】:

这是在 ruby​​ 中执行此操作的另一种方式:

var = 1
var = var || 2
=> 1

var = nil
var = var || 2
=> 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    相关资源
    最近更新 更多