dry-rb / dry-container

A simple, configurable object container implemented in Ruby
https://dry-rb.org/gems/dry-container
MIT License
335 stars 41 forks source link

Getting an `ArgumentError` missing keywords on Ruby 3 #79

Closed alo-zi closed 3 years ago

alo-zi commented 3 years ago

Describe the bug

I have been using dry-container & dry-auto_inject since use ruby 2.3, everything works well until ruby 2.7, when I try upgrade to ruby 3.0 I'm getting an ArgumentError missing keywords.

ArgumentError (wrong number of arguments (given 1, expected 0; required keywords: status_message, data, meta)):

app/services/version1/list_result.rb:7:in `initialize'

To Reproduce

Ruby <= 2.7 & Rails <= 6.1.x ✅ Ruby 3.0.1 & Rails 6.1.x ❌

class ListResult
   attr_reader :status,
                    :status_message,
                    :data,
                    :meta

        SUCCESS = 1

        def initialize(status_message:, data:, meta:)
            @status = SUCCESS
            @status_message = status_message
            @data = data
            @meta = meta
        end
end

try to Register

require 'dry-container'
require 'dry-auto_inject'

module MyClass
    class DiContainer
        extend Dry::Container::Mixin

       register :list_result do
            ListResult
        end
    end

    # dependency injection
    INJECT = Dry::AutoInject(MyClass::DiContainer)
end

Try inject to the service

require 'my_class/di_container'
module Version1
   class MyService
       include MyClass::INJECT[:list_result]

      def get_data
            list_result.new(status_message: '', data: [], meta: {})
      end
   end
end

Expected behavior

Manual call without DI

ListResult.new(status_message: '', data: [], meta: {})
=> #<ListResult:0x00007f8d40a70970 @data=[], @meta={}, @status=1, @status_message="">

My environment

flash-gordon commented 3 years ago

Please provide a self-contained reproduction. From your code, it's not clear where the issue is. Likely, it's not a problem with dry-auto_inject given it's tested and being used with ruby 3.0.

Specifically, this code doesn't use dry-auto_inject:

def get_data
  list_result.new(status_message: '', data: [], meta: {})
end

list_result is set by dry_auto_inject in the constructor but by the time get_data it's already finished. ListResult itself doesn't use DI.

alo-zi commented 3 years ago

@flash-gordon got it, It's confirmed not DI issue, I will try to figure out about it. Thanks for your response. 🥂