Странно Руби поведение - PullRequest
       53

Странно Руби поведение

2 голосов
/ 17 августа 2011

Мне нужно проверить, является ли переменная массивом, и если нет, преобразовать ее в единицу, прежде чем приступить к дальнейшей обработке.Итак, мой код выглядит следующим образом:

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, которого я не понимаю, или что-то подозрительное происходит здесь?(используя ruby ​​1.9.3-dev на macosx, используя rvm)

1 Ответ

2 голосов
/ 17 августа 2011

На самом деле есть идиома Ruby для того, что вы пытаетесь сделать: [*args].* в этом контексте называется оператором splat:

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

Если вы передадите массив, splat "сведет" массив в новый, если вы передадитеодин аргумент, он станет массивом из одного элемента.

Для странного поведения: мне кажется, что вы создаете локальную переменную args в своем методе eval, который инициализируется nil, потому чтоэто на LHS задания.Тогда троичное значение оценивается как ложное, потому что args не является массивом и создает массив текущего значения, которое по-прежнему равно nil.Если args будет переменной экземпляра (@args), все будет работать так, как вы ожидаете.Другими словами, хотя наследование от Struct даст вам методы args и args=, оно не даст вам @args переменную экземпляра.

...