ruby Rails将多个参数传递给dry-monad

zpgglvta  于 2022-12-18  发布在  Ruby
关注(0)|答案(1)|浏览(111)

我们假设我有下面的单子类:

require 'dry-monads'
require 'dry/monads/all'

module Test
  class MonadsClass
    include Dry::Monads

    def initialize(signees)
      @signees = signees
    end

    def call
      Success(signees)
        .bind(method(:fetch_template))
        .bind(method(:envelope_from_template))
    end

    attr_reader :signees

    private

    def fetch_template(signees)
      key = "template_#{signees.size}".to_sym
      template_id = Rails.application.credentials.some_api.fetch(key)

      Success(template_id: template_id, key: key)
    end

    def envelope_from_template(template_id:, key:)
      response = some_api.copy_from_template(template_id, key)

      response.failure? ? Failure(response.failure) : Success(response.value!)
    end
  end
end

为什么在这个组合我得到奇怪的错误:

Failure/Error:
def envelope_from_template(template_id:, key:)
  response = some_api.copy_from_template(template_id)

  response.failure? ? Failure(response.failure) : Success(response.value!)
end

ArgumentError:
wrong number of arguments (given 1, expected 0; required keywords: template_id, key)
azpvetkf

azpvetkf1#

我认为问题在于你期望它传递kwargs(关键字参数),但是它传递的是Hash。Ruby 2.7不赞成哈希到kwargs的“自动转换”,Ruby 3.0完全删除了它。你可以阅读更多关于位置参数和关键字参数Here分离的内容
换句话说,您希望它调用

envelope_from_template(template_id: 123, key: 'abc')

但你实际上是在

envelope_from_template({template_id: 123, key: 'abc'})

相反,你有一对夫妇的选择,应该工作:

  • 选项1(使用块调用bind
def call
  Success(signees)
    .bind(method(:fetch_template))
    .bind {|h| envelope_from_template(**h) }
end

  • 选项2 -更改方法签名,然后在主体中使用Hash访问方法
def envelope_from_template(params)
  response = some_api.copy_from_template(params.values_at(:template_id, :key))

  response.failure? ? Failure(response.failure) : Success(response.value!)
end

相关问题