Giter Site home page Giter Site logo

dry-rb / dry-auto_inject Goto Github PK

View Code? Open in Web Editor NEW
178.0 19.0 29.0 507 KB

Container-agnostic constructor injection mixin

Home Page: https://dry-rb.org/gems/dry-auto_inject/

License: MIT License

Ruby 97.23% Shell 0.20% HTML 2.57%
dry-rb dependency-injection ioc ruby

dry-auto_inject's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dry-auto_inject's Issues

Inheritance broken

class A
  def initialize(args)
    super
  end
end

class B < A
  include AutoInject[:user_repository]
end

B.new({})

This leads to the following exception.

`initialize': wrong number of arguments (0 for 1) (ArgumentError)
    from /home/nick/.rvm/gems/ruby-2.2.3/gems/dry-auto_inject-0.4.1/lib/dry/auto_inject/strategies/kwargs.rb:61:in `initialize'
    from /home/nick/.rvm/gems/ruby-2.2.3/gems/dry-auto_inject-0.4.1/lib/dry/auto_inject/strategies/kwargs.rb:17:in `new'
    from /home/nick/.rvm/gems/ruby-2.2.3/gems/dry-auto_inject-0.4.1/lib/dry/auto_inject/strategies/kwargs.rb:17:in `new'

This only happens with B, not with A.

License?

I have a build that's failing due to license_finder being unable to determine the license for dry-auto_inject. It seems like the other dry-rb projects are MIT, so I assume this one should be as well?

Auto-inject loses parameters if a class defines `initialize`

Here's my container.rb:

class Container
  extend Dry::Container::Mixin

   # Some more stuff

  register(:rom, memoize: true) do
    ROM.container(Database.configuration)
  end

  # Repositories
  register(:product_repo) { ProductRepo.new(resolve(:rom)) }

  def self.import
    @import ||= Dry::AutoInject(self)
  end
end

And my products/create.rb:

module Products
  class Create < ::BaseService
    include Container.import[:product_repo]

    class Contract < Dry::Validation::Contract
      params do
        required(:name).filled(:string)
        required(:price).filled(:float)
      end
    end

    attr_accessor :data, :errors

    def initialize(params)
      @params = params
    end

    # More stuff
  end
end

And when I try to instantiate it:

pry(main)> Products::Create.new({'name' => 'CoolPenz WonderPen', 'price' => 1.2})
ArgumentError: wrong number of arguments (given 2, expected 1)

If I replace Container.import with Container.import.args, I get this:

pry(main)> Products::Create.new({'name' => 'CoolPenz WonderPen', 'price' => 1.2})
=> #<Products::Create:0x0000564065c300e0 @params={"name"=>"CoolPenz WonderPen", "price"=>1.2}>
pry(main)> r.product_repo
=> nil

There's no exception, but the product_repo value isn't injected.

I use dry-auto_inject 0.6.1 and dry-container 0.7.1.

Incompatibility with ActiveRecord

Hello, thanks for the great DRY libs.
However, when trying to use dry-auto_inject with ActiveRecord, the container isn't injected properly on MyModel.first, MyModel.find, etc.

Unfortunately, I haven't been able to identify the root cause. But I have published a minimal working example here: https://github.com/RomainEndelin/dry_auto_inject_active_record_incompatibility

irb(main):001:0> User.new.hello
=> "world"
irb(main):002:0> User.first.hello
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> nil

Builder interface

I take dependency injection as a means to enable easy ability to swap out classes. This does provide that because we have constructor injection. However, the examples I have seen show that we are using it with a specific class. I would like to see more examples of using it with abstract classes and building the interfaces.

require 'dry/types'

Types = Dry.Types()
adapter = Types.Interface(:broadcast, :subscribe)

class Main
include Import[adapter: 'adapters.async_adapter'] # how to insure adapter satisfies adapter interface?

def subscribe(name)
adapter.subscribe(name)
end

def mail
adapter.broadcast.each do |n|
mail(n)
end
end

end

so, would like a method to build with a different adapter - from container so, instead of
redis = Container('adapter.redis_adapter')
redis = Main.new(adapter: redis)

would like something like this:
redis_main = Main.build_with(adapter: 'adapter.redis_adapter') # will search container for redis adapter

Code idea from: http://gafur.me/2018/01/01/strategy-pattern-in-the-hanami-events-code.html

Handle invalid or separator characters when making local names for dependencies

Right now we expect dependency names to use dots as delimiter characters, e.g. "my_app.foo.bar". We split the name up by the dots and use the last portion as the local name for the dependency (its instance variable and accessor method name).

We should expand on this so dependencies with other separator characters or otherwise invalid characters are handled appropriately.

We've had some discussion on this over in #23 (comment). My feeling is that something like this would be a reasonable approach:

I think it'd might be better if we just had a regex of invalid variable-name characters, split the container identifier on that regex, and then just use the last segment as the local variable name. What do you think? This seems fair to me, especially now that people can explicitly provide their own aliases for their injected dependencies too.

kwargs are sent to super class initializer that does not accept kwargs

Describe the bug

When the class hierarchy includes a direct parent that splats args but whose own parent (i.e. grandparent of child) does not accept any kwargs, the current implementation for the kwargs strategy will still attempt to pass-through any kwargs not listed as dependencies of the parent to the grandparent, resulting in an ArgumentError.

To Reproduce

The test I have added in #81 will fail without the corresponding update to the implementation.

Expected behavior

We should still be able to use the default kwargs strategy for dependency injection even with two layers of dependency injection in the hierarchy and a super class that does not itself accept kwargs. (This may or may not be a valid expectation, but I could not find any documentation to contradict it).

My environment

  • Affects my production application: NO, but (for reasons not worth elaborating on here) is blocking upgrade of prod system to ruby 3
  • Ruby version: 3.1.1
  • OS: macOS

v0.5.0 breaks isolation tests with minitest mocks

class Foobar
  include Inject[foo: 'bar']

  def do_something
    foo.do_something
    # ....
  end
end

# would be tested like this

class FoobarTest < Minitest::Test
  def test_it_calls_do_something_of_foo
    mock = Minitest::Mock.new
    mock.expect :do_something
    Foobar.new(foo: mock).do_something
    assert_mocked mock
  end
end

This was working fine before 0.5.0. Now, it gets the error unmocked method :nil?, expected one of [:do_something] due to 193ed48#diff-f6dd1c9acc3de0d2ccbed1741aa38257, thus rendering mocking non straightforward

Injecting in ActiveJob no longer works

I think #48 broke the ability to use AutoInject in ActiveJob classes.

We have a Job that looks like this:

class MessageAutoDeliverJob < ApplicationJob
  include Channels::Import[:account_channel]

  def perform(message)
    account_channel.new(account: message.conversation.account).message(message: message)
  end
end

The Channels container has registered :account_channel as simply AccountChannel.

When I upgraded the AutoInject gem from 0.4.6 to 0.6.0, I get an error in my specs:

     ActiveJob::SerializationError:
       Unsupported argument type: Class

I tossed a debugger in the enqueue process, and in 0.4.8 it attempts to serialize the @arguments, which looks like this:

=> [#<Message:0x000055dd19eddd88
  id: 946066008,
  body: "Chuck Norris can instantiate an abstract class.">]

In 0.6.0, however, now @arguments includes the injected AccountChannel:

[#<Message:0x0000564c8adda108
  id: 946066008,
  body: "When Chuck Norris gives a method an argument, the method loses.">,
 {:account_channel=>AccountChannel}]

If I'm understanding it right, I seems #48 changed the initializer from removing the keys it knows about from the kwargs passed to the inheriting class, to instead just passing everything through if the class's #initialize function splats its args?

One of my prime use-cases for dry-container/auto_inject was to get around the brain-dead way ActiveJob handles initialization, because it can't differentiate between kwargs passed to the initializer for DI, and params passed to the #perform method to do the work. It was really nice that Dry::AutoInject allowed us to do that without having to jump through a bunch of hoops.

#48 mentioned possible breakage in Rails Controllers, could something like that be adapted to work with ActiveJob?

Errors with multiple classes in hierarchy with injectors from different containers

So this doesn't work as you'd expect:

container_one = {"one" => "hi"}
container_two = {"two" => "hi"}

InjectOne = Dry::AutoInject(container_one).kwargs
InjectTwo = Dry::AutoInject(container_two).kwargs

class One
  include InjectOne["one"]
end

class Two < One
  include InjectTwo["two"]
end

Two.new
# => #<Two:0x007fa667cfd950 @one=nil, @two="hi">

You'd think that @one should also be set to "hi" here, courtesy of the One.new method generated by include InjectOne["one"]

However, the issue is that .new, as generated by Strategies::Kwargs#define_new, accesses a container class accessor, which in Two's case is container_two, so when the .new method on One is run, "one" is no longer available, since the container has been changed when Two's injector was included.

Would be nice if we could somehow keep the reference to the original container around for the .new in each of the classes to use.

Ability to replace container after initialization

include Import construction requires dry-auto_inject injector to be present on load time.

But dependency might be set after application is loaded, and before it start the work.

Good example, when I use include Import in a gem, and then, I load gem first, and define container after my main application is loaded.

Currently it's impossible, because include Import injects container to every class on load time, not while new instance is creating.

Also, In integration tests it'd be cool to replace container.

Overall, it'd be better to have lazy load for dependencies from a container.

Make kwargs injection strategy the default

I'd like to help dry-auto_inject be as usable as possible for people, and I think making the kwargs injection strategy the default would help a lot for this.

Positional args are a bit magical and complex, and it the manual replacement of specific dependencies feels really awkward (e.g. MyThing.new(nil, nil, my_dep)). Keyword arguments make this feel a lot more natural (MyThing.new(my_dep: dep)) and will make for more flexible objects in general.

I don't think we should rely on each user coming this same conclusion and then having to make the decision themselves to switch strategies; I think kwargs should be the default, and users can then switch away from this in cases where they have compelling reasons.

This is a simple change to make, and it feels like it would nice to include in the upcoming release, given we have a lot of other nice improvements to share at the same time. What do you think?

Allow aliasing of registered classes using AutoInject

I have two namespaces (let's say bill and bob), both of which have a service named service registered in the container. If I want to use Registry::AutoInject["bill.service", "bob.service"] I receive the error Dry::AutoInject::DuplicateDependencyError: name +service+ is already used.

If there are multiple dependencies using the same name, can we not prefix them with the namespace name (bob_service and bill_service) when injecting them into a class?

Interactions with dry-initializer

I was trying to implement this but it feels like it doesn't play that nice with other constructors or initializers. Is there more documentation on how this is supposed to function?

Error when a parent class recieves arbitrary number of arguments and a parent of the parent is not

It's better to show on modules actually:

module Shiny
  def initialize(*)
    super
    @foo = 1
  end
end

Inject = Dry::AutoInject(one: 1)

class Foo
  include Shiny
  include Inject[:one]
end

Foo.new

__END__
[8] pry(main)> wtf?
Exception: ArgumentError: wrong number of arguments (given 1, expected 0)
--
0: (pry):3:in `initialize'
1: (pry):3:in `initialize'
2: /Users/gordon/dev/dry-auto_inject/lib/dry/auto_inject/injection.rb:123:in `initialize'

@timriley do you think the case is valid? I think about removing all injected arguments prior to call super method as a default behavior, what do you think?

Oh, and one more issue. Currently .new accepts arbitrary number of arguments but silently ignores superfluous.

Can't include in a class with already defined constructor

Maybe it's an anti-pattern, but I'd like my classes being usable without any container or injector being ready. It used to work to include the injector in an existing class like so:

class Foo
  attr_reader :foo
  def initialize(foo)
    @foo = foo
  end
end

Foo.new("local foo").foo # => "local foo"

container = { foo: "container foo"}
injector = Dry::AutoInject(container)
Foo.include(injector[:foo])

Foo.new.foo  # => "container foo"

But now it fails on include with:

# ~> NoMethodError
# ~> undefined method `parameters' for nil:NilClass

Seems like Dry::AutoInject::super_method returns nil if the method (#initialize in this case) is defined, and this is not checked for.

I'm not sure my use case is very strong, but I like seeing the use of AutoInject as a configuration detail.

Kwargs strategy doesn't know how new delegation syntax can be used

Describe the bug

Here dry-auto_inject assumes if a signature has ... then it's a pass-through constructor. However, it's not the case, ruby 2.7's syntax uses ... for delegation and this means arguments can be forwarded to other methods rather than a superclass.

To Reproduce

This spec is failing but it shouldn't:

  fit "supports argument delegation" do
    base_klass = Class.new do
      def initialize(...)
        delegated(...)
      end

      def delegated(one:)
        @one = one
      end
    end

    klass = Class.new(base_klass) do
      include Test::AutoInject[:one]

      def initialize(*)
        super
      end
      ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
    end

    expect(klass.new).to have_attributes(one: "dep 1")
  end

My environment

  • Affects my production application: NOT MINE BUT SOMEONE'S
  • Ruby version: 2.7, 3.0, 3.1
  • OS: N/A

Release dry-auto_inject 0.x version with support for ruby 3.2.1

This commit 5605781 fixes dry-auto_inject for ruby 3.2.1 It was released as 1.0.1 version. It would be nice to release 0.x version with the same fix so it works with ruby 3.2.1 too. I have a project which can't update dry-auto_inject easily to 1.0.1 (karafka 1.x blocks updating it) and it would help to have 0.x having this fix.

Currently I have to monkey patch PASS_THROUGH array.

Ruby 3.0.3 kwargs error

Describe the bug

If I use hanami-controller 1.3.3 with dry-aut_inject 0.7(8 and 9) with ruby 3.0.0

module Controllers
  module Graphql
    class Endpoint
      include Hanami::Action
      include Import[:service]

      def call(params)
        self.format = :json
        query = params.get(:query)
        graphql_response = service.execute(query)
        status 200, graphql_response.to_json
      end
    end
  end
end

I get following error:

Failure/Error: response = subject.call(**params)

ArgumentError:
 wrong number of arguments (given 1, expected 0)
# /usr/local/bundle/gems/dry-auto_inject-0.9.0/lib/dry/auto_inject/strategies/kwargs.rb:48:in `block (2 levels) in define_initialize_with_keywords'
# /usr/local/bundle/gems/hanami-controller-1.3.3/lib/hanami/action/rack.rb:179:in `initialize'
# /usr/local/bundle/gems/hanami-controller-1.3.3/lib/hanami/action/mime.rb:214:in `initialize'
# /usr/local/bundle/gems/dry-auto_inject-0.9.0/lib/dry/auto_inject/strategies/kwargs.rb:22:in `new'
# /usr/local/bundle/gems/dry-auto_inject-0.9.0/lib/dry/auto_inject/strategies/kwargs.rb:22:in `block (2 levels) in define_new'
# ./spec/controllers/graphql/endpoint_spec.rb:18:in `block (3 levels) in <top (required)>

To Reproduce

Use ruby >= 3.0.3 hanami-controller 1.3.3 with dry-aut_inject 0.7(8 and 9) and import a dependency with default strategy into a Hanami::Action

Expected behavior

The Hanami Action should be instantiated properly.

My environment

ruby:3.0.3-slim-buster

rails 7.1 kwargs strategy error

Describe the bug

After upgrade from rails 7.0.8 to 7.1, the Inject will raise error ArgumentError (wrong number of arguments (given 1, expected 0)).

class TestController < ActionController::API
  include Inject[
    create_service: 'admin_services_create_service',
    update_service: 'admin_services_update_service'
  ]

  def create
    create_service.call(**params)
  end
end

After debugging, at this code block

        def define_initialize(klass)
          super_parameters = MethodParameters.of(klass, :initialize).each do |ps|
            # Look upwards past `def foo(*)` and `def foo(...)` methods
            # until we get an explicit list of parameters
            break ps unless ps.pass_through?
          end

          if super_parameters.splat? || super_parameters.sequential_arguments?
            define_initialize_with_splat(super_parameters)
          else
            define_initialize_with_keywords(super_parameters)
          end

          self
        end

For rails 7.0.8's controller, the super_parameters is not splat or sequential_arguments, but rails 7.1 will be.

I am still not understand what the problem is. I will try to debug and find out problem.

To Reproduce

Use the code above using rails 7.1

Expected behavior

Can inject the service

My environment

  • Affects my production application: YES
  • Ruby version: 3.2.2
  • OS: macos 13.4
  • Rails version: 7.1

Injecting 2 containers causes ArgumentError

For the following code:

class Foo
  def initialize(param)
  end
end

class Bar < Foo
  include AutoInject_1[:method_1]
  include AutoInject_2[:method_2]
end

Bar.new('test')

I get:

ArgumentError:
       wrong number of arguments (given 2, expected 1)

It's because only one dependencies parameter is removed in the initialize method, so the base class is initialized by super('test', method_1: ...) instead of super('test')

My environment

  • Affects my production application: NO
  • Ruby version: 3.0.3

dry-auto_inject needs new docs

We have a bunch of nice features that are completely undocumented :(

TODO

  • document how to create a custom injector with options no need for this for now (after all)
  • document kwargs strategy
  • document *args strategy
  • point to dry-system

Respect the container's `namespace_separator` when making local names for dependencies

Right now we're presuming the namespace separator is a ".", but since this is configurable on dry-container, we should probably respect different separators.

The trick will be to work out an approach to this that still allows auto_inject to be "container agnostic" โ€“ ideally we don't do anything that requires dry-container to be used at all times.

[Security] Workflow sync_configs.yml is using vulnerable action actions/checkout

The workflow sync_configs.yml is referencing action actions/checkout using references v1. However this reference is missing the commit a6747255bd19d7a757dbdda8c654a9f84db19839 which may contain fix to the some vulnerability.
The vulnerability fix that is missing by actions version could be related to:
(1) CVE fix
(2) upgrade of vulnerable dependency
(3) fix to secret leak and others.
Please consider to update the reference to the action.

New DI strategies

I've played with Dry::AutoInject in Rails. But as you know, one of biggest pain points in Rails is zero control over controllers initialization which makes Dry::AutoInject unusable here. So I started to play with other DI strategies last night. And this is the result...

I've created three additional strategies:

  1. Dry::KeyInject constructor DI using keyword arguments
  2. Dry::SetterInject setter DI; allows to set visibility of readers
  3. Dry::GetterInject not real DI (maybe container injection is the right term?), adding only readers to container settings which can be stubbed when needed; allows to set visibility of readers

The code lives as gist for now here: https://gist.github.com/wojtha/b9730d108625e04a0642

Example of using Dry::GetterInject in Rails controllers and using Rails.configuration as DI container: https://gist.github.com/wojtha/322ddfe6323b647e4fc3

@solnic what do you think? should I start PR or a new gem?

Wrong Number of Arguments When Resolving from Container

Guys,

This is probably a rookie error, but I am trying to implement dry-container with dry-autoinject as per http://icelab.com.au/articles/better-code-with-an-inversion-of-control-container/.

Here's my container:

require "dry-container"
require "dry-auto_inject"
require "easy_json_matcher/node"
require "easy_json_matcher/array_generator"
require "easy_json_matcher/attribute_generator"
require "easy_json_matcher/schema_library"


module EasyJSONMatcher
  class Container
    extend Dry::Container::Mixin
  end

  Container.register "node", -> { Node }
  Container.register "array_generator", -> { ArrayGenerator }
  Container.register "attribute_generator", -> { AttributeGenerator }
  Container.register "schema_library", -> { SchemaLibrary }

  AutoInject = Dry::AutoInject(Container)
end

and here's the injection:

module EasyJSONMatcher
  class NodeGenerator
    include AutoInject["node", "attribute_generator", "array_generator", "schema_library"]
    include AttributeTypeMethods

...which looks right to me (naturally), however when I try to create an instance of the NodeGenerator class by calling #new I get the following error:

ArgumentError: wrong number of arguments (given 4, expected 0)

...don't really know where to start with this. Any input would be appreciated!

dry-auto_inject 0.4.6 can lose values imported into both base and derived classes

We have a project with a complex class hierarchy that uses a dry-auto_inject importer in a base class, and also uses it in a derived class. If the base class (or anything else in the class hierarchy) has a non-default initialize method, and both the base and derived class try to import the same names, the imported value will get set to nil.

class Base
  include Import[:name]

  def initialize(*args)
    super
  end
end

class Derived < Base
  include Import[:name]
end

puts Derived.new.name

https://gist.github.com/dmaze/1dff0e3db045157b5fab9dd90437f2b9 is a more complete reproduction.

This was not a problem in dry-auto_inject 0.4.5; we hit it on an upgrade. It is a very reasonable workaround to just remove the duplicate import from the derived class.

If I'm reading the kwargs strategy code correctly, the generated .new fills in keyword parameters from the container, then that gets passed to #initialize. At https://github.com/dry-rb/dry-auto_inject/blob/master/lib/dry/auto_inject/strategies/kwargs.rb#L63 any kwarg that's consumed by this class gets stripped from the parameter list before getting passed on to the base class, so when Base#initialize finally gets run the parameter that was injected in the derived class now isn't in the parameters and the instance variable gets set to nil. In commit d330299 the order of "set the injected variables" and "call super" got swapped, so before that commit the base class would set the variable to nil and then the derived class would set it to the correct value.

undefined method `is_a?' for #<Dry::AutoInject::Builder:0x00007f52d26c51e8>

Describe the bug

When I use Zeitwerk::Loader.eager_load_all in my rake task I get this error

NoMethodError: undefined method `is_a?' for #<Dry::AutoInject::Builder:0x00007f52d26c51e8>                                                    
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/dry-auto_inject-0.8.0/lib/dry/auto_inject/builder.rb:35:in `method_missing'                        
/root/hexlet/vendor/bundle/ruby/3.1.0/bundler/gems/rails-6f0700865cae/railties/lib/rails/application/finisher.rb:34:in `block (2 levels) in <m
odule:Finisher>'                                                                                                                              
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader/callbacks.rb:90:in `block in run_on_load_callbacks'             
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader/callbacks.rb:90:in `each'                                       
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader/callbacks.rb:90:in `run_on_load_callbacks'                      
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader/callbacks.rb:23:in `on_file_autoloaded'                         
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/kernel.rb:28:in `require'                                              
/root/hexlet/app/jobs/update_project_from_repository_job.rb:4:in `<class:UpdateProjectFromRepositoryJob>'                                     
/root/hexlet/app/jobs/update_project_from_repository_job.rb:3:in `<top (required)>'                                                           
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/kernel.rb:27:in `require'                                              
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/kernel.rb:27:in `require'                                              
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader/helpers.rb:95:in `const_get'                                    
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader/helpers.rb:95:in `cget'                                         
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader.rb:231:in `block (2 levels) in eager_load'                      
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader/helpers.rb:26:in `block in ls'                                  
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader/helpers.rb:18:in `each_child'                                   
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader/helpers.rb:18:in `ls'                                           
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader.rb:226:in `block in eager_load'                                 
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader.rb:211:in `synchronize'                                         
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader.rb:211:in `eager_load'                                          
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader.rb:311:in `each'                                                
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader.rb:311:in `eager_load_all'                                      
/root/hexlet/lib/tasks/app.rake:9:in `block (3 levels) in <top (required)>'                                                                   
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute'                                             
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `each'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `execute'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/sentry-ruby-core-4.8.3/lib/sentry/rake.rb:26:in `execute'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader.rb:211:in `eager_load'                                          
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader.rb:311:in `each'                                                
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/zeitwerk-2.5.3/lib/zeitwerk/loader.rb:311:in `eager_load_all'                                      
/root/hexlet/lib/tasks/app.rake:9:in `block (3 levels) in <top (required)>'                                                                   
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute'                                             
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `each'                                                         
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `execute'                                                      
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/sentry-ruby-core-4.8.3/lib/sentry/rake.rb:26:in `execute'                                          
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:219:in `block in invoke_with_call_chain'                              
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize'                                                  
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `invoke_with_call_chain'                                       
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/task.rb:188:in `invoke'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:160:in `invoke_task'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `each'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block in top_level'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:125:in `run_with_threads'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:110:in `top_level'
/root/hexlet/vendor/bundle/ruby/3.1.0/bundler/gems/rails-6f0700865cae/railties/lib/rails/commands/rake/rake_command.rb:24:in `block (2 levels) in perform'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/application.rb:186:in `standard_exception_handling'
/root/hexlet/vendor/bundle/ruby/3.1.0/bundler/gems/rails-6f0700865cae/railties/lib/rails/commands/rake/rake_command.rb:24:in `block in perform'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib/rake/rake_module.rb:59:in `with_application'
/root/hexlet/vendor/bundle/ruby/3.1.0/bundler/gems/rails-6f0700865cae/railties/lib/rails/commands/rake/rake_command.rb:18:in `perform'
/root/hexlet/vendor/bundle/ruby/3.1.0/bundler/gems/rails-6f0700865cae/railties/lib/rails/command.rb:51:in `invoke'
/root/hexlet/vendor/bundle/ruby/3.1.0/bundler/gems/rails-6f0700865cae/railties/lib/rails/commands.rb:18:in `<top (required)>'
/root/hexlet/bin/rails:5:in `require'
/root/hexlet/bin/rails:5:in `<top (required)>'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/spring-4.0.0/lib/spring/client/rails.rb:30:in `load'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/spring-4.0.0/lib/spring/client/rails.rb:30:in `call'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/spring-4.0.0/lib/spring/client/command.rb:7:in `call'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/spring-4.0.0/lib/spring/client.rb:30:in `run'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/spring-4.0.0/bin/spring:49:in `<top (required)>'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/spring-4.0.0/lib/spring/binstub.rb:11:in `load'
/root/hexlet/vendor/bundle/ruby/3.1.0/gems/spring-4.0.0/lib/spring/binstub.rb:11:in `<top (required)>'
<internal:/usr/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
<internal:/usr/local/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
/root/hexlet/bin/spring:10:in `block in <top (required)>'
<internal:kernel>:90:in `tap'
/root/hexlet/bin/spring:7:in `<top (required)>'
bin/rails:2:in `load'
bin/rails:2:in `<main>'

To Reproduce

namespace :app do
   task my_test_task: :environment do
      Zeitwerk::Loader.eager_load_all
   end
end

Expected behavior

No error appears.

I find same error in other product dry-rb/dry-matcher#31 and this is solution dry-rb/dry-matcher#32

My environment

  • Affects my production application: YES/NO
  • Ruby version: 3.1
  • Rails version: 7.0.1
  • OS: Ubuntu

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.