Ruby send использует splat не работает должным образом

У меня есть класс служб, который помогает санировать данные из полезной нагрузки JSON.

  attr_reader :data, :method, :args

  def self.call(*args)
    new(*args).call
  end

  def initialize(data, sanitization_method, *method_args)
    @data = data
    @method = sanitization_method
    @args = *method_args
  end

  def call
    data.send(method, args)
  end

Проблема в том, что когда я вызываю метод класса, он возвращает Enumerator:

PaidGigs::Services::SanitizeData.call("shd234", :gsub, /[^0-9]/, "")

=>  #<Enumerator: "shd234":gsub([/[^0-9]/, ""])>

Вместо оценки метода и возврата:

=> "234"

Я играл в консоли, и это потому, что массив splat не конвертируется в отдельные аргументы, что противоречит тому, что предлагают документы Ruby. У кого-нибудь была такая проблема с Object#send? Любая помощь с благодарностью!

2 ответа

Решение

Вы должны хранить args как Array и использовать splat в последний момент:

class SanitizeData
  attr_reader :data, :method, :args

  def self.call(*args)
    new(*args).call
  end

  def initialize(data, sanitization_method, *method_args)
    @data = data
    @method = sanitization_method
    @args = method_args
  end

  def call
    data.send(method, *args)
  end
end

puts SanitizeData.call("shd234", :gsub, /[^0-9]/, "").inspect

Вы храните аргументы в виде массива, поэтому, когда вы вызываете этот метод, вам нужно разделить его снова:

def call
  data.send(method, *args)
end

И это:

@args = *method_args

Сплат ничего не делает для вас, так что это может быть просто:

@args = method_args
Другие вопросы по тегам