2

我需要检查一个变量是否是一个数组,如果不是,则在继续进一步处理之前将其转换为一个。所以,我的代码如下所示:

class Test < Struct.new(:args)
    def eval
        p "1. #{args}"
        args = (args.instance_of? Array) ? args : [args]
        p "2. #{args}" # woah! [nil]?
        # ...other things, with "args" being an array for sure..or not?!?
    end
end

我对 ruby​​ 很陌生,所以也许这不是很惯用,但在我看来,这段代码至少应该可以工作。相反,我第二次打印args变量时,它是[nil]. 请注意,如果我eval稍微改变方法:

def eval
    p "1. #{args}"
    a = args
    args = (a.instance_of? Array) ? a : [a]
    p "2. #{args}"
end

一切都按预期工作。那么,是否有一些我不明白的 Struct 类非常具体的东西,或者这里发生了什么可疑的事情?(在 macOS 上使用 ruby​​ 1.9.3-dev,使用 rvm)

4

1 回答 1

2

实际上,您尝试做的事情有一个 Ruby 习语:[*args]. *在这种情况下称为 splat 运算符:

http://raflabs.com/blogs/silence-is-foo/2010/08/07/ruby-idioms-what-is-the-splatunary-operator-useful-for/

如果您传递了一个数组,splat 会将数组“展平”为新的数组,如果您传递一个参数,它将成为一个单元素数组。

对于奇怪的行为:在我看来,您argseval方法中创建了一个局部变量,该变量被初始化为,nil因为它位于赋值的 LHS 上。然后三元计算结果为 false,因为args它不是一个数组,并创建一个当前值的数组,它仍然是nil。如果args将是一个实例变量 ( @args),事情会按照你期望的方式工作。换句话说,虽然继承了Structwill 给你argsargs=方法,但它不会给你一个@args实例变量。

于 2011-08-17T08:50:43.887 回答