Параметры Splat ведут себя по-разному для средств записи атрибутов по сравнению с обычным методом.

У меня есть следующие два метода, которые, как я считаю, должны иметь одинаковое поведение независимо от их имен:

def a=(*params)
  params
end

def b(*params)
  params
end

Но когда на самом деле я их использую:

a=(1) # => 1
b(1) # => [1]
(a=1) == b(1) # => false

пока интересно:

(a=1,2) == b(1,2) # => true

Почему их поведение не одинаково?

Редактировать: забыл обернуть вышеизложенное в класс/вызов с self., который случайно приводит к такому же поведению, но по другой причине. Это было указано в ответах.


person thisismydesign    schedule 08.09.2017    source источник
comment
Я отменил ваше редактирование, потому что вы изменили вопрос после получения ответа от мудасобва, который критически указывает на то, что связано с той частью, которую вы изменили. Не меняйте свои вопросы в это время.   -  person sawa    schedule 08.09.2017
comment
Извините, забыл добавить self., когда пытался привести минимальный пример, где проблема может быть воспроизведена, потому что случайно она по-прежнему вызывала ту же проблему. К сожалению, таким образом, вопрос глупый, но в конце концов я получил ответ на свою настоящую проблему в ответе, на который вы ссылаетесь.   -  person thisismydesign    schedule 08.09.2017


Ответы (2)


Это не имеет ничего общего со сплэтом. Это оператор присваивания. В ruby ​​оператор присваивания возвращает присвоенное значение. Возвращаемое значение метода игнорируется.

Итак, a=1 возвращает 1, а не [1].

Но, как уже упоминал @mudasobwa, здесь вы даже не вызываете метод. Но если бы вы были, это то, что произошло бы (игнорируя возвращаемое значение).

class Foo

  def a=(*params)
    params
  end

end

f = Foo.new

f.a = 1 # => 1
f.a = 1,2 # => [1, 2]

Чтобы не игнорировать возвращаемое значение, вызовите этот сеттер без использования оператора присваивания.

f.send 'a=', 1 # => [1]
person Sergio Tulentsev    schedule 08.09.2017
comment
Проголосовал за .send 'a=', 1 # => [1] Я этого не знал. - person Aleksei Matiushkin; 08.09.2017

Дело в том, что

a = 1

устанавливает локальную переменную и вообще не вызывает ваш метод. Попробуйте с

def a=(*param)
  puts "I AM HERE"
end

var= методов требуется явный получатель. Чтобы вызвать свой метод, вызовите его с явным получателем:

self.a = 1

Он по-прежнему не вернет ничего, кроме 1, потому что методы присваивания возвращают значение (точно так же, как initialize, вызванный через MyClass.new, возвращает экземпляр, несмотря ни на что.) Но вы можете проверить, что splat работает с:

def a=(*param)
  puts param.inspect
end
self.a = 1
# [1]
#⇒ 1
person Aleksei Matiushkin    schedule 08.09.2017
comment
ах да, сплат наверняка работает, даже если выглядит так, как будто это не так :) - person Sergio Tulentsev; 08.09.2017
comment
Забыл добавить self., когда пытался предоставить минимальный пример, где проблема может быть воспроизведена, потому что случайно она по-прежнему вызывала ту же проблему. Таким образом, методы присваивания возвращают значение, несмотря ни на что. Спасибо! - person thisismydesign; 08.09.2017