奇怪的 Ruby 行为

发布于 2024-11-30 09:05:55 字数 708 浏览 0 评论 0 原文

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

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 类的非常具体的东西我不明白,或者这里发生了什么可疑的事情? (在macosx上使用ruby 1.9.3-dev,使用rvm)

I need to check if a variable is an array, and if not convert it into one before proceed with further processing. So, my code looks like this:

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

I am quite new to ruby, so perhaps this is not very idiomatic, but to me looks like this code should at least work. Instead, the second time I print the args variable, it is [nil].
Notice that if I change the method eval slightly:

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

everything works as expected. So, is there something very specific to the Struct class that I don't get it, or something fishy is going on here?
(using ruby 1.9.3-dev on macosx, using rvm)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初心 2024-12-07 09:05:55

实际上,有一个 Ruby 习惯用法可以满足您想要执行的操作:[*args]* 在这种情况下称为 splat 运算符:

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

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

对于奇怪的行为:在我看来,您在 eval 方法中创建了一个局部变量 args ,该变量被初始化为 nil 因为它处于打开状态作业的 LHS。然后,三元计算结果为 false,因为 args 不是数组,它会生成当前值的数组,该值仍然是 nil。如果 args 是一个实例变量 (@args),事情就会按照您期望的方式工作。换句话说,虽然从 Struct 继承将为您提供 argsargs= 方法,但它不会为您提供 @ args 实例变量。

Actually there's a Ruby idiom for what you are trying to do: [*args]. * in this context is called the splat operator:

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

If you get passed an array, splat will "flatten" the array into the new one, if you pass a single argument, it will become a one element array.

For the odd behavior: it looks to me like you create a local variable args in your eval method, which gets initialized to nil because it's on the LHS of an assignment. Then the ternary evaluates to false because args is not an array and makes an array of the current value, which is still nil. If args would be an instance variable (@args), things would work the way you expect. In other words, while inheriting from the Struct will give you args and args= methods, it won't give you an @args instance variable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文