【问题标题】:Ruby send using splat not working as expectedRuby 使用 splat 发送未按预期工作
【发布时间】:2023-08-14 17:59:01
【问题描述】:

我有一个服务类,可以帮助清理 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

问题是当我调用类方法时,它返回一个枚举器:

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

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

而不是评估方法并返回:

=> "234"

我在控制台中玩过,这是因为 splat 数组没有被转换为单独的参数,这与 Ruby 文档的建议相反。 有人遇到过 Object#send 的问题吗?非常感谢任何帮助!

【问题讨论】:

    标签: ruby methods arguments send splat


    【解决方案1】:

    您将 args 存储为一个数组,因此当您调用该方法时,您需要再次 splat:

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

    还有这个:

    @args = *method_args
    

    splat 对你没有任何作用,所以它可以是:

    @args = method_args
    

    【讨论】:

      【解决方案2】:

      您应该将 args 存储为数组并在最后一刻使用 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
      

      【讨论】:

      • 太棒了!谢谢你。假设调用 splat 实际上会分解数组?
      • 我会说 splat 将参数列表转换为数组或将数组转换为参数列表。